diff --git a/.circleci/config.yml b/.circleci/config.yml index 83fde80ad18..c3deab6ad19 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -130,6 +130,9 @@ jobs: winpost-test: type: string default: "0" + deadline-test: + type: string + default: "0" test-suite-name: type: string default: unit @@ -163,6 +166,7 @@ jobs: name: go test environment: LOTUS_TEST_WINDOW_POST: << parameters.winpost-test >> + LOTUS_TEST_DEADLINE_TOGGLING: << parameters.deadline-test >> SKIP_CONFORMANCE: "1" command: | mkdir -p /tmp/test-reports/<< parameters.test-suite-name >> @@ -204,6 +208,8 @@ jobs: <<: *test test-window-post-dispute: <<: *test + test-deadline-toggling: + <<: *test test-terminate: <<: *test test-conformance: @@ -278,11 +284,41 @@ jobs: - install-deps - prepare - run: make calibnet - - run: mkdir linux-calibnet && mv lotus lotus-miner lotus-worker linux-calibnet + - run: mkdir linux-calibrationnet && mv lotus lotus-miner lotus-worker linux-calibrationnet + - persist_to_workspace: + root: "." + paths: + - linux-calibrationnet + build-ntwk-butterfly: + description: | + Compile lotus binaries for the butterfly network + parameters: + <<: *test-params + executor: << parameters.executor >> + steps: + - install-deps + - prepare + - run: make butterflynet + - run: mkdir linux-butterflynet && mv lotus lotus-miner lotus-worker linux-butterflynet - persist_to_workspace: root: "." paths: - - linux-calibnet + - linux-butterflynet + build-ntwk-nerpa: + description: | + Compile lotus binaries for the nerpa network + parameters: + <<: *test-params + executor: << parameters.executor >> + steps: + - install-deps + - prepare + - run: make nerpanet + - run: mkdir linux-nerpanet && mv lotus lotus-miner lotus-worker linux-nerpanet + - persist_to_workspace: + root: "." + paths: + - linux-nerpanet build-lotus-soup: description: | Compile `lotus-soup` Testground test plan @@ -358,6 +394,15 @@ jobs: command: | curl --location https://github.com/stedolan/jq/releases/download/jq-1.6/jq-osx-amd64 --output /usr/local/bin/jq chmod +x /usr/local/bin/jq + - run: + name: Install hwloc + command: | + mkdir ~/hwloc + curl --location https://download.open-mpi.org/release/hwloc/v2.4/hwloc-2.4.1.tar.gz --output ~/hwloc/hwloc-2.4.1.tar.gz + cd ~/hwloc + tar -xvzpf hwloc-2.4.1.tar.gz + cd hwloc-2.4.1 + ./configure && make && sudo make install - restore_cache: name: restore cargo cache key: v3-go-deps-{{ arch }}-{{ checksum "~/go/src/github.com/filecoin-project/lotus/go.sum" }} @@ -391,7 +436,7 @@ jobs: - run: command: "! go fmt ./... 2>&1 | read" - cbor-gen-check: + gen-check: executor: golang steps: - install-deps @@ -399,7 +444,10 @@ jobs: - run: make deps - run: go install golang.org/x/tools/cmd/goimports - run: go install github.com/hannahhoward/cbor-gen-for - - run: go generate ./... + - run: make gen + - run: git --no-pager diff + - run: git --no-pager diff --quiet + - run: make docsgen-cli - run: git --no-pager diff - run: git --no-pager diff --quiet @@ -408,6 +456,7 @@ jobs: steps: - install-deps - prepare + - run: go install golang.org/x/tools/cmd/goimports - run: zcat build/openrpc/full.json.gz | jq > ../pre-openrpc-full - run: zcat build/openrpc/miner.json.gz | jq > ../pre-openrpc-miner - run: zcat build/openrpc/worker.json.gz | jq > ../pre-openrpc-worker @@ -598,7 +647,7 @@ jobs: docker push $<>/<>:${tag} done - publish-packer: + publish-packer-mainnet: description: build and push AWS IAM and DigitalOcean droplet. executor: name: packer/default @@ -610,9 +659,42 @@ jobs: - packer/build: template: tools/packer/lotus.pkr.hcl args: "-var ci_workspace_bins=./linux -var lotus_network=mainnet -var git_tag=$CIRCLE_TAG" + publish-packer-calibrationnet: + description: build and push AWS IAM and DigitalOcean droplet. + executor: + name: packer/default + packer-version: 1.6.6 + steps: + - checkout + - attach_workspace: + at: "." - packer/build: template: tools/packer/lotus.pkr.hcl - args: "-var ci_workspace_bins=./linux-calibnet -var lotus_network=calibrationnet -var git_tag=$CIRCLE_TAG" + args: "-var ci_workspace_bins=./linux-calibrationnet -var lotus_network=calibrationnet -var git_tag=$CIRCLE_TAG" + publish-packer-butterflynet: + description: build and push AWS IAM and DigitalOcean droplet. + executor: + name: packer/default + packer-version: 1.6.6 + steps: + - checkout + - attach_workspace: + at: "." + - packer/build: + template: tools/packer/lotus.pkr.hcl + args: "-var ci_workspace_bins=./linux-butterflynet -var lotus_network=butterflynet -var git_tag=$CIRCLE_TAG" + publish-packer-nerpanet: + description: build and push AWS IAM and DigitalOcean droplet. + executor: + name: packer/default + packer-version: 1.6.6 + steps: + - checkout + - attach_workspace: + at: "." + - packer/build: + template: tools/packer/lotus.pkr.hcl + args: "-var ci_workspace_bins=./linux-nerpanet -var lotus_network=nerpanet -var git_tag=$CIRCLE_TAG" workflows: version: 2.1 @@ -622,7 +704,7 @@ workflows: concurrency: "16" # expend all docker 2xlarge CPUs. - mod-tidy-check - gofmt - - cbor-gen-check + - gen-check - docs-check - test: codecov-upload: true @@ -658,6 +740,11 @@ workflows: go-test-flags: "-run=TestTerminate" winpost-test: "1" test-suite-name: terminate + - test-deadline-toggling: + codecov-upload: true + go-test-flags: "-run=TestDeadlineToggling" + deadline-test: "1" + test-suite-name: deadline-toggling - test-short: go-test-flags: "--timeout 10m --short" test-suite-name: short @@ -673,8 +760,6 @@ workflows: test-suite-name: conformance-bleeding-edge packages: "./conformance" vectors-branch: master - - build-ntwk-calibration - - build-lotus-soup - trigger-testplans: filters: branches: @@ -688,6 +773,28 @@ workflows: tags: only: - /^v\d+\.\d+\.\d+$/ + - build-ntwk-calibration: + requires: + - test-short + filters: + tags: + only: + - /^v\d+\.\d+\.\d+$/ + - build-ntwk-butterfly: + requires: + - test-short + filters: + tags: + only: + - /^v\d+\.\d+\.\d+$/ + - build-ntwk-nerpa: + requires: + - test-short + filters: + tags: + only: + - /^v\d+\.\d+\.\d+$/ + - build-lotus-soup - build-macos: requires: - test-short @@ -714,9 +821,18 @@ workflows: path: . repo: lotus-dev tag: '${CIRCLE_SHA1:0:8}' - - publish-packer: + - publish-packer-mainnet: requires: - build-all + filters: + branches: + ignore: + - /.*/ + tags: + only: + - /^v\d+\.\d+\.\d+$/ + - publish-packer-calibrationnet: + requires: - build-ntwk-calibration filters: branches: @@ -725,4 +841,23 @@ workflows: tags: only: - /^v\d+\.\d+\.\d+$/ - + - publish-packer-butterflynet: + requires: + - build-ntwk-butterfly + filters: + branches: + ignore: + - /.*/ + tags: + only: + - /^v\d+\.\d+\.\d+$/ + - publish-packer-nerpanet: + requires: + - build-ntwk-nerpa + filters: + branches: + ignore: + - /.*/ + tags: + only: + - /^v\d+\.\d+\.\d+$/ diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 6d717b44d69..9da543c975f 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -8,9 +8,9 @@ ## the PR before merging. ### Global owners. -* @magik6k @whyrusleeping @Kubuxu +* @magik6k @arajasek ### Conformance testing. -conformance/ @raulk -extern/test-vectors @raulk -cmd/tvx @raulk \ No newline at end of file +conformance/ @ZenGround0 +extern/test-vectors @ZenGround0 +cmd/tvx @ZenGround0 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 00000000000..2bf602a851d --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,65 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ master ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ master ] + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + language: [ 'go' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] + # Learn more: + # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + # ℹī¸ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏ī¸ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 diff --git a/.github/workflows/testground-on-push.yml b/.github/workflows/testground-on-push.yml new file mode 100644 index 00000000000..9d58db9626d --- /dev/null +++ b/.github/workflows/testground-on-push.yml @@ -0,0 +1,29 @@ +--- +name: Testground PR Checker + +on: [push] + +jobs: + testground: + runs-on: ubuntu-latest + name: ${{ matrix.composition_file }} + strategy: + matrix: + include: + - backend_addr: ci.testground.ipfs.team + backend_proto: https + plan_directory: testplans/lotus-soup + composition_file: testplans/lotus-soup/_compositions/baseline-k8s-3-1.toml + - backend_addr: ci.testground.ipfs.team + backend_proto: https + plan_directory: testplans/lotus-soup + composition_file: testplans/lotus-soup/_compositions/paych-stress-k8s.toml + steps: + - uses: actions/checkout@v2 + - name: testground run + uses: coryschwartz/testground-github-action@v1.0 + with: + backend_addr: ${{ matrix.backend_addr }} + backend_proto: ${{ matrix.backend_proto }} + plan_directory: ${{ matrix.plan_directory }} + composition_file: ${{ matrix.composition_file }} diff --git a/.golangci.yml b/.golangci.yml index 8bdba64f0b6..87db745e427 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -16,6 +16,12 @@ linters: - deadcode - scopelint +# We don't want to skip builtin/ +skip-dirs-use-default: false +skip-dirs: + - vendor$ + - testdata$ + - examples$ issues: exclude: diff --git a/CHANGELOG.md b/CHANGELOG.md index 854166c4cfc..55534ff0514 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,32 @@ # Lotus changelog +# 1.8.0 / 2021-04-27 + +This is a mandatory release of Lotus that upgrades the network to version 12, which introduces various performance improvements to the cron processing of the power actor. The network will upgrade at height 712320, which is 2021-04-29T06:00:00Z. + +## Changes + +- v4 specs-actors integration, nv12 migration (https://github.com/filecoin-project/lotus/pull/6116) + +# 1.6.0 / 2021-04-05 + +This is a mandatory release of Lotus that upgrades the network to version 11, which implements [FIP-0014](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0014.md). The network will upgrade at height 665280, which is 2021-04-12T22:00:00Z. + +## v1 sector extension CLI + +This release also expands the `lotus-miner sectors extend` CLI, with a new option that automatically extends all extensible v1 sectors. The option can be run using `lotus-miner sectors extend --v1-sectors`. + +- The `tolerance` flag can be passed to indicate what durations aren't "worth" extending. It defaults to one week, which means that sectors whose current lifetime's are within one week of the maximum possible lifetime will not be extended. + +- The `expiration-cutoff` flag can be passed to skip sectors whose expiration is past a certain point from the current head. It defaults to infinity (no cutoff), but if, say, 28800 was specified, then only sectors expiring in the next 10 days would be extended (2880 epochs in 1 day). + +## Changes + +- Util for miners to extend all v1 sectors (https://github.com/filecoin-project/lotus/pull/5924) +- Upgrade the butterfly network (https://github.com/filecoin-project/lotus/pull/5929) +- Introduce the v11 network upgrade (https://github.com/filecoin-project/lotus/pull/5904) +- Debug mode: Make upgrade heights controllable by an envvar (https://github.com/filecoin-project/lotus/pull/5919) + # 1.5.3 / 2021-03-24 This is a patch release of Lotus that introduces small fixes to the Storage FSM. diff --git a/Makefile b/Makefile index 16269e13393..67d26a71b74 100644 --- a/Makefile +++ b/Makefile @@ -233,6 +233,13 @@ testground: .PHONY: testground BINS+=testground + +tvx: + rm -f tvx + go build -o tvx ./cmd/tvx +.PHONY: tvx +BINS+=tvx + install-chainwatch: lotus-chainwatch install -C ./lotus-chainwatch /usr/local/bin/lotus-chainwatch @@ -318,48 +325,60 @@ dist-clean: git submodule deinit --all -f .PHONY: dist-clean -type-gen: +type-gen: api-gen go run ./gen/main.go - go generate ./... + go generate -x ./... + goimports -w api/ -method-gen: +method-gen: api-gen (cd ./lotuspond/front/src/chain && go run ./methodgen.go) +actors-gen: + go run ./chain/actors/agen + go fmt ./... + api-gen: - go run ./gen/api > api/apistruct/struct.go - goimports -w api/apistruct - goimports -w api/apistruct + go run ./gen/api + goimports -w api + goimports -w api .PHONY: api-gen docsgen: docsgen-md docsgen-openrpc -docsgen-md-bin: +docsgen-md-bin: api-gen actors-gen go build $(GOFLAGS) -o docgen-md ./api/docgen/cmd -docsgen-openrpc-bin: +docsgen-openrpc-bin: api-gen actors-gen go build $(GOFLAGS) -o docgen-openrpc ./api/docgen-openrpc/cmd docsgen-md: docsgen-md-full docsgen-md-storage docsgen-md-worker docsgen-md-full: docsgen-md-bin - ./docgen-md "api/api_full.go" "FullNode" > documentation/en/api-methods.md + ./docgen-md "api/api_full.go" "FullNode" "api" "./api" > documentation/en/api-v1-unstable-methods.md + ./docgen-md "api/v0api/full.go" "FullNode" "v0api" "./api/v0api" > documentation/en/api-v0-methods.md docsgen-md-storage: docsgen-md-bin - ./docgen-md "api/api_storage.go" "StorageMiner" > documentation/en/api-methods-miner.md + ./docgen-md "api/api_storage.go" "StorageMiner" "api" "./api" > documentation/en/api-v0-methods-miner.md docsgen-md-worker: docsgen-md-bin - ./docgen-md "api/api_worker.go" "Worker" > documentation/en/api-methods-worker.md + ./docgen-md "api/api_worker.go" "Worker" "api" "./api" > documentation/en/api-v0-methods-worker.md docsgen-openrpc: docsgen-openrpc-full docsgen-openrpc-storage docsgen-openrpc-worker docsgen-openrpc-full: docsgen-openrpc-bin - ./docgen-openrpc "api/api_full.go" "FullNode" -gzip > build/openrpc/full.json.gz + ./docgen-openrpc "api/api_full.go" "FullNode" "api" "./api" -gzip > build/openrpc/full.json.gz docsgen-openrpc-storage: docsgen-openrpc-bin - ./docgen-openrpc "api/api_storage.go" "StorageMiner" -gzip > build/openrpc/miner.json.gz + ./docgen-openrpc "api/api_storage.go" "StorageMiner" "api" "./api" -gzip > build/openrpc/miner.json.gz docsgen-openrpc-worker: docsgen-openrpc-bin - ./docgen-openrpc "api/api_worker.go" "Worker" -gzip > build/openrpc/worker.json.gz + ./docgen-openrpc "api/api_worker.go" "Worker" "api" "./api" -gzip > build/openrpc/worker.json.gz .PHONY: docsgen docsgen-md-bin docsgen-openrpc-bin -gen: type-gen method-gen docsgen api-gen +gen: actors-gen type-gen method-gen docsgen api-gen + @echo ">>> IF YOU'VE MODIFIED THE CLI, REMEMBER TO ALSO MAKE docsgen-cli" .PHONY: gen +# separate from gen because it needs binaries +docsgen-cli: lotus lotus-miner lotus-worker + python ./scripts/generate-lotus-cli.py +.PHONY: docsgen-cli + print-%: @echo $*=$($*) diff --git a/api/README.md b/api/README.md new file mode 100644 index 00000000000..07089d7ae9f --- /dev/null +++ b/api/README.md @@ -0,0 +1,14 @@ +## Lotus API + +This package contains all lotus API definitions. Interfaces defined here are +exposed as JsonRPC 2.0 endpoints by lotus programs. + +### Versions + +| File | Alias File | Interface | Exposed by | Version | HTTP Endpoint | Status | Docs +|------------------|-------------------|----------------|--------------------|---------|---------------|------------------------------|------ +| `api_common.go` | `v0api/latest.go` | `Common` | lotus; lotus-miner | v0 | `/rpc/v0` | Latest, Stable | [Methods](../documentation/en/api-v0-methods.md) +| `api_full.go` | `v1api/latest.go` | `FullNode` | lotus | v1 | `/rpc/v1` | Latest, **Work in progress** | [Methods](../documentation/en/api-v1-unstable-methods.md) +| `api_storage.go` | `v0api/latest.go` | `StorageMiner` | lotus-miner | v0 | `/rpc/v0` | Latest, Stable | [Methods](../documentation/en/api-v0-methods-miner.md) +| `api_worker.go` | `v0api/latest.go` | `Worker` | lotus-worker | v0 | `/rpc/v0` | Latest, Stable | [Methods](../documentation/en/api-v0-methods-worker.md) +| `v0api/full.go` | | `FullNode` | lotus | v0 | `/rpc/v0` | Stable | [Methods](../documentation/en/api-v0-methods.md) diff --git a/api/api_common.go b/api/api_common.go index b1aaa4a82e9..2f27eb95f57 100644 --- a/api/api_common.go +++ b/api/api_common.go @@ -15,6 +15,17 @@ import ( apitypes "github.com/filecoin-project/lotus/api/types" ) +// MODIFYING THE API INTERFACE +// +// When adding / changing methods in this file: +// * Do the change here +// * Adjust implementation in `node/impl/` +// * Run `make gen` - this will: +// * Generate proxy structs +// * Generate mocks +// * Generate markdown docs +// * Generate openrpc blobs + type Common interface { // MethodGroup: Auth diff --git a/api/api_full.go b/api/api_full.go index b66b0e402a6..fed9cece5cd 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -39,6 +39,22 @@ type ChainIO interface { ChainHasObj(context.Context, cid.Cid) (bool, error) } +const LookbackNoLimit = abi.ChainEpoch(-1) + +// MODIFYING THE API INTERFACE +// +// NOTE: This is the V1 (Unstable) API - to add methods to the V0 (Stable) API +// you'll have to add those methods to interfaces in `api/v0api` +// +// When adding / changing methods in this file: +// * Do the change here +// * Adjust implementation in `node/impl/` +// * Run `make gen` - this will: +// * Generate proxy structs +// * Generate mocks +// * Generate markdown docs +// * Generate openrpc blobs + // FullNode API is a low-level interface to the Filecoin network full node type FullNode interface { Common @@ -236,6 +252,13 @@ type FullNode interface { // MpoolBatchPushMessage batch pushes a unsigned message to mempool. MpoolBatchPushMessage(context.Context, []*types.Message, *MessageSendSpec) ([]*types.SignedMessage, error) //perm:sign + // MpoolCheckMessages performs logical checks on a batch of messages + MpoolCheckMessages(context.Context, []*MessagePrototype) ([][]MessageCheckStatus, error) //perm:read + // MpoolCheckPendingMessages performs logical checks for all pending messages from a given address + MpoolCheckPendingMessages(context.Context, address.Address) ([][]MessageCheckStatus, error) //perm:read + // MpoolCheckReplaceMessages performs logical checks on pending messages with replacement + MpoolCheckReplaceMessages(context.Context, []*types.Message) ([][]MessageCheckStatus, error) //perm:read + // 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) //perm:read @@ -340,6 +363,9 @@ type FullNode interface { // which are stuck due to insufficient funds ClientRetrieveTryRestartInsufficientFunds(ctx context.Context, paymentChannel address.Address) error //perm:write + // ClientCancelRetrievalDeal cancels an ongoing retrieval deal based on DealID + ClientCancelRetrievalDeal(ctx context.Context, dealid retrievalmarket.DealID) error //perm:write + // ClientUnimport removes references to the specified file from filestore //ClientUnimport(path string) @@ -427,40 +453,7 @@ type FullNode interface { StateSectorExpiration(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorExpiration, error) //perm:read // StateSectorPartition finds deadline/partition with the specified sector StateSectorPartition(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok types.TipSetKey) (*miner.SectorLocation, error) //perm:read - // StateSearchMsg searches for a message in the chain, and returns its receipt and the tipset where it was executed - // - // NOTE: If a replacing message is found on chain, this method will return - // a MsgLookup for the replacing message - the MsgLookup.Message will be a different - // CID than the one provided in the 'cid' param, MsgLookup.Receipt will contain the - // result of the execution of the replacing message. - // - // If the caller wants to ensure that exactly the requested message was executed, - // they MUST check that MsgLookup.Message is equal to the provided 'cid'. - // Without this check both the requested and original message may appear as - // successfully executed on-chain, which may look like a double-spend. - // - // A replacing message is a message with a different CID, any of Gas values, and - // different signature, but with all other parameters matching (source/destination, - // nonce, params, etc.) - StateSearchMsg(context.Context, cid.Cid) (*MsgLookup, error) //perm:read - // StateSearchMsgLimited looks back up to limit epochs in the chain for a message, and returns its receipt and the tipset where it was executed - // - // NOTE: If a replacing message is found on chain, this method will return - // a MsgLookup for the replacing message - the MsgLookup.Message will be a different - // CID than the one provided in the 'cid' param, MsgLookup.Receipt will contain the - // result of the execution of the replacing message. - // - // If the caller wants to ensure that exactly the requested message was executed, - // they MUST check that MsgLookup.Message is equal to the provided 'cid'. - // Without this check both the requested and original message may appear as - // successfully executed on-chain, which may look like a double-spend. - // - // A replacing message is a message with a different CID, any of Gas values, and - // different signature, but with all other parameters matching (source/destination, - // nonce, params, etc.) - StateSearchMsgLimited(ctx context.Context, msg cid.Cid, limit abi.ChainEpoch) (*MsgLookup, error) //perm:read - // 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. + // StateSearchMsg looks back up to limit epochs in the chain for a message, and returns its receipt and the tipset where it was executed // // NOTE: If a replacing message is found on chain, this method will return // a MsgLookup for the replacing message - the MsgLookup.Message will be a different @@ -468,15 +461,16 @@ type FullNode interface { // result of the execution of the replacing message. // // If the caller wants to ensure that exactly the requested message was executed, - // they MUST check that MsgLookup.Message is equal to the provided 'cid'. - // Without this check both the requested and original message may appear as + // they must check that MsgLookup.Message is equal to the provided 'cid', or set the + // `allowReplaced` parameter to false. Without this check, and with `allowReplaced` + // set to true, both the requested and original message may appear as // successfully executed on-chain, which may look like a double-spend. // // A replacing message is a message with a different CID, any of Gas values, and // different signature, but with all other parameters matching (source/destination, // nonce, params, etc.) - StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64) (*MsgLookup, error) //perm:read - // StateWaitMsgLimited looks back up to limit epochs in the chain for a message. + StateSearchMsg(ctx context.Context, from types.TipSetKey, msg cid.Cid, limit abi.ChainEpoch, allowReplaced bool) (*MsgLookup, error) //perm:read + // StateWaitMsg looks back up to limit epochs in the chain for a message. // If not found, it blocks until the message arrives on chain, and gets to the // indicated confidence depth. // @@ -486,14 +480,15 @@ type FullNode interface { // result of the execution of the replacing message. // // If the caller wants to ensure that exactly the requested message was executed, - // they MUST check that MsgLookup.Message is equal to the provided 'cid'. - // Without this check both the requested and original message may appear as + // they must check that MsgLookup.Message is equal to the provided 'cid', or set the + // `allowReplaced` parameter to false. Without this check, and with `allowReplaced` + // set to true, both the requested and original message may appear as // successfully executed on-chain, which may look like a double-spend. // // A replacing message is a message with a different CID, any of Gas values, and // different signature, but with all other parameters matching (source/destination, // nonce, params, etc.) - StateWaitMsgLimited(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch) (*MsgLookup, error) //perm:read + StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*MsgLookup, error) //perm:read // StateListMiners returns the addresses of every miner that has claimed power in the Power Actor StateListMiners(context.Context, types.TipSetKey) ([]address.Address, error) //perm:read // StateListActors returns the addresses of every actor in the state @@ -513,16 +508,6 @@ type FullNode interface { // StateChangedActors returns all the actors whose states change between the two given state CIDs // TODO: Should this take tipset keys instead? StateChangedActors(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error) //perm:read - // StateGetReceipt returns the message receipt for the given message or for a - // matching gas-repriced replacing message - // - // NOTE: If the requested message was replaced, this method will return the receipt - // for the replacing message - if the caller needs the receipt for exactly the - // requested message, use StateSearchMsg().Receipt, and check that MsgLookup.Message - // is matching the requested CID - // - // DEPRECATED: Use StateSearchMsg, this method won't be supported in v1 API - StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) //perm:read // StateMinerSectorCount returns the number of sectors in a miner's sector set and proving set StateMinerSectorCount(context.Context, address.Address, types.TipSetKey) (MinerSectors, error) //perm:read // StateCompute is a flexible command that applies the given messages on the given tipset. @@ -601,15 +586,16 @@ type FullNode interface { // MsigCreate creates a multisig wallet // It takes the following params: , , //, , - MsigCreate(context.Context, uint64, []address.Address, abi.ChainEpoch, types.BigInt, address.Address, types.BigInt) (cid.Cid, error) //perm:sign + MsigCreate(context.Context, uint64, []address.Address, abi.ChainEpoch, types.BigInt, address.Address, types.BigInt) (*MessagePrototype, error) //perm:sign + // MsigPropose proposes a multisig message // It takes the following params: , , , // , , - MsigPropose(context.Context, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) //perm:sign + MsigPropose(context.Context, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (*MessagePrototype, error) //perm:sign // MsigApprove approves a previously-proposed multisig message by transaction ID // It takes the following params: , - MsigApprove(context.Context, address.Address, uint64, address.Address) (cid.Cid, error) //perm:sign + MsigApprove(context.Context, address.Address, uint64, address.Address) (*MessagePrototype, error) //perm:sign // MsigApproveTxnHash approves a previously-proposed multisig message, specified // using both transaction ID and a hash of the parameters used in the @@ -617,43 +603,49 @@ type FullNode interface { // exactly the transaction you think you are. // It takes the following params: , , , , , // , , - MsigApproveTxnHash(context.Context, address.Address, uint64, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) //perm:sign + MsigApproveTxnHash(context.Context, address.Address, uint64, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (*MessagePrototype, error) //perm:sign // MsigCancel cancels a previously-proposed multisig message // It takes the following params: , , , , // , , - MsigCancel(context.Context, address.Address, uint64, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) //perm:sign + MsigCancel(context.Context, address.Address, uint64, address.Address, types.BigInt, address.Address, uint64, []byte) (*MessagePrototype, error) //perm:sign + // MsigAddPropose proposes adding a signer in the multisig // It takes the following params: , , // , - MsigAddPropose(context.Context, address.Address, address.Address, address.Address, bool) (cid.Cid, error) //perm:sign + MsigAddPropose(context.Context, address.Address, address.Address, address.Address, bool) (*MessagePrototype, error) //perm:sign + // MsigAddApprove approves a previously proposed AddSigner message // It takes the following params: , , , // , , - MsigAddApprove(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, bool) (cid.Cid, error) //perm:sign + MsigAddApprove(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, bool) (*MessagePrototype, error) //perm:sign + // MsigAddCancel cancels a previously proposed AddSigner message // It takes the following params: , , , // , - MsigAddCancel(context.Context, address.Address, address.Address, uint64, address.Address, bool) (cid.Cid, error) //perm:sign + MsigAddCancel(context.Context, address.Address, address.Address, uint64, address.Address, bool) (*MessagePrototype, error) //perm:sign + // MsigSwapPropose proposes swapping 2 signers in the multisig // It takes the following params: , , // , - MsigSwapPropose(context.Context, address.Address, address.Address, address.Address, address.Address) (cid.Cid, error) //perm:sign + MsigSwapPropose(context.Context, address.Address, address.Address, address.Address, address.Address) (*MessagePrototype, error) //perm:sign + // MsigSwapApprove approves a previously proposed SwapSigner // It takes the following params: , , , // , , - MsigSwapApprove(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, address.Address) (cid.Cid, error) //perm:sign + MsigSwapApprove(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, address.Address) (*MessagePrototype, error) //perm:sign + // MsigSwapCancel cancels a previously proposed SwapSigner message // It takes the following params: , , , // , - MsigSwapCancel(context.Context, address.Address, address.Address, uint64, address.Address, address.Address) (cid.Cid, error) //perm:sign + MsigSwapCancel(context.Context, address.Address, address.Address, uint64, address.Address, address.Address) (*MessagePrototype, error) //perm:sign // MsigRemoveSigner proposes the removal of a signer from the multisig. // It accepts the multisig to make the change on, the proposer address to // send the message from, the address to be removed, and a boolean // indicating whether or not the signing threshold should be lowered by one // along with the address removal. - MsigRemoveSigner(ctx context.Context, msig address.Address, proposer address.Address, toRemove address.Address, decrease bool) (cid.Cid, error) //perm:sign + MsigRemoveSigner(ctx context.Context, msig address.Address, proposer address.Address, toRemove address.Address, decrease bool) (*MessagePrototype, error) //perm:sign // MarketAddBalance adds funds to the market actor MarketAddBalance(ctx context.Context, wallet, addr address.Address, amt types.BigInt) (cid.Cid, error) //perm:sign @@ -686,6 +678,11 @@ type FullNode interface { PaychVoucherList(context.Context, address.Address) ([]*paych.SignedVoucher, error) //perm:write PaychVoucherSubmit(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (cid.Cid, error) //perm:sign + // MethodGroup: Node + // These methods are general node management and status commands + + NodeStatus(ctx context.Context, inclChainStatus bool) (NodeStatus, error) //perm:read + // CreateBackup creates node backup onder the specified file name. The // method requires that the lotus daemon is running with the // LOTUS_BACKUP_BASE_PATH environment variable set to some path, and that @@ -725,6 +722,7 @@ type DealInfo struct { ProposalCid cid.Cid State storagemarket.StorageDealStatus Message string // more information about deal state, particularly errors + DealStages *storagemarket.DealStages Provider address.Address DataRef *storagemarket.DataRef @@ -880,7 +878,7 @@ func (o *QueryOffer) Order(client address.Address) RetrievalOrder { Client: client, Miner: o.Miner, - MinerPeer: o.MinerPeer, + MinerPeer: &o.MinerPeer, } } @@ -899,6 +897,8 @@ type RetrievalOrder struct { Root cid.Cid Piece *cid.Cid Size uint64 + + LocalStore *multistore.StoreID // if specified, get data from local store // TODO: support offset Total types.BigInt UnsealPrice types.BigInt @@ -906,7 +906,7 @@ type RetrievalOrder struct { PaymentIntervalIncrease uint64 Client address.Address Miner address.Address - MinerPeer retrievalmarket.RetrievalPeer + MinerPeer *retrievalmarket.RetrievalPeer } type InvocResult struct { @@ -1032,11 +1032,12 @@ type DealCollateralBounds struct { } type CirculatingSupply struct { - FilVested abi.TokenAmount - FilMined abi.TokenAmount - FilBurnt abi.TokenAmount - FilLocked abi.TokenAmount - FilCirculating abi.TokenAmount + FilVested abi.TokenAmount + FilMined abi.TokenAmount + FilBurnt abi.TokenAmount + FilLocked abi.TokenAmount + FilCirculating abi.TokenAmount + FilReserveDisbursed abi.TokenAmount } type MiningBaseInfo struct { diff --git a/api/api_gateway.go b/api/api_gateway.go index b550bcbbc33..130a18c5503 100644 --- a/api/api_gateway.go +++ b/api/api_gateway.go @@ -14,6 +14,20 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) +// MODIFYING THE API INTERFACE +// +// NOTE: This is the V1 (Unstable) API - to add methods to the V0 (Stable) API +// you'll have to add those methods to interfaces in `api/v0api` +// +// When adding / changing methods in this file: +// * Do the change here +// * Adjust implementation in `node/impl/` +// * Run `make gen` - this will: +// * Generate proxy structs +// * Generate mocks +// * Generate markdown docs +// * Generate openrpc blobs + type Gateway interface { ChainHasObj(context.Context, cid.Cid) (bool, error) ChainHead(ctx context.Context) (*types.TipSet, error) @@ -31,7 +45,6 @@ type Gateway interface { 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) @@ -40,8 +53,9 @@ type Gateway interface { 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) (apitypes.NetworkVersion, error) - StateSearchMsg(ctx context.Context, msg cid.Cid) (*MsgLookup, error) StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, 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) + StateSearchMsg(ctx context.Context, from types.TipSetKey, msg cid.Cid, limit abi.ChainEpoch, allowReplaced bool) (*MsgLookup, error) + StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*MsgLookup, error) + WalletBalance(context.Context, address.Address) (types.BigInt, error) } diff --git a/api/api_storage.go b/api/api_storage.go index f6efcd8af3c..1131f45a0fe 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -5,6 +5,8 @@ import ( "context" "time" + "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/google/uuid" "github.com/ipfs/go-cid" "github.com/libp2p/go-libp2p-core/peer" @@ -24,6 +26,17 @@ import ( "github.com/filecoin-project/lotus/extern/sector-storage/storiface" ) +// MODIFYING THE API INTERFACE +// +// When adding / changing methods in this file: +// * Do the change here +// * Adjust implementation in `node/impl/` +// * Run `make gen` - this will: +// * Generate proxy structs +// * Generate mocks +// * Generate markdown docs +// * Generate openrpc blobs + // StorageMiner is a low-level interface to the Filecoin network storage miner node type StorageMiner interface { Common @@ -165,6 +178,8 @@ type StorageMiner interface { CreateBackup(ctx context.Context, fpath string) error //perm:admin CheckProvable(ctx context.Context, pp abi.RegisteredPoStProof, sectors []storage.SectorRef, expensive bool) (map[abi.SectorNumber]string, error) //perm:admin + + ComputeProof(ctx context.Context, ssi []builtin.SectorInfo, rand abi.PoStRandomness) ([]builtin.PoStProof, error) //perm:read } var _ storiface.WorkerReturn = *new(StorageMiner) diff --git a/api/api_test.go b/api/api_test.go index 70d918b5cd3..738e1b06799 100644 --- a/api/api_test.go +++ b/api/api_test.go @@ -113,3 +113,9 @@ func TestReturnTypes(t *testing.T) { t.Run("miner", tst(new(StorageMiner))) t.Run("worker", tst(new(Worker))) } + +func TestPermTags(t *testing.T) { + _ = PermissionedFullAPI(&FullNodeStruct{}) + _ = PermissionedStorMinerAPI(&StorageMinerStruct{}) + _ = PermissionedWorkerAPI(&WorkerStruct{}) +} diff --git a/api/api_worker.go b/api/api_worker.go index 3232de449d6..e834b792cfe 100644 --- a/api/api_worker.go +++ b/api/api_worker.go @@ -14,6 +14,17 @@ import ( "github.com/filecoin-project/specs-storage/storage" ) +// MODIFYING THE API INTERFACE +// +// When adding / changing methods in this file: +// * Do the change here +// * Adjust implementation in `node/impl/` +// * Run `make gen` - this will: +// * Generate proxy structs +// * Generate mocks +// * Generate markdown docs +// * Generate openrpc blobs + type Worker interface { Version(context.Context) (Version, error) //perm:admin diff --git a/api/apistruct/struct_test.go b/api/apistruct/struct_test.go deleted file mode 100644 index 9f5f5836015..00000000000 --- a/api/apistruct/struct_test.go +++ /dev/null @@ -1,9 +0,0 @@ -package apistruct - -import "testing" - -func TestPermTags(t *testing.T) { - _ = PermissionedFullAPI(&FullNodeStruct{}) - _ = PermissionedStorMinerAPI(&StorageMinerStruct{}) - _ = PermissionedWorkerAPI(&WorkerStruct{}) -} diff --git a/api/checkstatuscode_string.go b/api/checkstatuscode_string.go new file mode 100644 index 00000000000..072f7798975 --- /dev/null +++ b/api/checkstatuscode_string.go @@ -0,0 +1,35 @@ +// Code generated by "stringer -type=CheckStatusCode -trimprefix=CheckStatus"; DO NOT EDIT. + +package api + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[CheckStatusMessageSerialize-1] + _ = x[CheckStatusMessageSize-2] + _ = x[CheckStatusMessageValidity-3] + _ = x[CheckStatusMessageMinGas-4] + _ = x[CheckStatusMessageMinBaseFee-5] + _ = x[CheckStatusMessageBaseFee-6] + _ = x[CheckStatusMessageBaseFeeLowerBound-7] + _ = x[CheckStatusMessageBaseFeeUpperBound-8] + _ = x[CheckStatusMessageGetStateNonce-9] + _ = x[CheckStatusMessageNonce-10] + _ = x[CheckStatusMessageGetStateBalance-11] + _ = x[CheckStatusMessageBalance-12] +} + +const _CheckStatusCode_name = "MessageSerializeMessageSizeMessageValidityMessageMinGasMessageMinBaseFeeMessageBaseFeeMessageBaseFeeLowerBoundMessageBaseFeeUpperBoundMessageGetStateNonceMessageNonceMessageGetStateBalanceMessageBalance" + +var _CheckStatusCode_index = [...]uint8{0, 16, 27, 42, 55, 72, 86, 110, 134, 154, 166, 188, 202} + +func (i CheckStatusCode) String() string { + i -= 1 + if i < 0 || i >= CheckStatusCode(len(_CheckStatusCode_index)-1) { + return "CheckStatusCode(" + strconv.FormatInt(int64(i+1), 10) + ")" + } + return _CheckStatusCode_name[_CheckStatusCode_index[i]:_CheckStatusCode_index[i+1]] +} diff --git a/api/client/client.go b/api/client/client.go index 9ffd1707ec5..90fe714bf72 100644 --- a/api/client/client.go +++ b/api/client/client.go @@ -10,13 +10,14 @@ import ( "github.com/filecoin-project/go-jsonrpc" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/api/apistruct" + "github.com/filecoin-project/lotus/api/v0api" + "github.com/filecoin-project/lotus/api/v1api" "github.com/filecoin-project/lotus/lib/rpcenc" ) -// NewCommonRPC creates a new http jsonrpc client. -func NewCommonRPC(ctx context.Context, addr string, requestHeader http.Header) (api.Common, jsonrpc.ClientCloser, error) { - var res apistruct.CommonStruct +// NewCommonRPCV0 creates a new http jsonrpc client. +func NewCommonRPCV0(ctx context.Context, addr string, requestHeader http.Header) (api.Common, jsonrpc.ClientCloser, error) { + var res v0api.CommonStruct closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin", []interface{}{ &res.Internal, @@ -27,9 +28,9 @@ func NewCommonRPC(ctx context.Context, addr string, requestHeader http.Header) ( return &res, closer, err } -// NewFullNodeRPC creates a new http jsonrpc client. -func NewFullNodeRPC(ctx context.Context, addr string, requestHeader http.Header) (api.FullNode, jsonrpc.ClientCloser, error) { - var res apistruct.FullNodeStruct +// NewFullNodeRPCV0 creates a new http jsonrpc client. +func NewFullNodeRPCV0(ctx context.Context, addr string, requestHeader http.Header) (v0api.FullNode, jsonrpc.ClientCloser, error) { + var res v0api.FullNodeStruct closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin", []interface{}{ &res.CommonStruct.Internal, @@ -39,9 +40,21 @@ func NewFullNodeRPC(ctx context.Context, addr string, requestHeader http.Header) return &res, closer, err } -// NewStorageMinerRPC creates a new http jsonrpc client for miner -func NewStorageMinerRPC(ctx context.Context, addr string, requestHeader http.Header, opts ...jsonrpc.Option) (api.StorageMiner, jsonrpc.ClientCloser, error) { - var res apistruct.StorageMinerStruct +// NewFullNodeRPCV1 creates a new http jsonrpc client. +func NewFullNodeRPCV1(ctx context.Context, addr string, requestHeader http.Header) (api.FullNode, jsonrpc.ClientCloser, error) { + var res v1api.FullNodeStruct + closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin", + []interface{}{ + &res.CommonStruct.Internal, + &res.Internal, + }, requestHeader) + + return &res, closer, err +} + +// NewStorageMinerRPCV0 creates a new http jsonrpc client for miner +func NewStorageMinerRPCV0(ctx context.Context, addr string, requestHeader http.Header, opts ...jsonrpc.Option) (v0api.StorageMiner, jsonrpc.ClientCloser, error) { + var res v0api.StorageMinerStruct closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin", []interface{}{ &res.CommonStruct.Internal, @@ -54,7 +67,7 @@ func NewStorageMinerRPC(ctx context.Context, addr string, requestHeader http.Hea return &res, closer, err } -func NewWorkerRPC(ctx context.Context, addr string, requestHeader http.Header) (api.Worker, jsonrpc.ClientCloser, error) { +func NewWorkerRPCV0(ctx context.Context, addr string, requestHeader http.Header) (api.Worker, jsonrpc.ClientCloser, error) { u, err := url.Parse(addr) if err != nil { return nil, nil, err @@ -69,7 +82,7 @@ func NewWorkerRPC(ctx context.Context, addr string, requestHeader http.Header) ( u.Path = path.Join(u.Path, "../streams/v0/push") - var res apistruct.WorkerStruct + var res api.WorkerStruct closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin", []interface{}{ &res.Internal, @@ -83,9 +96,23 @@ func NewWorkerRPC(ctx context.Context, addr string, requestHeader http.Header) ( return &res, closer, err } -// NewGatewayRPC creates a new http jsonrpc client for a gateway node. -func NewGatewayRPC(ctx context.Context, addr string, requestHeader http.Header, opts ...jsonrpc.Option) (api.Gateway, jsonrpc.ClientCloser, error) { - var res apistruct.GatewayStruct +// NewGatewayRPCV1 creates a new http jsonrpc client for a gateway node. +func NewGatewayRPCV1(ctx context.Context, addr string, requestHeader http.Header, opts ...jsonrpc.Option) (api.Gateway, jsonrpc.ClientCloser, error) { + var res api.GatewayStruct + closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin", + []interface{}{ + &res.Internal, + }, + requestHeader, + opts..., + ) + + return &res, closer, err +} + +// NewGatewayRPCV0 creates a new http jsonrpc client for a gateway node. +func NewGatewayRPCV0(ctx context.Context, addr string, requestHeader http.Header, opts ...jsonrpc.Option) (v0api.Gateway, jsonrpc.ClientCloser, error) { + var res v0api.GatewayStruct closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin", []interface{}{ &res.Internal, @@ -97,8 +124,8 @@ func NewGatewayRPC(ctx context.Context, addr string, requestHeader http.Header, return &res, closer, err } -func NewWalletRPC(ctx context.Context, addr string, requestHeader http.Header) (api.Wallet, jsonrpc.ClientCloser, error) { - var res apistruct.WalletStruct +func NewWalletRPCV0(ctx context.Context, addr string, requestHeader http.Header) (api.Wallet, jsonrpc.ClientCloser, error) { + var res api.WalletStruct closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin", []interface{}{ &res.Internal, diff --git a/api/docgen-openrpc/cmd/docgen_openrpc.go b/api/docgen-openrpc/cmd/docgen_openrpc.go index 81683e04d58..febbef3e412 100644 --- a/api/docgen-openrpc/cmd/docgen_openrpc.go +++ b/api/docgen-openrpc/cmd/docgen_openrpc.go @@ -7,7 +7,8 @@ import ( "log" "os" - "github.com/filecoin-project/lotus/api/apistruct" + "github.com/filecoin-project/lotus/api/docgen" + docgen_openrpc "github.com/filecoin-project/lotus/api/docgen-openrpc" ) @@ -29,16 +30,12 @@ Use: */ func main() { - doc := docgen_openrpc.NewLotusOpenRPCDocument() - - switch os.Args[2] { - case "FullNode": - doc.RegisterReceiverName("Filecoin", &apistruct.FullNodeStruct{}) - case "StorageMiner": - doc.RegisterReceiverName("Filecoin", &apistruct.StorageMinerStruct{}) - case "Worker": - doc.RegisterReceiverName("Filecoin", &apistruct.WorkerStruct{}) - } + Comments, GroupDocs := docgen.ParseApiASTInfo(os.Args[1], os.Args[2], os.Args[3], os.Args[4]) + + doc := docgen_openrpc.NewLotusOpenRPCDocument(Comments, GroupDocs) + + i, _, _, _ := docgen.GetAPIType(os.Args[2], os.Args[3]) + doc.RegisterReceiverName("Filecoin", i) out, err := doc.Discover() if err != nil { @@ -52,7 +49,7 @@ func main() { // Could use flags package to handle this more cleanly, but that requires changes elsewhere // the scope of which just isn't warranted by this one use case which will usually be run // programmatically anyways. - if len(os.Args) > 3 && os.Args[3] == "-gzip" { + if len(os.Args) > 5 && os.Args[5] == "-gzip" { jsonOut, err = json.Marshal(out) if err != nil { log.Fatalln(err) diff --git a/api/docgen-openrpc/openrpc.go b/api/docgen-openrpc/openrpc.go index 507ad3cb113..271b43ac607 100644 --- a/api/docgen-openrpc/openrpc.go +++ b/api/docgen-openrpc/openrpc.go @@ -4,7 +4,6 @@ import ( "encoding/json" "go/ast" "net" - "os" "reflect" "github.com/alecthomas/jsonschema" @@ -15,16 +14,6 @@ import ( meta_schema "github.com/open-rpc/meta-schema" ) -// Comments holds API method comments collected by AST parsing. -var Comments map[string]string - -// GroupDocs holds documentation for documentation groups. -var GroupDocs map[string]string - -func init() { - Comments, GroupDocs = docgen.ParseApiASTInfo(os.Args[1], os.Args[2]) -} - // schemaDictEntry represents a type association passed to the jsonschema reflector. type schemaDictEntry struct { example interface{} @@ -94,7 +83,7 @@ func OpenRPCSchemaTypeMapper(ty reflect.Type) *jsonschema.Type { } // NewLotusOpenRPCDocument defines application-specific documentation and configuration for its OpenRPC document. -func NewLotusOpenRPCDocument() *go_openrpc_reflect.Document { +func NewLotusOpenRPCDocument(Comments, GroupDocs map[string]string) *go_openrpc_reflect.Document { d := &go_openrpc_reflect.Document{} // Register "Meta" document fields. diff --git a/api/docgen/cmd/docgen.go b/api/docgen/cmd/docgen.go index c47d4420873..912eea841cd 100644 --- a/api/docgen/cmd/docgen.go +++ b/api/docgen/cmd/docgen.go @@ -4,39 +4,18 @@ import ( "encoding/json" "fmt" "os" - "reflect" "sort" "strings" - "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/api/apistruct" "github.com/filecoin-project/lotus/api/docgen" ) func main() { - comments, groupComments := docgen.ParseApiASTInfo(os.Args[1], os.Args[2]) + comments, groupComments := docgen.ParseApiASTInfo(os.Args[1], os.Args[2], os.Args[3], os.Args[4]) groups := make(map[string]*docgen.MethodGroup) - var t reflect.Type - var permStruct, commonPermStruct reflect.Type - - switch os.Args[2] { - case "FullNode": - t = reflect.TypeOf(new(struct{ api.FullNode })).Elem() - permStruct = reflect.TypeOf(apistruct.FullNodeStruct{}.Internal) - commonPermStruct = reflect.TypeOf(apistruct.CommonStruct{}.Internal) - case "StorageMiner": - t = reflect.TypeOf(new(struct{ api.StorageMiner })).Elem() - permStruct = reflect.TypeOf(apistruct.StorageMinerStruct{}.Internal) - commonPermStruct = reflect.TypeOf(apistruct.CommonStruct{}.Internal) - case "Worker": - t = reflect.TypeOf(new(struct{ api.Worker })).Elem() - permStruct = reflect.TypeOf(apistruct.WorkerStruct{}.Internal) - commonPermStruct = reflect.TypeOf(apistruct.WorkerStruct{}.Internal) - default: - panic("unknown type") - } + _, t, permStruct, commonPermStruct := docgen.GetAPIType(os.Args[2], os.Args[3]) for i := 0; i < t.NumMethod(); i++ { m := t.Method(i) diff --git a/api/docgen/docgen.go b/api/docgen/docgen.go index e17238d887a..4f9bc637ebd 100644 --- a/api/docgen/docgen.go +++ b/api/docgen/docgen.go @@ -35,6 +35,7 @@ import ( "github.com/filecoin-project/lotus/api" apitypes "github.com/filecoin-project/lotus/api/types" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/extern/sector-storage/sealtasks" @@ -113,7 +114,7 @@ func init() { addExample(network.Connected) addExample(dtypes.NetworkName("lotus")) addExample(api.SyncStateStage(1)) - addExample(api.FullAPIVersion) + addExample(api.FullAPIVersion1) addExample(api.PCHInbound) addExample(time.Minute) addExample(datatransfer.TransferID(3)) @@ -260,6 +261,45 @@ func init() { }, "methods": []interface{}{}}, ) + + addExample(api.CheckStatusCode(0)) + addExample(map[string]interface{}{"abc": 123}) +} + +func GetAPIType(name, pkg string) (i interface{}, t, permStruct, commonPermStruct reflect.Type) { + switch pkg { + case "api": // latest + switch name { + case "FullNode": + i = &api.FullNodeStruct{} + t = reflect.TypeOf(new(struct{ api.FullNode })).Elem() + permStruct = reflect.TypeOf(api.FullNodeStruct{}.Internal) + commonPermStruct = reflect.TypeOf(api.CommonStruct{}.Internal) + case "StorageMiner": + i = &api.StorageMinerStruct{} + t = reflect.TypeOf(new(struct{ api.StorageMiner })).Elem() + permStruct = reflect.TypeOf(api.StorageMinerStruct{}.Internal) + commonPermStruct = reflect.TypeOf(api.CommonStruct{}.Internal) + case "Worker": + i = &api.WorkerStruct{} + t = reflect.TypeOf(new(struct{ api.Worker })).Elem() + permStruct = reflect.TypeOf(api.WorkerStruct{}.Internal) + commonPermStruct = reflect.TypeOf(api.WorkerStruct{}.Internal) + default: + panic("unknown type") + } + case "v0api": + switch name { + case "FullNode": + i = v0api.FullNodeStruct{} + t = reflect.TypeOf(new(struct{ v0api.FullNode })).Elem() + permStruct = reflect.TypeOf(v0api.FullNodeStruct{}.Internal) + commonPermStruct = reflect.TypeOf(v0api.CommonStruct{}.Internal) + default: + panic("unknown type") + } + } + return } func ExampleValue(method string, t, parent reflect.Type) interface{} { @@ -342,9 +382,9 @@ func (v *Visitor) Visit(node ast.Node) ast.Visitor { const NoComment = "There are not yet any comments for this method." -func ParseApiASTInfo(apiFile, iface string) (comments map[string]string, groupDocs map[string]string) { //nolint:golint +func ParseApiASTInfo(apiFile, iface, pkg, dir string) (comments map[string]string, groupDocs map[string]string) { //nolint:golint fset := token.NewFileSet() - apiDir, err := filepath.Abs("./api") + apiDir, err := filepath.Abs(dir) if err != nil { fmt.Println("./api filepath absolute error: ", err) return @@ -360,14 +400,14 @@ func ParseApiASTInfo(apiFile, iface string) (comments map[string]string, groupDo return } - ap := pkgs["api"] + ap := pkgs[pkg] f := ap.Files[apiFile] cmap := ast.NewCommentMap(fset, f, f.Comments) v := &Visitor{iface, make(map[string]ast.Node)} - ast.Walk(v, pkgs["api"]) + ast.Walk(v, ap) comments = make(map[string]string) groupDocs = make(map[string]string) diff --git a/api/mocks/mock_full.go b/api/mocks/mock_full.go index 8fd646d9abe..6feee64f784 100644 --- a/api/mocks/mock_full.go +++ b/api/mocks/mock_full.go @@ -6,9 +6,12 @@ package mocks import ( context "context" + reflect "reflect" + address "github.com/filecoin-project/go-address" bitfield "github.com/filecoin-project/go-bitfield" datatransfer "github.com/filecoin-project/go-data-transfer" + retrievalmarket "github.com/filecoin-project/go-fil-markets/retrievalmarket" storagemarket "github.com/filecoin-project/go-fil-markets/storagemarket" auth "github.com/filecoin-project/go-jsonrpc/auth" multistore "github.com/filecoin-project/go-multistore" @@ -32,7 +35,6 @@ import ( network0 "github.com/libp2p/go-libp2p-core/network" peer "github.com/libp2p/go-libp2p-core/peer" protocol "github.com/libp2p/go-libp2p-core/protocol" - reflect "reflect" ) // MockFullNode is a mock of FullNode interface @@ -445,6 +447,20 @@ func (mr *MockFullNodeMockRecorder) ClientCancelDataTransfer(arg0, arg1, arg2, a return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientCancelDataTransfer", reflect.TypeOf((*MockFullNode)(nil).ClientCancelDataTransfer), arg0, arg1, arg2, arg3) } +// ClientCancelRetrievalDeal mocks base method +func (m *MockFullNode) ClientCancelRetrievalDeal(arg0 context.Context, arg1 retrievalmarket.DealID) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientCancelRetrievalDeal", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ClientCancelRetrievalDeal indicates an expected call of ClientCancelRetrievalDeal +func (mr *MockFullNodeMockRecorder) ClientCancelRetrievalDeal(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientCancelRetrievalDeal", reflect.TypeOf((*MockFullNode)(nil).ClientCancelRetrievalDeal), arg0, arg1) +} + // ClientDataTransferUpdates mocks base method func (m *MockFullNode) ClientDataTransferUpdates(arg0 context.Context) (<-chan api.DataTransferChannel, error) { m.ctrl.T.Helper() @@ -1052,6 +1068,51 @@ func (mr *MockFullNodeMockRecorder) MpoolBatchPushUntrusted(arg0, arg1 interface return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolBatchPushUntrusted", reflect.TypeOf((*MockFullNode)(nil).MpoolBatchPushUntrusted), arg0, arg1) } +// MpoolCheckMessages mocks base method +func (m *MockFullNode) MpoolCheckMessages(arg0 context.Context, arg1 []*api.MessagePrototype) ([][]api.MessageCheckStatus, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolCheckMessages", arg0, arg1) + ret0, _ := ret[0].([][]api.MessageCheckStatus) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MpoolCheckMessages indicates an expected call of MpoolCheckMessages +func (mr *MockFullNodeMockRecorder) MpoolCheckMessages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolCheckMessages", reflect.TypeOf((*MockFullNode)(nil).MpoolCheckMessages), arg0, arg1) +} + +// MpoolCheckPendingMessages mocks base method +func (m *MockFullNode) MpoolCheckPendingMessages(arg0 context.Context, arg1 address.Address) ([][]api.MessageCheckStatus, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolCheckPendingMessages", arg0, arg1) + ret0, _ := ret[0].([][]api.MessageCheckStatus) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MpoolCheckPendingMessages indicates an expected call of MpoolCheckPendingMessages +func (mr *MockFullNodeMockRecorder) MpoolCheckPendingMessages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolCheckPendingMessages", reflect.TypeOf((*MockFullNode)(nil).MpoolCheckPendingMessages), arg0, arg1) +} + +// MpoolCheckReplaceMessages mocks base method +func (m *MockFullNode) MpoolCheckReplaceMessages(arg0 context.Context, arg1 []*types.Message) ([][]api.MessageCheckStatus, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolCheckReplaceMessages", arg0, arg1) + ret0, _ := ret[0].([][]api.MessageCheckStatus) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MpoolCheckReplaceMessages indicates an expected call of MpoolCheckReplaceMessages +func (mr *MockFullNodeMockRecorder) MpoolCheckReplaceMessages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolCheckReplaceMessages", reflect.TypeOf((*MockFullNode)(nil).MpoolCheckReplaceMessages), arg0, arg1) +} + // MpoolClear mocks base method func (m *MockFullNode) MpoolClear(arg0 context.Context, arg1 bool) error { m.ctrl.T.Helper() @@ -1201,10 +1262,10 @@ func (mr *MockFullNodeMockRecorder) MpoolSub(arg0 interface{}) *gomock.Call { } // MsigAddApprove mocks base method -func (m *MockFullNode) MsigAddApprove(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4, arg5 address.Address, arg6 bool) (cid.Cid, error) { +func (m *MockFullNode) MsigAddApprove(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4, arg5 address.Address, arg6 bool) (*api.MessagePrototype, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigAddApprove", arg0, arg1, arg2, arg3, arg4, arg5, arg6) - ret0, _ := ret[0].(cid.Cid) + ret0, _ := ret[0].(*api.MessagePrototype) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1216,10 +1277,10 @@ func (mr *MockFullNodeMockRecorder) MsigAddApprove(arg0, arg1, arg2, arg3, arg4, } // MsigAddCancel mocks base method -func (m *MockFullNode) MsigAddCancel(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4 address.Address, arg5 bool) (cid.Cid, error) { +func (m *MockFullNode) MsigAddCancel(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4 address.Address, arg5 bool) (*api.MessagePrototype, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigAddCancel", arg0, arg1, arg2, arg3, arg4, arg5) - ret0, _ := ret[0].(cid.Cid) + ret0, _ := ret[0].(*api.MessagePrototype) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1231,10 +1292,10 @@ func (mr *MockFullNodeMockRecorder) MsigAddCancel(arg0, arg1, arg2, arg3, arg4, } // MsigAddPropose mocks base method -func (m *MockFullNode) MsigAddPropose(arg0 context.Context, arg1, arg2, arg3 address.Address, arg4 bool) (cid.Cid, error) { +func (m *MockFullNode) MsigAddPropose(arg0 context.Context, arg1, arg2, arg3 address.Address, arg4 bool) (*api.MessagePrototype, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigAddPropose", arg0, arg1, arg2, arg3, arg4) - ret0, _ := ret[0].(cid.Cid) + ret0, _ := ret[0].(*api.MessagePrototype) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1246,10 +1307,10 @@ func (mr *MockFullNodeMockRecorder) MsigAddPropose(arg0, arg1, arg2, arg3, arg4 } // MsigApprove mocks base method -func (m *MockFullNode) MsigApprove(arg0 context.Context, arg1 address.Address, arg2 uint64, arg3 address.Address) (cid.Cid, error) { +func (m *MockFullNode) MsigApprove(arg0 context.Context, arg1 address.Address, arg2 uint64, arg3 address.Address) (*api.MessagePrototype, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigApprove", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(cid.Cid) + ret0, _ := ret[0].(*api.MessagePrototype) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1261,10 +1322,10 @@ func (mr *MockFullNodeMockRecorder) MsigApprove(arg0, arg1, arg2, arg3 interface } // MsigApproveTxnHash mocks base method -func (m *MockFullNode) MsigApproveTxnHash(arg0 context.Context, arg1 address.Address, arg2 uint64, arg3, arg4 address.Address, arg5 big.Int, arg6 address.Address, arg7 uint64, arg8 []byte) (cid.Cid, error) { +func (m *MockFullNode) MsigApproveTxnHash(arg0 context.Context, arg1 address.Address, arg2 uint64, arg3, arg4 address.Address, arg5 big.Int, arg6 address.Address, arg7 uint64, arg8 []byte) (*api.MessagePrototype, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigApproveTxnHash", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) - ret0, _ := ret[0].(cid.Cid) + ret0, _ := ret[0].(*api.MessagePrototype) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1276,10 +1337,10 @@ func (mr *MockFullNodeMockRecorder) MsigApproveTxnHash(arg0, arg1, arg2, arg3, a } // MsigCancel mocks base method -func (m *MockFullNode) MsigCancel(arg0 context.Context, arg1 address.Address, arg2 uint64, arg3 address.Address, arg4 big.Int, arg5 address.Address, arg6 uint64, arg7 []byte) (cid.Cid, error) { +func (m *MockFullNode) MsigCancel(arg0 context.Context, arg1 address.Address, arg2 uint64, arg3 address.Address, arg4 big.Int, arg5 address.Address, arg6 uint64, arg7 []byte) (*api.MessagePrototype, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigCancel", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) - ret0, _ := ret[0].(cid.Cid) + ret0, _ := ret[0].(*api.MessagePrototype) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1291,10 +1352,10 @@ func (mr *MockFullNodeMockRecorder) MsigCancel(arg0, arg1, arg2, arg3, arg4, arg } // MsigCreate mocks base method -func (m *MockFullNode) MsigCreate(arg0 context.Context, arg1 uint64, arg2 []address.Address, arg3 abi.ChainEpoch, arg4 big.Int, arg5 address.Address, arg6 big.Int) (cid.Cid, error) { +func (m *MockFullNode) MsigCreate(arg0 context.Context, arg1 uint64, arg2 []address.Address, arg3 abi.ChainEpoch, arg4 big.Int, arg5 address.Address, arg6 big.Int) (*api.MessagePrototype, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigCreate", arg0, arg1, arg2, arg3, arg4, arg5, arg6) - ret0, _ := ret[0].(cid.Cid) + ret0, _ := ret[0].(*api.MessagePrototype) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1366,10 +1427,10 @@ func (mr *MockFullNodeMockRecorder) MsigGetVestingSchedule(arg0, arg1, arg2 inte } // MsigPropose mocks base method -func (m *MockFullNode) MsigPropose(arg0 context.Context, arg1, arg2 address.Address, arg3 big.Int, arg4 address.Address, arg5 uint64, arg6 []byte) (cid.Cid, error) { +func (m *MockFullNode) MsigPropose(arg0 context.Context, arg1, arg2 address.Address, arg3 big.Int, arg4 address.Address, arg5 uint64, arg6 []byte) (*api.MessagePrototype, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigPropose", arg0, arg1, arg2, arg3, arg4, arg5, arg6) - ret0, _ := ret[0].(cid.Cid) + ret0, _ := ret[0].(*api.MessagePrototype) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1381,10 +1442,10 @@ func (mr *MockFullNodeMockRecorder) MsigPropose(arg0, arg1, arg2, arg3, arg4, ar } // MsigRemoveSigner mocks base method -func (m *MockFullNode) MsigRemoveSigner(arg0 context.Context, arg1, arg2, arg3 address.Address, arg4 bool) (cid.Cid, error) { +func (m *MockFullNode) MsigRemoveSigner(arg0 context.Context, arg1, arg2, arg3 address.Address, arg4 bool) (*api.MessagePrototype, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigRemoveSigner", arg0, arg1, arg2, arg3, arg4) - ret0, _ := ret[0].(cid.Cid) + ret0, _ := ret[0].(*api.MessagePrototype) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1396,10 +1457,10 @@ func (mr *MockFullNodeMockRecorder) MsigRemoveSigner(arg0, arg1, arg2, arg3, arg } // MsigSwapApprove mocks base method -func (m *MockFullNode) MsigSwapApprove(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4, arg5, arg6 address.Address) (cid.Cid, error) { +func (m *MockFullNode) MsigSwapApprove(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4, arg5, arg6 address.Address) (*api.MessagePrototype, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigSwapApprove", arg0, arg1, arg2, arg3, arg4, arg5, arg6) - ret0, _ := ret[0].(cid.Cid) + ret0, _ := ret[0].(*api.MessagePrototype) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1411,10 +1472,10 @@ func (mr *MockFullNodeMockRecorder) MsigSwapApprove(arg0, arg1, arg2, arg3, arg4 } // MsigSwapCancel mocks base method -func (m *MockFullNode) MsigSwapCancel(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4, arg5 address.Address) (cid.Cid, error) { +func (m *MockFullNode) MsigSwapCancel(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4, arg5 address.Address) (*api.MessagePrototype, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigSwapCancel", arg0, arg1, arg2, arg3, arg4, arg5) - ret0, _ := ret[0].(cid.Cid) + ret0, _ := ret[0].(*api.MessagePrototype) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1426,10 +1487,10 @@ func (mr *MockFullNodeMockRecorder) MsigSwapCancel(arg0, arg1, arg2, arg3, arg4, } // MsigSwapPropose mocks base method -func (m *MockFullNode) MsigSwapPropose(arg0 context.Context, arg1, arg2, arg3, arg4 address.Address) (cid.Cid, error) { +func (m *MockFullNode) MsigSwapPropose(arg0 context.Context, arg1, arg2, arg3, arg4 address.Address) (*api.MessagePrototype, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigSwapPropose", arg0, arg1, arg2, arg3, arg4) - ret0, _ := ret[0].(cid.Cid) + ret0, _ := ret[0].(*api.MessagePrototype) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1676,6 +1737,21 @@ func (mr *MockFullNodeMockRecorder) NetPubsubScores(arg0 interface{}) *gomock.Ca return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetPubsubScores", reflect.TypeOf((*MockFullNode)(nil).NetPubsubScores), arg0) } +// NodeStatus mocks base method +func (m *MockFullNode) NodeStatus(arg0 context.Context, arg1 bool) (api.NodeStatus, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NodeStatus", arg0, arg1) + ret0, _ := ret[0].(api.NodeStatus) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NodeStatus indicates an expected call of NodeStatus +func (mr *MockFullNodeMockRecorder) NodeStatus(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NodeStatus", reflect.TypeOf((*MockFullNode)(nil).NodeStatus), arg0, arg1) +} + // PaychAllocateLane mocks base method func (m *MockFullNode) PaychAllocateLane(arg0 context.Context, arg1 address.Address) (uint64, error) { m.ctrl.T.Helper() @@ -2079,21 +2155,6 @@ func (mr *MockFullNodeMockRecorder) StateGetActor(arg0, arg1, arg2 interface{}) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateGetActor", reflect.TypeOf((*MockFullNode)(nil).StateGetActor), arg0, arg1, arg2) } -// StateGetReceipt mocks base method -func (m *MockFullNode) StateGetReceipt(arg0 context.Context, arg1 cid.Cid, arg2 types.TipSetKey) (*types.MessageReceipt, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "StateGetReceipt", arg0, arg1, arg2) - ret0, _ := ret[0].(*types.MessageReceipt) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// StateGetReceipt indicates an expected call of StateGetReceipt -func (mr *MockFullNodeMockRecorder) StateGetReceipt(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateGetReceipt", reflect.TypeOf((*MockFullNode)(nil).StateGetReceipt), arg0, arg1, arg2) -} - // StateListActors mocks base method func (m *MockFullNode) StateListActors(arg0 context.Context, arg1 types.TipSetKey) ([]address.Address, error) { m.ctrl.T.Helper() @@ -2485,33 +2546,18 @@ func (mr *MockFullNodeMockRecorder) StateReplay(arg0, arg1, arg2 interface{}) *g } // StateSearchMsg mocks base method -func (m *MockFullNode) StateSearchMsg(arg0 context.Context, arg1 cid.Cid) (*api.MsgLookup, error) { +func (m *MockFullNode) StateSearchMsg(arg0 context.Context, arg1 types.TipSetKey, arg2 cid.Cid, arg3 abi.ChainEpoch, arg4 bool) (*api.MsgLookup, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "StateSearchMsg", arg0, arg1) + ret := m.ctrl.Call(m, "StateSearchMsg", arg0, arg1, arg2, arg3, arg4) ret0, _ := ret[0].(*api.MsgLookup) ret1, _ := ret[1].(error) return ret0, ret1 } // StateSearchMsg indicates an expected call of StateSearchMsg -func (mr *MockFullNodeMockRecorder) StateSearchMsg(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSearchMsg", reflect.TypeOf((*MockFullNode)(nil).StateSearchMsg), arg0, arg1) -} - -// StateSearchMsgLimited mocks base method -func (m *MockFullNode) StateSearchMsgLimited(arg0 context.Context, arg1 cid.Cid, arg2 abi.ChainEpoch) (*api.MsgLookup, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "StateSearchMsgLimited", arg0, arg1, arg2) - ret0, _ := ret[0].(*api.MsgLookup) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// StateSearchMsgLimited indicates an expected call of StateSearchMsgLimited -func (mr *MockFullNodeMockRecorder) StateSearchMsgLimited(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockFullNodeMockRecorder) StateSearchMsg(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSearchMsgLimited", reflect.TypeOf((*MockFullNode)(nil).StateSearchMsgLimited), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSearchMsg", reflect.TypeOf((*MockFullNode)(nil).StateSearchMsg), arg0, arg1, arg2, arg3, arg4) } // StateSectorExpiration mocks base method @@ -2635,33 +2681,18 @@ func (mr *MockFullNodeMockRecorder) StateVerifierStatus(arg0, arg1, arg2 interfa } // StateWaitMsg mocks base method -func (m *MockFullNode) StateWaitMsg(arg0 context.Context, arg1 cid.Cid, arg2 uint64) (*api.MsgLookup, error) { +func (m *MockFullNode) StateWaitMsg(arg0 context.Context, arg1 cid.Cid, arg2 uint64, arg3 abi.ChainEpoch, arg4 bool) (*api.MsgLookup, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "StateWaitMsg", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "StateWaitMsg", arg0, arg1, arg2, arg3, arg4) ret0, _ := ret[0].(*api.MsgLookup) ret1, _ := ret[1].(error) return ret0, ret1 } // StateWaitMsg indicates an expected call of StateWaitMsg -func (mr *MockFullNodeMockRecorder) StateWaitMsg(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateWaitMsg", reflect.TypeOf((*MockFullNode)(nil).StateWaitMsg), arg0, arg1, arg2) -} - -// StateWaitMsgLimited mocks base method -func (m *MockFullNode) StateWaitMsgLimited(arg0 context.Context, arg1 cid.Cid, arg2 uint64, arg3 abi.ChainEpoch) (*api.MsgLookup, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "StateWaitMsgLimited", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(*api.MsgLookup) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// StateWaitMsgLimited indicates an expected call of StateWaitMsgLimited -func (mr *MockFullNodeMockRecorder) StateWaitMsgLimited(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockFullNodeMockRecorder) StateWaitMsg(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateWaitMsgLimited", reflect.TypeOf((*MockFullNode)(nil).StateWaitMsgLimited), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateWaitMsg", reflect.TypeOf((*MockFullNode)(nil).StateWaitMsg), arg0, arg1, arg2, arg3, arg4) } // SyncCheckBad mocks base method diff --git a/api/apistruct/permissioned.go b/api/permissioned.go similarity index 78% rename from api/apistruct/permissioned.go rename to api/permissioned.go index 23259fa8746..d99e5943b8b 100644 --- a/api/apistruct/permissioned.go +++ b/api/permissioned.go @@ -1,8 +1,7 @@ -package apistruct +package api import ( "github.com/filecoin-project/go-jsonrpc/auth" - "github.com/filecoin-project/lotus/api" ) const ( @@ -17,27 +16,27 @@ const ( var AllPermissions = []auth.Permission{PermRead, PermWrite, PermSign, PermAdmin} var DefaultPerms = []auth.Permission{PermRead} -func PermissionedStorMinerAPI(a api.StorageMiner) api.StorageMiner { +func PermissionedStorMinerAPI(a StorageMiner) StorageMiner { var out StorageMinerStruct auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.Internal) auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.CommonStruct.Internal) return &out } -func PermissionedFullAPI(a api.FullNode) api.FullNode { +func PermissionedFullAPI(a FullNode) FullNode { var out FullNodeStruct auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.Internal) auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.CommonStruct.Internal) return &out } -func PermissionedWorkerAPI(a api.Worker) api.Worker { +func PermissionedWorkerAPI(a Worker) Worker { var out WorkerStruct auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.Internal) return &out } -func PermissionedWalletAPI(a api.Wallet) api.Wallet { +func PermissionedWalletAPI(a Wallet) Wallet { var out WalletStruct auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.Internal) return &out diff --git a/api/proxy_gen.go b/api/proxy_gen.go new file mode 100644 index 00000000000..2d4d4150371 --- /dev/null +++ b/api/proxy_gen.go @@ -0,0 +1,3621 @@ +// Code generated by github.com/filecoin-project/lotus/gen/api. DO NOT EDIT. + +package api + +import ( + "context" + "io" + "time" + + "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" + "github.com/filecoin-project/go-jsonrpc/auth" + "github.com/filecoin-project/go-multistore" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/crypto" + "github.com/filecoin-project/go-state-types/dline" + apitypes "github.com/filecoin-project/lotus/api/types" + "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + "github.com/filecoin-project/lotus/chain/actors/builtin/paych" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/extern/sector-storage/fsutil" + "github.com/filecoin-project/lotus/extern/sector-storage/sealtasks" + "github.com/filecoin-project/lotus/extern/sector-storage/stores" + "github.com/filecoin-project/lotus/extern/sector-storage/storiface" + marketevents "github.com/filecoin-project/lotus/markets/loggers" + "github.com/filecoin-project/lotus/node/modules/dtypes" + "github.com/filecoin-project/specs-storage/storage" + "github.com/google/uuid" + "github.com/ipfs/go-cid" + metrics "github.com/libp2p/go-libp2p-core/metrics" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + protocol "github.com/libp2p/go-libp2p-core/protocol" + xerrors "golang.org/x/xerrors" +) + +type ChainIOStruct struct { + Internal struct { + ChainHasObj func(p0 context.Context, p1 cid.Cid) (bool, error) `` + + ChainReadObj func(p0 context.Context, p1 cid.Cid) ([]byte, error) `` + } +} + +type ChainIOStub struct { +} + +type CommonStruct struct { + Internal struct { + AuthNew func(p0 context.Context, p1 []auth.Permission) ([]byte, error) `perm:"admin"` + + AuthVerify func(p0 context.Context, p1 string) ([]auth.Permission, error) `perm:"read"` + + Closing func(p0 context.Context) (<-chan struct{}, error) `perm:"read"` + + Discover func(p0 context.Context) (apitypes.OpenRPCDocument, error) `perm:"read"` + + ID func(p0 context.Context) (peer.ID, error) `perm:"read"` + + LogList func(p0 context.Context) ([]string, error) `perm:"write"` + + LogSetLevel func(p0 context.Context, p1 string, p2 string) error `perm:"write"` + + NetAddrsListen func(p0 context.Context) (peer.AddrInfo, error) `perm:"read"` + + NetAgentVersion func(p0 context.Context, p1 peer.ID) (string, error) `perm:"read"` + + NetAutoNatStatus func(p0 context.Context) (NatInfo, error) `perm:"read"` + + NetBandwidthStats func(p0 context.Context) (metrics.Stats, error) `perm:"read"` + + NetBandwidthStatsByPeer func(p0 context.Context) (map[string]metrics.Stats, error) `perm:"read"` + + NetBandwidthStatsByProtocol func(p0 context.Context) (map[protocol.ID]metrics.Stats, error) `perm:"read"` + + NetBlockAdd func(p0 context.Context, p1 NetBlockList) error `perm:"admin"` + + NetBlockList func(p0 context.Context) (NetBlockList, error) `perm:"read"` + + NetBlockRemove func(p0 context.Context, p1 NetBlockList) error `perm:"admin"` + + NetConnect func(p0 context.Context, p1 peer.AddrInfo) error `perm:"write"` + + NetConnectedness func(p0 context.Context, p1 peer.ID) (network.Connectedness, error) `perm:"read"` + + NetDisconnect func(p0 context.Context, p1 peer.ID) error `perm:"write"` + + NetFindPeer func(p0 context.Context, p1 peer.ID) (peer.AddrInfo, error) `perm:"read"` + + NetPeerInfo func(p0 context.Context, p1 peer.ID) (*ExtendedPeerInfo, error) `perm:"read"` + + NetPeers func(p0 context.Context) ([]peer.AddrInfo, error) `perm:"read"` + + NetPubsubScores func(p0 context.Context) ([]PubsubScore, error) `perm:"read"` + + Session func(p0 context.Context) (uuid.UUID, error) `perm:"read"` + + Shutdown func(p0 context.Context) error `perm:"admin"` + + Version func(p0 context.Context) (APIVersion, error) `perm:"read"` + } +} + +type CommonStub struct { +} + +type FullNodeStruct struct { + CommonStruct + + Internal struct { + BeaconGetEntry func(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) `perm:"read"` + + ChainDeleteObj func(p0 context.Context, p1 cid.Cid) error `perm:"admin"` + + ChainExport func(p0 context.Context, p1 abi.ChainEpoch, p2 bool, p3 types.TipSetKey) (<-chan []byte, error) `perm:"read"` + + ChainGetBlock func(p0 context.Context, p1 cid.Cid) (*types.BlockHeader, error) `perm:"read"` + + ChainGetBlockMessages func(p0 context.Context, p1 cid.Cid) (*BlockMessages, error) `perm:"read"` + + ChainGetGenesis func(p0 context.Context) (*types.TipSet, error) `perm:"read"` + + ChainGetMessage func(p0 context.Context, p1 cid.Cid) (*types.Message, error) `perm:"read"` + + ChainGetNode func(p0 context.Context, p1 string) (*IpldObject, error) `perm:"read"` + + ChainGetParentMessages func(p0 context.Context, p1 cid.Cid) ([]Message, error) `perm:"read"` + + ChainGetParentReceipts func(p0 context.Context, p1 cid.Cid) ([]*types.MessageReceipt, error) `perm:"read"` + + ChainGetPath func(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey) ([]*HeadChange, error) `perm:"read"` + + ChainGetRandomnessFromBeacon func(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) `perm:"read"` + + ChainGetRandomnessFromTickets func(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) `perm:"read"` + + ChainGetTipSet func(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) `perm:"read"` + + ChainGetTipSetByHeight func(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) `perm:"read"` + + ChainHasObj func(p0 context.Context, p1 cid.Cid) (bool, error) `perm:"read"` + + ChainHead func(p0 context.Context) (*types.TipSet, error) `perm:"read"` + + ChainNotify func(p0 context.Context) (<-chan []*HeadChange, error) `perm:"read"` + + ChainReadObj func(p0 context.Context, p1 cid.Cid) ([]byte, error) `perm:"read"` + + ChainSetHead func(p0 context.Context, p1 types.TipSetKey) error `perm:"admin"` + + ChainStatObj func(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (ObjStat, error) `perm:"read"` + + ChainTipSetWeight func(p0 context.Context, p1 types.TipSetKey) (types.BigInt, error) `perm:"read"` + + ClientCalcCommP func(p0 context.Context, p1 string) (*CommPRet, error) `perm:"write"` + + ClientCancelDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"` + + ClientCancelRetrievalDeal func(p0 context.Context, p1 retrievalmarket.DealID) error `perm:"write"` + + ClientDataTransferUpdates func(p0 context.Context) (<-chan DataTransferChannel, error) `perm:"write"` + + ClientDealPieceCID func(p0 context.Context, p1 cid.Cid) (DataCIDSize, error) `perm:"read"` + + ClientDealSize func(p0 context.Context, p1 cid.Cid) (DataSize, error) `perm:"read"` + + ClientFindData func(p0 context.Context, p1 cid.Cid, p2 *cid.Cid) ([]QueryOffer, error) `perm:"read"` + + ClientGenCar func(p0 context.Context, p1 FileRef, p2 string) error `perm:"write"` + + ClientGetDealInfo func(p0 context.Context, p1 cid.Cid) (*DealInfo, error) `perm:"read"` + + ClientGetDealStatus func(p0 context.Context, p1 uint64) (string, error) `perm:"read"` + + ClientGetDealUpdates func(p0 context.Context) (<-chan DealInfo, error) `perm:"write"` + + ClientHasLocal func(p0 context.Context, p1 cid.Cid) (bool, error) `perm:"write"` + + ClientImport func(p0 context.Context, p1 FileRef) (*ImportRes, error) `perm:"admin"` + + ClientListDataTransfers func(p0 context.Context) ([]DataTransferChannel, error) `perm:"write"` + + ClientListDeals func(p0 context.Context) ([]DealInfo, error) `perm:"write"` + + ClientListImports func(p0 context.Context) ([]Import, error) `perm:"write"` + + ClientMinerQueryOffer func(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (QueryOffer, error) `perm:"read"` + + ClientQueryAsk func(p0 context.Context, p1 peer.ID, p2 address.Address) (*storagemarket.StorageAsk, error) `perm:"read"` + + ClientRemoveImport func(p0 context.Context, p1 multistore.StoreID) error `perm:"admin"` + + ClientRestartDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"` + + ClientRetrieve func(p0 context.Context, p1 RetrievalOrder, p2 *FileRef) error `perm:"admin"` + + ClientRetrieveTryRestartInsufficientFunds func(p0 context.Context, p1 address.Address) error `perm:"write"` + + ClientRetrieveWithEvents func(p0 context.Context, p1 RetrievalOrder, p2 *FileRef) (<-chan marketevents.RetrievalEvent, error) `perm:"admin"` + + ClientStartDeal func(p0 context.Context, p1 *StartDealParams) (*cid.Cid, error) `perm:"admin"` + + CreateBackup func(p0 context.Context, p1 string) error `perm:"admin"` + + GasEstimateFeeCap func(p0 context.Context, p1 *types.Message, p2 int64, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"` + + GasEstimateGasLimit func(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (int64, error) `perm:"read"` + + GasEstimateGasPremium func(p0 context.Context, p1 uint64, p2 address.Address, p3 int64, p4 types.TipSetKey) (types.BigInt, error) `perm:"read"` + + GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) `perm:"read"` + + MarketAddBalance func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) `perm:"sign"` + + MarketGetReserved func(p0 context.Context, p1 address.Address) (types.BigInt, error) `perm:"sign"` + + MarketReleaseFunds func(p0 context.Context, p1 address.Address, p2 types.BigInt) error `perm:"sign"` + + MarketReserveFunds func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) `perm:"sign"` + + MarketWithdraw func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) `perm:"sign"` + + MinerCreateBlock func(p0 context.Context, p1 *BlockTemplate) (*types.BlockMsg, error) `perm:"write"` + + MinerGetBaseInfo func(p0 context.Context, p1 address.Address, p2 abi.ChainEpoch, p3 types.TipSetKey) (*MiningBaseInfo, error) `perm:"read"` + + MpoolBatchPush func(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) `perm:"write"` + + MpoolBatchPushMessage func(p0 context.Context, p1 []*types.Message, p2 *MessageSendSpec) ([]*types.SignedMessage, error) `perm:"sign"` + + MpoolBatchPushUntrusted func(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) `perm:"write"` + + MpoolCheckMessages func(p0 context.Context, p1 []*MessagePrototype) ([][]MessageCheckStatus, error) `perm:"read"` + + MpoolCheckPendingMessages func(p0 context.Context, p1 address.Address) ([][]MessageCheckStatus, error) `perm:"read"` + + MpoolCheckReplaceMessages func(p0 context.Context, p1 []*types.Message) ([][]MessageCheckStatus, error) `perm:"read"` + + MpoolClear func(p0 context.Context, p1 bool) error `perm:"write"` + + MpoolGetConfig func(p0 context.Context) (*types.MpoolConfig, error) `perm:"read"` + + MpoolGetNonce func(p0 context.Context, p1 address.Address) (uint64, error) `perm:"read"` + + MpoolPending func(p0 context.Context, p1 types.TipSetKey) ([]*types.SignedMessage, error) `perm:"read"` + + MpoolPush func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) `perm:"write"` + + MpoolPushMessage func(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec) (*types.SignedMessage, error) `perm:"sign"` + + MpoolPushUntrusted func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) `perm:"write"` + + MpoolSelect func(p0 context.Context, p1 types.TipSetKey, p2 float64) ([]*types.SignedMessage, error) `perm:"read"` + + MpoolSetConfig func(p0 context.Context, p1 *types.MpoolConfig) error `perm:"admin"` + + MpoolSub func(p0 context.Context) (<-chan MpoolUpdate, error) `perm:"read"` + + MsigAddApprove func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (*MessagePrototype, error) `perm:"sign"` + + MsigAddCancel func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (*MessagePrototype, error) `perm:"sign"` + + MsigAddPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (*MessagePrototype, error) `perm:"sign"` + + MsigApprove func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (*MessagePrototype, error) `perm:"sign"` + + MsigApproveTxnHash func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 address.Address, p5 types.BigInt, p6 address.Address, p7 uint64, p8 []byte) (*MessagePrototype, error) `perm:"sign"` + + MsigCancel func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (*MessagePrototype, error) `perm:"sign"` + + MsigCreate func(p0 context.Context, p1 uint64, p2 []address.Address, p3 abi.ChainEpoch, p4 types.BigInt, p5 address.Address, p6 types.BigInt) (*MessagePrototype, error) `perm:"sign"` + + MsigGetAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) `perm:"read"` + + MsigGetPending func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*MsigTransaction, error) `perm:"read"` + + MsigGetVested func(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"` + + MsigGetVestingSchedule func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MsigVesting, error) `perm:"read"` + + MsigPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (*MessagePrototype, error) `perm:"sign"` + + MsigRemoveSigner func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (*MessagePrototype, error) `perm:"sign"` + + MsigSwapApprove func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 address.Address) (*MessagePrototype, error) `perm:"sign"` + + MsigSwapCancel func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (*MessagePrototype, error) `perm:"sign"` + + MsigSwapPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (*MessagePrototype, error) `perm:"sign"` + + NodeStatus func(p0 context.Context, p1 bool) (NodeStatus, error) `perm:"read"` + + PaychAllocateLane func(p0 context.Context, p1 address.Address) (uint64, error) `perm:"sign"` + + PaychAvailableFunds func(p0 context.Context, p1 address.Address) (*ChannelAvailableFunds, error) `perm:"sign"` + + PaychAvailableFundsByFromTo func(p0 context.Context, p1 address.Address, p2 address.Address) (*ChannelAvailableFunds, error) `perm:"sign"` + + PaychCollect func(p0 context.Context, p1 address.Address) (cid.Cid, error) `perm:"sign"` + + PaychGet func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*ChannelInfo, error) `perm:"sign"` + + PaychGetWaitReady func(p0 context.Context, p1 cid.Cid) (address.Address, error) `perm:"sign"` + + PaychList func(p0 context.Context) ([]address.Address, error) `perm:"read"` + + PaychNewPayment func(p0 context.Context, p1 address.Address, p2 address.Address, p3 []VoucherSpec) (*PaymentInfo, error) `perm:"sign"` + + PaychSettle func(p0 context.Context, p1 address.Address) (cid.Cid, error) `perm:"sign"` + + PaychStatus func(p0 context.Context, p1 address.Address) (*PaychStatus, error) `perm:"read"` + + PaychVoucherAdd func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 types.BigInt) (types.BigInt, error) `perm:"write"` + + PaychVoucherCheckSpendable func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (bool, error) `perm:"read"` + + PaychVoucherCheckValid func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher) error `perm:"read"` + + PaychVoucherCreate func(p0 context.Context, p1 address.Address, p2 types.BigInt, p3 uint64) (*VoucherCreateResult, error) `perm:"sign"` + + PaychVoucherList func(p0 context.Context, p1 address.Address) ([]*paych.SignedVoucher, error) `perm:"write"` + + PaychVoucherSubmit func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (cid.Cid, error) `perm:"sign"` + + StateAccountKey func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `perm:"read"` + + StateAllMinerFaults func(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) ([]*Fault, error) `perm:"read"` + + StateCall func(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*InvocResult, error) `perm:"read"` + + StateChangedActors func(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (map[string]types.Actor, error) `perm:"read"` + + StateCirculatingSupply func(p0 context.Context, p1 types.TipSetKey) (abi.TokenAmount, error) `perm:"read"` + + StateCompute func(p0 context.Context, p1 abi.ChainEpoch, p2 []*types.Message, p3 types.TipSetKey) (*ComputeStateOutput, error) `perm:"read"` + + StateDealProviderCollateralBounds func(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (DealCollateralBounds, error) `perm:"read"` + + StateDecodeParams func(p0 context.Context, p1 address.Address, p2 abi.MethodNum, p3 []byte, p4 types.TipSetKey) (interface{}, error) `perm:"read"` + + StateGetActor func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) `perm:"read"` + + StateListActors func(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) `perm:"read"` + + StateListMessages func(p0 context.Context, p1 *MessageMatch, p2 types.TipSetKey, p3 abi.ChainEpoch) ([]cid.Cid, error) `perm:"read"` + + StateListMiners func(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) `perm:"read"` + + StateLookupID func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `perm:"read"` + + StateMarketBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MarketBalance, error) `perm:"read"` + + StateMarketDeals func(p0 context.Context, p1 types.TipSetKey) (map[string]MarketDeal, error) `perm:"read"` + + StateMarketParticipants func(p0 context.Context, p1 types.TipSetKey) (map[string]MarketBalance, error) `perm:"read"` + + StateMarketStorageDeal func(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*MarketDeal, error) `perm:"read"` + + StateMinerActiveSectors func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) `perm:"read"` + + StateMinerAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) `perm:"read"` + + StateMinerDeadlines func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]Deadline, error) `perm:"read"` + + StateMinerFaults func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) `perm:"read"` + + StateMinerInfo func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) `perm:"read"` + + StateMinerInitialPledgeCollateral func(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"` + + StateMinerPartitions func(p0 context.Context, p1 address.Address, p2 uint64, p3 types.TipSetKey) ([]Partition, error) `perm:"read"` + + StateMinerPower func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*MinerPower, error) `perm:"read"` + + StateMinerPreCommitDepositForPower func(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"` + + StateMinerProvingDeadline func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) `perm:"read"` + + StateMinerRecoveries func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) `perm:"read"` + + StateMinerSectorAllocated func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (bool, error) `perm:"read"` + + StateMinerSectorCount func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MinerSectors, error) `perm:"read"` + + StateMinerSectors func(p0 context.Context, p1 address.Address, p2 *bitfield.BitField, p3 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) `perm:"read"` + + StateNetworkName func(p0 context.Context) (dtypes.NetworkName, error) `perm:"read"` + + StateNetworkVersion func(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) `perm:"read"` + + StateReadState func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*ActorState, error) `perm:"read"` + + StateReplay func(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*InvocResult, error) `perm:"read"` + + StateSearchMsg func(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) `perm:"read"` + + StateSectorExpiration func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorExpiration, error) `perm:"read"` + + StateSectorGetInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) `perm:"read"` + + StateSectorPartition func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorLocation, error) `perm:"read"` + + StateSectorPreCommitInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) `perm:"read"` + + StateVMCirculatingSupplyInternal func(p0 context.Context, p1 types.TipSetKey) (CirculatingSupply, error) `perm:"read"` + + StateVerifiedClientStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) `perm:"read"` + + StateVerifiedRegistryRootKey func(p0 context.Context, p1 types.TipSetKey) (address.Address, error) `perm:"read"` + + StateVerifierStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) `perm:"read"` + + StateWaitMsg func(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) `perm:"read"` + + SyncCheckBad func(p0 context.Context, p1 cid.Cid) (string, error) `perm:"read"` + + SyncCheckpoint func(p0 context.Context, p1 types.TipSetKey) error `perm:"admin"` + + SyncIncomingBlocks func(p0 context.Context) (<-chan *types.BlockHeader, error) `perm:"read"` + + SyncMarkBad func(p0 context.Context, p1 cid.Cid) error `perm:"admin"` + + SyncState func(p0 context.Context) (*SyncState, error) `perm:"read"` + + SyncSubmitBlock func(p0 context.Context, p1 *types.BlockMsg) error `perm:"write"` + + SyncUnmarkAllBad func(p0 context.Context) error `perm:"admin"` + + SyncUnmarkBad func(p0 context.Context, p1 cid.Cid) error `perm:"admin"` + + SyncValidateTipset func(p0 context.Context, p1 types.TipSetKey) (bool, error) `perm:"read"` + + WalletBalance func(p0 context.Context, p1 address.Address) (types.BigInt, error) `perm:"read"` + + WalletDefaultAddress func(p0 context.Context) (address.Address, error) `perm:"write"` + + WalletDelete func(p0 context.Context, p1 address.Address) error `perm:"admin"` + + WalletExport func(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) `perm:"admin"` + + WalletHas func(p0 context.Context, p1 address.Address) (bool, error) `perm:"write"` + + WalletImport func(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) `perm:"admin"` + + WalletList func(p0 context.Context) ([]address.Address, error) `perm:"write"` + + WalletNew func(p0 context.Context, p1 types.KeyType) (address.Address, error) `perm:"write"` + + WalletSetDefault func(p0 context.Context, p1 address.Address) error `perm:"write"` + + WalletSign func(p0 context.Context, p1 address.Address, p2 []byte) (*crypto.Signature, error) `perm:"sign"` + + WalletSignMessage func(p0 context.Context, p1 address.Address, p2 *types.Message) (*types.SignedMessage, error) `perm:"sign"` + + WalletValidateAddress func(p0 context.Context, p1 string) (address.Address, error) `perm:"read"` + + WalletVerify func(p0 context.Context, p1 address.Address, p2 []byte, p3 *crypto.Signature) (bool, error) `perm:"read"` + } +} + +type FullNodeStub struct { + CommonStub +} + +type GatewayStruct struct { + Internal struct { + ChainGetBlockMessages func(p0 context.Context, p1 cid.Cid) (*BlockMessages, error) `` + + ChainGetMessage func(p0 context.Context, p1 cid.Cid) (*types.Message, error) `` + + ChainGetTipSet func(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) `` + + ChainGetTipSetByHeight func(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) `` + + ChainHasObj func(p0 context.Context, p1 cid.Cid) (bool, error) `` + + ChainHead func(p0 context.Context) (*types.TipSet, error) `` + + ChainNotify func(p0 context.Context) (<-chan []*HeadChange, error) `` + + ChainReadObj func(p0 context.Context, p1 cid.Cid) ([]byte, error) `` + + GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) `` + + MpoolPush func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) `` + + MsigGetAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) `` + + MsigGetPending func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*MsigTransaction, error) `` + + MsigGetVested func(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) `` + + StateAccountKey func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `` + + StateDealProviderCollateralBounds func(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (DealCollateralBounds, error) `` + + StateGetActor func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) `` + + StateListMiners func(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) `` + + StateLookupID func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `` + + StateMarketBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MarketBalance, error) `` + + StateMarketStorageDeal func(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*MarketDeal, error) `` + + StateMinerInfo func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) `` + + StateMinerPower func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*MinerPower, error) `` + + StateMinerProvingDeadline func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) `` + + StateNetworkVersion func(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) `` + + StateSearchMsg func(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) `` + + StateSectorGetInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) `` + + StateVerifiedClientStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) `` + + StateWaitMsg func(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) `` + + WalletBalance func(p0 context.Context, p1 address.Address) (types.BigInt, error) `` + } +} + +type GatewayStub struct { +} + +type SignableStruct struct { + Internal struct { + Sign func(p0 context.Context, p1 SignFunc) error `` + } +} + +type SignableStub struct { +} + +type StorageMinerStruct struct { + CommonStruct + + Internal struct { + ActorAddress func(p0 context.Context) (address.Address, error) `perm:"read"` + + ActorAddressConfig func(p0 context.Context) (AddressConfig, error) `perm:"read"` + + ActorSectorSize func(p0 context.Context, p1 address.Address) (abi.SectorSize, error) `perm:"read"` + + CheckProvable func(p0 context.Context, p1 abi.RegisteredPoStProof, p2 []storage.SectorRef, p3 bool) (map[abi.SectorNumber]string, error) `perm:"admin"` + + ComputeProof func(p0 context.Context, p1 []builtin.SectorInfo, p2 abi.PoStRandomness) ([]builtin.PoStProof, error) `perm:"read"` + + CreateBackup func(p0 context.Context, p1 string) error `perm:"admin"` + + DealsConsiderOfflineRetrievalDeals func(p0 context.Context) (bool, error) `perm:"admin"` + + DealsConsiderOfflineStorageDeals func(p0 context.Context) (bool, error) `perm:"admin"` + + DealsConsiderOnlineRetrievalDeals func(p0 context.Context) (bool, error) `perm:"admin"` + + DealsConsiderOnlineStorageDeals func(p0 context.Context) (bool, error) `perm:"admin"` + + DealsConsiderUnverifiedStorageDeals func(p0 context.Context) (bool, error) `perm:"admin"` + + DealsConsiderVerifiedStorageDeals func(p0 context.Context) (bool, error) `perm:"admin"` + + DealsImportData func(p0 context.Context, p1 cid.Cid, p2 string) error `perm:"admin"` + + DealsList func(p0 context.Context) ([]MarketDeal, error) `perm:"admin"` + + DealsPieceCidBlocklist func(p0 context.Context) ([]cid.Cid, error) `perm:"admin"` + + DealsSetConsiderOfflineRetrievalDeals func(p0 context.Context, p1 bool) error `perm:"admin"` + + DealsSetConsiderOfflineStorageDeals func(p0 context.Context, p1 bool) error `perm:"admin"` + + DealsSetConsiderOnlineRetrievalDeals func(p0 context.Context, p1 bool) error `perm:"admin"` + + DealsSetConsiderOnlineStorageDeals func(p0 context.Context, p1 bool) error `perm:"admin"` + + DealsSetConsiderUnverifiedStorageDeals func(p0 context.Context, p1 bool) error `perm:"admin"` + + DealsSetConsiderVerifiedStorageDeals func(p0 context.Context, p1 bool) error `perm:"admin"` + + DealsSetPieceCidBlocklist func(p0 context.Context, p1 []cid.Cid) error `perm:"admin"` + + MarketCancelDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"` + + MarketDataTransferUpdates func(p0 context.Context) (<-chan DataTransferChannel, error) `perm:"write"` + + MarketGetAsk func(p0 context.Context) (*storagemarket.SignedStorageAsk, error) `perm:"read"` + + MarketGetDealUpdates func(p0 context.Context) (<-chan storagemarket.MinerDeal, error) `perm:"read"` + + MarketGetRetrievalAsk func(p0 context.Context) (*retrievalmarket.Ask, error) `perm:"read"` + + MarketImportDealData func(p0 context.Context, p1 cid.Cid, p2 string) error `perm:"write"` + + MarketListDataTransfers func(p0 context.Context) ([]DataTransferChannel, error) `perm:"write"` + + MarketListDeals func(p0 context.Context) ([]MarketDeal, error) `perm:"read"` + + MarketListIncompleteDeals func(p0 context.Context) ([]storagemarket.MinerDeal, error) `perm:"read"` + + MarketListRetrievalDeals func(p0 context.Context) ([]retrievalmarket.ProviderDealState, error) `perm:"read"` + + MarketPendingDeals func(p0 context.Context) (PendingDealInfo, error) `perm:"write"` + + MarketPublishPendingDeals func(p0 context.Context) error `perm:"admin"` + + MarketRestartDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"` + + MarketSetAsk func(p0 context.Context, p1 types.BigInt, p2 types.BigInt, p3 abi.ChainEpoch, p4 abi.PaddedPieceSize, p5 abi.PaddedPieceSize) error `perm:"admin"` + + MarketSetRetrievalAsk func(p0 context.Context, p1 *retrievalmarket.Ask) error `perm:"admin"` + + MiningBase func(p0 context.Context) (*types.TipSet, error) `perm:"read"` + + PiecesGetCIDInfo func(p0 context.Context, p1 cid.Cid) (*piecestore.CIDInfo, error) `perm:"read"` + + PiecesGetPieceInfo func(p0 context.Context, p1 cid.Cid) (*piecestore.PieceInfo, error) `perm:"read"` + + PiecesListCidInfos func(p0 context.Context) ([]cid.Cid, error) `perm:"read"` + + PiecesListPieces func(p0 context.Context) ([]cid.Cid, error) `perm:"read"` + + PledgeSector func(p0 context.Context) (abi.SectorID, error) `perm:"write"` + + ReturnAddPiece func(p0 context.Context, p1 storiface.CallID, p2 abi.PieceInfo, p3 *storiface.CallError) error `perm:"admin"` + + ReturnFetch func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"` + + ReturnFinalizeSector func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"` + + ReturnMoveStorage func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"` + + ReturnReadPiece func(p0 context.Context, p1 storiface.CallID, p2 bool, p3 *storiface.CallError) error `perm:"admin"` + + ReturnReleaseUnsealed func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"` + + ReturnSealCommit1 func(p0 context.Context, p1 storiface.CallID, p2 storage.Commit1Out, p3 *storiface.CallError) error `perm:"admin"` + + ReturnSealCommit2 func(p0 context.Context, p1 storiface.CallID, p2 storage.Proof, p3 *storiface.CallError) error `perm:"admin"` + + ReturnSealPreCommit1 func(p0 context.Context, p1 storiface.CallID, p2 storage.PreCommit1Out, p3 *storiface.CallError) error `perm:"admin"` + + ReturnSealPreCommit2 func(p0 context.Context, p1 storiface.CallID, p2 storage.SectorCids, p3 *storiface.CallError) error `perm:"admin"` + + ReturnUnsealPiece func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"` + + SealingAbort func(p0 context.Context, p1 storiface.CallID) error `perm:"admin"` + + SealingSchedDiag func(p0 context.Context, p1 bool) (interface{}, error) `perm:"admin"` + + SectorGetExpectedSealDuration func(p0 context.Context) (time.Duration, error) `perm:"read"` + + SectorGetSealDelay func(p0 context.Context) (time.Duration, error) `perm:"read"` + + SectorMarkForUpgrade func(p0 context.Context, p1 abi.SectorNumber) error `perm:"admin"` + + SectorRemove func(p0 context.Context, p1 abi.SectorNumber) error `perm:"admin"` + + SectorSetExpectedSealDuration func(p0 context.Context, p1 time.Duration) error `perm:"write"` + + SectorSetSealDelay func(p0 context.Context, p1 time.Duration) error `perm:"write"` + + SectorStartSealing func(p0 context.Context, p1 abi.SectorNumber) error `perm:"write"` + + SectorTerminate func(p0 context.Context, p1 abi.SectorNumber) error `perm:"admin"` + + SectorTerminateFlush func(p0 context.Context) (*cid.Cid, error) `perm:"admin"` + + SectorTerminatePending func(p0 context.Context) ([]abi.SectorID, error) `perm:"admin"` + + SectorsList func(p0 context.Context) ([]abi.SectorNumber, error) `perm:"read"` + + SectorsListInStates func(p0 context.Context, p1 []SectorState) ([]abi.SectorNumber, error) `perm:"read"` + + SectorsRefs func(p0 context.Context) (map[string][]SealedRef, error) `perm:"read"` + + SectorsStatus func(p0 context.Context, p1 abi.SectorNumber, p2 bool) (SectorInfo, error) `perm:"read"` + + SectorsSummary func(p0 context.Context) (map[SectorState]int, error) `perm:"read"` + + SectorsUpdate func(p0 context.Context, p1 abi.SectorNumber, p2 SectorState) error `perm:"admin"` + + StorageAddLocal func(p0 context.Context, p1 string) error `perm:"admin"` + + StorageAttach func(p0 context.Context, p1 stores.StorageInfo, p2 fsutil.FsStat) error `perm:"admin"` + + StorageBestAlloc func(p0 context.Context, p1 storiface.SectorFileType, p2 abi.SectorSize, p3 storiface.PathType) ([]stores.StorageInfo, error) `perm:"admin"` + + StorageDeclareSector func(p0 context.Context, p1 stores.ID, p2 abi.SectorID, p3 storiface.SectorFileType, p4 bool) error `perm:"admin"` + + StorageDropSector func(p0 context.Context, p1 stores.ID, p2 abi.SectorID, p3 storiface.SectorFileType) error `perm:"admin"` + + StorageFindSector func(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 abi.SectorSize, p4 bool) ([]stores.SectorStorageInfo, error) `perm:"admin"` + + StorageInfo func(p0 context.Context, p1 stores.ID) (stores.StorageInfo, error) `perm:"admin"` + + StorageList func(p0 context.Context) (map[stores.ID][]stores.Decl, error) `perm:"admin"` + + StorageLocal func(p0 context.Context) (map[stores.ID]string, error) `perm:"admin"` + + StorageLock func(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 storiface.SectorFileType) error `perm:"admin"` + + StorageReportHealth func(p0 context.Context, p1 stores.ID, p2 stores.HealthReport) error `perm:"admin"` + + StorageStat func(p0 context.Context, p1 stores.ID) (fsutil.FsStat, error) `perm:"admin"` + + StorageTryLock func(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 storiface.SectorFileType) (bool, error) `perm:"admin"` + + WorkerConnect func(p0 context.Context, p1 string) error `perm:"admin"` + + WorkerJobs func(p0 context.Context) (map[uuid.UUID][]storiface.WorkerJob, error) `perm:"admin"` + + WorkerStats func(p0 context.Context) (map[uuid.UUID]storiface.WorkerStats, error) `perm:"admin"` + } +} + +type StorageMinerStub struct { + CommonStub +} + +type WalletStruct struct { + Internal struct { + WalletDelete func(p0 context.Context, p1 address.Address) error `` + + WalletExport func(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) `` + + WalletHas func(p0 context.Context, p1 address.Address) (bool, error) `` + + WalletImport func(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) `` + + WalletList func(p0 context.Context) ([]address.Address, error) `` + + WalletNew func(p0 context.Context, p1 types.KeyType) (address.Address, error) `` + + WalletSign func(p0 context.Context, p1 address.Address, p2 []byte, p3 MsgMeta) (*crypto.Signature, error) `` + } +} + +type WalletStub struct { +} + +type WorkerStruct struct { + Internal struct { + AddPiece func(p0 context.Context, p1 storage.SectorRef, p2 []abi.UnpaddedPieceSize, p3 abi.UnpaddedPieceSize, p4 storage.Data) (storiface.CallID, error) `perm:"admin"` + + Enabled func(p0 context.Context) (bool, error) `perm:"admin"` + + Fetch func(p0 context.Context, p1 storage.SectorRef, p2 storiface.SectorFileType, p3 storiface.PathType, p4 storiface.AcquireMode) (storiface.CallID, error) `perm:"admin"` + + FinalizeSector func(p0 context.Context, p1 storage.SectorRef, p2 []storage.Range) (storiface.CallID, error) `perm:"admin"` + + Info func(p0 context.Context) (storiface.WorkerInfo, error) `perm:"admin"` + + MoveStorage func(p0 context.Context, p1 storage.SectorRef, p2 storiface.SectorFileType) (storiface.CallID, error) `perm:"admin"` + + Paths func(p0 context.Context) ([]stores.StoragePath, error) `perm:"admin"` + + ProcessSession func(p0 context.Context) (uuid.UUID, error) `perm:"admin"` + + ReadPiece func(p0 context.Context, p1 io.Writer, p2 storage.SectorRef, p3 storiface.UnpaddedByteIndex, p4 abi.UnpaddedPieceSize) (storiface.CallID, error) `perm:"admin"` + + ReleaseUnsealed func(p0 context.Context, p1 storage.SectorRef, p2 []storage.Range) (storiface.CallID, error) `perm:"admin"` + + Remove func(p0 context.Context, p1 abi.SectorID) error `perm:"admin"` + + SealCommit1 func(p0 context.Context, p1 storage.SectorRef, p2 abi.SealRandomness, p3 abi.InteractiveSealRandomness, p4 []abi.PieceInfo, p5 storage.SectorCids) (storiface.CallID, error) `perm:"admin"` + + SealCommit2 func(p0 context.Context, p1 storage.SectorRef, p2 storage.Commit1Out) (storiface.CallID, error) `perm:"admin"` + + SealPreCommit1 func(p0 context.Context, p1 storage.SectorRef, p2 abi.SealRandomness, p3 []abi.PieceInfo) (storiface.CallID, error) `perm:"admin"` + + SealPreCommit2 func(p0 context.Context, p1 storage.SectorRef, p2 storage.PreCommit1Out) (storiface.CallID, error) `perm:"admin"` + + Session func(p0 context.Context) (uuid.UUID, error) `perm:"admin"` + + SetEnabled func(p0 context.Context, p1 bool) error `perm:"admin"` + + StorageAddLocal func(p0 context.Context, p1 string) error `perm:"admin"` + + TaskDisable func(p0 context.Context, p1 sealtasks.TaskType) error `perm:"admin"` + + TaskEnable func(p0 context.Context, p1 sealtasks.TaskType) error `perm:"admin"` + + TaskTypes func(p0 context.Context) (map[sealtasks.TaskType]struct{}, error) `perm:"admin"` + + UnsealPiece func(p0 context.Context, p1 storage.SectorRef, p2 storiface.UnpaddedByteIndex, p3 abi.UnpaddedPieceSize, p4 abi.SealRandomness, p5 cid.Cid) (storiface.CallID, error) `perm:"admin"` + + Version func(p0 context.Context) (Version, error) `perm:"admin"` + + WaitQuiet func(p0 context.Context) error `perm:"admin"` + } +} + +type WorkerStub struct { +} + +func (s *ChainIOStruct) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { + return s.Internal.ChainHasObj(p0, p1) +} + +func (s *ChainIOStub) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { + return false, xerrors.New("method not supported") +} + +func (s *ChainIOStruct) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { + return s.Internal.ChainReadObj(p0, p1) +} + +func (s *ChainIOStub) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { + return *new([]byte), xerrors.New("method not supported") +} + +func (s *CommonStruct) AuthNew(p0 context.Context, p1 []auth.Permission) ([]byte, error) { + return s.Internal.AuthNew(p0, p1) +} + +func (s *CommonStub) AuthNew(p0 context.Context, p1 []auth.Permission) ([]byte, error) { + return *new([]byte), xerrors.New("method not supported") +} + +func (s *CommonStruct) AuthVerify(p0 context.Context, p1 string) ([]auth.Permission, error) { + return s.Internal.AuthVerify(p0, p1) +} + +func (s *CommonStub) AuthVerify(p0 context.Context, p1 string) ([]auth.Permission, error) { + return *new([]auth.Permission), xerrors.New("method not supported") +} + +func (s *CommonStruct) Closing(p0 context.Context) (<-chan struct{}, error) { + return s.Internal.Closing(p0) +} + +func (s *CommonStub) Closing(p0 context.Context) (<-chan struct{}, error) { + return nil, xerrors.New("method not supported") +} + +func (s *CommonStruct) Discover(p0 context.Context) (apitypes.OpenRPCDocument, error) { + return s.Internal.Discover(p0) +} + +func (s *CommonStub) Discover(p0 context.Context) (apitypes.OpenRPCDocument, error) { + return *new(apitypes.OpenRPCDocument), xerrors.New("method not supported") +} + +func (s *CommonStruct) ID(p0 context.Context) (peer.ID, error) { + return s.Internal.ID(p0) +} + +func (s *CommonStub) ID(p0 context.Context) (peer.ID, error) { + return *new(peer.ID), xerrors.New("method not supported") +} + +func (s *CommonStruct) LogList(p0 context.Context) ([]string, error) { + return s.Internal.LogList(p0) +} + +func (s *CommonStub) LogList(p0 context.Context) ([]string, error) { + return *new([]string), xerrors.New("method not supported") +} + +func (s *CommonStruct) LogSetLevel(p0 context.Context, p1 string, p2 string) error { + return s.Internal.LogSetLevel(p0, p1, p2) +} + +func (s *CommonStub) LogSetLevel(p0 context.Context, p1 string, p2 string) error { + return xerrors.New("method not supported") +} + +func (s *CommonStruct) NetAddrsListen(p0 context.Context) (peer.AddrInfo, error) { + return s.Internal.NetAddrsListen(p0) +} + +func (s *CommonStub) NetAddrsListen(p0 context.Context) (peer.AddrInfo, error) { + return *new(peer.AddrInfo), xerrors.New("method not supported") +} + +func (s *CommonStruct) NetAgentVersion(p0 context.Context, p1 peer.ID) (string, error) { + return s.Internal.NetAgentVersion(p0, p1) +} + +func (s *CommonStub) NetAgentVersion(p0 context.Context, p1 peer.ID) (string, error) { + return "", xerrors.New("method not supported") +} + +func (s *CommonStruct) NetAutoNatStatus(p0 context.Context) (NatInfo, error) { + return s.Internal.NetAutoNatStatus(p0) +} + +func (s *CommonStub) NetAutoNatStatus(p0 context.Context) (NatInfo, error) { + return *new(NatInfo), xerrors.New("method not supported") +} + +func (s *CommonStruct) NetBandwidthStats(p0 context.Context) (metrics.Stats, error) { + return s.Internal.NetBandwidthStats(p0) +} + +func (s *CommonStub) NetBandwidthStats(p0 context.Context) (metrics.Stats, error) { + return *new(metrics.Stats), xerrors.New("method not supported") +} + +func (s *CommonStruct) NetBandwidthStatsByPeer(p0 context.Context) (map[string]metrics.Stats, error) { + return s.Internal.NetBandwidthStatsByPeer(p0) +} + +func (s *CommonStub) NetBandwidthStatsByPeer(p0 context.Context) (map[string]metrics.Stats, error) { + return *new(map[string]metrics.Stats), xerrors.New("method not supported") +} + +func (s *CommonStruct) NetBandwidthStatsByProtocol(p0 context.Context) (map[protocol.ID]metrics.Stats, error) { + return s.Internal.NetBandwidthStatsByProtocol(p0) +} + +func (s *CommonStub) NetBandwidthStatsByProtocol(p0 context.Context) (map[protocol.ID]metrics.Stats, error) { + return *new(map[protocol.ID]metrics.Stats), xerrors.New("method not supported") +} + +func (s *CommonStruct) NetBlockAdd(p0 context.Context, p1 NetBlockList) error { + return s.Internal.NetBlockAdd(p0, p1) +} + +func (s *CommonStub) NetBlockAdd(p0 context.Context, p1 NetBlockList) error { + return xerrors.New("method not supported") +} + +func (s *CommonStruct) NetBlockList(p0 context.Context) (NetBlockList, error) { + return s.Internal.NetBlockList(p0) +} + +func (s *CommonStub) NetBlockList(p0 context.Context) (NetBlockList, error) { + return *new(NetBlockList), xerrors.New("method not supported") +} + +func (s *CommonStruct) NetBlockRemove(p0 context.Context, p1 NetBlockList) error { + return s.Internal.NetBlockRemove(p0, p1) +} + +func (s *CommonStub) NetBlockRemove(p0 context.Context, p1 NetBlockList) error { + return xerrors.New("method not supported") +} + +func (s *CommonStruct) NetConnect(p0 context.Context, p1 peer.AddrInfo) error { + return s.Internal.NetConnect(p0, p1) +} + +func (s *CommonStub) NetConnect(p0 context.Context, p1 peer.AddrInfo) error { + return xerrors.New("method not supported") +} + +func (s *CommonStruct) NetConnectedness(p0 context.Context, p1 peer.ID) (network.Connectedness, error) { + return s.Internal.NetConnectedness(p0, p1) +} + +func (s *CommonStub) NetConnectedness(p0 context.Context, p1 peer.ID) (network.Connectedness, error) { + return *new(network.Connectedness), xerrors.New("method not supported") +} + +func (s *CommonStruct) NetDisconnect(p0 context.Context, p1 peer.ID) error { + return s.Internal.NetDisconnect(p0, p1) +} + +func (s *CommonStub) NetDisconnect(p0 context.Context, p1 peer.ID) error { + return xerrors.New("method not supported") +} + +func (s *CommonStruct) NetFindPeer(p0 context.Context, p1 peer.ID) (peer.AddrInfo, error) { + return s.Internal.NetFindPeer(p0, p1) +} + +func (s *CommonStub) NetFindPeer(p0 context.Context, p1 peer.ID) (peer.AddrInfo, error) { + return *new(peer.AddrInfo), xerrors.New("method not supported") +} + +func (s *CommonStruct) NetPeerInfo(p0 context.Context, p1 peer.ID) (*ExtendedPeerInfo, error) { + return s.Internal.NetPeerInfo(p0, p1) +} + +func (s *CommonStub) NetPeerInfo(p0 context.Context, p1 peer.ID) (*ExtendedPeerInfo, error) { + return nil, xerrors.New("method not supported") +} + +func (s *CommonStruct) NetPeers(p0 context.Context) ([]peer.AddrInfo, error) { + return s.Internal.NetPeers(p0) +} + +func (s *CommonStub) NetPeers(p0 context.Context) ([]peer.AddrInfo, error) { + return *new([]peer.AddrInfo), xerrors.New("method not supported") +} + +func (s *CommonStruct) NetPubsubScores(p0 context.Context) ([]PubsubScore, error) { + return s.Internal.NetPubsubScores(p0) +} + +func (s *CommonStub) NetPubsubScores(p0 context.Context) ([]PubsubScore, error) { + return *new([]PubsubScore), xerrors.New("method not supported") +} + +func (s *CommonStruct) Session(p0 context.Context) (uuid.UUID, error) { + return s.Internal.Session(p0) +} + +func (s *CommonStub) Session(p0 context.Context) (uuid.UUID, error) { + return *new(uuid.UUID), xerrors.New("method not supported") +} + +func (s *CommonStruct) Shutdown(p0 context.Context) error { + return s.Internal.Shutdown(p0) +} + +func (s *CommonStub) Shutdown(p0 context.Context) error { + return xerrors.New("method not supported") +} + +func (s *CommonStruct) Version(p0 context.Context) (APIVersion, error) { + return s.Internal.Version(p0) +} + +func (s *CommonStub) Version(p0 context.Context) (APIVersion, error) { + return *new(APIVersion), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) BeaconGetEntry(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) { + return s.Internal.BeaconGetEntry(p0, p1) +} + +func (s *FullNodeStub) BeaconGetEntry(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ChainDeleteObj(p0 context.Context, p1 cid.Cid) error { + return s.Internal.ChainDeleteObj(p0, p1) +} + +func (s *FullNodeStub) ChainDeleteObj(p0 context.Context, p1 cid.Cid) error { + return xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ChainExport(p0 context.Context, p1 abi.ChainEpoch, p2 bool, p3 types.TipSetKey) (<-chan []byte, error) { + return s.Internal.ChainExport(p0, p1, p2, p3) +} + +func (s *FullNodeStub) ChainExport(p0 context.Context, p1 abi.ChainEpoch, p2 bool, p3 types.TipSetKey) (<-chan []byte, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ChainGetBlock(p0 context.Context, p1 cid.Cid) (*types.BlockHeader, error) { + return s.Internal.ChainGetBlock(p0, p1) +} + +func (s *FullNodeStub) ChainGetBlock(p0 context.Context, p1 cid.Cid) (*types.BlockHeader, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*BlockMessages, error) { + return s.Internal.ChainGetBlockMessages(p0, p1) +} + +func (s *FullNodeStub) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*BlockMessages, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ChainGetGenesis(p0 context.Context) (*types.TipSet, error) { + return s.Internal.ChainGetGenesis(p0) +} + +func (s *FullNodeStub) ChainGetGenesis(p0 context.Context) (*types.TipSet, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ChainGetMessage(p0 context.Context, p1 cid.Cid) (*types.Message, error) { + return s.Internal.ChainGetMessage(p0, p1) +} + +func (s *FullNodeStub) ChainGetMessage(p0 context.Context, p1 cid.Cid) (*types.Message, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ChainGetNode(p0 context.Context, p1 string) (*IpldObject, error) { + return s.Internal.ChainGetNode(p0, p1) +} + +func (s *FullNodeStub) ChainGetNode(p0 context.Context, p1 string) (*IpldObject, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ChainGetParentMessages(p0 context.Context, p1 cid.Cid) ([]Message, error) { + return s.Internal.ChainGetParentMessages(p0, p1) +} + +func (s *FullNodeStub) ChainGetParentMessages(p0 context.Context, p1 cid.Cid) ([]Message, error) { + return *new([]Message), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ChainGetParentReceipts(p0 context.Context, p1 cid.Cid) ([]*types.MessageReceipt, error) { + return s.Internal.ChainGetParentReceipts(p0, p1) +} + +func (s *FullNodeStub) ChainGetParentReceipts(p0 context.Context, p1 cid.Cid) ([]*types.MessageReceipt, error) { + return *new([]*types.MessageReceipt), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ChainGetPath(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey) ([]*HeadChange, error) { + return s.Internal.ChainGetPath(p0, p1, p2) +} + +func (s *FullNodeStub) ChainGetPath(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey) ([]*HeadChange, error) { + return *new([]*HeadChange), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ChainGetRandomnessFromBeacon(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) { + return s.Internal.ChainGetRandomnessFromBeacon(p0, p1, p2, p3, p4) +} + +func (s *FullNodeStub) ChainGetRandomnessFromBeacon(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) { + return *new(abi.Randomness), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ChainGetRandomnessFromTickets(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) { + return s.Internal.ChainGetRandomnessFromTickets(p0, p1, p2, p3, p4) +} + +func (s *FullNodeStub) ChainGetRandomnessFromTickets(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) { + return *new(abi.Randomness), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ChainGetTipSet(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) { + return s.Internal.ChainGetTipSet(p0, p1) +} + +func (s *FullNodeStub) ChainGetTipSet(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ChainGetTipSetByHeight(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) { + return s.Internal.ChainGetTipSetByHeight(p0, p1, p2) +} + +func (s *FullNodeStub) ChainGetTipSetByHeight(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { + return s.Internal.ChainHasObj(p0, p1) +} + +func (s *FullNodeStub) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { + return false, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ChainHead(p0 context.Context) (*types.TipSet, error) { + return s.Internal.ChainHead(p0) +} + +func (s *FullNodeStub) ChainHead(p0 context.Context) (*types.TipSet, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ChainNotify(p0 context.Context) (<-chan []*HeadChange, error) { + return s.Internal.ChainNotify(p0) +} + +func (s *FullNodeStub) ChainNotify(p0 context.Context) (<-chan []*HeadChange, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { + return s.Internal.ChainReadObj(p0, p1) +} + +func (s *FullNodeStub) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { + return *new([]byte), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ChainSetHead(p0 context.Context, p1 types.TipSetKey) error { + return s.Internal.ChainSetHead(p0, p1) +} + +func (s *FullNodeStub) ChainSetHead(p0 context.Context, p1 types.TipSetKey) error { + return xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ChainStatObj(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (ObjStat, error) { + return s.Internal.ChainStatObj(p0, p1, p2) +} + +func (s *FullNodeStub) ChainStatObj(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (ObjStat, error) { + return *new(ObjStat), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ChainTipSetWeight(p0 context.Context, p1 types.TipSetKey) (types.BigInt, error) { + return s.Internal.ChainTipSetWeight(p0, p1) +} + +func (s *FullNodeStub) ChainTipSetWeight(p0 context.Context, p1 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ClientCalcCommP(p0 context.Context, p1 string) (*CommPRet, error) { + return s.Internal.ClientCalcCommP(p0, p1) +} + +func (s *FullNodeStub) ClientCalcCommP(p0 context.Context, p1 string) (*CommPRet, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ClientCancelDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { + return s.Internal.ClientCancelDataTransfer(p0, p1, p2, p3) +} + +func (s *FullNodeStub) ClientCancelDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { + return xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ClientCancelRetrievalDeal(p0 context.Context, p1 retrievalmarket.DealID) error { + return s.Internal.ClientCancelRetrievalDeal(p0, p1) +} + +func (s *FullNodeStub) ClientCancelRetrievalDeal(p0 context.Context, p1 retrievalmarket.DealID) error { + return xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ClientDataTransferUpdates(p0 context.Context) (<-chan DataTransferChannel, error) { + return s.Internal.ClientDataTransferUpdates(p0) +} + +func (s *FullNodeStub) ClientDataTransferUpdates(p0 context.Context) (<-chan DataTransferChannel, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ClientDealPieceCID(p0 context.Context, p1 cid.Cid) (DataCIDSize, error) { + return s.Internal.ClientDealPieceCID(p0, p1) +} + +func (s *FullNodeStub) ClientDealPieceCID(p0 context.Context, p1 cid.Cid) (DataCIDSize, error) { + return *new(DataCIDSize), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ClientDealSize(p0 context.Context, p1 cid.Cid) (DataSize, error) { + return s.Internal.ClientDealSize(p0, p1) +} + +func (s *FullNodeStub) ClientDealSize(p0 context.Context, p1 cid.Cid) (DataSize, error) { + return *new(DataSize), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ClientFindData(p0 context.Context, p1 cid.Cid, p2 *cid.Cid) ([]QueryOffer, error) { + return s.Internal.ClientFindData(p0, p1, p2) +} + +func (s *FullNodeStub) ClientFindData(p0 context.Context, p1 cid.Cid, p2 *cid.Cid) ([]QueryOffer, error) { + return *new([]QueryOffer), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ClientGenCar(p0 context.Context, p1 FileRef, p2 string) error { + return s.Internal.ClientGenCar(p0, p1, p2) +} + +func (s *FullNodeStub) ClientGenCar(p0 context.Context, p1 FileRef, p2 string) error { + return xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ClientGetDealInfo(p0 context.Context, p1 cid.Cid) (*DealInfo, error) { + return s.Internal.ClientGetDealInfo(p0, p1) +} + +func (s *FullNodeStub) ClientGetDealInfo(p0 context.Context, p1 cid.Cid) (*DealInfo, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ClientGetDealStatus(p0 context.Context, p1 uint64) (string, error) { + return s.Internal.ClientGetDealStatus(p0, p1) +} + +func (s *FullNodeStub) ClientGetDealStatus(p0 context.Context, p1 uint64) (string, error) { + return "", xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ClientGetDealUpdates(p0 context.Context) (<-chan DealInfo, error) { + return s.Internal.ClientGetDealUpdates(p0) +} + +func (s *FullNodeStub) ClientGetDealUpdates(p0 context.Context) (<-chan DealInfo, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ClientHasLocal(p0 context.Context, p1 cid.Cid) (bool, error) { + return s.Internal.ClientHasLocal(p0, p1) +} + +func (s *FullNodeStub) ClientHasLocal(p0 context.Context, p1 cid.Cid) (bool, error) { + return false, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ClientImport(p0 context.Context, p1 FileRef) (*ImportRes, error) { + return s.Internal.ClientImport(p0, p1) +} + +func (s *FullNodeStub) ClientImport(p0 context.Context, p1 FileRef) (*ImportRes, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ClientListDataTransfers(p0 context.Context) ([]DataTransferChannel, error) { + return s.Internal.ClientListDataTransfers(p0) +} + +func (s *FullNodeStub) ClientListDataTransfers(p0 context.Context) ([]DataTransferChannel, error) { + return *new([]DataTransferChannel), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ClientListDeals(p0 context.Context) ([]DealInfo, error) { + return s.Internal.ClientListDeals(p0) +} + +func (s *FullNodeStub) ClientListDeals(p0 context.Context) ([]DealInfo, error) { + return *new([]DealInfo), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ClientListImports(p0 context.Context) ([]Import, error) { + return s.Internal.ClientListImports(p0) +} + +func (s *FullNodeStub) ClientListImports(p0 context.Context) ([]Import, error) { + return *new([]Import), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ClientMinerQueryOffer(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (QueryOffer, error) { + return s.Internal.ClientMinerQueryOffer(p0, p1, p2, p3) +} + +func (s *FullNodeStub) ClientMinerQueryOffer(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (QueryOffer, error) { + return *new(QueryOffer), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ClientQueryAsk(p0 context.Context, p1 peer.ID, p2 address.Address) (*storagemarket.StorageAsk, error) { + return s.Internal.ClientQueryAsk(p0, p1, p2) +} + +func (s *FullNodeStub) ClientQueryAsk(p0 context.Context, p1 peer.ID, p2 address.Address) (*storagemarket.StorageAsk, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ClientRemoveImport(p0 context.Context, p1 multistore.StoreID) error { + return s.Internal.ClientRemoveImport(p0, p1) +} + +func (s *FullNodeStub) ClientRemoveImport(p0 context.Context, p1 multistore.StoreID) error { + return xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ClientRestartDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { + return s.Internal.ClientRestartDataTransfer(p0, p1, p2, p3) +} + +func (s *FullNodeStub) ClientRestartDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { + return xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ClientRetrieve(p0 context.Context, p1 RetrievalOrder, p2 *FileRef) error { + return s.Internal.ClientRetrieve(p0, p1, p2) +} + +func (s *FullNodeStub) ClientRetrieve(p0 context.Context, p1 RetrievalOrder, p2 *FileRef) error { + return xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ClientRetrieveTryRestartInsufficientFunds(p0 context.Context, p1 address.Address) error { + return s.Internal.ClientRetrieveTryRestartInsufficientFunds(p0, p1) +} + +func (s *FullNodeStub) ClientRetrieveTryRestartInsufficientFunds(p0 context.Context, p1 address.Address) error { + return xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ClientRetrieveWithEvents(p0 context.Context, p1 RetrievalOrder, p2 *FileRef) (<-chan marketevents.RetrievalEvent, error) { + return s.Internal.ClientRetrieveWithEvents(p0, p1, p2) +} + +func (s *FullNodeStub) ClientRetrieveWithEvents(p0 context.Context, p1 RetrievalOrder, p2 *FileRef) (<-chan marketevents.RetrievalEvent, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) ClientStartDeal(p0 context.Context, p1 *StartDealParams) (*cid.Cid, error) { + return s.Internal.ClientStartDeal(p0, p1) +} + +func (s *FullNodeStub) ClientStartDeal(p0 context.Context, p1 *StartDealParams) (*cid.Cid, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) CreateBackup(p0 context.Context, p1 string) error { + return s.Internal.CreateBackup(p0, p1) +} + +func (s *FullNodeStub) CreateBackup(p0 context.Context, p1 string) error { + return xerrors.New("method not supported") +} + +func (s *FullNodeStruct) GasEstimateFeeCap(p0 context.Context, p1 *types.Message, p2 int64, p3 types.TipSetKey) (types.BigInt, error) { + return s.Internal.GasEstimateFeeCap(p0, p1, p2, p3) +} + +func (s *FullNodeStub) GasEstimateFeeCap(p0 context.Context, p1 *types.Message, p2 int64, p3 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) GasEstimateGasLimit(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (int64, error) { + return s.Internal.GasEstimateGasLimit(p0, p1, p2) +} + +func (s *FullNodeStub) GasEstimateGasLimit(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (int64, error) { + return 0, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) GasEstimateGasPremium(p0 context.Context, p1 uint64, p2 address.Address, p3 int64, p4 types.TipSetKey) (types.BigInt, error) { + return s.Internal.GasEstimateGasPremium(p0, p1, p2, p3, p4) +} + +func (s *FullNodeStub) GasEstimateGasPremium(p0 context.Context, p1 uint64, p2 address.Address, p3 int64, p4 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { + return s.Internal.GasEstimateMessageGas(p0, p1, p2, p3) +} + +func (s *FullNodeStub) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MarketAddBalance(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { + return s.Internal.MarketAddBalance(p0, p1, p2, p3) +} + +func (s *FullNodeStub) MarketAddBalance(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MarketGetReserved(p0 context.Context, p1 address.Address) (types.BigInt, error) { + return s.Internal.MarketGetReserved(p0, p1) +} + +func (s *FullNodeStub) MarketGetReserved(p0 context.Context, p1 address.Address) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MarketReleaseFunds(p0 context.Context, p1 address.Address, p2 types.BigInt) error { + return s.Internal.MarketReleaseFunds(p0, p1, p2) +} + +func (s *FullNodeStub) MarketReleaseFunds(p0 context.Context, p1 address.Address, p2 types.BigInt) error { + return xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MarketReserveFunds(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { + return s.Internal.MarketReserveFunds(p0, p1, p2, p3) +} + +func (s *FullNodeStub) MarketReserveFunds(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MarketWithdraw(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { + return s.Internal.MarketWithdraw(p0, p1, p2, p3) +} + +func (s *FullNodeStub) MarketWithdraw(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MinerCreateBlock(p0 context.Context, p1 *BlockTemplate) (*types.BlockMsg, error) { + return s.Internal.MinerCreateBlock(p0, p1) +} + +func (s *FullNodeStub) MinerCreateBlock(p0 context.Context, p1 *BlockTemplate) (*types.BlockMsg, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MinerGetBaseInfo(p0 context.Context, p1 address.Address, p2 abi.ChainEpoch, p3 types.TipSetKey) (*MiningBaseInfo, error) { + return s.Internal.MinerGetBaseInfo(p0, p1, p2, p3) +} + +func (s *FullNodeStub) MinerGetBaseInfo(p0 context.Context, p1 address.Address, p2 abi.ChainEpoch, p3 types.TipSetKey) (*MiningBaseInfo, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MpoolBatchPush(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) { + return s.Internal.MpoolBatchPush(p0, p1) +} + +func (s *FullNodeStub) MpoolBatchPush(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) { + return *new([]cid.Cid), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MpoolBatchPushMessage(p0 context.Context, p1 []*types.Message, p2 *MessageSendSpec) ([]*types.SignedMessage, error) { + return s.Internal.MpoolBatchPushMessage(p0, p1, p2) +} + +func (s *FullNodeStub) MpoolBatchPushMessage(p0 context.Context, p1 []*types.Message, p2 *MessageSendSpec) ([]*types.SignedMessage, error) { + return *new([]*types.SignedMessage), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MpoolBatchPushUntrusted(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) { + return s.Internal.MpoolBatchPushUntrusted(p0, p1) +} + +func (s *FullNodeStub) MpoolBatchPushUntrusted(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) { + return *new([]cid.Cid), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MpoolCheckMessages(p0 context.Context, p1 []*MessagePrototype) ([][]MessageCheckStatus, error) { + return s.Internal.MpoolCheckMessages(p0, p1) +} + +func (s *FullNodeStub) MpoolCheckMessages(p0 context.Context, p1 []*MessagePrototype) ([][]MessageCheckStatus, error) { + return *new([][]MessageCheckStatus), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MpoolCheckPendingMessages(p0 context.Context, p1 address.Address) ([][]MessageCheckStatus, error) { + return s.Internal.MpoolCheckPendingMessages(p0, p1) +} + +func (s *FullNodeStub) MpoolCheckPendingMessages(p0 context.Context, p1 address.Address) ([][]MessageCheckStatus, error) { + return *new([][]MessageCheckStatus), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MpoolCheckReplaceMessages(p0 context.Context, p1 []*types.Message) ([][]MessageCheckStatus, error) { + return s.Internal.MpoolCheckReplaceMessages(p0, p1) +} + +func (s *FullNodeStub) MpoolCheckReplaceMessages(p0 context.Context, p1 []*types.Message) ([][]MessageCheckStatus, error) { + return *new([][]MessageCheckStatus), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MpoolClear(p0 context.Context, p1 bool) error { + return s.Internal.MpoolClear(p0, p1) +} + +func (s *FullNodeStub) MpoolClear(p0 context.Context, p1 bool) error { + return xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MpoolGetConfig(p0 context.Context) (*types.MpoolConfig, error) { + return s.Internal.MpoolGetConfig(p0) +} + +func (s *FullNodeStub) MpoolGetConfig(p0 context.Context) (*types.MpoolConfig, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MpoolGetNonce(p0 context.Context, p1 address.Address) (uint64, error) { + return s.Internal.MpoolGetNonce(p0, p1) +} + +func (s *FullNodeStub) MpoolGetNonce(p0 context.Context, p1 address.Address) (uint64, error) { + return 0, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MpoolPending(p0 context.Context, p1 types.TipSetKey) ([]*types.SignedMessage, error) { + return s.Internal.MpoolPending(p0, p1) +} + +func (s *FullNodeStub) MpoolPending(p0 context.Context, p1 types.TipSetKey) ([]*types.SignedMessage, error) { + return *new([]*types.SignedMessage), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MpoolPush(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { + return s.Internal.MpoolPush(p0, p1) +} + +func (s *FullNodeStub) MpoolPush(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MpoolPushMessage(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec) (*types.SignedMessage, error) { + return s.Internal.MpoolPushMessage(p0, p1, p2) +} + +func (s *FullNodeStub) MpoolPushMessage(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec) (*types.SignedMessage, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MpoolPushUntrusted(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { + return s.Internal.MpoolPushUntrusted(p0, p1) +} + +func (s *FullNodeStub) MpoolPushUntrusted(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MpoolSelect(p0 context.Context, p1 types.TipSetKey, p2 float64) ([]*types.SignedMessage, error) { + return s.Internal.MpoolSelect(p0, p1, p2) +} + +func (s *FullNodeStub) MpoolSelect(p0 context.Context, p1 types.TipSetKey, p2 float64) ([]*types.SignedMessage, error) { + return *new([]*types.SignedMessage), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MpoolSetConfig(p0 context.Context, p1 *types.MpoolConfig) error { + return s.Internal.MpoolSetConfig(p0, p1) +} + +func (s *FullNodeStub) MpoolSetConfig(p0 context.Context, p1 *types.MpoolConfig) error { + return xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MpoolSub(p0 context.Context) (<-chan MpoolUpdate, error) { + return s.Internal.MpoolSub(p0) +} + +func (s *FullNodeStub) MpoolSub(p0 context.Context) (<-chan MpoolUpdate, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MsigAddApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (*MessagePrototype, error) { + return s.Internal.MsigAddApprove(p0, p1, p2, p3, p4, p5, p6) +} + +func (s *FullNodeStub) MsigAddApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (*MessagePrototype, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MsigAddCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (*MessagePrototype, error) { + return s.Internal.MsigAddCancel(p0, p1, p2, p3, p4, p5) +} + +func (s *FullNodeStub) MsigAddCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (*MessagePrototype, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MsigAddPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (*MessagePrototype, error) { + return s.Internal.MsigAddPropose(p0, p1, p2, p3, p4) +} + +func (s *FullNodeStub) MsigAddPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (*MessagePrototype, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MsigApprove(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (*MessagePrototype, error) { + return s.Internal.MsigApprove(p0, p1, p2, p3) +} + +func (s *FullNodeStub) MsigApprove(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (*MessagePrototype, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MsigApproveTxnHash(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 address.Address, p5 types.BigInt, p6 address.Address, p7 uint64, p8 []byte) (*MessagePrototype, error) { + return s.Internal.MsigApproveTxnHash(p0, p1, p2, p3, p4, p5, p6, p7, p8) +} + +func (s *FullNodeStub) MsigApproveTxnHash(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 address.Address, p5 types.BigInt, p6 address.Address, p7 uint64, p8 []byte) (*MessagePrototype, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MsigCancel(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (*MessagePrototype, error) { + return s.Internal.MsigCancel(p0, p1, p2, p3, p4, p5, p6, p7) +} + +func (s *FullNodeStub) MsigCancel(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (*MessagePrototype, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MsigCreate(p0 context.Context, p1 uint64, p2 []address.Address, p3 abi.ChainEpoch, p4 types.BigInt, p5 address.Address, p6 types.BigInt) (*MessagePrototype, error) { + return s.Internal.MsigCreate(p0, p1, p2, p3, p4, p5, p6) +} + +func (s *FullNodeStub) MsigCreate(p0 context.Context, p1 uint64, p2 []address.Address, p3 abi.ChainEpoch, p4 types.BigInt, p5 address.Address, p6 types.BigInt) (*MessagePrototype, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MsigGetAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { + return s.Internal.MsigGetAvailableBalance(p0, p1, p2) +} + +func (s *FullNodeStub) MsigGetAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MsigGetPending(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*MsigTransaction, error) { + return s.Internal.MsigGetPending(p0, p1, p2) +} + +func (s *FullNodeStub) MsigGetPending(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*MsigTransaction, error) { + return *new([]*MsigTransaction), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MsigGetVested(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) { + return s.Internal.MsigGetVested(p0, p1, p2, p3) +} + +func (s *FullNodeStub) MsigGetVested(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MsigGetVestingSchedule(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MsigVesting, error) { + return s.Internal.MsigGetVestingSchedule(p0, p1, p2) +} + +func (s *FullNodeStub) MsigGetVestingSchedule(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MsigVesting, error) { + return *new(MsigVesting), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MsigPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (*MessagePrototype, error) { + return s.Internal.MsigPropose(p0, p1, p2, p3, p4, p5, p6) +} + +func (s *FullNodeStub) MsigPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (*MessagePrototype, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MsigRemoveSigner(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (*MessagePrototype, error) { + return s.Internal.MsigRemoveSigner(p0, p1, p2, p3, p4) +} + +func (s *FullNodeStub) MsigRemoveSigner(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (*MessagePrototype, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MsigSwapApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 address.Address) (*MessagePrototype, error) { + return s.Internal.MsigSwapApprove(p0, p1, p2, p3, p4, p5, p6) +} + +func (s *FullNodeStub) MsigSwapApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 address.Address) (*MessagePrototype, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MsigSwapCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (*MessagePrototype, error) { + return s.Internal.MsigSwapCancel(p0, p1, p2, p3, p4, p5) +} + +func (s *FullNodeStub) MsigSwapCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (*MessagePrototype, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) MsigSwapPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (*MessagePrototype, error) { + return s.Internal.MsigSwapPropose(p0, p1, p2, p3, p4) +} + +func (s *FullNodeStub) MsigSwapPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (*MessagePrototype, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) NodeStatus(p0 context.Context, p1 bool) (NodeStatus, error) { + return s.Internal.NodeStatus(p0, p1) +} + +func (s *FullNodeStub) NodeStatus(p0 context.Context, p1 bool) (NodeStatus, error) { + return *new(NodeStatus), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) PaychAllocateLane(p0 context.Context, p1 address.Address) (uint64, error) { + return s.Internal.PaychAllocateLane(p0, p1) +} + +func (s *FullNodeStub) PaychAllocateLane(p0 context.Context, p1 address.Address) (uint64, error) { + return 0, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) PaychAvailableFunds(p0 context.Context, p1 address.Address) (*ChannelAvailableFunds, error) { + return s.Internal.PaychAvailableFunds(p0, p1) +} + +func (s *FullNodeStub) PaychAvailableFunds(p0 context.Context, p1 address.Address) (*ChannelAvailableFunds, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) PaychAvailableFundsByFromTo(p0 context.Context, p1 address.Address, p2 address.Address) (*ChannelAvailableFunds, error) { + return s.Internal.PaychAvailableFundsByFromTo(p0, p1, p2) +} + +func (s *FullNodeStub) PaychAvailableFundsByFromTo(p0 context.Context, p1 address.Address, p2 address.Address) (*ChannelAvailableFunds, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) PaychCollect(p0 context.Context, p1 address.Address) (cid.Cid, error) { + return s.Internal.PaychCollect(p0, p1) +} + +func (s *FullNodeStub) PaychCollect(p0 context.Context, p1 address.Address) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) PaychGet(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*ChannelInfo, error) { + return s.Internal.PaychGet(p0, p1, p2, p3) +} + +func (s *FullNodeStub) PaychGet(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*ChannelInfo, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) PaychGetWaitReady(p0 context.Context, p1 cid.Cid) (address.Address, error) { + return s.Internal.PaychGetWaitReady(p0, p1) +} + +func (s *FullNodeStub) PaychGetWaitReady(p0 context.Context, p1 cid.Cid) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) PaychList(p0 context.Context) ([]address.Address, error) { + return s.Internal.PaychList(p0) +} + +func (s *FullNodeStub) PaychList(p0 context.Context) ([]address.Address, error) { + return *new([]address.Address), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) PaychNewPayment(p0 context.Context, p1 address.Address, p2 address.Address, p3 []VoucherSpec) (*PaymentInfo, error) { + return s.Internal.PaychNewPayment(p0, p1, p2, p3) +} + +func (s *FullNodeStub) PaychNewPayment(p0 context.Context, p1 address.Address, p2 address.Address, p3 []VoucherSpec) (*PaymentInfo, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) PaychSettle(p0 context.Context, p1 address.Address) (cid.Cid, error) { + return s.Internal.PaychSettle(p0, p1) +} + +func (s *FullNodeStub) PaychSettle(p0 context.Context, p1 address.Address) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) PaychStatus(p0 context.Context, p1 address.Address) (*PaychStatus, error) { + return s.Internal.PaychStatus(p0, p1) +} + +func (s *FullNodeStub) PaychStatus(p0 context.Context, p1 address.Address) (*PaychStatus, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) PaychVoucherAdd(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 types.BigInt) (types.BigInt, error) { + return s.Internal.PaychVoucherAdd(p0, p1, p2, p3, p4) +} + +func (s *FullNodeStub) PaychVoucherAdd(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 types.BigInt) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) PaychVoucherCheckSpendable(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (bool, error) { + return s.Internal.PaychVoucherCheckSpendable(p0, p1, p2, p3, p4) +} + +func (s *FullNodeStub) PaychVoucherCheckSpendable(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (bool, error) { + return false, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) PaychVoucherCheckValid(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher) error { + return s.Internal.PaychVoucherCheckValid(p0, p1, p2) +} + +func (s *FullNodeStub) PaychVoucherCheckValid(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher) error { + return xerrors.New("method not supported") +} + +func (s *FullNodeStruct) PaychVoucherCreate(p0 context.Context, p1 address.Address, p2 types.BigInt, p3 uint64) (*VoucherCreateResult, error) { + return s.Internal.PaychVoucherCreate(p0, p1, p2, p3) +} + +func (s *FullNodeStub) PaychVoucherCreate(p0 context.Context, p1 address.Address, p2 types.BigInt, p3 uint64) (*VoucherCreateResult, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) PaychVoucherList(p0 context.Context, p1 address.Address) ([]*paych.SignedVoucher, error) { + return s.Internal.PaychVoucherList(p0, p1) +} + +func (s *FullNodeStub) PaychVoucherList(p0 context.Context, p1 address.Address) ([]*paych.SignedVoucher, error) { + return *new([]*paych.SignedVoucher), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) PaychVoucherSubmit(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (cid.Cid, error) { + return s.Internal.PaychVoucherSubmit(p0, p1, p2, p3, p4) +} + +func (s *FullNodeStub) PaychVoucherSubmit(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + return s.Internal.StateAccountKey(p0, p1, p2) +} + +func (s *FullNodeStub) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateAllMinerFaults(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) ([]*Fault, error) { + return s.Internal.StateAllMinerFaults(p0, p1, p2) +} + +func (s *FullNodeStub) StateAllMinerFaults(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) ([]*Fault, error) { + return *new([]*Fault), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateCall(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*InvocResult, error) { + return s.Internal.StateCall(p0, p1, p2) +} + +func (s *FullNodeStub) StateCall(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*InvocResult, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateChangedActors(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (map[string]types.Actor, error) { + return s.Internal.StateChangedActors(p0, p1, p2) +} + +func (s *FullNodeStub) StateChangedActors(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (map[string]types.Actor, error) { + return *new(map[string]types.Actor), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateCirculatingSupply(p0 context.Context, p1 types.TipSetKey) (abi.TokenAmount, error) { + return s.Internal.StateCirculatingSupply(p0, p1) +} + +func (s *FullNodeStub) StateCirculatingSupply(p0 context.Context, p1 types.TipSetKey) (abi.TokenAmount, error) { + return *new(abi.TokenAmount), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateCompute(p0 context.Context, p1 abi.ChainEpoch, p2 []*types.Message, p3 types.TipSetKey) (*ComputeStateOutput, error) { + return s.Internal.StateCompute(p0, p1, p2, p3) +} + +func (s *FullNodeStub) StateCompute(p0 context.Context, p1 abi.ChainEpoch, p2 []*types.Message, p3 types.TipSetKey) (*ComputeStateOutput, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (DealCollateralBounds, error) { + return s.Internal.StateDealProviderCollateralBounds(p0, p1, p2, p3) +} + +func (s *FullNodeStub) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (DealCollateralBounds, error) { + return *new(DealCollateralBounds), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateDecodeParams(p0 context.Context, p1 address.Address, p2 abi.MethodNum, p3 []byte, p4 types.TipSetKey) (interface{}, error) { + return s.Internal.StateDecodeParams(p0, p1, p2, p3, p4) +} + +func (s *FullNodeStub) StateDecodeParams(p0 context.Context, p1 address.Address, p2 abi.MethodNum, p3 []byte, p4 types.TipSetKey) (interface{}, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) { + return s.Internal.StateGetActor(p0, p1, p2) +} + +func (s *FullNodeStub) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateListActors(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { + return s.Internal.StateListActors(p0, p1) +} + +func (s *FullNodeStub) StateListActors(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { + return *new([]address.Address), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateListMessages(p0 context.Context, p1 *MessageMatch, p2 types.TipSetKey, p3 abi.ChainEpoch) ([]cid.Cid, error) { + return s.Internal.StateListMessages(p0, p1, p2, p3) +} + +func (s *FullNodeStub) StateListMessages(p0 context.Context, p1 *MessageMatch, p2 types.TipSetKey, p3 abi.ChainEpoch) ([]cid.Cid, error) { + return *new([]cid.Cid), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateListMiners(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { + return s.Internal.StateListMiners(p0, p1) +} + +func (s *FullNodeStub) StateListMiners(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { + return *new([]address.Address), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateLookupID(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + return s.Internal.StateLookupID(p0, p1, p2) +} + +func (s *FullNodeStub) StateLookupID(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MarketBalance, error) { + return s.Internal.StateMarketBalance(p0, p1, p2) +} + +func (s *FullNodeStub) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MarketBalance, error) { + return *new(MarketBalance), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateMarketDeals(p0 context.Context, p1 types.TipSetKey) (map[string]MarketDeal, error) { + return s.Internal.StateMarketDeals(p0, p1) +} + +func (s *FullNodeStub) StateMarketDeals(p0 context.Context, p1 types.TipSetKey) (map[string]MarketDeal, error) { + return *new(map[string]MarketDeal), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateMarketParticipants(p0 context.Context, p1 types.TipSetKey) (map[string]MarketBalance, error) { + return s.Internal.StateMarketParticipants(p0, p1) +} + +func (s *FullNodeStub) StateMarketParticipants(p0 context.Context, p1 types.TipSetKey) (map[string]MarketBalance, error) { + return *new(map[string]MarketBalance), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*MarketDeal, error) { + return s.Internal.StateMarketStorageDeal(p0, p1, p2) +} + +func (s *FullNodeStub) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*MarketDeal, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateMinerActiveSectors(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { + return s.Internal.StateMinerActiveSectors(p0, p1, p2) +} + +func (s *FullNodeStub) StateMinerActiveSectors(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { + return *new([]*miner.SectorOnChainInfo), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateMinerAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { + return s.Internal.StateMinerAvailableBalance(p0, p1, p2) +} + +func (s *FullNodeStub) StateMinerAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateMinerDeadlines(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]Deadline, error) { + return s.Internal.StateMinerDeadlines(p0, p1, p2) +} + +func (s *FullNodeStub) StateMinerDeadlines(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]Deadline, error) { + return *new([]Deadline), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateMinerFaults(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) { + return s.Internal.StateMinerFaults(p0, p1, p2) +} + +func (s *FullNodeStub) StateMinerFaults(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) { + return *new(bitfield.BitField), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateMinerInfo(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) { + return s.Internal.StateMinerInfo(p0, p1, p2) +} + +func (s *FullNodeStub) StateMinerInfo(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) { + return *new(miner.MinerInfo), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateMinerInitialPledgeCollateral(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) { + return s.Internal.StateMinerInitialPledgeCollateral(p0, p1, p2, p3) +} + +func (s *FullNodeStub) StateMinerInitialPledgeCollateral(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateMinerPartitions(p0 context.Context, p1 address.Address, p2 uint64, p3 types.TipSetKey) ([]Partition, error) { + return s.Internal.StateMinerPartitions(p0, p1, p2, p3) +} + +func (s *FullNodeStub) StateMinerPartitions(p0 context.Context, p1 address.Address, p2 uint64, p3 types.TipSetKey) ([]Partition, error) { + return *new([]Partition), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*MinerPower, error) { + return s.Internal.StateMinerPower(p0, p1, p2) +} + +func (s *FullNodeStub) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*MinerPower, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateMinerPreCommitDepositForPower(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) { + return s.Internal.StateMinerPreCommitDepositForPower(p0, p1, p2, p3) +} + +func (s *FullNodeStub) StateMinerPreCommitDepositForPower(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateMinerProvingDeadline(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) { + return s.Internal.StateMinerProvingDeadline(p0, p1, p2) +} + +func (s *FullNodeStub) StateMinerProvingDeadline(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateMinerRecoveries(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) { + return s.Internal.StateMinerRecoveries(p0, p1, p2) +} + +func (s *FullNodeStub) StateMinerRecoveries(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) { + return *new(bitfield.BitField), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateMinerSectorAllocated(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (bool, error) { + return s.Internal.StateMinerSectorAllocated(p0, p1, p2, p3) +} + +func (s *FullNodeStub) StateMinerSectorAllocated(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (bool, error) { + return false, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateMinerSectorCount(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MinerSectors, error) { + return s.Internal.StateMinerSectorCount(p0, p1, p2) +} + +func (s *FullNodeStub) StateMinerSectorCount(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MinerSectors, error) { + return *new(MinerSectors), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateMinerSectors(p0 context.Context, p1 address.Address, p2 *bitfield.BitField, p3 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { + return s.Internal.StateMinerSectors(p0, p1, p2, p3) +} + +func (s *FullNodeStub) StateMinerSectors(p0 context.Context, p1 address.Address, p2 *bitfield.BitField, p3 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { + return *new([]*miner.SectorOnChainInfo), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateNetworkName(p0 context.Context) (dtypes.NetworkName, error) { + return s.Internal.StateNetworkName(p0) +} + +func (s *FullNodeStub) StateNetworkName(p0 context.Context) (dtypes.NetworkName, error) { + return *new(dtypes.NetworkName), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) { + return s.Internal.StateNetworkVersion(p0, p1) +} + +func (s *FullNodeStub) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) { + return *new(apitypes.NetworkVersion), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateReadState(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*ActorState, error) { + return s.Internal.StateReadState(p0, p1, p2) +} + +func (s *FullNodeStub) StateReadState(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*ActorState, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateReplay(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*InvocResult, error) { + return s.Internal.StateReplay(p0, p1, p2) +} + +func (s *FullNodeStub) StateReplay(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*InvocResult, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateSearchMsg(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) { + return s.Internal.StateSearchMsg(p0, p1, p2, p3, p4) +} + +func (s *FullNodeStub) StateSearchMsg(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateSectorExpiration(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorExpiration, error) { + return s.Internal.StateSectorExpiration(p0, p1, p2, p3) +} + +func (s *FullNodeStub) StateSectorExpiration(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorExpiration, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { + return s.Internal.StateSectorGetInfo(p0, p1, p2, p3) +} + +func (s *FullNodeStub) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateSectorPartition(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorLocation, error) { + return s.Internal.StateSectorPartition(p0, p1, p2, p3) +} + +func (s *FullNodeStub) StateSectorPartition(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorLocation, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateSectorPreCommitInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) { + return s.Internal.StateSectorPreCommitInfo(p0, p1, p2, p3) +} + +func (s *FullNodeStub) StateSectorPreCommitInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) { + return *new(miner.SectorPreCommitOnChainInfo), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateVMCirculatingSupplyInternal(p0 context.Context, p1 types.TipSetKey) (CirculatingSupply, error) { + return s.Internal.StateVMCirculatingSupplyInternal(p0, p1) +} + +func (s *FullNodeStub) StateVMCirculatingSupplyInternal(p0 context.Context, p1 types.TipSetKey) (CirculatingSupply, error) { + return *new(CirculatingSupply), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateVerifiedClientStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { + return s.Internal.StateVerifiedClientStatus(p0, p1, p2) +} + +func (s *FullNodeStub) StateVerifiedClientStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateVerifiedRegistryRootKey(p0 context.Context, p1 types.TipSetKey) (address.Address, error) { + return s.Internal.StateVerifiedRegistryRootKey(p0, p1) +} + +func (s *FullNodeStub) StateVerifiedRegistryRootKey(p0 context.Context, p1 types.TipSetKey) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateVerifierStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { + return s.Internal.StateVerifierStatus(p0, p1, p2) +} + +func (s *FullNodeStub) StateVerifierStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) { + return s.Internal.StateWaitMsg(p0, p1, p2, p3, p4) +} + +func (s *FullNodeStub) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) SyncCheckBad(p0 context.Context, p1 cid.Cid) (string, error) { + return s.Internal.SyncCheckBad(p0, p1) +} + +func (s *FullNodeStub) SyncCheckBad(p0 context.Context, p1 cid.Cid) (string, error) { + return "", xerrors.New("method not supported") +} + +func (s *FullNodeStruct) SyncCheckpoint(p0 context.Context, p1 types.TipSetKey) error { + return s.Internal.SyncCheckpoint(p0, p1) +} + +func (s *FullNodeStub) SyncCheckpoint(p0 context.Context, p1 types.TipSetKey) error { + return xerrors.New("method not supported") +} + +func (s *FullNodeStruct) SyncIncomingBlocks(p0 context.Context) (<-chan *types.BlockHeader, error) { + return s.Internal.SyncIncomingBlocks(p0) +} + +func (s *FullNodeStub) SyncIncomingBlocks(p0 context.Context) (<-chan *types.BlockHeader, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) SyncMarkBad(p0 context.Context, p1 cid.Cid) error { + return s.Internal.SyncMarkBad(p0, p1) +} + +func (s *FullNodeStub) SyncMarkBad(p0 context.Context, p1 cid.Cid) error { + return xerrors.New("method not supported") +} + +func (s *FullNodeStruct) SyncState(p0 context.Context) (*SyncState, error) { + return s.Internal.SyncState(p0) +} + +func (s *FullNodeStub) SyncState(p0 context.Context) (*SyncState, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) SyncSubmitBlock(p0 context.Context, p1 *types.BlockMsg) error { + return s.Internal.SyncSubmitBlock(p0, p1) +} + +func (s *FullNodeStub) SyncSubmitBlock(p0 context.Context, p1 *types.BlockMsg) error { + return xerrors.New("method not supported") +} + +func (s *FullNodeStruct) SyncUnmarkAllBad(p0 context.Context) error { + return s.Internal.SyncUnmarkAllBad(p0) +} + +func (s *FullNodeStub) SyncUnmarkAllBad(p0 context.Context) error { + return xerrors.New("method not supported") +} + +func (s *FullNodeStruct) SyncUnmarkBad(p0 context.Context, p1 cid.Cid) error { + return s.Internal.SyncUnmarkBad(p0, p1) +} + +func (s *FullNodeStub) SyncUnmarkBad(p0 context.Context, p1 cid.Cid) error { + return xerrors.New("method not supported") +} + +func (s *FullNodeStruct) SyncValidateTipset(p0 context.Context, p1 types.TipSetKey) (bool, error) { + return s.Internal.SyncValidateTipset(p0, p1) +} + +func (s *FullNodeStub) SyncValidateTipset(p0 context.Context, p1 types.TipSetKey) (bool, error) { + return false, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) WalletBalance(p0 context.Context, p1 address.Address) (types.BigInt, error) { + return s.Internal.WalletBalance(p0, p1) +} + +func (s *FullNodeStub) WalletBalance(p0 context.Context, p1 address.Address) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) WalletDefaultAddress(p0 context.Context) (address.Address, error) { + return s.Internal.WalletDefaultAddress(p0) +} + +func (s *FullNodeStub) WalletDefaultAddress(p0 context.Context) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) WalletDelete(p0 context.Context, p1 address.Address) error { + return s.Internal.WalletDelete(p0, p1) +} + +func (s *FullNodeStub) WalletDelete(p0 context.Context, p1 address.Address) error { + return xerrors.New("method not supported") +} + +func (s *FullNodeStruct) WalletExport(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) { + return s.Internal.WalletExport(p0, p1) +} + +func (s *FullNodeStub) WalletExport(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) WalletHas(p0 context.Context, p1 address.Address) (bool, error) { + return s.Internal.WalletHas(p0, p1) +} + +func (s *FullNodeStub) WalletHas(p0 context.Context, p1 address.Address) (bool, error) { + return false, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) WalletImport(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) { + return s.Internal.WalletImport(p0, p1) +} + +func (s *FullNodeStub) WalletImport(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) WalletList(p0 context.Context) ([]address.Address, error) { + return s.Internal.WalletList(p0) +} + +func (s *FullNodeStub) WalletList(p0 context.Context) ([]address.Address, error) { + return *new([]address.Address), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) WalletNew(p0 context.Context, p1 types.KeyType) (address.Address, error) { + return s.Internal.WalletNew(p0, p1) +} + +func (s *FullNodeStub) WalletNew(p0 context.Context, p1 types.KeyType) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) WalletSetDefault(p0 context.Context, p1 address.Address) error { + return s.Internal.WalletSetDefault(p0, p1) +} + +func (s *FullNodeStub) WalletSetDefault(p0 context.Context, p1 address.Address) error { + return xerrors.New("method not supported") +} + +func (s *FullNodeStruct) WalletSign(p0 context.Context, p1 address.Address, p2 []byte) (*crypto.Signature, error) { + return s.Internal.WalletSign(p0, p1, p2) +} + +func (s *FullNodeStub) WalletSign(p0 context.Context, p1 address.Address, p2 []byte) (*crypto.Signature, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) WalletSignMessage(p0 context.Context, p1 address.Address, p2 *types.Message) (*types.SignedMessage, error) { + return s.Internal.WalletSignMessage(p0, p1, p2) +} + +func (s *FullNodeStub) WalletSignMessage(p0 context.Context, p1 address.Address, p2 *types.Message) (*types.SignedMessage, error) { + return nil, xerrors.New("method not supported") +} + +func (s *FullNodeStruct) WalletValidateAddress(p0 context.Context, p1 string) (address.Address, error) { + return s.Internal.WalletValidateAddress(p0, p1) +} + +func (s *FullNodeStub) WalletValidateAddress(p0 context.Context, p1 string) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + +func (s *FullNodeStruct) WalletVerify(p0 context.Context, p1 address.Address, p2 []byte, p3 *crypto.Signature) (bool, error) { + return s.Internal.WalletVerify(p0, p1, p2, p3) +} + +func (s *FullNodeStub) WalletVerify(p0 context.Context, p1 address.Address, p2 []byte, p3 *crypto.Signature) (bool, error) { + return false, xerrors.New("method not supported") +} + +func (s *GatewayStruct) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*BlockMessages, error) { + return s.Internal.ChainGetBlockMessages(p0, p1) +} + +func (s *GatewayStub) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*BlockMessages, error) { + return nil, xerrors.New("method not supported") +} + +func (s *GatewayStruct) ChainGetMessage(p0 context.Context, p1 cid.Cid) (*types.Message, error) { + return s.Internal.ChainGetMessage(p0, p1) +} + +func (s *GatewayStub) ChainGetMessage(p0 context.Context, p1 cid.Cid) (*types.Message, error) { + return nil, xerrors.New("method not supported") +} + +func (s *GatewayStruct) ChainGetTipSet(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) { + return s.Internal.ChainGetTipSet(p0, p1) +} + +func (s *GatewayStub) ChainGetTipSet(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) { + return nil, xerrors.New("method not supported") +} + +func (s *GatewayStruct) ChainGetTipSetByHeight(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) { + return s.Internal.ChainGetTipSetByHeight(p0, p1, p2) +} + +func (s *GatewayStub) ChainGetTipSetByHeight(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) { + return nil, xerrors.New("method not supported") +} + +func (s *GatewayStruct) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { + return s.Internal.ChainHasObj(p0, p1) +} + +func (s *GatewayStub) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { + return false, xerrors.New("method not supported") +} + +func (s *GatewayStruct) ChainHead(p0 context.Context) (*types.TipSet, error) { + return s.Internal.ChainHead(p0) +} + +func (s *GatewayStub) ChainHead(p0 context.Context) (*types.TipSet, error) { + return nil, xerrors.New("method not supported") +} + +func (s *GatewayStruct) ChainNotify(p0 context.Context) (<-chan []*HeadChange, error) { + return s.Internal.ChainNotify(p0) +} + +func (s *GatewayStub) ChainNotify(p0 context.Context) (<-chan []*HeadChange, error) { + return nil, xerrors.New("method not supported") +} + +func (s *GatewayStruct) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { + return s.Internal.ChainReadObj(p0, p1) +} + +func (s *GatewayStub) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { + return *new([]byte), xerrors.New("method not supported") +} + +func (s *GatewayStruct) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { + return s.Internal.GasEstimateMessageGas(p0, p1, p2, p3) +} + +func (s *GatewayStub) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { + return nil, xerrors.New("method not supported") +} + +func (s *GatewayStruct) MpoolPush(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { + return s.Internal.MpoolPush(p0, p1) +} + +func (s *GatewayStub) MpoolPush(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + +func (s *GatewayStruct) MsigGetAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { + return s.Internal.MsigGetAvailableBalance(p0, p1, p2) +} + +func (s *GatewayStub) MsigGetAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + +func (s *GatewayStruct) MsigGetPending(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*MsigTransaction, error) { + return s.Internal.MsigGetPending(p0, p1, p2) +} + +func (s *GatewayStub) MsigGetPending(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*MsigTransaction, error) { + return *new([]*MsigTransaction), xerrors.New("method not supported") +} + +func (s *GatewayStruct) MsigGetVested(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) { + return s.Internal.MsigGetVested(p0, p1, p2, p3) +} + +func (s *GatewayStub) MsigGetVested(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + return s.Internal.StateAccountKey(p0, p1, p2) +} + +func (s *GatewayStub) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (DealCollateralBounds, error) { + return s.Internal.StateDealProviderCollateralBounds(p0, p1, p2, p3) +} + +func (s *GatewayStub) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (DealCollateralBounds, error) { + return *new(DealCollateralBounds), xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) { + return s.Internal.StateGetActor(p0, p1, p2) +} + +func (s *GatewayStub) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) { + return nil, xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateListMiners(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { + return s.Internal.StateListMiners(p0, p1) +} + +func (s *GatewayStub) StateListMiners(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { + return *new([]address.Address), xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateLookupID(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + return s.Internal.StateLookupID(p0, p1, p2) +} + +func (s *GatewayStub) StateLookupID(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MarketBalance, error) { + return s.Internal.StateMarketBalance(p0, p1, p2) +} + +func (s *GatewayStub) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MarketBalance, error) { + return *new(MarketBalance), xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*MarketDeal, error) { + return s.Internal.StateMarketStorageDeal(p0, p1, p2) +} + +func (s *GatewayStub) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*MarketDeal, error) { + return nil, xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateMinerInfo(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) { + return s.Internal.StateMinerInfo(p0, p1, p2) +} + +func (s *GatewayStub) StateMinerInfo(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) { + return *new(miner.MinerInfo), xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*MinerPower, error) { + return s.Internal.StateMinerPower(p0, p1, p2) +} + +func (s *GatewayStub) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*MinerPower, error) { + return nil, xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateMinerProvingDeadline(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) { + return s.Internal.StateMinerProvingDeadline(p0, p1, p2) +} + +func (s *GatewayStub) StateMinerProvingDeadline(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) { + return nil, xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) { + return s.Internal.StateNetworkVersion(p0, p1) +} + +func (s *GatewayStub) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) { + return *new(apitypes.NetworkVersion), xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateSearchMsg(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) { + return s.Internal.StateSearchMsg(p0, p1, p2, p3, p4) +} + +func (s *GatewayStub) StateSearchMsg(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) { + return nil, xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { + return s.Internal.StateSectorGetInfo(p0, p1, p2, p3) +} + +func (s *GatewayStub) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { + return nil, xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateVerifiedClientStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { + return s.Internal.StateVerifiedClientStatus(p0, p1, p2) +} + +func (s *GatewayStub) StateVerifiedClientStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { + return nil, xerrors.New("method not supported") +} + +func (s *GatewayStruct) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) { + return s.Internal.StateWaitMsg(p0, p1, p2, p3, p4) +} + +func (s *GatewayStub) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) { + return nil, xerrors.New("method not supported") +} + +func (s *GatewayStruct) WalletBalance(p0 context.Context, p1 address.Address) (types.BigInt, error) { + return s.Internal.WalletBalance(p0, p1) +} + +func (s *GatewayStub) WalletBalance(p0 context.Context, p1 address.Address) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + +func (s *SignableStruct) Sign(p0 context.Context, p1 SignFunc) error { + return s.Internal.Sign(p0, p1) +} + +func (s *SignableStub) Sign(p0 context.Context, p1 SignFunc) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) ActorAddress(p0 context.Context) (address.Address, error) { + return s.Internal.ActorAddress(p0) +} + +func (s *StorageMinerStub) ActorAddress(p0 context.Context) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) ActorAddressConfig(p0 context.Context) (AddressConfig, error) { + return s.Internal.ActorAddressConfig(p0) +} + +func (s *StorageMinerStub) ActorAddressConfig(p0 context.Context) (AddressConfig, error) { + return *new(AddressConfig), xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) ActorSectorSize(p0 context.Context, p1 address.Address) (abi.SectorSize, error) { + return s.Internal.ActorSectorSize(p0, p1) +} + +func (s *StorageMinerStub) ActorSectorSize(p0 context.Context, p1 address.Address) (abi.SectorSize, error) { + return *new(abi.SectorSize), xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) CheckProvable(p0 context.Context, p1 abi.RegisteredPoStProof, p2 []storage.SectorRef, p3 bool) (map[abi.SectorNumber]string, error) { + return s.Internal.CheckProvable(p0, p1, p2, p3) +} + +func (s *StorageMinerStub) CheckProvable(p0 context.Context, p1 abi.RegisteredPoStProof, p2 []storage.SectorRef, p3 bool) (map[abi.SectorNumber]string, error) { + return *new(map[abi.SectorNumber]string), xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) ComputeProof(p0 context.Context, p1 []builtin.SectorInfo, p2 abi.PoStRandomness) ([]builtin.PoStProof, error) { + return s.Internal.ComputeProof(p0, p1, p2) +} + +func (s *StorageMinerStub) ComputeProof(p0 context.Context, p1 []builtin.SectorInfo, p2 abi.PoStRandomness) ([]builtin.PoStProof, error) { + return *new([]builtin.PoStProof), xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) CreateBackup(p0 context.Context, p1 string) error { + return s.Internal.CreateBackup(p0, p1) +} + +func (s *StorageMinerStub) CreateBackup(p0 context.Context, p1 string) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) DealsConsiderOfflineRetrievalDeals(p0 context.Context) (bool, error) { + return s.Internal.DealsConsiderOfflineRetrievalDeals(p0) +} + +func (s *StorageMinerStub) DealsConsiderOfflineRetrievalDeals(p0 context.Context) (bool, error) { + return false, xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) DealsConsiderOfflineStorageDeals(p0 context.Context) (bool, error) { + return s.Internal.DealsConsiderOfflineStorageDeals(p0) +} + +func (s *StorageMinerStub) DealsConsiderOfflineStorageDeals(p0 context.Context) (bool, error) { + return false, xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) DealsConsiderOnlineRetrievalDeals(p0 context.Context) (bool, error) { + return s.Internal.DealsConsiderOnlineRetrievalDeals(p0) +} + +func (s *StorageMinerStub) DealsConsiderOnlineRetrievalDeals(p0 context.Context) (bool, error) { + return false, xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) DealsConsiderOnlineStorageDeals(p0 context.Context) (bool, error) { + return s.Internal.DealsConsiderOnlineStorageDeals(p0) +} + +func (s *StorageMinerStub) DealsConsiderOnlineStorageDeals(p0 context.Context) (bool, error) { + return false, xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) DealsConsiderUnverifiedStorageDeals(p0 context.Context) (bool, error) { + return s.Internal.DealsConsiderUnverifiedStorageDeals(p0) +} + +func (s *StorageMinerStub) DealsConsiderUnverifiedStorageDeals(p0 context.Context) (bool, error) { + return false, xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) DealsConsiderVerifiedStorageDeals(p0 context.Context) (bool, error) { + return s.Internal.DealsConsiderVerifiedStorageDeals(p0) +} + +func (s *StorageMinerStub) DealsConsiderVerifiedStorageDeals(p0 context.Context) (bool, error) { + return false, xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) DealsImportData(p0 context.Context, p1 cid.Cid, p2 string) error { + return s.Internal.DealsImportData(p0, p1, p2) +} + +func (s *StorageMinerStub) DealsImportData(p0 context.Context, p1 cid.Cid, p2 string) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) DealsList(p0 context.Context) ([]MarketDeal, error) { + return s.Internal.DealsList(p0) +} + +func (s *StorageMinerStub) DealsList(p0 context.Context) ([]MarketDeal, error) { + return *new([]MarketDeal), xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) DealsPieceCidBlocklist(p0 context.Context) ([]cid.Cid, error) { + return s.Internal.DealsPieceCidBlocklist(p0) +} + +func (s *StorageMinerStub) DealsPieceCidBlocklist(p0 context.Context) ([]cid.Cid, error) { + return *new([]cid.Cid), xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) DealsSetConsiderOfflineRetrievalDeals(p0 context.Context, p1 bool) error { + return s.Internal.DealsSetConsiderOfflineRetrievalDeals(p0, p1) +} + +func (s *StorageMinerStub) DealsSetConsiderOfflineRetrievalDeals(p0 context.Context, p1 bool) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) DealsSetConsiderOfflineStorageDeals(p0 context.Context, p1 bool) error { + return s.Internal.DealsSetConsiderOfflineStorageDeals(p0, p1) +} + +func (s *StorageMinerStub) DealsSetConsiderOfflineStorageDeals(p0 context.Context, p1 bool) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) DealsSetConsiderOnlineRetrievalDeals(p0 context.Context, p1 bool) error { + return s.Internal.DealsSetConsiderOnlineRetrievalDeals(p0, p1) +} + +func (s *StorageMinerStub) DealsSetConsiderOnlineRetrievalDeals(p0 context.Context, p1 bool) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) DealsSetConsiderOnlineStorageDeals(p0 context.Context, p1 bool) error { + return s.Internal.DealsSetConsiderOnlineStorageDeals(p0, p1) +} + +func (s *StorageMinerStub) DealsSetConsiderOnlineStorageDeals(p0 context.Context, p1 bool) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) DealsSetConsiderUnverifiedStorageDeals(p0 context.Context, p1 bool) error { + return s.Internal.DealsSetConsiderUnverifiedStorageDeals(p0, p1) +} + +func (s *StorageMinerStub) DealsSetConsiderUnverifiedStorageDeals(p0 context.Context, p1 bool) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) DealsSetConsiderVerifiedStorageDeals(p0 context.Context, p1 bool) error { + return s.Internal.DealsSetConsiderVerifiedStorageDeals(p0, p1) +} + +func (s *StorageMinerStub) DealsSetConsiderVerifiedStorageDeals(p0 context.Context, p1 bool) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) DealsSetPieceCidBlocklist(p0 context.Context, p1 []cid.Cid) error { + return s.Internal.DealsSetPieceCidBlocklist(p0, p1) +} + +func (s *StorageMinerStub) DealsSetPieceCidBlocklist(p0 context.Context, p1 []cid.Cid) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) MarketCancelDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { + return s.Internal.MarketCancelDataTransfer(p0, p1, p2, p3) +} + +func (s *StorageMinerStub) MarketCancelDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) MarketDataTransferUpdates(p0 context.Context) (<-chan DataTransferChannel, error) { + return s.Internal.MarketDataTransferUpdates(p0) +} + +func (s *StorageMinerStub) MarketDataTransferUpdates(p0 context.Context) (<-chan DataTransferChannel, error) { + return nil, xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) MarketGetAsk(p0 context.Context) (*storagemarket.SignedStorageAsk, error) { + return s.Internal.MarketGetAsk(p0) +} + +func (s *StorageMinerStub) MarketGetAsk(p0 context.Context) (*storagemarket.SignedStorageAsk, error) { + return nil, xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) MarketGetDealUpdates(p0 context.Context) (<-chan storagemarket.MinerDeal, error) { + return s.Internal.MarketGetDealUpdates(p0) +} + +func (s *StorageMinerStub) MarketGetDealUpdates(p0 context.Context) (<-chan storagemarket.MinerDeal, error) { + return nil, xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) MarketGetRetrievalAsk(p0 context.Context) (*retrievalmarket.Ask, error) { + return s.Internal.MarketGetRetrievalAsk(p0) +} + +func (s *StorageMinerStub) MarketGetRetrievalAsk(p0 context.Context) (*retrievalmarket.Ask, error) { + return nil, xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) MarketImportDealData(p0 context.Context, p1 cid.Cid, p2 string) error { + return s.Internal.MarketImportDealData(p0, p1, p2) +} + +func (s *StorageMinerStub) MarketImportDealData(p0 context.Context, p1 cid.Cid, p2 string) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) MarketListDataTransfers(p0 context.Context) ([]DataTransferChannel, error) { + return s.Internal.MarketListDataTransfers(p0) +} + +func (s *StorageMinerStub) MarketListDataTransfers(p0 context.Context) ([]DataTransferChannel, error) { + return *new([]DataTransferChannel), xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) MarketListDeals(p0 context.Context) ([]MarketDeal, error) { + return s.Internal.MarketListDeals(p0) +} + +func (s *StorageMinerStub) MarketListDeals(p0 context.Context) ([]MarketDeal, error) { + return *new([]MarketDeal), xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) MarketListIncompleteDeals(p0 context.Context) ([]storagemarket.MinerDeal, error) { + return s.Internal.MarketListIncompleteDeals(p0) +} + +func (s *StorageMinerStub) MarketListIncompleteDeals(p0 context.Context) ([]storagemarket.MinerDeal, error) { + return *new([]storagemarket.MinerDeal), xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) MarketListRetrievalDeals(p0 context.Context) ([]retrievalmarket.ProviderDealState, error) { + return s.Internal.MarketListRetrievalDeals(p0) +} + +func (s *StorageMinerStub) MarketListRetrievalDeals(p0 context.Context) ([]retrievalmarket.ProviderDealState, error) { + return *new([]retrievalmarket.ProviderDealState), xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) MarketPendingDeals(p0 context.Context) (PendingDealInfo, error) { + return s.Internal.MarketPendingDeals(p0) +} + +func (s *StorageMinerStub) MarketPendingDeals(p0 context.Context) (PendingDealInfo, error) { + return *new(PendingDealInfo), xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) MarketPublishPendingDeals(p0 context.Context) error { + return s.Internal.MarketPublishPendingDeals(p0) +} + +func (s *StorageMinerStub) MarketPublishPendingDeals(p0 context.Context) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) MarketRestartDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { + return s.Internal.MarketRestartDataTransfer(p0, p1, p2, p3) +} + +func (s *StorageMinerStub) MarketRestartDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) MarketSetAsk(p0 context.Context, p1 types.BigInt, p2 types.BigInt, p3 abi.ChainEpoch, p4 abi.PaddedPieceSize, p5 abi.PaddedPieceSize) error { + return s.Internal.MarketSetAsk(p0, p1, p2, p3, p4, p5) +} + +func (s *StorageMinerStub) MarketSetAsk(p0 context.Context, p1 types.BigInt, p2 types.BigInt, p3 abi.ChainEpoch, p4 abi.PaddedPieceSize, p5 abi.PaddedPieceSize) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) MarketSetRetrievalAsk(p0 context.Context, p1 *retrievalmarket.Ask) error { + return s.Internal.MarketSetRetrievalAsk(p0, p1) +} + +func (s *StorageMinerStub) MarketSetRetrievalAsk(p0 context.Context, p1 *retrievalmarket.Ask) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) MiningBase(p0 context.Context) (*types.TipSet, error) { + return s.Internal.MiningBase(p0) +} + +func (s *StorageMinerStub) MiningBase(p0 context.Context) (*types.TipSet, error) { + return nil, xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) PiecesGetCIDInfo(p0 context.Context, p1 cid.Cid) (*piecestore.CIDInfo, error) { + return s.Internal.PiecesGetCIDInfo(p0, p1) +} + +func (s *StorageMinerStub) PiecesGetCIDInfo(p0 context.Context, p1 cid.Cid) (*piecestore.CIDInfo, error) { + return nil, xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) PiecesGetPieceInfo(p0 context.Context, p1 cid.Cid) (*piecestore.PieceInfo, error) { + return s.Internal.PiecesGetPieceInfo(p0, p1) +} + +func (s *StorageMinerStub) PiecesGetPieceInfo(p0 context.Context, p1 cid.Cid) (*piecestore.PieceInfo, error) { + return nil, xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) PiecesListCidInfos(p0 context.Context) ([]cid.Cid, error) { + return s.Internal.PiecesListCidInfos(p0) +} + +func (s *StorageMinerStub) PiecesListCidInfos(p0 context.Context) ([]cid.Cid, error) { + return *new([]cid.Cid), xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) PiecesListPieces(p0 context.Context) ([]cid.Cid, error) { + return s.Internal.PiecesListPieces(p0) +} + +func (s *StorageMinerStub) PiecesListPieces(p0 context.Context) ([]cid.Cid, error) { + return *new([]cid.Cid), xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) PledgeSector(p0 context.Context) (abi.SectorID, error) { + return s.Internal.PledgeSector(p0) +} + +func (s *StorageMinerStub) PledgeSector(p0 context.Context) (abi.SectorID, error) { + return *new(abi.SectorID), xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) ReturnAddPiece(p0 context.Context, p1 storiface.CallID, p2 abi.PieceInfo, p3 *storiface.CallError) error { + return s.Internal.ReturnAddPiece(p0, p1, p2, p3) +} + +func (s *StorageMinerStub) ReturnAddPiece(p0 context.Context, p1 storiface.CallID, p2 abi.PieceInfo, p3 *storiface.CallError) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) ReturnFetch(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { + return s.Internal.ReturnFetch(p0, p1, p2) +} + +func (s *StorageMinerStub) ReturnFetch(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) ReturnFinalizeSector(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { + return s.Internal.ReturnFinalizeSector(p0, p1, p2) +} + +func (s *StorageMinerStub) ReturnFinalizeSector(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) ReturnMoveStorage(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { + return s.Internal.ReturnMoveStorage(p0, p1, p2) +} + +func (s *StorageMinerStub) ReturnMoveStorage(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) ReturnReadPiece(p0 context.Context, p1 storiface.CallID, p2 bool, p3 *storiface.CallError) error { + return s.Internal.ReturnReadPiece(p0, p1, p2, p3) +} + +func (s *StorageMinerStub) ReturnReadPiece(p0 context.Context, p1 storiface.CallID, p2 bool, p3 *storiface.CallError) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) ReturnReleaseUnsealed(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { + return s.Internal.ReturnReleaseUnsealed(p0, p1, p2) +} + +func (s *StorageMinerStub) ReturnReleaseUnsealed(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) ReturnSealCommit1(p0 context.Context, p1 storiface.CallID, p2 storage.Commit1Out, p3 *storiface.CallError) error { + return s.Internal.ReturnSealCommit1(p0, p1, p2, p3) +} + +func (s *StorageMinerStub) ReturnSealCommit1(p0 context.Context, p1 storiface.CallID, p2 storage.Commit1Out, p3 *storiface.CallError) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) ReturnSealCommit2(p0 context.Context, p1 storiface.CallID, p2 storage.Proof, p3 *storiface.CallError) error { + return s.Internal.ReturnSealCommit2(p0, p1, p2, p3) +} + +func (s *StorageMinerStub) ReturnSealCommit2(p0 context.Context, p1 storiface.CallID, p2 storage.Proof, p3 *storiface.CallError) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) ReturnSealPreCommit1(p0 context.Context, p1 storiface.CallID, p2 storage.PreCommit1Out, p3 *storiface.CallError) error { + return s.Internal.ReturnSealPreCommit1(p0, p1, p2, p3) +} + +func (s *StorageMinerStub) ReturnSealPreCommit1(p0 context.Context, p1 storiface.CallID, p2 storage.PreCommit1Out, p3 *storiface.CallError) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) ReturnSealPreCommit2(p0 context.Context, p1 storiface.CallID, p2 storage.SectorCids, p3 *storiface.CallError) error { + return s.Internal.ReturnSealPreCommit2(p0, p1, p2, p3) +} + +func (s *StorageMinerStub) ReturnSealPreCommit2(p0 context.Context, p1 storiface.CallID, p2 storage.SectorCids, p3 *storiface.CallError) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) ReturnUnsealPiece(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { + return s.Internal.ReturnUnsealPiece(p0, p1, p2) +} + +func (s *StorageMinerStub) ReturnUnsealPiece(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) SealingAbort(p0 context.Context, p1 storiface.CallID) error { + return s.Internal.SealingAbort(p0, p1) +} + +func (s *StorageMinerStub) SealingAbort(p0 context.Context, p1 storiface.CallID) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) SealingSchedDiag(p0 context.Context, p1 bool) (interface{}, error) { + return s.Internal.SealingSchedDiag(p0, p1) +} + +func (s *StorageMinerStub) SealingSchedDiag(p0 context.Context, p1 bool) (interface{}, error) { + return nil, xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) SectorGetExpectedSealDuration(p0 context.Context) (time.Duration, error) { + return s.Internal.SectorGetExpectedSealDuration(p0) +} + +func (s *StorageMinerStub) SectorGetExpectedSealDuration(p0 context.Context) (time.Duration, error) { + return *new(time.Duration), xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) SectorGetSealDelay(p0 context.Context) (time.Duration, error) { + return s.Internal.SectorGetSealDelay(p0) +} + +func (s *StorageMinerStub) SectorGetSealDelay(p0 context.Context) (time.Duration, error) { + return *new(time.Duration), xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) SectorMarkForUpgrade(p0 context.Context, p1 abi.SectorNumber) error { + return s.Internal.SectorMarkForUpgrade(p0, p1) +} + +func (s *StorageMinerStub) SectorMarkForUpgrade(p0 context.Context, p1 abi.SectorNumber) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) SectorRemove(p0 context.Context, p1 abi.SectorNumber) error { + return s.Internal.SectorRemove(p0, p1) +} + +func (s *StorageMinerStub) SectorRemove(p0 context.Context, p1 abi.SectorNumber) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) SectorSetExpectedSealDuration(p0 context.Context, p1 time.Duration) error { + return s.Internal.SectorSetExpectedSealDuration(p0, p1) +} + +func (s *StorageMinerStub) SectorSetExpectedSealDuration(p0 context.Context, p1 time.Duration) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) SectorSetSealDelay(p0 context.Context, p1 time.Duration) error { + return s.Internal.SectorSetSealDelay(p0, p1) +} + +func (s *StorageMinerStub) SectorSetSealDelay(p0 context.Context, p1 time.Duration) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) SectorStartSealing(p0 context.Context, p1 abi.SectorNumber) error { + return s.Internal.SectorStartSealing(p0, p1) +} + +func (s *StorageMinerStub) SectorStartSealing(p0 context.Context, p1 abi.SectorNumber) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) SectorTerminate(p0 context.Context, p1 abi.SectorNumber) error { + return s.Internal.SectorTerminate(p0, p1) +} + +func (s *StorageMinerStub) SectorTerminate(p0 context.Context, p1 abi.SectorNumber) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) SectorTerminateFlush(p0 context.Context) (*cid.Cid, error) { + return s.Internal.SectorTerminateFlush(p0) +} + +func (s *StorageMinerStub) SectorTerminateFlush(p0 context.Context) (*cid.Cid, error) { + return nil, xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) SectorTerminatePending(p0 context.Context) ([]abi.SectorID, error) { + return s.Internal.SectorTerminatePending(p0) +} + +func (s *StorageMinerStub) SectorTerminatePending(p0 context.Context) ([]abi.SectorID, error) { + return *new([]abi.SectorID), xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) SectorsList(p0 context.Context) ([]abi.SectorNumber, error) { + return s.Internal.SectorsList(p0) +} + +func (s *StorageMinerStub) SectorsList(p0 context.Context) ([]abi.SectorNumber, error) { + return *new([]abi.SectorNumber), xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) SectorsListInStates(p0 context.Context, p1 []SectorState) ([]abi.SectorNumber, error) { + return s.Internal.SectorsListInStates(p0, p1) +} + +func (s *StorageMinerStub) SectorsListInStates(p0 context.Context, p1 []SectorState) ([]abi.SectorNumber, error) { + return *new([]abi.SectorNumber), xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) SectorsRefs(p0 context.Context) (map[string][]SealedRef, error) { + return s.Internal.SectorsRefs(p0) +} + +func (s *StorageMinerStub) SectorsRefs(p0 context.Context) (map[string][]SealedRef, error) { + return *new(map[string][]SealedRef), xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) SectorsStatus(p0 context.Context, p1 abi.SectorNumber, p2 bool) (SectorInfo, error) { + return s.Internal.SectorsStatus(p0, p1, p2) +} + +func (s *StorageMinerStub) SectorsStatus(p0 context.Context, p1 abi.SectorNumber, p2 bool) (SectorInfo, error) { + return *new(SectorInfo), xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) SectorsSummary(p0 context.Context) (map[SectorState]int, error) { + return s.Internal.SectorsSummary(p0) +} + +func (s *StorageMinerStub) SectorsSummary(p0 context.Context) (map[SectorState]int, error) { + return *new(map[SectorState]int), xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) SectorsUpdate(p0 context.Context, p1 abi.SectorNumber, p2 SectorState) error { + return s.Internal.SectorsUpdate(p0, p1, p2) +} + +func (s *StorageMinerStub) SectorsUpdate(p0 context.Context, p1 abi.SectorNumber, p2 SectorState) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) StorageAddLocal(p0 context.Context, p1 string) error { + return s.Internal.StorageAddLocal(p0, p1) +} + +func (s *StorageMinerStub) StorageAddLocal(p0 context.Context, p1 string) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) StorageAttach(p0 context.Context, p1 stores.StorageInfo, p2 fsutil.FsStat) error { + return s.Internal.StorageAttach(p0, p1, p2) +} + +func (s *StorageMinerStub) StorageAttach(p0 context.Context, p1 stores.StorageInfo, p2 fsutil.FsStat) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) StorageBestAlloc(p0 context.Context, p1 storiface.SectorFileType, p2 abi.SectorSize, p3 storiface.PathType) ([]stores.StorageInfo, error) { + return s.Internal.StorageBestAlloc(p0, p1, p2, p3) +} + +func (s *StorageMinerStub) StorageBestAlloc(p0 context.Context, p1 storiface.SectorFileType, p2 abi.SectorSize, p3 storiface.PathType) ([]stores.StorageInfo, error) { + return *new([]stores.StorageInfo), xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) StorageDeclareSector(p0 context.Context, p1 stores.ID, p2 abi.SectorID, p3 storiface.SectorFileType, p4 bool) error { + return s.Internal.StorageDeclareSector(p0, p1, p2, p3, p4) +} + +func (s *StorageMinerStub) StorageDeclareSector(p0 context.Context, p1 stores.ID, p2 abi.SectorID, p3 storiface.SectorFileType, p4 bool) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) StorageDropSector(p0 context.Context, p1 stores.ID, p2 abi.SectorID, p3 storiface.SectorFileType) error { + return s.Internal.StorageDropSector(p0, p1, p2, p3) +} + +func (s *StorageMinerStub) StorageDropSector(p0 context.Context, p1 stores.ID, p2 abi.SectorID, p3 storiface.SectorFileType) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) StorageFindSector(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 abi.SectorSize, p4 bool) ([]stores.SectorStorageInfo, error) { + return s.Internal.StorageFindSector(p0, p1, p2, p3, p4) +} + +func (s *StorageMinerStub) StorageFindSector(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 abi.SectorSize, p4 bool) ([]stores.SectorStorageInfo, error) { + return *new([]stores.SectorStorageInfo), xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) StorageInfo(p0 context.Context, p1 stores.ID) (stores.StorageInfo, error) { + return s.Internal.StorageInfo(p0, p1) +} + +func (s *StorageMinerStub) StorageInfo(p0 context.Context, p1 stores.ID) (stores.StorageInfo, error) { + return *new(stores.StorageInfo), xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) StorageList(p0 context.Context) (map[stores.ID][]stores.Decl, error) { + return s.Internal.StorageList(p0) +} + +func (s *StorageMinerStub) StorageList(p0 context.Context) (map[stores.ID][]stores.Decl, error) { + return *new(map[stores.ID][]stores.Decl), xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) StorageLocal(p0 context.Context) (map[stores.ID]string, error) { + return s.Internal.StorageLocal(p0) +} + +func (s *StorageMinerStub) StorageLocal(p0 context.Context) (map[stores.ID]string, error) { + return *new(map[stores.ID]string), xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) StorageLock(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 storiface.SectorFileType) error { + return s.Internal.StorageLock(p0, p1, p2, p3) +} + +func (s *StorageMinerStub) StorageLock(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 storiface.SectorFileType) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) StorageReportHealth(p0 context.Context, p1 stores.ID, p2 stores.HealthReport) error { + return s.Internal.StorageReportHealth(p0, p1, p2) +} + +func (s *StorageMinerStub) StorageReportHealth(p0 context.Context, p1 stores.ID, p2 stores.HealthReport) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) StorageStat(p0 context.Context, p1 stores.ID) (fsutil.FsStat, error) { + return s.Internal.StorageStat(p0, p1) +} + +func (s *StorageMinerStub) StorageStat(p0 context.Context, p1 stores.ID) (fsutil.FsStat, error) { + return *new(fsutil.FsStat), xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) StorageTryLock(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 storiface.SectorFileType) (bool, error) { + return s.Internal.StorageTryLock(p0, p1, p2, p3) +} + +func (s *StorageMinerStub) StorageTryLock(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 storiface.SectorFileType) (bool, error) { + return false, xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) WorkerConnect(p0 context.Context, p1 string) error { + return s.Internal.WorkerConnect(p0, p1) +} + +func (s *StorageMinerStub) WorkerConnect(p0 context.Context, p1 string) error { + return xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) WorkerJobs(p0 context.Context) (map[uuid.UUID][]storiface.WorkerJob, error) { + return s.Internal.WorkerJobs(p0) +} + +func (s *StorageMinerStub) WorkerJobs(p0 context.Context) (map[uuid.UUID][]storiface.WorkerJob, error) { + return *new(map[uuid.UUID][]storiface.WorkerJob), xerrors.New("method not supported") +} + +func (s *StorageMinerStruct) WorkerStats(p0 context.Context) (map[uuid.UUID]storiface.WorkerStats, error) { + return s.Internal.WorkerStats(p0) +} + +func (s *StorageMinerStub) WorkerStats(p0 context.Context) (map[uuid.UUID]storiface.WorkerStats, error) { + return *new(map[uuid.UUID]storiface.WorkerStats), xerrors.New("method not supported") +} + +func (s *WalletStruct) WalletDelete(p0 context.Context, p1 address.Address) error { + return s.Internal.WalletDelete(p0, p1) +} + +func (s *WalletStub) WalletDelete(p0 context.Context, p1 address.Address) error { + return xerrors.New("method not supported") +} + +func (s *WalletStruct) WalletExport(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) { + return s.Internal.WalletExport(p0, p1) +} + +func (s *WalletStub) WalletExport(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) { + return nil, xerrors.New("method not supported") +} + +func (s *WalletStruct) WalletHas(p0 context.Context, p1 address.Address) (bool, error) { + return s.Internal.WalletHas(p0, p1) +} + +func (s *WalletStub) WalletHas(p0 context.Context, p1 address.Address) (bool, error) { + return false, xerrors.New("method not supported") +} + +func (s *WalletStruct) WalletImport(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) { + return s.Internal.WalletImport(p0, p1) +} + +func (s *WalletStub) WalletImport(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + +func (s *WalletStruct) WalletList(p0 context.Context) ([]address.Address, error) { + return s.Internal.WalletList(p0) +} + +func (s *WalletStub) WalletList(p0 context.Context) ([]address.Address, error) { + return *new([]address.Address), xerrors.New("method not supported") +} + +func (s *WalletStruct) WalletNew(p0 context.Context, p1 types.KeyType) (address.Address, error) { + return s.Internal.WalletNew(p0, p1) +} + +func (s *WalletStub) WalletNew(p0 context.Context, p1 types.KeyType) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") +} + +func (s *WalletStruct) WalletSign(p0 context.Context, p1 address.Address, p2 []byte, p3 MsgMeta) (*crypto.Signature, error) { + return s.Internal.WalletSign(p0, p1, p2, p3) +} + +func (s *WalletStub) WalletSign(p0 context.Context, p1 address.Address, p2 []byte, p3 MsgMeta) (*crypto.Signature, error) { + return nil, xerrors.New("method not supported") +} + +func (s *WorkerStruct) AddPiece(p0 context.Context, p1 storage.SectorRef, p2 []abi.UnpaddedPieceSize, p3 abi.UnpaddedPieceSize, p4 storage.Data) (storiface.CallID, error) { + return s.Internal.AddPiece(p0, p1, p2, p3, p4) +} + +func (s *WorkerStub) AddPiece(p0 context.Context, p1 storage.SectorRef, p2 []abi.UnpaddedPieceSize, p3 abi.UnpaddedPieceSize, p4 storage.Data) (storiface.CallID, error) { + return *new(storiface.CallID), xerrors.New("method not supported") +} + +func (s *WorkerStruct) Enabled(p0 context.Context) (bool, error) { + return s.Internal.Enabled(p0) +} + +func (s *WorkerStub) Enabled(p0 context.Context) (bool, error) { + return false, xerrors.New("method not supported") +} + +func (s *WorkerStruct) Fetch(p0 context.Context, p1 storage.SectorRef, p2 storiface.SectorFileType, p3 storiface.PathType, p4 storiface.AcquireMode) (storiface.CallID, error) { + return s.Internal.Fetch(p0, p1, p2, p3, p4) +} + +func (s *WorkerStub) Fetch(p0 context.Context, p1 storage.SectorRef, p2 storiface.SectorFileType, p3 storiface.PathType, p4 storiface.AcquireMode) (storiface.CallID, error) { + return *new(storiface.CallID), xerrors.New("method not supported") +} + +func (s *WorkerStruct) FinalizeSector(p0 context.Context, p1 storage.SectorRef, p2 []storage.Range) (storiface.CallID, error) { + return s.Internal.FinalizeSector(p0, p1, p2) +} + +func (s *WorkerStub) FinalizeSector(p0 context.Context, p1 storage.SectorRef, p2 []storage.Range) (storiface.CallID, error) { + return *new(storiface.CallID), xerrors.New("method not supported") +} + +func (s *WorkerStruct) Info(p0 context.Context) (storiface.WorkerInfo, error) { + return s.Internal.Info(p0) +} + +func (s *WorkerStub) Info(p0 context.Context) (storiface.WorkerInfo, error) { + return *new(storiface.WorkerInfo), xerrors.New("method not supported") +} + +func (s *WorkerStruct) MoveStorage(p0 context.Context, p1 storage.SectorRef, p2 storiface.SectorFileType) (storiface.CallID, error) { + return s.Internal.MoveStorage(p0, p1, p2) +} + +func (s *WorkerStub) MoveStorage(p0 context.Context, p1 storage.SectorRef, p2 storiface.SectorFileType) (storiface.CallID, error) { + return *new(storiface.CallID), xerrors.New("method not supported") +} + +func (s *WorkerStruct) Paths(p0 context.Context) ([]stores.StoragePath, error) { + return s.Internal.Paths(p0) +} + +func (s *WorkerStub) Paths(p0 context.Context) ([]stores.StoragePath, error) { + return *new([]stores.StoragePath), xerrors.New("method not supported") +} + +func (s *WorkerStruct) ProcessSession(p0 context.Context) (uuid.UUID, error) { + return s.Internal.ProcessSession(p0) +} + +func (s *WorkerStub) ProcessSession(p0 context.Context) (uuid.UUID, error) { + return *new(uuid.UUID), xerrors.New("method not supported") +} + +func (s *WorkerStruct) ReadPiece(p0 context.Context, p1 io.Writer, p2 storage.SectorRef, p3 storiface.UnpaddedByteIndex, p4 abi.UnpaddedPieceSize) (storiface.CallID, error) { + return s.Internal.ReadPiece(p0, p1, p2, p3, p4) +} + +func (s *WorkerStub) ReadPiece(p0 context.Context, p1 io.Writer, p2 storage.SectorRef, p3 storiface.UnpaddedByteIndex, p4 abi.UnpaddedPieceSize) (storiface.CallID, error) { + return *new(storiface.CallID), xerrors.New("method not supported") +} + +func (s *WorkerStruct) ReleaseUnsealed(p0 context.Context, p1 storage.SectorRef, p2 []storage.Range) (storiface.CallID, error) { + return s.Internal.ReleaseUnsealed(p0, p1, p2) +} + +func (s *WorkerStub) ReleaseUnsealed(p0 context.Context, p1 storage.SectorRef, p2 []storage.Range) (storiface.CallID, error) { + return *new(storiface.CallID), xerrors.New("method not supported") +} + +func (s *WorkerStruct) Remove(p0 context.Context, p1 abi.SectorID) error { + return s.Internal.Remove(p0, p1) +} + +func (s *WorkerStub) Remove(p0 context.Context, p1 abi.SectorID) error { + return xerrors.New("method not supported") +} + +func (s *WorkerStruct) SealCommit1(p0 context.Context, p1 storage.SectorRef, p2 abi.SealRandomness, p3 abi.InteractiveSealRandomness, p4 []abi.PieceInfo, p5 storage.SectorCids) (storiface.CallID, error) { + return s.Internal.SealCommit1(p0, p1, p2, p3, p4, p5) +} + +func (s *WorkerStub) SealCommit1(p0 context.Context, p1 storage.SectorRef, p2 abi.SealRandomness, p3 abi.InteractiveSealRandomness, p4 []abi.PieceInfo, p5 storage.SectorCids) (storiface.CallID, error) { + return *new(storiface.CallID), xerrors.New("method not supported") +} + +func (s *WorkerStruct) SealCommit2(p0 context.Context, p1 storage.SectorRef, p2 storage.Commit1Out) (storiface.CallID, error) { + return s.Internal.SealCommit2(p0, p1, p2) +} + +func (s *WorkerStub) SealCommit2(p0 context.Context, p1 storage.SectorRef, p2 storage.Commit1Out) (storiface.CallID, error) { + return *new(storiface.CallID), xerrors.New("method not supported") +} + +func (s *WorkerStruct) SealPreCommit1(p0 context.Context, p1 storage.SectorRef, p2 abi.SealRandomness, p3 []abi.PieceInfo) (storiface.CallID, error) { + return s.Internal.SealPreCommit1(p0, p1, p2, p3) +} + +func (s *WorkerStub) SealPreCommit1(p0 context.Context, p1 storage.SectorRef, p2 abi.SealRandomness, p3 []abi.PieceInfo) (storiface.CallID, error) { + return *new(storiface.CallID), xerrors.New("method not supported") +} + +func (s *WorkerStruct) SealPreCommit2(p0 context.Context, p1 storage.SectorRef, p2 storage.PreCommit1Out) (storiface.CallID, error) { + return s.Internal.SealPreCommit2(p0, p1, p2) +} + +func (s *WorkerStub) SealPreCommit2(p0 context.Context, p1 storage.SectorRef, p2 storage.PreCommit1Out) (storiface.CallID, error) { + return *new(storiface.CallID), xerrors.New("method not supported") +} + +func (s *WorkerStruct) Session(p0 context.Context) (uuid.UUID, error) { + return s.Internal.Session(p0) +} + +func (s *WorkerStub) Session(p0 context.Context) (uuid.UUID, error) { + return *new(uuid.UUID), xerrors.New("method not supported") +} + +func (s *WorkerStruct) SetEnabled(p0 context.Context, p1 bool) error { + return s.Internal.SetEnabled(p0, p1) +} + +func (s *WorkerStub) SetEnabled(p0 context.Context, p1 bool) error { + return xerrors.New("method not supported") +} + +func (s *WorkerStruct) StorageAddLocal(p0 context.Context, p1 string) error { + return s.Internal.StorageAddLocal(p0, p1) +} + +func (s *WorkerStub) StorageAddLocal(p0 context.Context, p1 string) error { + return xerrors.New("method not supported") +} + +func (s *WorkerStruct) TaskDisable(p0 context.Context, p1 sealtasks.TaskType) error { + return s.Internal.TaskDisable(p0, p1) +} + +func (s *WorkerStub) TaskDisable(p0 context.Context, p1 sealtasks.TaskType) error { + return xerrors.New("method not supported") +} + +func (s *WorkerStruct) TaskEnable(p0 context.Context, p1 sealtasks.TaskType) error { + return s.Internal.TaskEnable(p0, p1) +} + +func (s *WorkerStub) TaskEnable(p0 context.Context, p1 sealtasks.TaskType) error { + return xerrors.New("method not supported") +} + +func (s *WorkerStruct) TaskTypes(p0 context.Context) (map[sealtasks.TaskType]struct{}, error) { + return s.Internal.TaskTypes(p0) +} + +func (s *WorkerStub) TaskTypes(p0 context.Context) (map[sealtasks.TaskType]struct{}, error) { + return *new(map[sealtasks.TaskType]struct{}), xerrors.New("method not supported") +} + +func (s *WorkerStruct) UnsealPiece(p0 context.Context, p1 storage.SectorRef, p2 storiface.UnpaddedByteIndex, p3 abi.UnpaddedPieceSize, p4 abi.SealRandomness, p5 cid.Cid) (storiface.CallID, error) { + return s.Internal.UnsealPiece(p0, p1, p2, p3, p4, p5) +} + +func (s *WorkerStub) UnsealPiece(p0 context.Context, p1 storage.SectorRef, p2 storiface.UnpaddedByteIndex, p3 abi.UnpaddedPieceSize, p4 abi.SealRandomness, p5 cid.Cid) (storiface.CallID, error) { + return *new(storiface.CallID), xerrors.New("method not supported") +} + +func (s *WorkerStruct) Version(p0 context.Context) (Version, error) { + return s.Internal.Version(p0) +} + +func (s *WorkerStub) Version(p0 context.Context) (Version, error) { + return *new(Version), xerrors.New("method not supported") +} + +func (s *WorkerStruct) WaitQuiet(p0 context.Context) error { + return s.Internal.WaitQuiet(p0) +} + +func (s *WorkerStub) WaitQuiet(p0 context.Context) error { + return xerrors.New("method not supported") +} + +var _ ChainIO = new(ChainIOStruct) +var _ Common = new(CommonStruct) +var _ FullNode = new(FullNodeStruct) +var _ Gateway = new(GatewayStruct) +var _ Signable = new(SignableStruct) +var _ StorageMiner = new(StorageMinerStruct) +var _ Wallet = new(WalletStruct) +var _ Worker = new(WorkerStruct) diff --git a/api/test/ccupgrade.go b/api/test/ccupgrade.go index 606b9f22b58..283c8f610c4 100644 --- a/api/test/ccupgrade.go +++ b/api/test/ccupgrade.go @@ -17,7 +17,7 @@ import ( func TestCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration) { for _, height := range []abi.ChainEpoch{ - 2, // before + -1, // before 162, // while sealing 530, // after upgrade deal 5000, // after @@ -31,7 +31,7 @@ func TestCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration) { func testCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration, upgradeHeight abi.ChainEpoch) { ctx := context.Background() - n, sn := b(t, []FullNodeOpts{FullNodeWithActorsV3At(upgradeHeight)}, OneMiner) + n, sn := b(t, []FullNodeOpts{FullNodeWithLatestActorsAt(upgradeHeight)}, OneMiner) client := n[0].FullNode.(*impl.FullNodeAPI) miner := sn[0] diff --git a/api/test/deadlines.go b/api/test/deadlines.go new file mode 100644 index 00000000000..43fa731be90 --- /dev/null +++ b/api/test/deadlines.go @@ -0,0 +1,352 @@ +package test + +import ( + "bytes" + "context" + "fmt" + "testing" + "time" + + "github.com/filecoin-project/lotus/api" + + "github.com/stretchr/testify/require" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-bitfield" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/go-state-types/exitcode" + "github.com/filecoin-project/go-state-types/network" + miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" + "github.com/ipfs/go-cid" + cbor "github.com/ipfs/go-ipld-cbor" + + "github.com/filecoin-project/lotus/blockstore" + "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/miner" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/extern/sector-storage/mock" + "github.com/filecoin-project/lotus/node/impl" +) + +// TestDeadlineToggling: +// * spins up a v3 network (miner A) +// * creates an inactive miner (miner B) +// * creates another miner, pledges a sector, waits for power (miner C) +// +// * goes through v4 upgrade +// * goes through PP +// * creates minerD, minerE +// * makes sure that miner B/D are inactive, A/C still are +// * pledges sectors on miner B/D +// * precommits a sector on minerE +// * disables post on miner C +// * goes through PP 0.5PP +// * asserts that minerE is active +// * goes through rest of PP (1.5) +// * asserts that miner C loses power +// * asserts that miner B/D is active and has power +// * asserts that minerE is inactive +// * disables post on miner B +// * terminates sectors on miner D +// * goes through another PP +// * asserts that miner B loses power +// * asserts that miner D loses power, is inactive +func TestDeadlineToggling(t *testing.T, b APIBuilder, blocktime time.Duration) { + var upgradeH abi.ChainEpoch = 4000 + var provingPeriod abi.ChainEpoch = 2880 + + const sectorsC, sectorsD, sectersB = 10, 9, 8 + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + n, sn := b(t, []FullNodeOpts{FullNodeWithLatestActorsAt(upgradeH)}, OneMiner) + + client := n[0].FullNode.(*impl.FullNodeAPI) + minerA := sn[0] + + { + addrinfo, err := client.NetAddrsListen(ctx) + if err != nil { + t.Fatal(err) + } + + if err := minerA.NetConnect(ctx, addrinfo); err != nil { + t.Fatal(err) + } + } + + defaultFrom, err := client.WalletDefaultAddress(ctx) + require.NoError(t, err) + + maddrA, err := minerA.ActorAddress(ctx) + require.NoError(t, 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 := minerA.MineOne(ctx, MineNext); err != nil { + if ctx.Err() != nil { + // context was canceled, ignore the error. + return + } + t.Error(err) + } + } + }() + defer func() { + cancel() + <-done + }() + + minerB := n[0].Stb(ctx, t, TestSpt, defaultFrom) + minerC := n[0].Stb(ctx, t, TestSpt, defaultFrom) + + maddrB, err := minerB.ActorAddress(ctx) + require.NoError(t, err) + maddrC, err := minerC.ActorAddress(ctx) + require.NoError(t, err) + + ssz, err := minerC.ActorSectorSize(ctx, maddrC) + require.NoError(t, err) + + // pledge sectors on C, go through a PP, check for power + { + pledgeSectors(t, ctx, minerC, sectorsC, 0, nil) + + di, err := client.StateMinerProvingDeadline(ctx, maddrC, types.EmptyTSK) + require.NoError(t, err) + + fmt.Printf("Running one proving period (miner C)\n") + fmt.Printf("End for head.Height > %d\n", di.PeriodStart+di.WPoStProvingPeriod*2) + + for { + head, err := client.ChainHead(ctx) + require.NoError(t, err) + + if head.Height() > di.PeriodStart+provingPeriod*2 { + fmt.Printf("Now head.Height = %d\n", head.Height()) + break + } + build.Clock.Sleep(blocktime) + } + + expectedPower := types.NewInt(uint64(ssz) * sectorsC) + + p, err := client.StateMinerPower(ctx, maddrC, types.EmptyTSK) + require.NoError(t, err) + + // make sure it has gained power. + require.Equal(t, p.MinerPower.RawBytePower, expectedPower) + } + + // go through upgrade + PP + for { + head, err := client.ChainHead(ctx) + require.NoError(t, err) + + if head.Height() > upgradeH+provingPeriod { + fmt.Printf("Now head.Height = %d\n", head.Height()) + break + } + build.Clock.Sleep(blocktime) + } + + checkMiner := func(ma address.Address, power abi.StoragePower, active bool, tsk types.TipSetKey) { + p, err := client.StateMinerPower(ctx, ma, tsk) + require.NoError(t, err) + + // make sure it has the expected power. + require.Equal(t, p.MinerPower.RawBytePower, power) + + mact, err := client.StateGetActor(ctx, ma, tsk) + require.NoError(t, err) + + mst, err := miner.Load(adt.WrapStore(ctx, cbor.NewCborStore(blockstore.NewAPIBlockstore(client))), mact) + require.NoError(t, err) + + act, err := mst.DeadlineCronActive() + require.NoError(t, err) + require.Equal(t, active, act) + } + + // check that just after the upgrade minerB was still active + { + uts, err := client.ChainGetTipSetByHeight(ctx, upgradeH+2, types.EmptyTSK) + require.NoError(t, err) + checkMiner(maddrB, types.NewInt(0), true, uts.Key()) + } + + nv, err := client.StateNetworkVersion(ctx, types.EmptyTSK) + require.NoError(t, err) + require.GreaterOrEqual(t, nv, network.Version12) + + minerD := n[0].Stb(ctx, t, TestSpt, defaultFrom) + minerE := n[0].Stb(ctx, t, TestSpt, defaultFrom) + + maddrD, err := minerD.ActorAddress(ctx) + require.NoError(t, err) + maddrE, err := minerE.ActorAddress(ctx) + require.NoError(t, err) + + // first round of miner checks + checkMiner(maddrA, types.NewInt(uint64(ssz)*GenesisPreseals), true, types.EmptyTSK) + checkMiner(maddrC, types.NewInt(uint64(ssz)*sectorsC), true, types.EmptyTSK) + + checkMiner(maddrB, types.NewInt(0), false, types.EmptyTSK) + checkMiner(maddrD, types.NewInt(0), false, types.EmptyTSK) + checkMiner(maddrE, types.NewInt(0), false, types.EmptyTSK) + + // pledge sectors on minerB/minerD, stop post on minerC + pledgeSectors(t, ctx, minerB, sectersB, 0, nil) + checkMiner(maddrB, types.NewInt(0), true, types.EmptyTSK) + + pledgeSectors(t, ctx, minerD, sectorsD, 0, nil) + checkMiner(maddrD, types.NewInt(0), true, types.EmptyTSK) + + minerC.StorageMiner.(*impl.StorageMinerAPI).IStorageMgr.(*mock.SectorMgr).Fail() + + // precommit a sector on minerE + { + head, err := client.ChainHead(ctx) + require.NoError(t, err) + + cr, err := cid.Parse("bagboea4b5abcatlxechwbp7kjpjguna6r6q7ejrhe6mdp3lf34pmswn27pkkiekz") + require.NoError(t, err) + + params := &miner.SectorPreCommitInfo{ + Expiration: 2880 * 300, + SectorNumber: 22, + SealProof: TestSpt, + + SealedCID: cr, + SealRandEpoch: head.Height() - 200, + } + + enc := new(bytes.Buffer) + require.NoError(t, params.MarshalCBOR(enc)) + + m, err := client.MpoolPushMessage(ctx, &types.Message{ + To: maddrE, + From: defaultFrom, + Value: types.FromFil(1), + Method: miner.Methods.PreCommitSector, + Params: enc.Bytes(), + }, nil) + require.NoError(t, err) + + r, err := client.StateWaitMsg(ctx, m.Cid(), 2, api.LookbackNoLimit, true) + require.NoError(t, err) + require.Equal(t, exitcode.Ok, r.Receipt.ExitCode) + } + + // go through 0.5 PP + for { + head, err := client.ChainHead(ctx) + require.NoError(t, err) + + if head.Height() > upgradeH+provingPeriod+(provingPeriod/2) { + fmt.Printf("Now head.Height = %d\n", head.Height()) + break + } + build.Clock.Sleep(blocktime) + } + + checkMiner(maddrE, types.NewInt(0), true, types.EmptyTSK) + + // go through rest of the PP + for { + head, err := client.ChainHead(ctx) + require.NoError(t, err) + + if head.Height() > upgradeH+(provingPeriod*3) { + fmt.Printf("Now head.Height = %d\n", head.Height()) + break + } + build.Clock.Sleep(blocktime) + } + + // second round of miner checks + checkMiner(maddrA, types.NewInt(uint64(ssz)*GenesisPreseals), true, types.EmptyTSK) + checkMiner(maddrC, types.NewInt(0), true, types.EmptyTSK) + checkMiner(maddrB, types.NewInt(uint64(ssz)*sectersB), true, types.EmptyTSK) + checkMiner(maddrD, types.NewInt(uint64(ssz)*sectorsD), true, types.EmptyTSK) + checkMiner(maddrE, types.NewInt(0), false, types.EmptyTSK) + + // disable post on minerB + minerB.StorageMiner.(*impl.StorageMinerAPI).IStorageMgr.(*mock.SectorMgr).Fail() + + // terminate sectors on minerD + { + var terminationDeclarationParams []miner2.TerminationDeclaration + secs, err := minerD.SectorsList(ctx) + require.NoError(t, err) + require.Len(t, secs, sectorsD) + + for _, sectorNum := range secs { + sectorbit := bitfield.New() + sectorbit.Set(uint64(sectorNum)) + + loca, err := client.StateSectorPartition(ctx, maddrD, sectorNum, types.EmptyTSK) + require.NoError(t, err) + + para := miner2.TerminationDeclaration{ + Deadline: loca.Deadline, + Partition: loca.Partition, + Sectors: sectorbit, + } + + terminationDeclarationParams = append(terminationDeclarationParams, para) + } + + terminateSectorParams := &miner2.TerminateSectorsParams{ + Terminations: terminationDeclarationParams, + } + + sp, aerr := actors.SerializeParams(terminateSectorParams) + require.NoError(t, aerr) + + smsg, err := client.MpoolPushMessage(ctx, &types.Message{ + From: defaultFrom, + To: maddrD, + Method: miner.Methods.TerminateSectors, + + Value: big.Zero(), + Params: sp, + }, nil) + require.NoError(t, err) + + fmt.Println("sent termination message:", smsg.Cid()) + + r, err := client.StateWaitMsg(ctx, smsg.Cid(), 2, api.LookbackNoLimit, true) + require.NoError(t, err) + require.Equal(t, exitcode.Ok, r.Receipt.ExitCode) + + checkMiner(maddrD, types.NewInt(0), true, r.TipSet) + } + + // go through another PP + for { + head, err := client.ChainHead(ctx) + require.NoError(t, err) + + if head.Height() > upgradeH+(provingPeriod*5) { + fmt.Printf("Now head.Height = %d\n", head.Height()) + break + } + build.Clock.Sleep(blocktime) + } + + // third round of miner checks + checkMiner(maddrA, types.NewInt(uint64(ssz)*GenesisPreseals), true, types.EmptyTSK) + checkMiner(maddrC, types.NewInt(0), true, types.EmptyTSK) + checkMiner(maddrB, types.NewInt(0), true, types.EmptyTSK) + checkMiner(maddrD, types.NewInt(0), false, types.EmptyTSK) +} diff --git a/api/test/mining.go b/api/test/mining.go index 8f3689333fa..4a4f1e1a492 100644 --- a/api/test/mining.go +++ b/api/test/mining.go @@ -11,10 +11,13 @@ import ( logging "github.com/ipfs/go-log/v2" - "github.com/filecoin-project/go-state-types/abi" "github.com/stretchr/testify/require" + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/miner" "github.com/filecoin-project/lotus/node/impl" ) @@ -199,3 +202,39 @@ func TestDealMining(t *testing.T, b APIBuilder, blocktime time.Duration, carExpo fmt.Println("shutting down mining") <-done } + +func (ts *testSuite) testNonGenesisMiner(t *testing.T) { + ctx := context.Background() + n, sn := ts.makeNodes(t, []FullNodeOpts{ + FullNodeWithLatestActorsAt(-1), + }, []StorageMiner{ + {Full: 0, Preseal: PresealGenesis}, + }) + + full, ok := n[0].FullNode.(*impl.FullNodeAPI) + if !ok { + t.Skip("not testing with a full node") + return + } + genesisMiner := sn[0] + + bm := NewBlockMiner(ctx, t, genesisMiner, 4*time.Millisecond) + bm.MineBlocks() + t.Cleanup(bm.Stop) + + gaa, err := genesisMiner.ActorAddress(ctx) + require.NoError(t, err) + + gmi, err := full.StateMinerInfo(ctx, gaa, types.EmptyTSK) + require.NoError(t, err) + + testm := n[0].Stb(ctx, t, TestSpt, gmi.Owner) + + ta, err := testm.ActorAddress(ctx) + require.NoError(t, err) + + tid, err := address.IDFromAddress(ta) + require.NoError(t, err) + + require.Equal(t, uint64(1001), tid) +} diff --git a/api/test/paych.go b/api/test/paych.go index b38ba6189f3..93a083c4a8c 100644 --- a/api/test/paych.go +++ b/api/test/paych.go @@ -235,7 +235,7 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) { if err != nil { t.Fatal(err) } - res, err = paymentReceiver.StateWaitMsg(ctx, collectMsg, 3) + res, err = paymentReceiver.StateWaitMsg(ctx, collectMsg, 3, api.LookbackNoLimit, true) if err != nil { t.Fatal(err) } @@ -287,7 +287,7 @@ func waitForBlocks(ctx context.Context, t *testing.T, bm *BlockMiner, paymentRec t.Fatal(err) } - _, err = paymentReceiver.StateWaitMsg(ctx, m.Cid(), 1) + _, err = paymentReceiver.StateWaitMsg(ctx, m.Cid(), 1, api.LookbackNoLimit, true) if err != nil { t.Fatal(err) } @@ -299,7 +299,7 @@ func waitForMessage(ctx context.Context, t *testing.T, paymentCreator TestNode, defer cancel() fmt.Println("Waiting for", desc) - res, err := paymentCreator.StateWaitMsg(ctx, msgCid, 1) + res, err := paymentCreator.StateWaitMsg(ctx, msgCid, 1, api.LookbackNoLimit, true) if err != nil { fmt.Println("Error waiting for", desc, err) t.Fatal(err) diff --git a/api/test/test.go b/api/test/test.go index eed760bc24c..d09827f5e12 100644 --- a/api/test/test.go +++ b/api/test/test.go @@ -8,20 +8,22 @@ import ( "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-address" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/network" - "github.com/filecoin-project/lotus/api" + + lapi "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v1api" "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/stmgr" + "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/miner" "github.com/filecoin-project/lotus/node" ) @@ -35,15 +37,19 @@ func init() { build.InsecurePoStValidation = true } +type StorageBuilder func(context.Context, *testing.T, abi.RegisteredSealProof, address.Address) TestStorageNode + type TestNode struct { - api.FullNode + v1api.FullNode // ListenAddr is the address on which an API server is listening, if an // API server is created for this Node ListenAddr multiaddr.Multiaddr + + Stb StorageBuilder } type TestStorageNode struct { - api.StorageMiner + lapi.StorageMiner // ListenAddr is the address on which an API server is listening, if an // API server is created for this Node ListenAddr multiaddr.Multiaddr @@ -56,6 +62,8 @@ var PresealGenesis = -1 const GenesisPreseals = 2 +const TestSpt = abi.RegisteredSealProof_StackedDrg2KiBV1_1 + // Options for setting up a mock storage miner type StorageMiner struct { Full int @@ -94,6 +102,7 @@ func TestApis(t *testing.T, b APIBuilder) { t.Run("testMining", ts.testMining) t.Run("testMiningReal", ts.testMiningReal) t.Run("testSearchMsg", ts.testSearchMsg) + t.Run("testNonGenesisMiner", ts.testNonGenesisMiner) } func DefaultFullOpts(nFull int) []FullNodeOpts { @@ -112,7 +121,11 @@ var OneMiner = []StorageMiner{{Full: 0, Preseal: PresealGenesis}} var OneFull = DefaultFullOpts(1) var TwoFull = DefaultFullOpts(2) -var FullNodeWithActorsV3At = func(upgradeHeight abi.ChainEpoch) FullNodeOpts { +var FullNodeWithLatestActorsAt = func(upgradeHeight abi.ChainEpoch) FullNodeOpts { + if upgradeHeight == -1 { + upgradeHeight = 3 + } + return FullNodeOpts{ Opts: func(nodes []TestNode) node.Option { return node.Override(new(stmgr.UpgradeSchedule), stmgr.UpgradeSchedule{{ @@ -121,10 +134,13 @@ var FullNodeWithActorsV3At = func(upgradeHeight abi.ChainEpoch) FullNodeOpts { Height: 1, Migration: stmgr.UpgradeActorsV2, }, { - // Skip directly to tape height so precommits work. Network: network.Version10, - Height: upgradeHeight, + Height: 2, Migration: stmgr.UpgradeActorsV3, + }, { + Network: network.Version12, + Height: upgradeHeight, + Migration: stmgr.UpgradeActorsV4, }}) }, } @@ -155,7 +171,10 @@ var MineNext = miner.MineReq{ } func (ts *testSuite) testVersion(t *testing.T) { - api.RunningNodeType = api.NodeFull + lapi.RunningNodeType = lapi.NodeFull + t.Cleanup(func() { + lapi.RunningNodeType = lapi.NodeUnknown + }) ctx := context.Background() apis, _ := ts.makeNodes(t, OneFull, OneMiner) @@ -196,7 +215,7 @@ func (ts *testSuite) testSearchMsg(t *testing.T) { if err != nil { t.Fatal(err) } - res, err := api.StateWaitMsg(ctx, sm.Cid(), 1) + res, err := api.StateWaitMsg(ctx, sm.Cid(), 1, lapi.LookbackNoLimit, true) if err != nil { t.Fatal(err) } @@ -204,7 +223,7 @@ func (ts *testSuite) testSearchMsg(t *testing.T) { t.Fatal("did not successfully send message") } - searchRes, err := api.StateSearchMsg(ctx, sm.Cid()) + searchRes, err := api.StateSearchMsg(ctx, types.EmptyTSK, sm.Cid(), lapi.LookbackNoLimit, true) if err != nil { t.Fatal(err) } diff --git a/api/test/util.go b/api/test/util.go index 8695e2e2efb..219dcf9ed73 100644 --- a/api/test/util.go +++ b/api/test/util.go @@ -8,6 +8,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-address" + lapi "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/miner" ) @@ -28,7 +29,7 @@ func SendFunds(ctx context.Context, t *testing.T, sender TestNode, addr address. if err != nil { t.Fatal(err) } - res, err := sender.StateWaitMsg(ctx, sm.Cid(), 1) + res, err := sender.StateWaitMsg(ctx, sm.Cid(), 3, lapi.LookbackNoLimit, true) if err != nil { t.Fatal(err) } diff --git a/api/test/window_post.go b/api/test/window_post.go index ce42318b2b2..bb5010b2579 100644 --- a/api/test/window_post.go +++ b/api/test/window_post.go @@ -206,7 +206,7 @@ func pledgeSectors(t *testing.T, ctx context.Context, miner TestStorageNode, n, func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int) { for _, height := range []abi.ChainEpoch{ - 2, // before + -1, // before 162, // while sealing 5000, // while proving } { @@ -223,7 +223,7 @@ func testWindowPostUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration, ctx, cancel := context.WithCancel(context.Background()) defer cancel() - n, sn := b(t, []FullNodeOpts{FullNodeWithActorsV3At(upgradeHeight)}, OneMiner) + n, sn := b(t, []FullNodeOpts{FullNodeWithLatestActorsAt(upgradeHeight)}, OneMiner) client := n[0].FullNode.(*impl.FullNodeAPI) miner := sn[0] @@ -442,7 +442,7 @@ func TestTerminate(t *testing.T, b APIBuilder, blocktime time.Duration) { nSectors := uint64(2) - n, sn := b(t, []FullNodeOpts{FullNodeWithActorsV3At(2)}, []StorageMiner{{Full: 0, Preseal: int(nSectors)}}) + n, sn := b(t, []FullNodeOpts{FullNodeWithLatestActorsAt(-1)}, []StorageMiner{{Full: 0, Preseal: int(nSectors)}}) client := n[0].FullNode.(*impl.FullNodeAPI) miner := sn[0] @@ -617,7 +617,7 @@ func TestWindowPostDispute(t *testing.T, b APIBuilder, blocktime time.Duration) /// // Then we're going to manually submit bad proofs. n, sn := b(t, []FullNodeOpts{ - FullNodeWithActorsV3At(2), + FullNodeWithLatestActorsAt(-1), }, []StorageMiner{ {Full: 0, Preseal: PresealGenesis}, {Full: 0}, @@ -766,7 +766,7 @@ func TestWindowPostDispute(t *testing.T, b APIBuilder, blocktime time.Duration) require.NoError(t, err) fmt.Println("waiting dispute") - rec, err := client.StateWaitMsg(ctx, sm.Cid(), build.MessageConfidence) + rec, err := client.StateWaitMsg(ctx, sm.Cid(), build.MessageConfidence, api.LookbackNoLimit, true) require.NoError(t, err) require.Zero(t, rec.Receipt.ExitCode, "dispute not accepted: %s", rec.Receipt.ExitCode.Error()) } @@ -807,7 +807,7 @@ func TestWindowPostDispute(t *testing.T, b APIBuilder, blocktime time.Duration) sm, err := client.MpoolPushMessage(ctx, msg, nil) require.NoError(t, err) - rec, err := client.StateWaitMsg(ctx, sm.Cid(), build.MessageConfidence) + rec, err := client.StateWaitMsg(ctx, sm.Cid(), build.MessageConfidence, api.LookbackNoLimit, true) require.NoError(t, err) require.Zero(t, rec.Receipt.ExitCode, "recovery not accepted: %s", rec.Receipt.ExitCode.Error()) } @@ -886,7 +886,7 @@ func submitBadProof( return err } - rec, err := client.StateWaitMsg(ctx, sm.Cid(), build.MessageConfidence) + rec, err := client.StateWaitMsg(ctx, sm.Cid(), build.MessageConfidence, api.LookbackNoLimit, true) if err != nil { return err } @@ -900,7 +900,7 @@ func TestWindowPostDisputeFails(t *testing.T, b APIBuilder, blocktime time.Durat ctx, cancel := context.WithCancel(context.Background()) defer cancel() - n, sn := b(t, []FullNodeOpts{FullNodeWithActorsV3At(2)}, OneMiner) + n, sn := b(t, []FullNodeOpts{FullNodeWithLatestActorsAt(-1)}, OneMiner) client := n[0].FullNode.(*impl.FullNodeAPI) miner := sn[0] diff --git a/api/types.go b/api/types.go index a463dd36eb0..83de131a243 100644 --- a/api/types.go +++ b/api/types.go @@ -5,6 +5,8 @@ import ( "fmt" "time" + "github.com/filecoin-project/lotus/chain/types" + datatransfer "github.com/filecoin-project/go-data-transfer" "github.com/filecoin-project/go-state-types/abi" "github.com/ipfs/go-cid" @@ -61,6 +63,7 @@ type DataTransferChannel struct { Message string OtherPeer peer.ID Transferred uint64 + Stages *datatransfer.ChannelStages } // NewDataTransferChannel constructs an API DataTransferChannel type from full channel state snapshot and a host id @@ -115,3 +118,61 @@ type ConnMgrInfo struct { Tags map[string]int Conns map[string]time.Time } + +type NodeStatus struct { + SyncStatus NodeSyncStatus + PeerStatus NodePeerStatus + ChainStatus NodeChainStatus +} + +type NodeSyncStatus struct { + Epoch uint64 + Behind uint64 +} + +type NodePeerStatus struct { + PeersToPublishMsgs int + PeersToPublishBlocks int +} + +type NodeChainStatus struct { + BlocksPerTipsetLast100 float64 + BlocksPerTipsetLastFinality float64 +} + +type CheckStatusCode int + +//go:generate go run golang.org/x/tools/cmd/stringer -type=CheckStatusCode -trimprefix=CheckStatus +const ( + _ CheckStatusCode = iota + // Message Checks + CheckStatusMessageSerialize + CheckStatusMessageSize + CheckStatusMessageValidity + CheckStatusMessageMinGas + CheckStatusMessageMinBaseFee + CheckStatusMessageBaseFee + CheckStatusMessageBaseFeeLowerBound + CheckStatusMessageBaseFeeUpperBound + CheckStatusMessageGetStateNonce + CheckStatusMessageNonce + CheckStatusMessageGetStateBalance + CheckStatusMessageBalance +) + +type CheckStatus struct { + Code CheckStatusCode + OK bool + Err string + Hint map[string]interface{} +} + +type MessageCheckStatus struct { + Cid cid.Cid + CheckStatus +} + +type MessagePrototype struct { + Message types.Message + ValidNonce bool +} diff --git a/api/v0api/full.go b/api/v0api/full.go new file mode 100644 index 00000000000..35100f0322b --- /dev/null +++ b/api/v0api/full.go @@ -0,0 +1,701 @@ +package v0api + +import ( + "context" + + "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/retrievalmarket" + "github.com/filecoin-project/go-fil-markets/storagemarket" + "github.com/filecoin-project/go-multistore" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/crypto" + "github.com/filecoin-project/go-state-types/dline" + "github.com/ipfs/go-cid" + "github.com/libp2p/go-libp2p-core/peer" + + "github.com/filecoin-project/lotus/api" + apitypes "github.com/filecoin-project/lotus/api/types" + "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + "github.com/filecoin-project/lotus/chain/actors/builtin/paych" + "github.com/filecoin-project/lotus/chain/types" + marketevents "github.com/filecoin-project/lotus/markets/loggers" + "github.com/filecoin-project/lotus/node/modules/dtypes" +) + +//go:generate go run github.com/golang/mock/mockgen -destination=v0mocks/mock_full.go -package=v0mocks . FullNode + +// MODIFYING THE API INTERFACE +// +// NOTE: This is the V0 (Stable) API - when adding methods to this interface, +// you'll need to make sure they are also present on the V1 (Unstable) API +// +// This API is implemented in `v1_wrapper.go` as a compatibility layer backed +// by the V1 api +// +// When adding / changing methods in this file: +// * Do the change here +// * Adjust implementation in `node/impl/` +// * Run `make gen` - this will: +// * Generate proxy structs +// * Generate mocks +// * Generate markdown docs +// * Generate openrpc blobs + +// FullNode API is a low-level interface to the Filecoin network full node +type FullNode interface { + Common + + // MethodGroup: Chain + // The Chain method group contains methods for interacting with the + // blockchain, but that do not require any form of state computation. + + // ChainNotify returns channel with chain head updates. + // First message is guaranteed to be of len == 1, and type == 'current'. + ChainNotify(context.Context) (<-chan []*api.HeadChange, error) //perm:read + + // ChainHead returns the current head of the chain. + ChainHead(context.Context) (*types.TipSet, error) //perm:read + + // ChainGetRandomnessFromTickets is used to sample the chain for randomness. + ChainGetRandomnessFromTickets(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) //perm:read + + // ChainGetRandomnessFromBeacon is used to sample the beacon for randomness. + ChainGetRandomnessFromBeacon(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) //perm:read + + // ChainGetBlock returns the block specified by the given CID. + ChainGetBlock(context.Context, cid.Cid) (*types.BlockHeader, error) //perm:read + // ChainGetTipSet returns the tipset specified by the given TipSetKey. + ChainGetTipSet(context.Context, types.TipSetKey) (*types.TipSet, error) //perm:read + + // ChainGetBlockMessages returns messages stored in the specified block. + // + // Note: If there are multiple blocks in a tipset, it's likely that some + // messages will be duplicated. It's also possible for blocks in a tipset to have + // different messages from the same sender at the same nonce. When that happens, + // only the first message (in a block with lowest ticket) will be considered + // for execution + // + // NOTE: THIS METHOD SHOULD ONLY BE USED FOR GETTING MESSAGES IN A SPECIFIC BLOCK + // + // DO NOT USE THIS METHOD TO GET MESSAGES INCLUDED IN A TIPSET + // Use ChainGetParentMessages, which will perform correct message deduplication + ChainGetBlockMessages(ctx context.Context, blockCid cid.Cid) (*api.BlockMessages, error) //perm:read + + // ChainGetParentReceipts returns receipts for messages in parent tipset of + // the specified block. The receipts in the list returned is one-to-one with the + // messages returned by a call to ChainGetParentMessages with the same blockCid. + ChainGetParentReceipts(ctx context.Context, blockCid cid.Cid) ([]*types.MessageReceipt, error) //perm:read + + // ChainGetParentMessages returns messages stored in parent tipset of the + // specified block. + ChainGetParentMessages(ctx context.Context, blockCid cid.Cid) ([]api.Message, error) //perm:read + + // ChainGetTipSetByHeight looks back for a tipset at the specified epoch. + // If there are no blocks at the specified epoch, a tipset at an earlier epoch + // will be returned. + ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error) //perm:read + + // ChainReadObj reads ipld nodes referenced by the specified CID from chain + // blockstore and returns raw bytes. + ChainReadObj(context.Context, cid.Cid) ([]byte, error) //perm:read + + // ChainDeleteObj deletes node referenced by the given CID + ChainDeleteObj(context.Context, cid.Cid) error //perm:admin + + // ChainHasObj checks if a given CID exists in the chain blockstore. + ChainHasObj(context.Context, cid.Cid) (bool, error) //perm:read + + // ChainStatObj returns statistics about the graph referenced by 'obj'. + // If 'base' is also specified, then the returned stat will be a diff + // between the two objects. + ChainStatObj(ctx context.Context, obj cid.Cid, base cid.Cid) (api.ObjStat, error) //perm:read + + // ChainSetHead forcefully sets current chain head. Use with caution. + ChainSetHead(context.Context, types.TipSetKey) error //perm:admin + + // ChainGetGenesis returns the genesis tipset. + ChainGetGenesis(context.Context) (*types.TipSet, error) //perm:read + + // ChainTipSetWeight computes weight for the specified tipset. + ChainTipSetWeight(context.Context, types.TipSetKey) (types.BigInt, error) //perm:read + ChainGetNode(ctx context.Context, p string) (*api.IpldObject, error) //perm:read + + // ChainGetMessage reads a message referenced by the specified CID from the + // chain blockstore. + ChainGetMessage(context.Context, cid.Cid) (*types.Message, error) //perm:read + + // ChainGetPath returns a set of revert/apply operations needed to get from + // one tipset to another, for example: + //``` + // to + // ^ + // from tAA + // ^ ^ + // tBA tAB + // ^---*--^ + // ^ + // tRR + //``` + // Would return `[revert(tBA), apply(tAB), apply(tAA)]` + ChainGetPath(ctx context.Context, from types.TipSetKey, to types.TipSetKey) ([]*api.HeadChange, error) //perm:read + + // ChainExport returns a stream of bytes with CAR dump of chain data. + // The exported chain data includes the header chain from the given tipset + // back to genesis, the entire genesis state, and the most recent 'nroots' + // state trees. + // If oldmsgskip is set, messages from before the requested roots are also not included. + ChainExport(ctx context.Context, nroots abi.ChainEpoch, oldmsgskip bool, tsk types.TipSetKey) (<-chan []byte, error) //perm:read + + // MethodGroup: Beacon + // The Beacon method group contains methods for interacting with the random beacon (DRAND) + + // BeaconGetEntry returns the beacon entry for the given filecoin epoch. If + // the entry has not yet been produced, the call will block until the entry + // becomes available + BeaconGetEntry(ctx context.Context, epoch abi.ChainEpoch) (*types.BeaconEntry, error) //perm:read + + // GasEstimateFeeCap estimates gas fee cap + GasEstimateFeeCap(context.Context, *types.Message, int64, types.TipSetKey) (types.BigInt, error) //perm:read + + // GasEstimateGasLimit estimates gas used by the message and returns it. + // It fails if message fails to execute. + GasEstimateGasLimit(context.Context, *types.Message, types.TipSetKey) (int64, error) //perm:read + + // GasEstimateGasPremium estimates what gas price should be used for a + // message to have high likelihood of inclusion in `nblocksincl` epochs. + + GasEstimateGasPremium(_ context.Context, nblocksincl uint64, + sender address.Address, gaslimit int64, tsk types.TipSetKey) (types.BigInt, error) //perm:read + + // GasEstimateMessageGas estimates gas values for unset message gas fields + GasEstimateMessageGas(context.Context, *types.Message, *api.MessageSendSpec, types.TipSetKey) (*types.Message, error) //perm:read + + // MethodGroup: Sync + // The Sync method group contains methods for interacting with and + // observing the lotus sync service. + + // SyncState returns the current status of the lotus sync system. + SyncState(context.Context) (*api.SyncState, error) //perm:read + + // SyncSubmitBlock can be used to submit a newly created block to the. + // network through this node + SyncSubmitBlock(ctx context.Context, blk *types.BlockMsg) error //perm:write + + // SyncIncomingBlocks returns a channel streaming incoming, potentially not + // yet synced block headers. + SyncIncomingBlocks(ctx context.Context) (<-chan *types.BlockHeader, error) //perm:read + + // SyncCheckpoint marks a blocks as checkpointed, meaning that it won't ever fork away from it. + SyncCheckpoint(ctx context.Context, tsk types.TipSetKey) error //perm:admin + + // SyncMarkBad marks a blocks as bad, meaning that it won't ever by synced. + // Use with extreme caution. + SyncMarkBad(ctx context.Context, bcid cid.Cid) error //perm:admin + + // SyncUnmarkBad unmarks a blocks as bad, making it possible to be validated and synced again. + SyncUnmarkBad(ctx context.Context, bcid cid.Cid) error //perm:admin + + // SyncUnmarkAllBad purges bad block cache, making it possible to sync to chains previously marked as bad + SyncUnmarkAllBad(ctx context.Context) error //perm:admin + + // SyncCheckBad checks if a block was marked as bad, and if it was, returns + // the reason. + SyncCheckBad(ctx context.Context, bcid cid.Cid) (string, error) //perm:read + + // SyncValidateTipset indicates whether the provided tipset is valid or not + SyncValidateTipset(ctx context.Context, tsk types.TipSetKey) (bool, error) //perm:read + + // MethodGroup: Mpool + // The Mpool methods are for interacting with the message pool. The message pool + // manages all incoming and outgoing 'messages' going over the network. + + // MpoolPending returns pending mempool messages. + MpoolPending(context.Context, types.TipSetKey) ([]*types.SignedMessage, error) //perm:read + + // MpoolSelect returns a list of pending messages for inclusion in the next block + MpoolSelect(context.Context, types.TipSetKey, float64) ([]*types.SignedMessage, error) //perm:read + + // MpoolPush pushes a signed message to mempool. + MpoolPush(context.Context, *types.SignedMessage) (cid.Cid, error) //perm:write + + // MpoolPushUntrusted pushes a signed message to mempool from untrusted sources. + MpoolPushUntrusted(context.Context, *types.SignedMessage) (cid.Cid, error) //perm:write + + // MpoolPushMessage atomically assigns a nonce, signs, and pushes a message + // to mempool. + // maxFee is only used when GasFeeCap/GasPremium fields aren't specified + // + // When maxFee is set to 0, MpoolPushMessage will guess appropriate fee + // based on current chain conditions + MpoolPushMessage(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec) (*types.SignedMessage, error) //perm:sign + + // MpoolBatchPush batch pushes a signed message to mempool. + MpoolBatchPush(context.Context, []*types.SignedMessage) ([]cid.Cid, error) //perm:write + + // MpoolBatchPushUntrusted batch pushes a signed message to mempool from untrusted sources. + MpoolBatchPushUntrusted(context.Context, []*types.SignedMessage) ([]cid.Cid, error) //perm:write + + // MpoolBatchPushMessage batch pushes a unsigned message to mempool. + MpoolBatchPushMessage(context.Context, []*types.Message, *api.MessageSendSpec) ([]*types.SignedMessage, error) //perm:sign + + // 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) //perm:read + MpoolSub(context.Context) (<-chan api.MpoolUpdate, error) //perm:read + + // MpoolClear clears pending messages from the mpool + MpoolClear(context.Context, bool) error //perm:write + + // MpoolGetConfig returns (a copy of) the current mpool config + MpoolGetConfig(context.Context) (*types.MpoolConfig, error) //perm:read + // MpoolSetConfig sets the mpool config to (a copy of) the supplied config + MpoolSetConfig(context.Context, *types.MpoolConfig) error //perm:admin + + // MethodGroup: Miner + + MinerGetBaseInfo(context.Context, address.Address, abi.ChainEpoch, types.TipSetKey) (*api.MiningBaseInfo, error) //perm:read + MinerCreateBlock(context.Context, *api.BlockTemplate) (*types.BlockMsg, error) //perm:write + + // // UX ? + + // 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) //perm:write + // WalletHas indicates whether the given address is in the wallet. + WalletHas(context.Context, address.Address) (bool, error) //perm:write + // WalletList lists all the addresses in the wallet. + WalletList(context.Context) ([]address.Address, error) //perm:write + // WalletBalance returns the balance of the given address at the current head of the chain. + WalletBalance(context.Context, address.Address) (types.BigInt, error) //perm:read + // WalletSign signs the given bytes using the given address. + WalletSign(context.Context, address.Address, []byte) (*crypto.Signature, error) //perm:sign + // WalletSignMessage signs the given message using the given address. + WalletSignMessage(context.Context, address.Address, *types.Message) (*types.SignedMessage, error) //perm:sign + // WalletVerify takes an address, a signature, and some bytes, and indicates whether the signature is valid. + // The address does not have to be in the wallet. + WalletVerify(context.Context, address.Address, []byte, *crypto.Signature) (bool, error) //perm:read + // WalletDefaultAddress returns the address marked as default in the wallet. + WalletDefaultAddress(context.Context) (address.Address, error) //perm:write + // WalletSetDefault marks the given address as as the default one. + WalletSetDefault(context.Context, address.Address) error //perm:write + // WalletExport returns the private key of an address in the wallet. + WalletExport(context.Context, address.Address) (*types.KeyInfo, error) //perm:admin + // WalletImport receives a KeyInfo, which includes a private key, and imports it into the wallet. + WalletImport(context.Context, *types.KeyInfo) (address.Address, error) //perm:admin + // WalletDelete deletes an address from the wallet. + WalletDelete(context.Context, address.Address) error //perm:admin + // WalletValidateAddress validates whether a given string can be decoded as a well-formed address + WalletValidateAddress(context.Context, string) (address.Address, error) //perm:read + + // Other + + // MethodGroup: Client + // The Client methods all have to do with interacting with the storage and + // retrieval markets as a client + + // ClientImport imports file under the specified path into filestore. + ClientImport(ctx context.Context, ref api.FileRef) (*api.ImportRes, error) //perm:admin + // ClientRemoveImport removes file import + ClientRemoveImport(ctx context.Context, importID multistore.StoreID) error //perm:admin + // ClientStartDeal proposes a deal with a miner. + ClientStartDeal(ctx context.Context, params *api.StartDealParams) (*cid.Cid, error) //perm:admin + // ClientGetDealInfo returns the latest information about a given deal. + ClientGetDealInfo(context.Context, cid.Cid) (*api.DealInfo, error) //perm:read + // ClientListDeals returns information about the deals made by the local client. + ClientListDeals(ctx context.Context) ([]api.DealInfo, error) //perm:write + // ClientGetDealUpdates returns the status of updated deals + ClientGetDealUpdates(ctx context.Context) (<-chan api.DealInfo, error) //perm:write + // ClientGetDealStatus returns status given a code + ClientGetDealStatus(ctx context.Context, statusCode uint64) (string, error) //perm:read + // ClientHasLocal indicates whether a certain CID is locally stored. + ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error) //perm:write + // ClientFindData identifies peers that have a certain file, and returns QueryOffers (one per peer). + ClientFindData(ctx context.Context, root cid.Cid, piece *cid.Cid) ([]api.QueryOffer, error) //perm:read + // ClientMinerQueryOffer returns a QueryOffer for the specific miner and file. + ClientMinerQueryOffer(ctx context.Context, miner address.Address, root cid.Cid, piece *cid.Cid) (api.QueryOffer, error) //perm:read + // ClientRetrieve initiates the retrieval of a file, as specified in the order. + ClientRetrieve(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) error //perm:admin + // ClientRetrieveWithEvents initiates the retrieval of a file, as specified in the order, and provides a channel + // of status updates. + ClientRetrieveWithEvents(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) (<-chan marketevents.RetrievalEvent, error) //perm:admin + // ClientQueryAsk returns a signed StorageAsk from the specified miner. + ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.StorageAsk, error) //perm:read + // ClientCalcCommP calculates the CommP and data size of the specified CID + ClientDealPieceCID(ctx context.Context, root cid.Cid) (api.DataCIDSize, error) //perm:read + // ClientCalcCommP calculates the CommP for a specified file + ClientCalcCommP(ctx context.Context, inpath string) (*api.CommPRet, error) //perm:write + // ClientGenCar generates a CAR file for the specified file. + ClientGenCar(ctx context.Context, ref api.FileRef, outpath string) error //perm:write + // ClientDealSize calculates real deal data size + ClientDealSize(ctx context.Context, root cid.Cid) (api.DataSize, error) //perm:read + // ClientListTransfers returns the status of all ongoing transfers of data + ClientListDataTransfers(ctx context.Context) ([]api.DataTransferChannel, error) //perm:write + ClientDataTransferUpdates(ctx context.Context) (<-chan api.DataTransferChannel, error) //perm:write + // 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 //perm:write + // 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 //perm:write + // 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 //perm:write + + // ClientCancelRetrievalDeal cancels an ongoing retrieval deal based on DealID + ClientCancelRetrievalDeal(ctx context.Context, dealid retrievalmarket.DealID) error //perm:write + + // ClientUnimport removes references to the specified file from filestore + //ClientUnimport(path string) + + // ClientListImports lists imported files and their root CIDs + ClientListImports(ctx context.Context) ([]api.Import, error) //perm:write + + //ClientListAsks() []Ask + + // 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 parent state of the 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 applies the message to the tipset's parent state. The + // message is not applied on-top-of the messages in the passed-in + // tipset. + StateCall(context.Context, *types.Message, types.TipSetKey) (*api.InvocResult, error) //perm:read + // StateReplay replays a given message, assuming it was included in a block in the specified tipset. + // + // If a tipset key is provided, and a replacing message is found on chain, + // the method will return an error saying that the message wasn't found + // + // If no tipset key is provided, the appropriate tipset is looked up, and if + // the message was gas-repriced, the on-chain message will be replayed - in + // that case the returned InvocResult.MsgCid will not match the Cid param + // + // If the caller wants to ensure that exactly the requested message was executed, + // they MUST check that InvocResult.MsgCid is equal to the provided Cid. + // Without this check both the requested and original message may appear as + // successfully executed on-chain, which may look like a double-spend. + // + // A replacing message is a message with a different CID, any of Gas values, and + // different signature, but with all other parameters matching (source/destination, + // nonce, params, etc.) + StateReplay(context.Context, types.TipSetKey, cid.Cid) (*api.InvocResult, error) //perm:read + // StateGetActor returns the indicated actor's nonce and balance. + StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) //perm:read + // StateReadState returns the indicated actor's state. + StateReadState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*api.ActorState, error) //perm:read + // StateListMessages looks back and returns all messages with a matching to or from address, stopping at the given height. + StateListMessages(ctx context.Context, match *api.MessageMatch, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error) //perm:read + // 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) //perm:read + + // StateNetworkName returns the name of the network the node is synced to + StateNetworkName(context.Context) (dtypes.NetworkName, error) //perm:read + // StateMinerSectors returns info about the given miner's sectors. If the filter bitfield is nil, all sectors are included. + StateMinerSectors(context.Context, address.Address, *bitfield.BitField, types.TipSetKey) ([]*miner.SectorOnChainInfo, error) //perm:read + // StateMinerActiveSectors returns info about sectors that a given miner is actively proving. + StateMinerActiveSectors(context.Context, address.Address, types.TipSetKey) ([]*miner.SectorOnChainInfo, error) //perm:read + // StateMinerProvingDeadline calculates the deadline at some epoch for a proving period + // and returns the deadline-related calculations. + StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*dline.Info, error) //perm:read + // StateMinerPower returns the power of the indicated miner + StateMinerPower(context.Context, address.Address, types.TipSetKey) (*api.MinerPower, error) //perm:read + // StateMinerInfo returns info about the indicated miner + StateMinerInfo(context.Context, address.Address, types.TipSetKey) (miner.MinerInfo, error) //perm:read + // StateMinerDeadlines returns all the proving deadlines for the given miner + StateMinerDeadlines(context.Context, address.Address, types.TipSetKey) ([]api.Deadline, error) //perm:read + // StateMinerPartitions returns all partitions in the specified deadline + StateMinerPartitions(ctx context.Context, m address.Address, dlIdx uint64, tsk types.TipSetKey) ([]api.Partition, error) //perm:read + // StateMinerFaults returns a bitfield indicating the faulty sectors of the given miner + StateMinerFaults(context.Context, address.Address, types.TipSetKey) (bitfield.BitField, error) //perm:read + // StateAllMinerFaults returns all non-expired Faults that occur within lookback epochs of the given tipset + StateAllMinerFaults(ctx context.Context, lookback abi.ChainEpoch, ts types.TipSetKey) ([]*api.Fault, error) //perm:read + // StateMinerRecoveries returns a bitfield indicating the recovering sectors of the given miner + StateMinerRecoveries(context.Context, address.Address, types.TipSetKey) (bitfield.BitField, error) //perm:read + // StateMinerInitialPledgeCollateral returns the precommit deposit for the specified miner's sector + StateMinerPreCommitDepositForPower(context.Context, address.Address, miner.SectorPreCommitInfo, types.TipSetKey) (types.BigInt, error) //perm:read + // StateMinerInitialPledgeCollateral returns the initial pledge collateral for the specified miner's sector + StateMinerInitialPledgeCollateral(context.Context, address.Address, miner.SectorPreCommitInfo, types.TipSetKey) (types.BigInt, error) //perm:read + // 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) //perm:read + // StateMinerSectorAllocated checks if a sector is allocated + StateMinerSectorAllocated(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (bool, error) //perm:read + // StateSectorPreCommitInfo returns the PreCommit info for the specified miner's sector + StateSectorPreCommitInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) //perm:read + // StateSectorGetInfo returns the on-chain info for the specified miner's sector. Returns null in case the sector info isn't found + // NOTE: returned info.Expiration may not be accurate in some cases, use StateSectorExpiration to get accurate + // expiration epoch + StateSectorGetInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorOnChainInfo, error) //perm:read + // StateSectorExpiration returns epoch at which given sector will expire + StateSectorExpiration(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorExpiration, error) //perm:read + // StateSectorPartition finds deadline/partition with the specified sector + StateSectorPartition(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok types.TipSetKey) (*miner.SectorLocation, error) //perm:read + // StateSearchMsg searches for a message in the chain, and returns its receipt and the tipset where it was executed + // + // NOTE: If a replacing message is found on chain, this method will return + // a MsgLookup for the replacing message - the MsgLookup.Message will be a different + // CID than the one provided in the 'cid' param, MsgLookup.Receipt will contain the + // result of the execution of the replacing message. + // + // If the caller wants to ensure that exactly the requested message was executed, + // they MUST check that MsgLookup.Message is equal to the provided 'cid'. + // Without this check both the requested and original message may appear as + // successfully executed on-chain, which may look like a double-spend. + // + // A replacing message is a message with a different CID, any of Gas values, and + // different signature, but with all other parameters matching (source/destination, + // nonce, params, etc.) + StateSearchMsg(context.Context, cid.Cid) (*api.MsgLookup, error) //perm:read + // StateSearchMsgLimited looks back up to limit epochs in the chain for a message, and returns its receipt and the tipset where it was executed + // + // NOTE: If a replacing message is found on chain, this method will return + // a MsgLookup for the replacing message - the MsgLookup.Message will be a different + // CID than the one provided in the 'cid' param, MsgLookup.Receipt will contain the + // result of the execution of the replacing message. + // + // If the caller wants to ensure that exactly the requested message was executed, + // they MUST check that MsgLookup.Message is equal to the provided 'cid'. + // Without this check both the requested and original message may appear as + // successfully executed on-chain, which may look like a double-spend. + // + // A replacing message is a message with a different CID, any of Gas values, and + // different signature, but with all other parameters matching (source/destination, + // nonce, params, etc.) + StateSearchMsgLimited(ctx context.Context, msg cid.Cid, limit abi.ChainEpoch) (*api.MsgLookup, error) //perm:read + // 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. + // + // NOTE: If a replacing message is found on chain, this method will return + // a MsgLookup for the replacing message - the MsgLookup.Message will be a different + // CID than the one provided in the 'cid' param, MsgLookup.Receipt will contain the + // result of the execution of the replacing message. + // + // If the caller wants to ensure that exactly the requested message was executed, + // they MUST check that MsgLookup.Message is equal to the provided 'cid'. + // Without this check both the requested and original message may appear as + // successfully executed on-chain, which may look like a double-spend. + // + // A replacing message is a message with a different CID, any of Gas values, and + // different signature, but with all other parameters matching (source/destination, + // nonce, params, etc.) + StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64) (*api.MsgLookup, error) //perm:read + // StateWaitMsgLimited looks back up to limit epochs in the chain for a message. + // If not found, it blocks until the message arrives on chain, and gets to the + // indicated confidence depth. + // + // NOTE: If a replacing message is found on chain, this method will return + // a MsgLookup for the replacing message - the MsgLookup.Message will be a different + // CID than the one provided in the 'cid' param, MsgLookup.Receipt will contain the + // result of the execution of the replacing message. + // + // If the caller wants to ensure that exactly the requested message was executed, + // they MUST check that MsgLookup.Message is equal to the provided 'cid'. + // Without this check both the requested and original message may appear as + // successfully executed on-chain, which may look like a double-spend. + // + // A replacing message is a message with a different CID, any of Gas values, and + // different signature, but with all other parameters matching (source/destination, + // nonce, params, etc.) + StateWaitMsgLimited(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch) (*api.MsgLookup, error) //perm:read + // StateListMiners returns the addresses of every miner that has claimed power in the Power Actor + StateListMiners(context.Context, types.TipSetKey) ([]address.Address, error) //perm:read + // StateListActors returns the addresses of every actor in the state + StateListActors(context.Context, types.TipSetKey) ([]address.Address, error) //perm:read + // StateMarketBalance looks up the Escrow and Locked balances of the given address in the Storage Market + StateMarketBalance(context.Context, address.Address, types.TipSetKey) (api.MarketBalance, error) //perm:read + // StateMarketParticipants returns the Escrow and Locked balances of every participant in the Storage Market + StateMarketParticipants(context.Context, types.TipSetKey) (map[string]api.MarketBalance, error) //perm:read + // StateMarketDeals returns information about every deal in the Storage Market + StateMarketDeals(context.Context, types.TipSetKey) (map[string]api.MarketDeal, error) //perm:read + // StateMarketStorageDeal returns information about the indicated deal + StateMarketStorageDeal(context.Context, abi.DealID, types.TipSetKey) (*api.MarketDeal, error) //perm:read + // StateLookupID retrieves the ID address of the given address + StateLookupID(context.Context, address.Address, types.TipSetKey) (address.Address, error) //perm:read + // StateAccountKey returns the public key address of the given ID address + StateAccountKey(context.Context, address.Address, types.TipSetKey) (address.Address, error) //perm:read + // StateChangedActors returns all the actors whose states change between the two given state CIDs + // TODO: Should this take tipset keys instead? + StateChangedActors(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error) //perm:read + // StateGetReceipt returns the message receipt for the given message or for a + // matching gas-repriced replacing message + // + // NOTE: If the requested message was replaced, this method will return the receipt + // for the replacing message - if the caller needs the receipt for exactly the + // requested message, use StateSearchMsg().Receipt, and check that MsgLookup.Message + // is matching the requested CID + // + // DEPRECATED: Use StateSearchMsg, this method won't be supported in v1 API + StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) //perm:read + // StateMinerSectorCount returns the number of sectors in a miner's sector set and proving set + StateMinerSectorCount(context.Context, address.Address, types.TipSetKey) (api.MinerSectors, error) //perm:read + // StateCompute is a flexible command that applies the given messages on the given tipset. + // The messages are run as though the VM were at the provided height. + // + // When called, StateCompute will: + // - Load the provided tipset, or use the current chain head if not provided + // - Compute the tipset state of the provided tipset on top of the parent state + // - (note that this step runs before vmheight is applied to the execution) + // - Execute state upgrade if any were scheduled at the epoch, or in null + // blocks preceding the tipset + // - Call the cron actor on null blocks preceding the tipset + // - For each block in the tipset + // - Apply messages in blocks in the specified + // - Award block reward by calling the reward actor + // - Call the cron actor for the current epoch + // - If the specified vmheight is higher than the current epoch, apply any + // needed state upgrades to the state + // - Apply the specified messages to the state + // + // The vmheight parameter sets VM execution epoch, and can be used to simulate + // message execution in different network versions. If the specified vmheight + // epoch is higher than the epoch of the specified tipset, any state upgrades + // until the vmheight will be executed on the state before applying messages + // specified by the user. + // + // Note that the initial tipset state computation is not affected by the + // vmheight parameter - only the messages in the `apply` set are + // + // If the caller wants to simply compute the state, vmheight should be set to + // the epoch of the specified tipset. + // + // Messages in the `apply` parameter must have the correct nonces, and gas + // values set. + StateCompute(context.Context, abi.ChainEpoch, []*types.Message, types.TipSetKey) (*api.ComputeStateOutput, error) //perm:read + // StateVerifierStatus returns the data cap for the given address. + // Returns nil if there is no entry in the data cap table for the + // address. + StateVerifierStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) //perm:read + // StateVerifiedClientStatus returns the data cap for the given address. + // Returns nil if there is no entry in the data cap table for the + // address. + StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) //perm:read + // StateVerifiedClientStatus returns the address of the Verified Registry's root key + StateVerifiedRegistryRootKey(ctx context.Context, tsk types.TipSetKey) (address.Address, error) //perm:read + // StateDealProviderCollateralBounds returns the min and max collateral a storage provider + // can issue. It takes the deal size and verified status as parameters. + StateDealProviderCollateralBounds(context.Context, abi.PaddedPieceSize, bool, types.TipSetKey) (api.DealCollateralBounds, error) //perm:read + + // 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) //perm:read + // 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) (api.CirculatingSupply, error) //perm:read + // StateNetworkVersion returns the network version at the given tipset + StateNetworkVersion(context.Context, types.TipSetKey) (apitypes.NetworkVersion, error) //perm:read + + // MethodGroup: Msig + // The Msig methods are used to interact with multisig wallets on the + // filecoin network + + // MsigGetAvailableBalance returns the portion of a multisig's balance that can be withdrawn or spent + MsigGetAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) //perm:read + // MsigGetVestingSchedule returns the vesting details of a given multisig. + MsigGetVestingSchedule(context.Context, address.Address, types.TipSetKey) (api.MsigVesting, error) //perm:read + // MsigGetVested returns the amount of FIL that vested in a multisig in a certain period. + // It takes the following params: , , + MsigGetVested(context.Context, address.Address, types.TipSetKey, types.TipSetKey) (types.BigInt, error) //perm:read + + //MsigGetPending returns pending transactions for the given multisig + //wallet. Once pending transactions are fully approved, they will no longer + //appear here. + MsigGetPending(context.Context, address.Address, types.TipSetKey) ([]*api.MsigTransaction, error) //perm:read + + // MsigCreate creates a multisig wallet + // It takes the following params: , , + //, , + MsigCreate(context.Context, uint64, []address.Address, abi.ChainEpoch, types.BigInt, address.Address, types.BigInt) (cid.Cid, error) //perm:sign + // MsigPropose proposes a multisig message + // It takes the following params: , , , + // , , + MsigPropose(context.Context, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) //perm:sign + + // MsigApprove approves a previously-proposed multisig message by transaction ID + // It takes the following params: , + MsigApprove(context.Context, address.Address, uint64, address.Address) (cid.Cid, error) //perm:sign + + // MsigApproveTxnHash approves a previously-proposed multisig message, specified + // using both transaction ID and a hash of the parameters used in the + // proposal. This method of approval can be used to ensure you only approve + // exactly the transaction you think you are. + // It takes the following params: , , , , , + // , , + MsigApproveTxnHash(context.Context, address.Address, uint64, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) //perm:sign + + // MsigCancel cancels a previously-proposed multisig message + // It takes the following params: , , , , + // , , + MsigCancel(context.Context, address.Address, uint64, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) //perm:sign + // MsigAddPropose proposes adding a signer in the multisig + // It takes the following params: , , + // , + MsigAddPropose(context.Context, address.Address, address.Address, address.Address, bool) (cid.Cid, error) //perm:sign + // MsigAddApprove approves a previously proposed AddSigner message + // It takes the following params: , , , + // , , + MsigAddApprove(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, bool) (cid.Cid, error) //perm:sign + // MsigAddCancel cancels a previously proposed AddSigner message + // It takes the following params: , , , + // , + MsigAddCancel(context.Context, address.Address, address.Address, uint64, address.Address, bool) (cid.Cid, error) //perm:sign + // MsigSwapPropose proposes swapping 2 signers in the multisig + // It takes the following params: , , + // , + MsigSwapPropose(context.Context, address.Address, address.Address, address.Address, address.Address) (cid.Cid, error) //perm:sign + // MsigSwapApprove approves a previously proposed SwapSigner + // It takes the following params: , , , + // , , + MsigSwapApprove(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, address.Address) (cid.Cid, error) //perm:sign + // MsigSwapCancel cancels a previously proposed SwapSigner message + // It takes the following params: , , , + // , + MsigSwapCancel(context.Context, address.Address, address.Address, uint64, address.Address, address.Address) (cid.Cid, error) //perm:sign + + // MsigRemoveSigner proposes the removal of a signer from the multisig. + // It accepts the multisig to make the change on, the proposer address to + // send the message from, the address to be removed, and a boolean + // indicating whether or not the signing threshold should be lowered by one + // along with the address removal. + MsigRemoveSigner(ctx context.Context, msig address.Address, proposer address.Address, toRemove address.Address, decrease bool) (cid.Cid, error) //perm:sign + + // MarketAddBalance adds funds to the market actor + MarketAddBalance(ctx context.Context, wallet, addr address.Address, amt types.BigInt) (cid.Cid, error) //perm:sign + // MarketGetReserved gets the amount of funds that are currently reserved for the address + MarketGetReserved(ctx context.Context, addr address.Address) (types.BigInt, error) //perm:sign + // MarketReserveFunds reserves funds for a deal + MarketReserveFunds(ctx context.Context, wallet address.Address, addr address.Address, amt types.BigInt) (cid.Cid, error) //perm:sign + // MarketReleaseFunds releases funds reserved by MarketReserveFunds + MarketReleaseFunds(ctx context.Context, addr address.Address, amt types.BigInt) error //perm:sign + // MarketWithdraw withdraws unlocked funds from the market actor + MarketWithdraw(ctx context.Context, wallet, addr address.Address, amt types.BigInt) (cid.Cid, error) //perm:sign + + // MethodGroup: Paych + // The Paych methods are for interacting with and managing payment channels + + PaychGet(ctx context.Context, from, to address.Address, amt types.BigInt) (*api.ChannelInfo, error) //perm:sign + PaychGetWaitReady(context.Context, cid.Cid) (address.Address, error) //perm:sign + PaychAvailableFunds(ctx context.Context, ch address.Address) (*api.ChannelAvailableFunds, error) //perm:sign + PaychAvailableFundsByFromTo(ctx context.Context, from, to address.Address) (*api.ChannelAvailableFunds, error) //perm:sign + PaychList(context.Context) ([]address.Address, error) //perm:read + PaychStatus(context.Context, address.Address) (*api.PaychStatus, error) //perm:read + PaychSettle(context.Context, address.Address) (cid.Cid, error) //perm:sign + PaychCollect(context.Context, address.Address) (cid.Cid, error) //perm:sign + PaychAllocateLane(ctx context.Context, ch address.Address) (uint64, error) //perm:sign + PaychNewPayment(ctx context.Context, from, to address.Address, vouchers []api.VoucherSpec) (*api.PaymentInfo, error) //perm:sign + PaychVoucherCheckValid(context.Context, address.Address, *paych.SignedVoucher) error //perm:read + PaychVoucherCheckSpendable(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (bool, error) //perm:read + PaychVoucherCreate(context.Context, address.Address, types.BigInt, uint64) (*api.VoucherCreateResult, error) //perm:sign + PaychVoucherAdd(context.Context, address.Address, *paych.SignedVoucher, []byte, types.BigInt) (types.BigInt, error) //perm:write + PaychVoucherList(context.Context, address.Address) ([]*paych.SignedVoucher, error) //perm:write + PaychVoucherSubmit(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (cid.Cid, error) //perm:sign + + // CreateBackup creates node backup onder the specified file name. The + // method requires that the lotus daemon is running with the + // LOTUS_BACKUP_BASE_PATH environment variable set to some path, and that + // the path specified when calling CreateBackup is within the base path + CreateBackup(ctx context.Context, fpath string) error //perm:admin +} diff --git a/api/v0api/gateway.go b/api/v0api/gateway.go new file mode 100644 index 00000000000..8a55b4c27a9 --- /dev/null +++ b/api/v0api/gateway.go @@ -0,0 +1,68 @@ +package v0api + +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/api" + "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + "github.com/filecoin-project/lotus/chain/types" +) + +// MODIFYING THE API INTERFACE +// +// NOTE: This is the V0 (Stable) API - when adding methods to this interface, +// you'll need to make sure they are also present on the V1 (Unstable) API +// +// This API is implemented in `v1_wrapper.go` as a compatibility layer backed +// by the V1 api +// +// When adding / changing methods in this file: +// * Do the change here +// * Adjust implementation in `node/impl/` +// * Run `make gen` - this will: +// * Generate proxy structs +// * Generate mocks +// * Generate markdown docs +// * Generate openrpc blobs + +type Gateway interface { + ChainHasObj(context.Context, cid.Cid) (bool, error) + ChainHead(ctx context.Context) (*types.TipSet, error) + ChainGetBlockMessages(context.Context, cid.Cid) (*api.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 []*api.HeadChange, error) + ChainReadObj(context.Context, cid.Cid) ([]byte, error) + GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *api.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) + MsigGetPending(context.Context, address.Address, types.TipSetKey) ([]*api.MsigTransaction, 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) (api.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) (api.MarketBalance, error) + StateMarketStorageDeal(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*api.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) (*api.MinerPower, error) + StateNetworkVersion(context.Context, types.TipSetKey) (network.Version, error) + StateSearchMsg(ctx context.Context, msg cid.Cid) (*api.MsgLookup, error) + StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error) + StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) + StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error) + WalletBalance(context.Context, address.Address) (types.BigInt, error) +} + +var _ Gateway = *new(FullNode) diff --git a/api/v0api/latest.go b/api/v0api/latest.go new file mode 100644 index 00000000000..87f977be608 --- /dev/null +++ b/api/v0api/latest.go @@ -0,0 +1,25 @@ +package v0api + +import ( + "github.com/filecoin-project/lotus/api" +) + +type Common = api.Common +type CommonStruct = api.CommonStruct +type CommonStub = api.CommonStub + +type StorageMiner = api.StorageMiner +type StorageMinerStruct = api.StorageMinerStruct + +type Worker = api.Worker +type WorkerStruct = api.WorkerStruct + +type Wallet = api.Wallet + +func PermissionedStorMinerAPI(a StorageMiner) StorageMiner { + return api.PermissionedStorMinerAPI(a) +} + +func PermissionedWorkerAPI(a Worker) Worker { + return api.PermissionedWorkerAPI(a) +} diff --git a/api/v0api/permissioned.go b/api/v0api/permissioned.go new file mode 100644 index 00000000000..ad64bc29ede --- /dev/null +++ b/api/v0api/permissioned.go @@ -0,0 +1,13 @@ +package v0api + +import ( + "github.com/filecoin-project/go-jsonrpc/auth" + "github.com/filecoin-project/lotus/api" +) + +func PermissionedFullAPI(a FullNode) FullNode { + var out FullNodeStruct + auth.PermissionedProxy(api.AllPermissions, api.DefaultPerms, a, &out.Internal) + auth.PermissionedProxy(api.AllPermissions, api.DefaultPerms, a, &out.CommonStruct.Internal) + return &out +} diff --git a/api/apistruct/struct.go b/api/v0api/proxy_gen.go similarity index 61% rename from api/apistruct/struct.go rename to api/v0api/proxy_gen.go index 34cf52fce07..171a9e05afd 100644 --- a/api/apistruct/struct.go +++ b/api/v0api/proxy_gen.go @@ -1,107 +1,32 @@ // Code generated by github.com/filecoin-project/lotus/gen/api. DO NOT EDIT. -package apistruct +package v0api import ( "context" - "io" - "time" "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" - "github.com/filecoin-project/go-jsonrpc/auth" "github.com/filecoin-project/go-multistore" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/go-state-types/dline" + "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/lotus/api" apitypes "github.com/filecoin-project/lotus/api/types" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" "github.com/filecoin-project/lotus/chain/actors/builtin/paych" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/extern/sector-storage/fsutil" - "github.com/filecoin-project/lotus/extern/sector-storage/sealtasks" - "github.com/filecoin-project/lotus/extern/sector-storage/stores" - "github.com/filecoin-project/lotus/extern/sector-storage/storiface" marketevents "github.com/filecoin-project/lotus/markets/loggers" "github.com/filecoin-project/lotus/node/modules/dtypes" - "github.com/filecoin-project/specs-storage/storage" - "github.com/google/uuid" "github.com/ipfs/go-cid" - "github.com/libp2p/go-libp2p-core/metrics" - "github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/protocol" + "golang.org/x/xerrors" ) -type ChainIOStruct struct { - Internal struct { - ChainHasObj func(p0 context.Context, p1 cid.Cid) (bool, error) `` - - ChainReadObj func(p0 context.Context, p1 cid.Cid) ([]byte, error) `` - } -} - -type CommonStruct struct { - Internal struct { - AuthNew func(p0 context.Context, p1 []auth.Permission) ([]byte, error) `perm:"admin"` - - AuthVerify func(p0 context.Context, p1 string) ([]auth.Permission, error) `perm:"read"` - - Closing func(p0 context.Context) (<-chan struct{}, error) `perm:"read"` - - Discover func(p0 context.Context) (apitypes.OpenRPCDocument, error) `perm:"read"` - - ID func(p0 context.Context) (peer.ID, error) `perm:"read"` - - LogList func(p0 context.Context) ([]string, error) `perm:"write"` - - LogSetLevel func(p0 context.Context, p1 string, p2 string) error `perm:"write"` - - NetAddrsListen func(p0 context.Context) (peer.AddrInfo, error) `perm:"read"` - - NetAgentVersion func(p0 context.Context, p1 peer.ID) (string, error) `perm:"read"` - - NetAutoNatStatus func(p0 context.Context) (api.NatInfo, error) `perm:"read"` - - NetBandwidthStats func(p0 context.Context) (metrics.Stats, error) `perm:"read"` - - NetBandwidthStatsByPeer func(p0 context.Context) (map[string]metrics.Stats, error) `perm:"read"` - - NetBandwidthStatsByProtocol func(p0 context.Context) (map[protocol.ID]metrics.Stats, error) `perm:"read"` - - NetBlockAdd func(p0 context.Context, p1 api.NetBlockList) error `perm:"admin"` - - NetBlockList func(p0 context.Context) (api.NetBlockList, error) `perm:"read"` - - NetBlockRemove func(p0 context.Context, p1 api.NetBlockList) error `perm:"admin"` - - NetConnect func(p0 context.Context, p1 peer.AddrInfo) error `perm:"write"` - - NetConnectedness func(p0 context.Context, p1 peer.ID) (network.Connectedness, error) `perm:"read"` - - NetDisconnect func(p0 context.Context, p1 peer.ID) error `perm:"write"` - - NetFindPeer func(p0 context.Context, p1 peer.ID) (peer.AddrInfo, error) `perm:"read"` - - NetPeerInfo func(p0 context.Context, p1 peer.ID) (*api.ExtendedPeerInfo, error) `perm:"read"` - - NetPeers func(p0 context.Context) ([]peer.AddrInfo, error) `perm:"read"` - - NetPubsubScores func(p0 context.Context) ([]api.PubsubScore, error) `perm:"read"` - - Session func(p0 context.Context) (uuid.UUID, error) `perm:"read"` - - Shutdown func(p0 context.Context) error `perm:"admin"` - - Version func(p0 context.Context) (api.APIVersion, error) `perm:"read"` - } -} - type FullNodeStruct struct { CommonStruct @@ -154,6 +79,8 @@ type FullNodeStruct struct { ClientCancelDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"` + ClientCancelRetrievalDeal func(p0 context.Context, p1 retrievalmarket.DealID) error `perm:"write"` + ClientDataTransferUpdates func(p0 context.Context) (<-chan api.DataTransferChannel, error) `perm:"write"` ClientDealPieceCID func(p0 context.Context, p1 cid.Cid) (api.DataCIDSize, error) `perm:"read"` @@ -452,6 +379,10 @@ type FullNodeStruct struct { } } +type FullNodeStub struct { + CommonStub +} + type GatewayStruct struct { Internal struct { ChainGetBlockMessages func(p0 context.Context, p1 cid.Cid) (*api.BlockMessages, error) `` @@ -502,7 +433,7 @@ type GatewayStruct struct { StateMinerProvingDeadline func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) `` - StateNetworkVersion func(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) `` + StateNetworkVersion func(p0 context.Context, p1 types.TipSetKey) (network.Version, error) `` StateSearchMsg func(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) `` @@ -511,1662 +442,1637 @@ type GatewayStruct struct { StateVerifiedClientStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) `` StateWaitMsg func(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) `` - } -} -type SignableStruct struct { - Internal struct { - Sign func(p0 context.Context, p1 api.SignFunc) error `` + WalletBalance func(p0 context.Context, p1 address.Address) (types.BigInt, error) `` } } -type StorageMinerStruct struct { - CommonStruct - - Internal struct { - ActorAddress func(p0 context.Context) (address.Address, error) `perm:"read"` - - ActorAddressConfig func(p0 context.Context) (api.AddressConfig, error) `perm:"read"` - - ActorSectorSize func(p0 context.Context, p1 address.Address) (abi.SectorSize, error) `perm:"read"` - - CheckProvable func(p0 context.Context, p1 abi.RegisteredPoStProof, p2 []storage.SectorRef, p3 bool) (map[abi.SectorNumber]string, error) `perm:"admin"` - - CreateBackup func(p0 context.Context, p1 string) error `perm:"admin"` - - DealsConsiderOfflineRetrievalDeals func(p0 context.Context) (bool, error) `perm:"admin"` - - DealsConsiderOfflineStorageDeals func(p0 context.Context) (bool, error) `perm:"admin"` - - DealsConsiderOnlineRetrievalDeals func(p0 context.Context) (bool, error) `perm:"admin"` - - DealsConsiderOnlineStorageDeals func(p0 context.Context) (bool, error) `perm:"admin"` - - DealsConsiderUnverifiedStorageDeals func(p0 context.Context) (bool, error) `perm:"admin"` - - DealsConsiderVerifiedStorageDeals func(p0 context.Context) (bool, error) `perm:"admin"` - - DealsImportData func(p0 context.Context, p1 cid.Cid, p2 string) error `perm:"admin"` - - DealsList func(p0 context.Context) ([]api.MarketDeal, error) `perm:"admin"` - - DealsPieceCidBlocklist func(p0 context.Context) ([]cid.Cid, error) `perm:"admin"` - - DealsSetConsiderOfflineRetrievalDeals func(p0 context.Context, p1 bool) error `perm:"admin"` - - DealsSetConsiderOfflineStorageDeals func(p0 context.Context, p1 bool) error `perm:"admin"` - - DealsSetConsiderOnlineRetrievalDeals func(p0 context.Context, p1 bool) error `perm:"admin"` - - DealsSetConsiderOnlineStorageDeals func(p0 context.Context, p1 bool) error `perm:"admin"` - - DealsSetConsiderUnverifiedStorageDeals func(p0 context.Context, p1 bool) error `perm:"admin"` - - DealsSetConsiderVerifiedStorageDeals func(p0 context.Context, p1 bool) error `perm:"admin"` - - DealsSetPieceCidBlocklist func(p0 context.Context, p1 []cid.Cid) error `perm:"admin"` - - MarketCancelDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"` - - MarketDataTransferUpdates func(p0 context.Context) (<-chan api.DataTransferChannel, error) `perm:"write"` - - MarketGetAsk func(p0 context.Context) (*storagemarket.SignedStorageAsk, error) `perm:"read"` - - MarketGetDealUpdates func(p0 context.Context) (<-chan storagemarket.MinerDeal, error) `perm:"read"` - - MarketGetRetrievalAsk func(p0 context.Context) (*retrievalmarket.Ask, error) `perm:"read"` - - MarketImportDealData func(p0 context.Context, p1 cid.Cid, p2 string) error `perm:"write"` - - MarketListDataTransfers func(p0 context.Context) ([]api.DataTransferChannel, error) `perm:"write"` - - MarketListDeals func(p0 context.Context) ([]api.MarketDeal, error) `perm:"read"` - - MarketListIncompleteDeals func(p0 context.Context) ([]storagemarket.MinerDeal, error) `perm:"read"` - - MarketListRetrievalDeals func(p0 context.Context) ([]retrievalmarket.ProviderDealState, error) `perm:"read"` - - MarketPendingDeals func(p0 context.Context) (api.PendingDealInfo, error) `perm:"write"` - - MarketPublishPendingDeals func(p0 context.Context) error `perm:"admin"` - - MarketRestartDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"` - - MarketSetAsk func(p0 context.Context, p1 types.BigInt, p2 types.BigInt, p3 abi.ChainEpoch, p4 abi.PaddedPieceSize, p5 abi.PaddedPieceSize) error `perm:"admin"` - - MarketSetRetrievalAsk func(p0 context.Context, p1 *retrievalmarket.Ask) error `perm:"admin"` - - MiningBase func(p0 context.Context) (*types.TipSet, error) `perm:"read"` - - PiecesGetCIDInfo func(p0 context.Context, p1 cid.Cid) (*piecestore.CIDInfo, error) `perm:"read"` - - PiecesGetPieceInfo func(p0 context.Context, p1 cid.Cid) (*piecestore.PieceInfo, error) `perm:"read"` - - PiecesListCidInfos func(p0 context.Context) ([]cid.Cid, error) `perm:"read"` - - PiecesListPieces func(p0 context.Context) ([]cid.Cid, error) `perm:"read"` - - PledgeSector func(p0 context.Context) (abi.SectorID, error) `perm:"write"` - - ReturnAddPiece func(p0 context.Context, p1 storiface.CallID, p2 abi.PieceInfo, p3 *storiface.CallError) error `perm:"admin"` - - ReturnFetch func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"` - - ReturnFinalizeSector func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"` - - ReturnMoveStorage func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"` - - ReturnReadPiece func(p0 context.Context, p1 storiface.CallID, p2 bool, p3 *storiface.CallError) error `perm:"admin"` - - ReturnReleaseUnsealed func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"` - - ReturnSealCommit1 func(p0 context.Context, p1 storiface.CallID, p2 storage.Commit1Out, p3 *storiface.CallError) error `perm:"admin"` - - ReturnSealCommit2 func(p0 context.Context, p1 storiface.CallID, p2 storage.Proof, p3 *storiface.CallError) error `perm:"admin"` - - ReturnSealPreCommit1 func(p0 context.Context, p1 storiface.CallID, p2 storage.PreCommit1Out, p3 *storiface.CallError) error `perm:"admin"` - - ReturnSealPreCommit2 func(p0 context.Context, p1 storiface.CallID, p2 storage.SectorCids, p3 *storiface.CallError) error `perm:"admin"` - - ReturnUnsealPiece func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"` - - SealingAbort func(p0 context.Context, p1 storiface.CallID) error `perm:"admin"` - - SealingSchedDiag func(p0 context.Context, p1 bool) (interface{}, error) `perm:"admin"` - - SectorGetExpectedSealDuration func(p0 context.Context) (time.Duration, error) `perm:"read"` +type GatewayStub struct { +} - SectorGetSealDelay func(p0 context.Context) (time.Duration, error) `perm:"read"` +func (s *FullNodeStruct) BeaconGetEntry(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) { + return s.Internal.BeaconGetEntry(p0, p1) +} - SectorMarkForUpgrade func(p0 context.Context, p1 abi.SectorNumber) error `perm:"admin"` +func (s *FullNodeStub) BeaconGetEntry(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) { + return nil, xerrors.New("method not supported") +} - SectorRemove func(p0 context.Context, p1 abi.SectorNumber) error `perm:"admin"` +func (s *FullNodeStruct) ChainDeleteObj(p0 context.Context, p1 cid.Cid) error { + return s.Internal.ChainDeleteObj(p0, p1) +} - SectorSetExpectedSealDuration func(p0 context.Context, p1 time.Duration) error `perm:"write"` +func (s *FullNodeStub) ChainDeleteObj(p0 context.Context, p1 cid.Cid) error { + return xerrors.New("method not supported") +} - SectorSetSealDelay func(p0 context.Context, p1 time.Duration) error `perm:"write"` +func (s *FullNodeStruct) ChainExport(p0 context.Context, p1 abi.ChainEpoch, p2 bool, p3 types.TipSetKey) (<-chan []byte, error) { + return s.Internal.ChainExport(p0, p1, p2, p3) +} - SectorStartSealing func(p0 context.Context, p1 abi.SectorNumber) error `perm:"write"` +func (s *FullNodeStub) ChainExport(p0 context.Context, p1 abi.ChainEpoch, p2 bool, p3 types.TipSetKey) (<-chan []byte, error) { + return nil, xerrors.New("method not supported") +} - SectorTerminate func(p0 context.Context, p1 abi.SectorNumber) error `perm:"admin"` +func (s *FullNodeStruct) ChainGetBlock(p0 context.Context, p1 cid.Cid) (*types.BlockHeader, error) { + return s.Internal.ChainGetBlock(p0, p1) +} - SectorTerminateFlush func(p0 context.Context) (*cid.Cid, error) `perm:"admin"` +func (s *FullNodeStub) ChainGetBlock(p0 context.Context, p1 cid.Cid) (*types.BlockHeader, error) { + return nil, xerrors.New("method not supported") +} - SectorTerminatePending func(p0 context.Context) ([]abi.SectorID, error) `perm:"admin"` +func (s *FullNodeStruct) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*api.BlockMessages, error) { + return s.Internal.ChainGetBlockMessages(p0, p1) +} - SectorsList func(p0 context.Context) ([]abi.SectorNumber, error) `perm:"read"` +func (s *FullNodeStub) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*api.BlockMessages, error) { + return nil, xerrors.New("method not supported") +} - SectorsListInStates func(p0 context.Context, p1 []api.SectorState) ([]abi.SectorNumber, error) `perm:"read"` +func (s *FullNodeStruct) ChainGetGenesis(p0 context.Context) (*types.TipSet, error) { + return s.Internal.ChainGetGenesis(p0) +} - SectorsRefs func(p0 context.Context) (map[string][]api.SealedRef, error) `perm:"read"` +func (s *FullNodeStub) ChainGetGenesis(p0 context.Context) (*types.TipSet, error) { + return nil, xerrors.New("method not supported") +} - SectorsStatus func(p0 context.Context, p1 abi.SectorNumber, p2 bool) (api.SectorInfo, error) `perm:"read"` +func (s *FullNodeStruct) ChainGetMessage(p0 context.Context, p1 cid.Cid) (*types.Message, error) { + return s.Internal.ChainGetMessage(p0, p1) +} - SectorsSummary func(p0 context.Context) (map[api.SectorState]int, error) `perm:"read"` +func (s *FullNodeStub) ChainGetMessage(p0 context.Context, p1 cid.Cid) (*types.Message, error) { + return nil, xerrors.New("method not supported") +} - SectorsUpdate func(p0 context.Context, p1 abi.SectorNumber, p2 api.SectorState) error `perm:"admin"` +func (s *FullNodeStruct) ChainGetNode(p0 context.Context, p1 string) (*api.IpldObject, error) { + return s.Internal.ChainGetNode(p0, p1) +} - StorageAddLocal func(p0 context.Context, p1 string) error `perm:"admin"` +func (s *FullNodeStub) ChainGetNode(p0 context.Context, p1 string) (*api.IpldObject, error) { + return nil, xerrors.New("method not supported") +} - StorageAttach func(p0 context.Context, p1 stores.StorageInfo, p2 fsutil.FsStat) error `perm:"admin"` +func (s *FullNodeStruct) ChainGetParentMessages(p0 context.Context, p1 cid.Cid) ([]api.Message, error) { + return s.Internal.ChainGetParentMessages(p0, p1) +} - StorageBestAlloc func(p0 context.Context, p1 storiface.SectorFileType, p2 abi.SectorSize, p3 storiface.PathType) ([]stores.StorageInfo, error) `perm:"admin"` +func (s *FullNodeStub) ChainGetParentMessages(p0 context.Context, p1 cid.Cid) ([]api.Message, error) { + return *new([]api.Message), xerrors.New("method not supported") +} - StorageDeclareSector func(p0 context.Context, p1 stores.ID, p2 abi.SectorID, p3 storiface.SectorFileType, p4 bool) error `perm:"admin"` +func (s *FullNodeStruct) ChainGetParentReceipts(p0 context.Context, p1 cid.Cid) ([]*types.MessageReceipt, error) { + return s.Internal.ChainGetParentReceipts(p0, p1) +} - StorageDropSector func(p0 context.Context, p1 stores.ID, p2 abi.SectorID, p3 storiface.SectorFileType) error `perm:"admin"` +func (s *FullNodeStub) ChainGetParentReceipts(p0 context.Context, p1 cid.Cid) ([]*types.MessageReceipt, error) { + return *new([]*types.MessageReceipt), xerrors.New("method not supported") +} - StorageFindSector func(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 abi.SectorSize, p4 bool) ([]stores.SectorStorageInfo, error) `perm:"admin"` +func (s *FullNodeStruct) ChainGetPath(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey) ([]*api.HeadChange, error) { + return s.Internal.ChainGetPath(p0, p1, p2) +} - StorageInfo func(p0 context.Context, p1 stores.ID) (stores.StorageInfo, error) `perm:"admin"` +func (s *FullNodeStub) ChainGetPath(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey) ([]*api.HeadChange, error) { + return *new([]*api.HeadChange), xerrors.New("method not supported") +} - StorageList func(p0 context.Context) (map[stores.ID][]stores.Decl, error) `perm:"admin"` +func (s *FullNodeStruct) ChainGetRandomnessFromBeacon(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) { + return s.Internal.ChainGetRandomnessFromBeacon(p0, p1, p2, p3, p4) +} - StorageLocal func(p0 context.Context) (map[stores.ID]string, error) `perm:"admin"` +func (s *FullNodeStub) ChainGetRandomnessFromBeacon(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) { + return *new(abi.Randomness), xerrors.New("method not supported") +} - StorageLock func(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 storiface.SectorFileType) error `perm:"admin"` +func (s *FullNodeStruct) ChainGetRandomnessFromTickets(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) { + return s.Internal.ChainGetRandomnessFromTickets(p0, p1, p2, p3, p4) +} - StorageReportHealth func(p0 context.Context, p1 stores.ID, p2 stores.HealthReport) error `perm:"admin"` +func (s *FullNodeStub) ChainGetRandomnessFromTickets(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) { + return *new(abi.Randomness), xerrors.New("method not supported") +} - StorageStat func(p0 context.Context, p1 stores.ID) (fsutil.FsStat, error) `perm:"admin"` +func (s *FullNodeStruct) ChainGetTipSet(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) { + return s.Internal.ChainGetTipSet(p0, p1) +} - StorageTryLock func(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 storiface.SectorFileType) (bool, error) `perm:"admin"` +func (s *FullNodeStub) ChainGetTipSet(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) { + return nil, xerrors.New("method not supported") +} - WorkerConnect func(p0 context.Context, p1 string) error `perm:"admin"` +func (s *FullNodeStruct) ChainGetTipSetByHeight(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) { + return s.Internal.ChainGetTipSetByHeight(p0, p1, p2) +} - WorkerJobs func(p0 context.Context) (map[uuid.UUID][]storiface.WorkerJob, error) `perm:"admin"` +func (s *FullNodeStub) ChainGetTipSetByHeight(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) { + return nil, xerrors.New("method not supported") +} - WorkerStats func(p0 context.Context) (map[uuid.UUID]storiface.WorkerStats, error) `perm:"admin"` - } +func (s *FullNodeStruct) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { + return s.Internal.ChainHasObj(p0, p1) } -type WalletStruct struct { - Internal struct { - WalletDelete func(p0 context.Context, p1 address.Address) error `` +func (s *FullNodeStub) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { + return false, xerrors.New("method not supported") +} - WalletExport func(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) `` +func (s *FullNodeStruct) ChainHead(p0 context.Context) (*types.TipSet, error) { + return s.Internal.ChainHead(p0) +} - WalletHas func(p0 context.Context, p1 address.Address) (bool, error) `` +func (s *FullNodeStub) ChainHead(p0 context.Context) (*types.TipSet, error) { + return nil, xerrors.New("method not supported") +} - WalletImport func(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) `` +func (s *FullNodeStruct) ChainNotify(p0 context.Context) (<-chan []*api.HeadChange, error) { + return s.Internal.ChainNotify(p0) +} - WalletList func(p0 context.Context) ([]address.Address, error) `` +func (s *FullNodeStub) ChainNotify(p0 context.Context) (<-chan []*api.HeadChange, error) { + return nil, xerrors.New("method not supported") +} - WalletNew func(p0 context.Context, p1 types.KeyType) (address.Address, error) `` +func (s *FullNodeStruct) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { + return s.Internal.ChainReadObj(p0, p1) +} - WalletSign func(p0 context.Context, p1 address.Address, p2 []byte, p3 api.MsgMeta) (*crypto.Signature, error) `` - } +func (s *FullNodeStub) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { + return *new([]byte), xerrors.New("method not supported") } -type WorkerStruct struct { - Internal struct { - AddPiece func(p0 context.Context, p1 storage.SectorRef, p2 []abi.UnpaddedPieceSize, p3 abi.UnpaddedPieceSize, p4 storage.Data) (storiface.CallID, error) `perm:"admin"` +func (s *FullNodeStruct) ChainSetHead(p0 context.Context, p1 types.TipSetKey) error { + return s.Internal.ChainSetHead(p0, p1) +} - Enabled func(p0 context.Context) (bool, error) `perm:"admin"` +func (s *FullNodeStub) ChainSetHead(p0 context.Context, p1 types.TipSetKey) error { + return xerrors.New("method not supported") +} - Fetch func(p0 context.Context, p1 storage.SectorRef, p2 storiface.SectorFileType, p3 storiface.PathType, p4 storiface.AcquireMode) (storiface.CallID, error) `perm:"admin"` +func (s *FullNodeStruct) ChainStatObj(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (api.ObjStat, error) { + return s.Internal.ChainStatObj(p0, p1, p2) +} - FinalizeSector func(p0 context.Context, p1 storage.SectorRef, p2 []storage.Range) (storiface.CallID, error) `perm:"admin"` +func (s *FullNodeStub) ChainStatObj(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (api.ObjStat, error) { + return *new(api.ObjStat), xerrors.New("method not supported") +} - Info func(p0 context.Context) (storiface.WorkerInfo, error) `perm:"admin"` +func (s *FullNodeStruct) ChainTipSetWeight(p0 context.Context, p1 types.TipSetKey) (types.BigInt, error) { + return s.Internal.ChainTipSetWeight(p0, p1) +} - MoveStorage func(p0 context.Context, p1 storage.SectorRef, p2 storiface.SectorFileType) (storiface.CallID, error) `perm:"admin"` +func (s *FullNodeStub) ChainTipSetWeight(p0 context.Context, p1 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} - Paths func(p0 context.Context) ([]stores.StoragePath, error) `perm:"admin"` +func (s *FullNodeStruct) ClientCalcCommP(p0 context.Context, p1 string) (*api.CommPRet, error) { + return s.Internal.ClientCalcCommP(p0, p1) +} - ProcessSession func(p0 context.Context) (uuid.UUID, error) `perm:"admin"` +func (s *FullNodeStub) ClientCalcCommP(p0 context.Context, p1 string) (*api.CommPRet, error) { + return nil, xerrors.New("method not supported") +} - ReadPiece func(p0 context.Context, p1 io.Writer, p2 storage.SectorRef, p3 storiface.UnpaddedByteIndex, p4 abi.UnpaddedPieceSize) (storiface.CallID, error) `perm:"admin"` +func (s *FullNodeStruct) ClientCancelDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { + return s.Internal.ClientCancelDataTransfer(p0, p1, p2, p3) +} - ReleaseUnsealed func(p0 context.Context, p1 storage.SectorRef, p2 []storage.Range) (storiface.CallID, error) `perm:"admin"` +func (s *FullNodeStub) ClientCancelDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { + return xerrors.New("method not supported") +} - Remove func(p0 context.Context, p1 abi.SectorID) error `perm:"admin"` +func (s *FullNodeStruct) ClientCancelRetrievalDeal(p0 context.Context, p1 retrievalmarket.DealID) error { + return s.Internal.ClientCancelRetrievalDeal(p0, p1) +} - SealCommit1 func(p0 context.Context, p1 storage.SectorRef, p2 abi.SealRandomness, p3 abi.InteractiveSealRandomness, p4 []abi.PieceInfo, p5 storage.SectorCids) (storiface.CallID, error) `perm:"admin"` +func (s *FullNodeStub) ClientCancelRetrievalDeal(p0 context.Context, p1 retrievalmarket.DealID) error { + return xerrors.New("method not supported") +} - SealCommit2 func(p0 context.Context, p1 storage.SectorRef, p2 storage.Commit1Out) (storiface.CallID, error) `perm:"admin"` +func (s *FullNodeStruct) ClientDataTransferUpdates(p0 context.Context) (<-chan api.DataTransferChannel, error) { + return s.Internal.ClientDataTransferUpdates(p0) +} - SealPreCommit1 func(p0 context.Context, p1 storage.SectorRef, p2 abi.SealRandomness, p3 []abi.PieceInfo) (storiface.CallID, error) `perm:"admin"` +func (s *FullNodeStub) ClientDataTransferUpdates(p0 context.Context) (<-chan api.DataTransferChannel, error) { + return nil, xerrors.New("method not supported") +} - SealPreCommit2 func(p0 context.Context, p1 storage.SectorRef, p2 storage.PreCommit1Out) (storiface.CallID, error) `perm:"admin"` +func (s *FullNodeStruct) ClientDealPieceCID(p0 context.Context, p1 cid.Cid) (api.DataCIDSize, error) { + return s.Internal.ClientDealPieceCID(p0, p1) +} - Session func(p0 context.Context) (uuid.UUID, error) `perm:"admin"` +func (s *FullNodeStub) ClientDealPieceCID(p0 context.Context, p1 cid.Cid) (api.DataCIDSize, error) { + return *new(api.DataCIDSize), xerrors.New("method not supported") +} - SetEnabled func(p0 context.Context, p1 bool) error `perm:"admin"` +func (s *FullNodeStruct) ClientDealSize(p0 context.Context, p1 cid.Cid) (api.DataSize, error) { + return s.Internal.ClientDealSize(p0, p1) +} - StorageAddLocal func(p0 context.Context, p1 string) error `perm:"admin"` +func (s *FullNodeStub) ClientDealSize(p0 context.Context, p1 cid.Cid) (api.DataSize, error) { + return *new(api.DataSize), xerrors.New("method not supported") +} - TaskDisable func(p0 context.Context, p1 sealtasks.TaskType) error `perm:"admin"` +func (s *FullNodeStruct) ClientFindData(p0 context.Context, p1 cid.Cid, p2 *cid.Cid) ([]api.QueryOffer, error) { + return s.Internal.ClientFindData(p0, p1, p2) +} - TaskEnable func(p0 context.Context, p1 sealtasks.TaskType) error `perm:"admin"` +func (s *FullNodeStub) ClientFindData(p0 context.Context, p1 cid.Cid, p2 *cid.Cid) ([]api.QueryOffer, error) { + return *new([]api.QueryOffer), xerrors.New("method not supported") +} - TaskTypes func(p0 context.Context) (map[sealtasks.TaskType]struct{}, error) `perm:"admin"` +func (s *FullNodeStruct) ClientGenCar(p0 context.Context, p1 api.FileRef, p2 string) error { + return s.Internal.ClientGenCar(p0, p1, p2) +} - UnsealPiece func(p0 context.Context, p1 storage.SectorRef, p2 storiface.UnpaddedByteIndex, p3 abi.UnpaddedPieceSize, p4 abi.SealRandomness, p5 cid.Cid) (storiface.CallID, error) `perm:"admin"` +func (s *FullNodeStub) ClientGenCar(p0 context.Context, p1 api.FileRef, p2 string) error { + return xerrors.New("method not supported") +} - Version func(p0 context.Context) (api.Version, error) `perm:"admin"` +func (s *FullNodeStruct) ClientGetDealInfo(p0 context.Context, p1 cid.Cid) (*api.DealInfo, error) { + return s.Internal.ClientGetDealInfo(p0, p1) +} - WaitQuiet func(p0 context.Context) error `perm:"admin"` - } +func (s *FullNodeStub) ClientGetDealInfo(p0 context.Context, p1 cid.Cid) (*api.DealInfo, error) { + return nil, xerrors.New("method not supported") } -func (s *ChainIOStruct) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { - return s.Internal.ChainHasObj(p0, p1) +func (s *FullNodeStruct) ClientGetDealStatus(p0 context.Context, p1 uint64) (string, error) { + return s.Internal.ClientGetDealStatus(p0, p1) } -func (s *ChainIOStruct) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { - return s.Internal.ChainReadObj(p0, p1) +func (s *FullNodeStub) ClientGetDealStatus(p0 context.Context, p1 uint64) (string, error) { + return "", xerrors.New("method not supported") } -func (s *CommonStruct) AuthNew(p0 context.Context, p1 []auth.Permission) ([]byte, error) { - return s.Internal.AuthNew(p0, p1) +func (s *FullNodeStruct) ClientGetDealUpdates(p0 context.Context) (<-chan api.DealInfo, error) { + return s.Internal.ClientGetDealUpdates(p0) } -func (s *CommonStruct) AuthVerify(p0 context.Context, p1 string) ([]auth.Permission, error) { - return s.Internal.AuthVerify(p0, p1) +func (s *FullNodeStub) ClientGetDealUpdates(p0 context.Context) (<-chan api.DealInfo, error) { + return nil, xerrors.New("method not supported") } -func (s *CommonStruct) Closing(p0 context.Context) (<-chan struct{}, error) { - return s.Internal.Closing(p0) +func (s *FullNodeStruct) ClientHasLocal(p0 context.Context, p1 cid.Cid) (bool, error) { + return s.Internal.ClientHasLocal(p0, p1) } -func (s *CommonStruct) Discover(p0 context.Context) (apitypes.OpenRPCDocument, error) { - return s.Internal.Discover(p0) +func (s *FullNodeStub) ClientHasLocal(p0 context.Context, p1 cid.Cid) (bool, error) { + return false, xerrors.New("method not supported") } -func (s *CommonStruct) ID(p0 context.Context) (peer.ID, error) { - return s.Internal.ID(p0) +func (s *FullNodeStruct) ClientImport(p0 context.Context, p1 api.FileRef) (*api.ImportRes, error) { + return s.Internal.ClientImport(p0, p1) } -func (s *CommonStruct) LogList(p0 context.Context) ([]string, error) { - return s.Internal.LogList(p0) +func (s *FullNodeStub) ClientImport(p0 context.Context, p1 api.FileRef) (*api.ImportRes, error) { + return nil, xerrors.New("method not supported") } -func (s *CommonStruct) LogSetLevel(p0 context.Context, p1 string, p2 string) error { - return s.Internal.LogSetLevel(p0, p1, p2) +func (s *FullNodeStruct) ClientListDataTransfers(p0 context.Context) ([]api.DataTransferChannel, error) { + return s.Internal.ClientListDataTransfers(p0) } -func (s *CommonStruct) NetAddrsListen(p0 context.Context) (peer.AddrInfo, error) { - return s.Internal.NetAddrsListen(p0) +func (s *FullNodeStub) ClientListDataTransfers(p0 context.Context) ([]api.DataTransferChannel, error) { + return *new([]api.DataTransferChannel), xerrors.New("method not supported") } -func (s *CommonStruct) NetAgentVersion(p0 context.Context, p1 peer.ID) (string, error) { - return s.Internal.NetAgentVersion(p0, p1) +func (s *FullNodeStruct) ClientListDeals(p0 context.Context) ([]api.DealInfo, error) { + return s.Internal.ClientListDeals(p0) } -func (s *CommonStruct) NetAutoNatStatus(p0 context.Context) (api.NatInfo, error) { - return s.Internal.NetAutoNatStatus(p0) +func (s *FullNodeStub) ClientListDeals(p0 context.Context) ([]api.DealInfo, error) { + return *new([]api.DealInfo), xerrors.New("method not supported") } -func (s *CommonStruct) NetBandwidthStats(p0 context.Context) (metrics.Stats, error) { - return s.Internal.NetBandwidthStats(p0) +func (s *FullNodeStruct) ClientListImports(p0 context.Context) ([]api.Import, error) { + return s.Internal.ClientListImports(p0) } -func (s *CommonStruct) NetBandwidthStatsByPeer(p0 context.Context) (map[string]metrics.Stats, error) { - return s.Internal.NetBandwidthStatsByPeer(p0) +func (s *FullNodeStub) ClientListImports(p0 context.Context) ([]api.Import, error) { + return *new([]api.Import), xerrors.New("method not supported") } -func (s *CommonStruct) NetBandwidthStatsByProtocol(p0 context.Context) (map[protocol.ID]metrics.Stats, error) { - return s.Internal.NetBandwidthStatsByProtocol(p0) +func (s *FullNodeStruct) ClientMinerQueryOffer(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (api.QueryOffer, error) { + return s.Internal.ClientMinerQueryOffer(p0, p1, p2, p3) } -func (s *CommonStruct) NetBlockAdd(p0 context.Context, p1 api.NetBlockList) error { - return s.Internal.NetBlockAdd(p0, p1) +func (s *FullNodeStub) ClientMinerQueryOffer(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (api.QueryOffer, error) { + return *new(api.QueryOffer), xerrors.New("method not supported") } -func (s *CommonStruct) NetBlockList(p0 context.Context) (api.NetBlockList, error) { - return s.Internal.NetBlockList(p0) +func (s *FullNodeStruct) ClientQueryAsk(p0 context.Context, p1 peer.ID, p2 address.Address) (*storagemarket.StorageAsk, error) { + return s.Internal.ClientQueryAsk(p0, p1, p2) } -func (s *CommonStruct) NetBlockRemove(p0 context.Context, p1 api.NetBlockList) error { - return s.Internal.NetBlockRemove(p0, p1) +func (s *FullNodeStub) ClientQueryAsk(p0 context.Context, p1 peer.ID, p2 address.Address) (*storagemarket.StorageAsk, error) { + return nil, xerrors.New("method not supported") } -func (s *CommonStruct) NetConnect(p0 context.Context, p1 peer.AddrInfo) error { - return s.Internal.NetConnect(p0, p1) +func (s *FullNodeStruct) ClientRemoveImport(p0 context.Context, p1 multistore.StoreID) error { + return s.Internal.ClientRemoveImport(p0, p1) } -func (s *CommonStruct) NetConnectedness(p0 context.Context, p1 peer.ID) (network.Connectedness, error) { - return s.Internal.NetConnectedness(p0, p1) +func (s *FullNodeStub) ClientRemoveImport(p0 context.Context, p1 multistore.StoreID) error { + return xerrors.New("method not supported") } -func (s *CommonStruct) NetDisconnect(p0 context.Context, p1 peer.ID) error { - return s.Internal.NetDisconnect(p0, p1) +func (s *FullNodeStruct) ClientRestartDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { + return s.Internal.ClientRestartDataTransfer(p0, p1, p2, p3) } -func (s *CommonStruct) NetFindPeer(p0 context.Context, p1 peer.ID) (peer.AddrInfo, error) { - return s.Internal.NetFindPeer(p0, p1) +func (s *FullNodeStub) ClientRestartDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { + return xerrors.New("method not supported") } -func (s *CommonStruct) NetPeerInfo(p0 context.Context, p1 peer.ID) (*api.ExtendedPeerInfo, error) { - return s.Internal.NetPeerInfo(p0, p1) +func (s *FullNodeStruct) ClientRetrieve(p0 context.Context, p1 api.RetrievalOrder, p2 *api.FileRef) error { + return s.Internal.ClientRetrieve(p0, p1, p2) } -func (s *CommonStruct) NetPeers(p0 context.Context) ([]peer.AddrInfo, error) { - return s.Internal.NetPeers(p0) +func (s *FullNodeStub) ClientRetrieve(p0 context.Context, p1 api.RetrievalOrder, p2 *api.FileRef) error { + return xerrors.New("method not supported") } -func (s *CommonStruct) NetPubsubScores(p0 context.Context) ([]api.PubsubScore, error) { - return s.Internal.NetPubsubScores(p0) +func (s *FullNodeStruct) ClientRetrieveTryRestartInsufficientFunds(p0 context.Context, p1 address.Address) error { + return s.Internal.ClientRetrieveTryRestartInsufficientFunds(p0, p1) } -func (s *CommonStruct) Session(p0 context.Context) (uuid.UUID, error) { - return s.Internal.Session(p0) +func (s *FullNodeStub) ClientRetrieveTryRestartInsufficientFunds(p0 context.Context, p1 address.Address) error { + return xerrors.New("method not supported") } -func (s *CommonStruct) Shutdown(p0 context.Context) error { - return s.Internal.Shutdown(p0) +func (s *FullNodeStruct) ClientRetrieveWithEvents(p0 context.Context, p1 api.RetrievalOrder, p2 *api.FileRef) (<-chan marketevents.RetrievalEvent, error) { + return s.Internal.ClientRetrieveWithEvents(p0, p1, p2) } -func (s *CommonStruct) Version(p0 context.Context) (api.APIVersion, error) { - return s.Internal.Version(p0) -} - -func (s *FullNodeStruct) BeaconGetEntry(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) { - return s.Internal.BeaconGetEntry(p0, p1) -} - -func (s *FullNodeStruct) ChainDeleteObj(p0 context.Context, p1 cid.Cid) error { - return s.Internal.ChainDeleteObj(p0, p1) -} - -func (s *FullNodeStruct) ChainExport(p0 context.Context, p1 abi.ChainEpoch, p2 bool, p3 types.TipSetKey) (<-chan []byte, error) { - return s.Internal.ChainExport(p0, p1, p2, p3) -} - -func (s *FullNodeStruct) ChainGetBlock(p0 context.Context, p1 cid.Cid) (*types.BlockHeader, error) { - return s.Internal.ChainGetBlock(p0, p1) -} - -func (s *FullNodeStruct) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*api.BlockMessages, error) { - return s.Internal.ChainGetBlockMessages(p0, p1) -} - -func (s *FullNodeStruct) ChainGetGenesis(p0 context.Context) (*types.TipSet, error) { - return s.Internal.ChainGetGenesis(p0) -} - -func (s *FullNodeStruct) ChainGetMessage(p0 context.Context, p1 cid.Cid) (*types.Message, error) { - return s.Internal.ChainGetMessage(p0, p1) -} - -func (s *FullNodeStruct) ChainGetNode(p0 context.Context, p1 string) (*api.IpldObject, error) { - return s.Internal.ChainGetNode(p0, p1) -} - -func (s *FullNodeStruct) ChainGetParentMessages(p0 context.Context, p1 cid.Cid) ([]api.Message, error) { - return s.Internal.ChainGetParentMessages(p0, p1) -} - -func (s *FullNodeStruct) ChainGetParentReceipts(p0 context.Context, p1 cid.Cid) ([]*types.MessageReceipt, error) { - return s.Internal.ChainGetParentReceipts(p0, p1) -} - -func (s *FullNodeStruct) ChainGetPath(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey) ([]*api.HeadChange, error) { - return s.Internal.ChainGetPath(p0, p1, p2) -} - -func (s *FullNodeStruct) ChainGetRandomnessFromBeacon(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) { - return s.Internal.ChainGetRandomnessFromBeacon(p0, p1, p2, p3, p4) -} - -func (s *FullNodeStruct) ChainGetRandomnessFromTickets(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) { - return s.Internal.ChainGetRandomnessFromTickets(p0, p1, p2, p3, p4) -} - -func (s *FullNodeStruct) ChainGetTipSet(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) { - return s.Internal.ChainGetTipSet(p0, p1) -} - -func (s *FullNodeStruct) ChainGetTipSetByHeight(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) { - return s.Internal.ChainGetTipSetByHeight(p0, p1, p2) -} - -func (s *FullNodeStruct) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { - return s.Internal.ChainHasObj(p0, p1) -} - -func (s *FullNodeStruct) ChainHead(p0 context.Context) (*types.TipSet, error) { - return s.Internal.ChainHead(p0) -} - -func (s *FullNodeStruct) ChainNotify(p0 context.Context) (<-chan []*api.HeadChange, error) { - return s.Internal.ChainNotify(p0) -} - -func (s *FullNodeStruct) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { - return s.Internal.ChainReadObj(p0, p1) -} - -func (s *FullNodeStruct) ChainSetHead(p0 context.Context, p1 types.TipSetKey) error { - return s.Internal.ChainSetHead(p0, p1) -} - -func (s *FullNodeStruct) ChainStatObj(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (api.ObjStat, error) { - return s.Internal.ChainStatObj(p0, p1, p2) -} - -func (s *FullNodeStruct) ChainTipSetWeight(p0 context.Context, p1 types.TipSetKey) (types.BigInt, error) { - return s.Internal.ChainTipSetWeight(p0, p1) -} - -func (s *FullNodeStruct) ClientCalcCommP(p0 context.Context, p1 string) (*api.CommPRet, error) { - return s.Internal.ClientCalcCommP(p0, p1) -} - -func (s *FullNodeStruct) ClientCancelDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { - return s.Internal.ClientCancelDataTransfer(p0, p1, p2, p3) -} - -func (s *FullNodeStruct) ClientDataTransferUpdates(p0 context.Context) (<-chan api.DataTransferChannel, error) { - return s.Internal.ClientDataTransferUpdates(p0) -} - -func (s *FullNodeStruct) ClientDealPieceCID(p0 context.Context, p1 cid.Cid) (api.DataCIDSize, error) { - return s.Internal.ClientDealPieceCID(p0, p1) -} - -func (s *FullNodeStruct) ClientDealSize(p0 context.Context, p1 cid.Cid) (api.DataSize, error) { - return s.Internal.ClientDealSize(p0, p1) -} - -func (s *FullNodeStruct) ClientFindData(p0 context.Context, p1 cid.Cid, p2 *cid.Cid) ([]api.QueryOffer, error) { - return s.Internal.ClientFindData(p0, p1, p2) -} - -func (s *FullNodeStruct) ClientGenCar(p0 context.Context, p1 api.FileRef, p2 string) error { - return s.Internal.ClientGenCar(p0, p1, p2) -} - -func (s *FullNodeStruct) ClientGetDealInfo(p0 context.Context, p1 cid.Cid) (*api.DealInfo, error) { - return s.Internal.ClientGetDealInfo(p0, p1) -} - -func (s *FullNodeStruct) ClientGetDealStatus(p0 context.Context, p1 uint64) (string, error) { - return s.Internal.ClientGetDealStatus(p0, p1) -} - -func (s *FullNodeStruct) ClientGetDealUpdates(p0 context.Context) (<-chan api.DealInfo, error) { - return s.Internal.ClientGetDealUpdates(p0) -} - -func (s *FullNodeStruct) ClientHasLocal(p0 context.Context, p1 cid.Cid) (bool, error) { - return s.Internal.ClientHasLocal(p0, p1) -} - -func (s *FullNodeStruct) ClientImport(p0 context.Context, p1 api.FileRef) (*api.ImportRes, error) { - return s.Internal.ClientImport(p0, p1) -} - -func (s *FullNodeStruct) ClientListDataTransfers(p0 context.Context) ([]api.DataTransferChannel, error) { - return s.Internal.ClientListDataTransfers(p0) -} - -func (s *FullNodeStruct) ClientListDeals(p0 context.Context) ([]api.DealInfo, error) { - return s.Internal.ClientListDeals(p0) -} - -func (s *FullNodeStruct) ClientListImports(p0 context.Context) ([]api.Import, error) { - return s.Internal.ClientListImports(p0) -} - -func (s *FullNodeStruct) ClientMinerQueryOffer(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (api.QueryOffer, error) { - return s.Internal.ClientMinerQueryOffer(p0, p1, p2, p3) -} - -func (s *FullNodeStruct) ClientQueryAsk(p0 context.Context, p1 peer.ID, p2 address.Address) (*storagemarket.StorageAsk, error) { - return s.Internal.ClientQueryAsk(p0, p1, p2) -} - -func (s *FullNodeStruct) ClientRemoveImport(p0 context.Context, p1 multistore.StoreID) error { - return s.Internal.ClientRemoveImport(p0, p1) -} - -func (s *FullNodeStruct) ClientRestartDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { - return s.Internal.ClientRestartDataTransfer(p0, p1, p2, p3) -} - -func (s *FullNodeStruct) ClientRetrieve(p0 context.Context, p1 api.RetrievalOrder, p2 *api.FileRef) error { - return s.Internal.ClientRetrieve(p0, p1, p2) -} - -func (s *FullNodeStruct) ClientRetrieveTryRestartInsufficientFunds(p0 context.Context, p1 address.Address) error { - return s.Internal.ClientRetrieveTryRestartInsufficientFunds(p0, p1) -} - -func (s *FullNodeStruct) ClientRetrieveWithEvents(p0 context.Context, p1 api.RetrievalOrder, p2 *api.FileRef) (<-chan marketevents.RetrievalEvent, error) { - return s.Internal.ClientRetrieveWithEvents(p0, p1, p2) +func (s *FullNodeStub) ClientRetrieveWithEvents(p0 context.Context, p1 api.RetrievalOrder, p2 *api.FileRef) (<-chan marketevents.RetrievalEvent, error) { + return nil, xerrors.New("method not supported") } func (s *FullNodeStruct) ClientStartDeal(p0 context.Context, p1 *api.StartDealParams) (*cid.Cid, error) { return s.Internal.ClientStartDeal(p0, p1) } +func (s *FullNodeStub) ClientStartDeal(p0 context.Context, p1 *api.StartDealParams) (*cid.Cid, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) CreateBackup(p0 context.Context, p1 string) error { return s.Internal.CreateBackup(p0, p1) } +func (s *FullNodeStub) CreateBackup(p0 context.Context, p1 string) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) GasEstimateFeeCap(p0 context.Context, p1 *types.Message, p2 int64, p3 types.TipSetKey) (types.BigInt, error) { return s.Internal.GasEstimateFeeCap(p0, p1, p2, p3) } +func (s *FullNodeStub) GasEstimateFeeCap(p0 context.Context, p1 *types.Message, p2 int64, p3 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + func (s *FullNodeStruct) GasEstimateGasLimit(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (int64, error) { return s.Internal.GasEstimateGasLimit(p0, p1, p2) } +func (s *FullNodeStub) GasEstimateGasLimit(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (int64, error) { + return 0, xerrors.New("method not supported") +} + func (s *FullNodeStruct) GasEstimateGasPremium(p0 context.Context, p1 uint64, p2 address.Address, p3 int64, p4 types.TipSetKey) (types.BigInt, error) { return s.Internal.GasEstimateGasPremium(p0, p1, p2, p3, p4) } +func (s *FullNodeStub) GasEstimateGasPremium(p0 context.Context, p1 uint64, p2 address.Address, p3 int64, p4 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + func (s *FullNodeStruct) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { return s.Internal.GasEstimateMessageGas(p0, p1, p2, p3) } +func (s *FullNodeStub) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) MarketAddBalance(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { return s.Internal.MarketAddBalance(p0, p1, p2, p3) } +func (s *FullNodeStub) MarketAddBalance(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MarketGetReserved(p0 context.Context, p1 address.Address) (types.BigInt, error) { return s.Internal.MarketGetReserved(p0, p1) } +func (s *FullNodeStub) MarketGetReserved(p0 context.Context, p1 address.Address) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MarketReleaseFunds(p0 context.Context, p1 address.Address, p2 types.BigInt) error { return s.Internal.MarketReleaseFunds(p0, p1, p2) } +func (s *FullNodeStub) MarketReleaseFunds(p0 context.Context, p1 address.Address, p2 types.BigInt) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) MarketReserveFunds(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { return s.Internal.MarketReserveFunds(p0, p1, p2, p3) } +func (s *FullNodeStub) MarketReserveFunds(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MarketWithdraw(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { return s.Internal.MarketWithdraw(p0, p1, p2, p3) } +func (s *FullNodeStub) MarketWithdraw(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MinerCreateBlock(p0 context.Context, p1 *api.BlockTemplate) (*types.BlockMsg, error) { return s.Internal.MinerCreateBlock(p0, p1) } +func (s *FullNodeStub) MinerCreateBlock(p0 context.Context, p1 *api.BlockTemplate) (*types.BlockMsg, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) MinerGetBaseInfo(p0 context.Context, p1 address.Address, p2 abi.ChainEpoch, p3 types.TipSetKey) (*api.MiningBaseInfo, error) { return s.Internal.MinerGetBaseInfo(p0, p1, p2, p3) } +func (s *FullNodeStub) MinerGetBaseInfo(p0 context.Context, p1 address.Address, p2 abi.ChainEpoch, p3 types.TipSetKey) (*api.MiningBaseInfo, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolBatchPush(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) { return s.Internal.MpoolBatchPush(p0, p1) } +func (s *FullNodeStub) MpoolBatchPush(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) { + return *new([]cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolBatchPushMessage(p0 context.Context, p1 []*types.Message, p2 *api.MessageSendSpec) ([]*types.SignedMessage, error) { return s.Internal.MpoolBatchPushMessage(p0, p1, p2) } +func (s *FullNodeStub) MpoolBatchPushMessage(p0 context.Context, p1 []*types.Message, p2 *api.MessageSendSpec) ([]*types.SignedMessage, error) { + return *new([]*types.SignedMessage), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolBatchPushUntrusted(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) { return s.Internal.MpoolBatchPushUntrusted(p0, p1) } +func (s *FullNodeStub) MpoolBatchPushUntrusted(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) { + return *new([]cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolClear(p0 context.Context, p1 bool) error { return s.Internal.MpoolClear(p0, p1) } +func (s *FullNodeStub) MpoolClear(p0 context.Context, p1 bool) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolGetConfig(p0 context.Context) (*types.MpoolConfig, error) { return s.Internal.MpoolGetConfig(p0) } +func (s *FullNodeStub) MpoolGetConfig(p0 context.Context) (*types.MpoolConfig, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolGetNonce(p0 context.Context, p1 address.Address) (uint64, error) { return s.Internal.MpoolGetNonce(p0, p1) } +func (s *FullNodeStub) MpoolGetNonce(p0 context.Context, p1 address.Address) (uint64, error) { + return 0, xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolPending(p0 context.Context, p1 types.TipSetKey) ([]*types.SignedMessage, error) { return s.Internal.MpoolPending(p0, p1) } +func (s *FullNodeStub) MpoolPending(p0 context.Context, p1 types.TipSetKey) ([]*types.SignedMessage, error) { + return *new([]*types.SignedMessage), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolPush(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { return s.Internal.MpoolPush(p0, p1) } +func (s *FullNodeStub) MpoolPush(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolPushMessage(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec) (*types.SignedMessage, error) { return s.Internal.MpoolPushMessage(p0, p1, p2) } +func (s *FullNodeStub) MpoolPushMessage(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec) (*types.SignedMessage, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolPushUntrusted(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { return s.Internal.MpoolPushUntrusted(p0, p1) } +func (s *FullNodeStub) MpoolPushUntrusted(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolSelect(p0 context.Context, p1 types.TipSetKey, p2 float64) ([]*types.SignedMessage, error) { return s.Internal.MpoolSelect(p0, p1, p2) } +func (s *FullNodeStub) MpoolSelect(p0 context.Context, p1 types.TipSetKey, p2 float64) ([]*types.SignedMessage, error) { + return *new([]*types.SignedMessage), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolSetConfig(p0 context.Context, p1 *types.MpoolConfig) error { return s.Internal.MpoolSetConfig(p0, p1) } +func (s *FullNodeStub) MpoolSetConfig(p0 context.Context, p1 *types.MpoolConfig) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) MpoolSub(p0 context.Context) (<-chan api.MpoolUpdate, error) { return s.Internal.MpoolSub(p0) } +func (s *FullNodeStub) MpoolSub(p0 context.Context) (<-chan api.MpoolUpdate, error) { + return nil, xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigAddApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (cid.Cid, error) { return s.Internal.MsigAddApprove(p0, p1, p2, p3, p4, p5, p6) } +func (s *FullNodeStub) MsigAddApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigAddCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (cid.Cid, error) { return s.Internal.MsigAddCancel(p0, p1, p2, p3, p4, p5) } +func (s *FullNodeStub) MsigAddCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigAddPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) { return s.Internal.MsigAddPropose(p0, p1, p2, p3, p4) } +func (s *FullNodeStub) MsigAddPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigApprove(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (cid.Cid, error) { return s.Internal.MsigApprove(p0, p1, p2, p3) } +func (s *FullNodeStub) MsigApprove(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigApproveTxnHash(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 address.Address, p5 types.BigInt, p6 address.Address, p7 uint64, p8 []byte) (cid.Cid, error) { return s.Internal.MsigApproveTxnHash(p0, p1, p2, p3, p4, p5, p6, p7, p8) } +func (s *FullNodeStub) MsigApproveTxnHash(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 address.Address, p5 types.BigInt, p6 address.Address, p7 uint64, p8 []byte) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigCancel(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (cid.Cid, error) { return s.Internal.MsigCancel(p0, p1, p2, p3, p4, p5, p6, p7) } +func (s *FullNodeStub) MsigCancel(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigCreate(p0 context.Context, p1 uint64, p2 []address.Address, p3 abi.ChainEpoch, p4 types.BigInt, p5 address.Address, p6 types.BigInt) (cid.Cid, error) { return s.Internal.MsigCreate(p0, p1, p2, p3, p4, p5, p6) } +func (s *FullNodeStub) MsigCreate(p0 context.Context, p1 uint64, p2 []address.Address, p3 abi.ChainEpoch, p4 types.BigInt, p5 address.Address, p6 types.BigInt) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigGetAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { return s.Internal.MsigGetAvailableBalance(p0, p1, p2) } +func (s *FullNodeStub) MsigGetAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigGetPending(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*api.MsigTransaction, error) { return s.Internal.MsigGetPending(p0, p1, p2) } +func (s *FullNodeStub) MsigGetPending(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*api.MsigTransaction, error) { + return *new([]*api.MsigTransaction), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigGetVested(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) { return s.Internal.MsigGetVested(p0, p1, p2, p3) } +func (s *FullNodeStub) MsigGetVested(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigGetVestingSchedule(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MsigVesting, error) { return s.Internal.MsigGetVestingSchedule(p0, p1, p2) } +func (s *FullNodeStub) MsigGetVestingSchedule(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MsigVesting, error) { + return *new(api.MsigVesting), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (cid.Cid, error) { return s.Internal.MsigPropose(p0, p1, p2, p3, p4, p5, p6) } +func (s *FullNodeStub) MsigPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigRemoveSigner(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) { return s.Internal.MsigRemoveSigner(p0, p1, p2, p3, p4) } +func (s *FullNodeStub) MsigRemoveSigner(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigSwapApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 address.Address) (cid.Cid, error) { return s.Internal.MsigSwapApprove(p0, p1, p2, p3, p4, p5, p6) } +func (s *FullNodeStub) MsigSwapApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 address.Address) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigSwapCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (cid.Cid, error) { return s.Internal.MsigSwapCancel(p0, p1, p2, p3, p4, p5) } +func (s *FullNodeStub) MsigSwapCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) MsigSwapPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (cid.Cid, error) { return s.Internal.MsigSwapPropose(p0, p1, p2, p3, p4) } +func (s *FullNodeStub) MsigSwapPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") +} + func (s *FullNodeStruct) PaychAllocateLane(p0 context.Context, p1 address.Address) (uint64, error) { return s.Internal.PaychAllocateLane(p0, p1) } -func (s *FullNodeStruct) PaychAvailableFunds(p0 context.Context, p1 address.Address) (*api.ChannelAvailableFunds, error) { - return s.Internal.PaychAvailableFunds(p0, p1) +func (s *FullNodeStub) PaychAllocateLane(p0 context.Context, p1 address.Address) (uint64, error) { + return 0, xerrors.New("method not supported") } -func (s *FullNodeStruct) PaychAvailableFundsByFromTo(p0 context.Context, p1 address.Address, p2 address.Address) (*api.ChannelAvailableFunds, error) { - return s.Internal.PaychAvailableFundsByFromTo(p0, p1, p2) -} - -func (s *FullNodeStruct) PaychCollect(p0 context.Context, p1 address.Address) (cid.Cid, error) { - return s.Internal.PaychCollect(p0, p1) +func (s *FullNodeStruct) PaychAvailableFunds(p0 context.Context, p1 address.Address) (*api.ChannelAvailableFunds, error) { + return s.Internal.PaychAvailableFunds(p0, p1) } -func (s *FullNodeStruct) PaychGet(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*api.ChannelInfo, error) { - return s.Internal.PaychGet(p0, p1, p2, p3) +func (s *FullNodeStub) PaychAvailableFunds(p0 context.Context, p1 address.Address) (*api.ChannelAvailableFunds, error) { + return nil, xerrors.New("method not supported") } -func (s *FullNodeStruct) PaychGetWaitReady(p0 context.Context, p1 cid.Cid) (address.Address, error) { - return s.Internal.PaychGetWaitReady(p0, p1) +func (s *FullNodeStruct) PaychAvailableFundsByFromTo(p0 context.Context, p1 address.Address, p2 address.Address) (*api.ChannelAvailableFunds, error) { + return s.Internal.PaychAvailableFundsByFromTo(p0, p1, p2) } -func (s *FullNodeStruct) PaychList(p0 context.Context) ([]address.Address, error) { - return s.Internal.PaychList(p0) +func (s *FullNodeStub) PaychAvailableFundsByFromTo(p0 context.Context, p1 address.Address, p2 address.Address) (*api.ChannelAvailableFunds, error) { + return nil, xerrors.New("method not supported") } -func (s *FullNodeStruct) PaychNewPayment(p0 context.Context, p1 address.Address, p2 address.Address, p3 []api.VoucherSpec) (*api.PaymentInfo, error) { - return s.Internal.PaychNewPayment(p0, p1, p2, p3) +func (s *FullNodeStruct) PaychCollect(p0 context.Context, p1 address.Address) (cid.Cid, error) { + return s.Internal.PaychCollect(p0, p1) } -func (s *FullNodeStruct) PaychSettle(p0 context.Context, p1 address.Address) (cid.Cid, error) { - return s.Internal.PaychSettle(p0, p1) +func (s *FullNodeStub) PaychCollect(p0 context.Context, p1 address.Address) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") } -func (s *FullNodeStruct) PaychStatus(p0 context.Context, p1 address.Address) (*api.PaychStatus, error) { - return s.Internal.PaychStatus(p0, p1) +func (s *FullNodeStruct) PaychGet(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*api.ChannelInfo, error) { + return s.Internal.PaychGet(p0, p1, p2, p3) } -func (s *FullNodeStruct) PaychVoucherAdd(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 types.BigInt) (types.BigInt, error) { - return s.Internal.PaychVoucherAdd(p0, p1, p2, p3, p4) +func (s *FullNodeStub) PaychGet(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*api.ChannelInfo, error) { + return nil, xerrors.New("method not supported") } -func (s *FullNodeStruct) PaychVoucherCheckSpendable(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (bool, error) { - return s.Internal.PaychVoucherCheckSpendable(p0, p1, p2, p3, p4) -} - -func (s *FullNodeStruct) PaychVoucherCheckValid(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher) error { - return s.Internal.PaychVoucherCheckValid(p0, p1, p2) +func (s *FullNodeStruct) PaychGetWaitReady(p0 context.Context, p1 cid.Cid) (address.Address, error) { + return s.Internal.PaychGetWaitReady(p0, p1) } -func (s *FullNodeStruct) PaychVoucherCreate(p0 context.Context, p1 address.Address, p2 types.BigInt, p3 uint64) (*api.VoucherCreateResult, error) { - return s.Internal.PaychVoucherCreate(p0, p1, p2, p3) +func (s *FullNodeStub) PaychGetWaitReady(p0 context.Context, p1 cid.Cid) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") } -func (s *FullNodeStruct) PaychVoucherList(p0 context.Context, p1 address.Address) ([]*paych.SignedVoucher, error) { - return s.Internal.PaychVoucherList(p0, p1) +func (s *FullNodeStruct) PaychList(p0 context.Context) ([]address.Address, error) { + return s.Internal.PaychList(p0) } -func (s *FullNodeStruct) PaychVoucherSubmit(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (cid.Cid, error) { - return s.Internal.PaychVoucherSubmit(p0, p1, p2, p3, p4) +func (s *FullNodeStub) PaychList(p0 context.Context) ([]address.Address, error) { + return *new([]address.Address), xerrors.New("method not supported") } -func (s *FullNodeStruct) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { - return s.Internal.StateAccountKey(p0, p1, p2) +func (s *FullNodeStruct) PaychNewPayment(p0 context.Context, p1 address.Address, p2 address.Address, p3 []api.VoucherSpec) (*api.PaymentInfo, error) { + return s.Internal.PaychNewPayment(p0, p1, p2, p3) } -func (s *FullNodeStruct) StateAllMinerFaults(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) ([]*api.Fault, error) { - return s.Internal.StateAllMinerFaults(p0, p1, p2) +func (s *FullNodeStub) PaychNewPayment(p0 context.Context, p1 address.Address, p2 address.Address, p3 []api.VoucherSpec) (*api.PaymentInfo, error) { + return nil, xerrors.New("method not supported") } -func (s *FullNodeStruct) StateCall(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*api.InvocResult, error) { - return s.Internal.StateCall(p0, p1, p2) +func (s *FullNodeStruct) PaychSettle(p0 context.Context, p1 address.Address) (cid.Cid, error) { + return s.Internal.PaychSettle(p0, p1) } -func (s *FullNodeStruct) StateChangedActors(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (map[string]types.Actor, error) { - return s.Internal.StateChangedActors(p0, p1, p2) +func (s *FullNodeStub) PaychSettle(p0 context.Context, p1 address.Address) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") } -func (s *FullNodeStruct) StateCirculatingSupply(p0 context.Context, p1 types.TipSetKey) (abi.TokenAmount, error) { - return s.Internal.StateCirculatingSupply(p0, p1) +func (s *FullNodeStruct) PaychStatus(p0 context.Context, p1 address.Address) (*api.PaychStatus, error) { + return s.Internal.PaychStatus(p0, p1) } -func (s *FullNodeStruct) StateCompute(p0 context.Context, p1 abi.ChainEpoch, p2 []*types.Message, p3 types.TipSetKey) (*api.ComputeStateOutput, error) { - return s.Internal.StateCompute(p0, p1, p2, p3) +func (s *FullNodeStub) PaychStatus(p0 context.Context, p1 address.Address) (*api.PaychStatus, error) { + return nil, xerrors.New("method not supported") } -func (s *FullNodeStruct) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) { - return s.Internal.StateDealProviderCollateralBounds(p0, p1, p2, p3) +func (s *FullNodeStruct) PaychVoucherAdd(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 types.BigInt) (types.BigInt, error) { + return s.Internal.PaychVoucherAdd(p0, p1, p2, p3, p4) } -func (s *FullNodeStruct) StateDecodeParams(p0 context.Context, p1 address.Address, p2 abi.MethodNum, p3 []byte, p4 types.TipSetKey) (interface{}, error) { - return s.Internal.StateDecodeParams(p0, p1, p2, p3, p4) +func (s *FullNodeStub) PaychVoucherAdd(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 types.BigInt) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") } -func (s *FullNodeStruct) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) { - return s.Internal.StateGetActor(p0, p1, p2) +func (s *FullNodeStruct) PaychVoucherCheckSpendable(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (bool, error) { + return s.Internal.PaychVoucherCheckSpendable(p0, p1, p2, p3, p4) } -func (s *FullNodeStruct) StateGetReceipt(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) { - return s.Internal.StateGetReceipt(p0, p1, p2) +func (s *FullNodeStub) PaychVoucherCheckSpendable(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (bool, error) { + return false, xerrors.New("method not supported") } -func (s *FullNodeStruct) StateListActors(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { - return s.Internal.StateListActors(p0, p1) +func (s *FullNodeStruct) PaychVoucherCheckValid(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher) error { + return s.Internal.PaychVoucherCheckValid(p0, p1, p2) } -func (s *FullNodeStruct) StateListMessages(p0 context.Context, p1 *api.MessageMatch, p2 types.TipSetKey, p3 abi.ChainEpoch) ([]cid.Cid, error) { - return s.Internal.StateListMessages(p0, p1, p2, p3) +func (s *FullNodeStub) PaychVoucherCheckValid(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher) error { + return xerrors.New("method not supported") } -func (s *FullNodeStruct) StateListMiners(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { - return s.Internal.StateListMiners(p0, p1) +func (s *FullNodeStruct) PaychVoucherCreate(p0 context.Context, p1 address.Address, p2 types.BigInt, p3 uint64) (*api.VoucherCreateResult, error) { + return s.Internal.PaychVoucherCreate(p0, p1, p2, p3) } -func (s *FullNodeStruct) StateLookupID(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { - return s.Internal.StateLookupID(p0, p1, p2) +func (s *FullNodeStub) PaychVoucherCreate(p0 context.Context, p1 address.Address, p2 types.BigInt, p3 uint64) (*api.VoucherCreateResult, error) { + return nil, xerrors.New("method not supported") } -func (s *FullNodeStruct) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MarketBalance, error) { - return s.Internal.StateMarketBalance(p0, p1, p2) +func (s *FullNodeStruct) PaychVoucherList(p0 context.Context, p1 address.Address) ([]*paych.SignedVoucher, error) { + return s.Internal.PaychVoucherList(p0, p1) } -func (s *FullNodeStruct) StateMarketDeals(p0 context.Context, p1 types.TipSetKey) (map[string]api.MarketDeal, error) { - return s.Internal.StateMarketDeals(p0, p1) +func (s *FullNodeStub) PaychVoucherList(p0 context.Context, p1 address.Address) ([]*paych.SignedVoucher, error) { + return *new([]*paych.SignedVoucher), xerrors.New("method not supported") } -func (s *FullNodeStruct) StateMarketParticipants(p0 context.Context, p1 types.TipSetKey) (map[string]api.MarketBalance, error) { - return s.Internal.StateMarketParticipants(p0, p1) +func (s *FullNodeStruct) PaychVoucherSubmit(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (cid.Cid, error) { + return s.Internal.PaychVoucherSubmit(p0, p1, p2, p3, p4) } -func (s *FullNodeStruct) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*api.MarketDeal, error) { - return s.Internal.StateMarketStorageDeal(p0, p1, p2) +func (s *FullNodeStub) PaychVoucherSubmit(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") } -func (s *FullNodeStruct) StateMinerActiveSectors(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { - return s.Internal.StateMinerActiveSectors(p0, p1, p2) +func (s *FullNodeStruct) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + return s.Internal.StateAccountKey(p0, p1, p2) } -func (s *FullNodeStruct) StateMinerAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { - return s.Internal.StateMinerAvailableBalance(p0, p1, p2) +func (s *FullNodeStub) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") } -func (s *FullNodeStruct) StateMinerDeadlines(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]api.Deadline, error) { - return s.Internal.StateMinerDeadlines(p0, p1, p2) +func (s *FullNodeStruct) StateAllMinerFaults(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) ([]*api.Fault, error) { + return s.Internal.StateAllMinerFaults(p0, p1, p2) } -func (s *FullNodeStruct) StateMinerFaults(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) { - return s.Internal.StateMinerFaults(p0, p1, p2) +func (s *FullNodeStub) StateAllMinerFaults(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) ([]*api.Fault, error) { + return *new([]*api.Fault), xerrors.New("method not supported") } -func (s *FullNodeStruct) StateMinerInfo(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) { - return s.Internal.StateMinerInfo(p0, p1, p2) +func (s *FullNodeStruct) StateCall(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*api.InvocResult, error) { + return s.Internal.StateCall(p0, p1, p2) } -func (s *FullNodeStruct) StateMinerInitialPledgeCollateral(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) { - return s.Internal.StateMinerInitialPledgeCollateral(p0, p1, p2, p3) +func (s *FullNodeStub) StateCall(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*api.InvocResult, error) { + return nil, xerrors.New("method not supported") } -func (s *FullNodeStruct) StateMinerPartitions(p0 context.Context, p1 address.Address, p2 uint64, p3 types.TipSetKey) ([]api.Partition, error) { - return s.Internal.StateMinerPartitions(p0, p1, p2, p3) +func (s *FullNodeStruct) StateChangedActors(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (map[string]types.Actor, error) { + return s.Internal.StateChangedActors(p0, p1, p2) } -func (s *FullNodeStruct) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.MinerPower, error) { - return s.Internal.StateMinerPower(p0, p1, p2) +func (s *FullNodeStub) StateChangedActors(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (map[string]types.Actor, error) { + return *new(map[string]types.Actor), xerrors.New("method not supported") } -func (s *FullNodeStruct) StateMinerPreCommitDepositForPower(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) { - return s.Internal.StateMinerPreCommitDepositForPower(p0, p1, p2, p3) +func (s *FullNodeStruct) StateCirculatingSupply(p0 context.Context, p1 types.TipSetKey) (abi.TokenAmount, error) { + return s.Internal.StateCirculatingSupply(p0, p1) } -func (s *FullNodeStruct) StateMinerProvingDeadline(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) { - return s.Internal.StateMinerProvingDeadline(p0, p1, p2) +func (s *FullNodeStub) StateCirculatingSupply(p0 context.Context, p1 types.TipSetKey) (abi.TokenAmount, error) { + return *new(abi.TokenAmount), xerrors.New("method not supported") } -func (s *FullNodeStruct) StateMinerRecoveries(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) { - return s.Internal.StateMinerRecoveries(p0, p1, p2) +func (s *FullNodeStruct) StateCompute(p0 context.Context, p1 abi.ChainEpoch, p2 []*types.Message, p3 types.TipSetKey) (*api.ComputeStateOutput, error) { + return s.Internal.StateCompute(p0, p1, p2, p3) } -func (s *FullNodeStruct) StateMinerSectorAllocated(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (bool, error) { - return s.Internal.StateMinerSectorAllocated(p0, p1, p2, p3) +func (s *FullNodeStub) StateCompute(p0 context.Context, p1 abi.ChainEpoch, p2 []*types.Message, p3 types.TipSetKey) (*api.ComputeStateOutput, error) { + return nil, xerrors.New("method not supported") } -func (s *FullNodeStruct) StateMinerSectorCount(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MinerSectors, error) { - return s.Internal.StateMinerSectorCount(p0, p1, p2) +func (s *FullNodeStruct) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) { + return s.Internal.StateDealProviderCollateralBounds(p0, p1, p2, p3) } -func (s *FullNodeStruct) StateMinerSectors(p0 context.Context, p1 address.Address, p2 *bitfield.BitField, p3 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { - return s.Internal.StateMinerSectors(p0, p1, p2, p3) +func (s *FullNodeStub) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) { + return *new(api.DealCollateralBounds), xerrors.New("method not supported") } -func (s *FullNodeStruct) StateNetworkName(p0 context.Context) (dtypes.NetworkName, error) { - return s.Internal.StateNetworkName(p0) +func (s *FullNodeStruct) StateDecodeParams(p0 context.Context, p1 address.Address, p2 abi.MethodNum, p3 []byte, p4 types.TipSetKey) (interface{}, error) { + return s.Internal.StateDecodeParams(p0, p1, p2, p3, p4) } -func (s *FullNodeStruct) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) { - return s.Internal.StateNetworkVersion(p0, p1) +func (s *FullNodeStub) StateDecodeParams(p0 context.Context, p1 address.Address, p2 abi.MethodNum, p3 []byte, p4 types.TipSetKey) (interface{}, error) { + return nil, xerrors.New("method not supported") } -func (s *FullNodeStruct) StateReadState(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.ActorState, error) { - return s.Internal.StateReadState(p0, p1, p2) +func (s *FullNodeStruct) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) { + return s.Internal.StateGetActor(p0, p1, p2) } -func (s *FullNodeStruct) StateReplay(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*api.InvocResult, error) { - return s.Internal.StateReplay(p0, p1, p2) +func (s *FullNodeStub) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) { + return nil, xerrors.New("method not supported") } -func (s *FullNodeStruct) StateSearchMsg(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) { - return s.Internal.StateSearchMsg(p0, p1) +func (s *FullNodeStruct) StateGetReceipt(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) { + return s.Internal.StateGetReceipt(p0, p1, p2) } -func (s *FullNodeStruct) StateSearchMsgLimited(p0 context.Context, p1 cid.Cid, p2 abi.ChainEpoch) (*api.MsgLookup, error) { - return s.Internal.StateSearchMsgLimited(p0, p1, p2) +func (s *FullNodeStub) StateGetReceipt(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) { + return nil, xerrors.New("method not supported") } -func (s *FullNodeStruct) StateSectorExpiration(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorExpiration, error) { - return s.Internal.StateSectorExpiration(p0, p1, p2, p3) +func (s *FullNodeStruct) StateListActors(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { + return s.Internal.StateListActors(p0, p1) } -func (s *FullNodeStruct) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { - return s.Internal.StateSectorGetInfo(p0, p1, p2, p3) +func (s *FullNodeStub) StateListActors(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { + return *new([]address.Address), xerrors.New("method not supported") } -func (s *FullNodeStruct) StateSectorPartition(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorLocation, error) { - return s.Internal.StateSectorPartition(p0, p1, p2, p3) +func (s *FullNodeStruct) StateListMessages(p0 context.Context, p1 *api.MessageMatch, p2 types.TipSetKey, p3 abi.ChainEpoch) ([]cid.Cid, error) { + return s.Internal.StateListMessages(p0, p1, p2, p3) } -func (s *FullNodeStruct) StateSectorPreCommitInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) { - return s.Internal.StateSectorPreCommitInfo(p0, p1, p2, p3) +func (s *FullNodeStub) StateListMessages(p0 context.Context, p1 *api.MessageMatch, p2 types.TipSetKey, p3 abi.ChainEpoch) ([]cid.Cid, error) { + return *new([]cid.Cid), xerrors.New("method not supported") } -func (s *FullNodeStruct) StateVMCirculatingSupplyInternal(p0 context.Context, p1 types.TipSetKey) (api.CirculatingSupply, error) { - return s.Internal.StateVMCirculatingSupplyInternal(p0, p1) +func (s *FullNodeStruct) StateListMiners(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { + return s.Internal.StateListMiners(p0, p1) } -func (s *FullNodeStruct) StateVerifiedClientStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { - return s.Internal.StateVerifiedClientStatus(p0, p1, p2) +func (s *FullNodeStub) StateListMiners(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { + return *new([]address.Address), xerrors.New("method not supported") } -func (s *FullNodeStruct) StateVerifiedRegistryRootKey(p0 context.Context, p1 types.TipSetKey) (address.Address, error) { - return s.Internal.StateVerifiedRegistryRootKey(p0, p1) +func (s *FullNodeStruct) StateLookupID(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + return s.Internal.StateLookupID(p0, p1, p2) } -func (s *FullNodeStruct) StateVerifierStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { - return s.Internal.StateVerifierStatus(p0, p1, p2) +func (s *FullNodeStub) StateLookupID(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") } -func (s *FullNodeStruct) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) { - return s.Internal.StateWaitMsg(p0, p1, p2) +func (s *FullNodeStruct) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MarketBalance, error) { + return s.Internal.StateMarketBalance(p0, p1, p2) } -func (s *FullNodeStruct) StateWaitMsgLimited(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch) (*api.MsgLookup, error) { - return s.Internal.StateWaitMsgLimited(p0, p1, p2, p3) +func (s *FullNodeStub) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MarketBalance, error) { + return *new(api.MarketBalance), xerrors.New("method not supported") } -func (s *FullNodeStruct) SyncCheckBad(p0 context.Context, p1 cid.Cid) (string, error) { - return s.Internal.SyncCheckBad(p0, p1) +func (s *FullNodeStruct) StateMarketDeals(p0 context.Context, p1 types.TipSetKey) (map[string]api.MarketDeal, error) { + return s.Internal.StateMarketDeals(p0, p1) } -func (s *FullNodeStruct) SyncCheckpoint(p0 context.Context, p1 types.TipSetKey) error { - return s.Internal.SyncCheckpoint(p0, p1) +func (s *FullNodeStub) StateMarketDeals(p0 context.Context, p1 types.TipSetKey) (map[string]api.MarketDeal, error) { + return *new(map[string]api.MarketDeal), xerrors.New("method not supported") } -func (s *FullNodeStruct) SyncIncomingBlocks(p0 context.Context) (<-chan *types.BlockHeader, error) { - return s.Internal.SyncIncomingBlocks(p0) +func (s *FullNodeStruct) StateMarketParticipants(p0 context.Context, p1 types.TipSetKey) (map[string]api.MarketBalance, error) { + return s.Internal.StateMarketParticipants(p0, p1) } -func (s *FullNodeStruct) SyncMarkBad(p0 context.Context, p1 cid.Cid) error { - return s.Internal.SyncMarkBad(p0, p1) +func (s *FullNodeStub) StateMarketParticipants(p0 context.Context, p1 types.TipSetKey) (map[string]api.MarketBalance, error) { + return *new(map[string]api.MarketBalance), xerrors.New("method not supported") } -func (s *FullNodeStruct) SyncState(p0 context.Context) (*api.SyncState, error) { - return s.Internal.SyncState(p0) +func (s *FullNodeStruct) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*api.MarketDeal, error) { + return s.Internal.StateMarketStorageDeal(p0, p1, p2) } -func (s *FullNodeStruct) SyncSubmitBlock(p0 context.Context, p1 *types.BlockMsg) error { - return s.Internal.SyncSubmitBlock(p0, p1) +func (s *FullNodeStub) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*api.MarketDeal, error) { + return nil, xerrors.New("method not supported") } -func (s *FullNodeStruct) SyncUnmarkAllBad(p0 context.Context) error { - return s.Internal.SyncUnmarkAllBad(p0) +func (s *FullNodeStruct) StateMinerActiveSectors(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { + return s.Internal.StateMinerActiveSectors(p0, p1, p2) } -func (s *FullNodeStruct) SyncUnmarkBad(p0 context.Context, p1 cid.Cid) error { - return s.Internal.SyncUnmarkBad(p0, p1) +func (s *FullNodeStub) StateMinerActiveSectors(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { + return *new([]*miner.SectorOnChainInfo), xerrors.New("method not supported") } -func (s *FullNodeStruct) SyncValidateTipset(p0 context.Context, p1 types.TipSetKey) (bool, error) { - return s.Internal.SyncValidateTipset(p0, p1) +func (s *FullNodeStruct) StateMinerAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { + return s.Internal.StateMinerAvailableBalance(p0, p1, p2) } -func (s *FullNodeStruct) WalletBalance(p0 context.Context, p1 address.Address) (types.BigInt, error) { - return s.Internal.WalletBalance(p0, p1) +func (s *FullNodeStub) StateMinerAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") } -func (s *FullNodeStruct) WalletDefaultAddress(p0 context.Context) (address.Address, error) { - return s.Internal.WalletDefaultAddress(p0) +func (s *FullNodeStruct) StateMinerDeadlines(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]api.Deadline, error) { + return s.Internal.StateMinerDeadlines(p0, p1, p2) } -func (s *FullNodeStruct) WalletDelete(p0 context.Context, p1 address.Address) error { - return s.Internal.WalletDelete(p0, p1) +func (s *FullNodeStub) StateMinerDeadlines(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]api.Deadline, error) { + return *new([]api.Deadline), xerrors.New("method not supported") } -func (s *FullNodeStruct) WalletExport(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) { - return s.Internal.WalletExport(p0, p1) +func (s *FullNodeStruct) StateMinerFaults(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) { + return s.Internal.StateMinerFaults(p0, p1, p2) } -func (s *FullNodeStruct) WalletHas(p0 context.Context, p1 address.Address) (bool, error) { - return s.Internal.WalletHas(p0, p1) +func (s *FullNodeStub) StateMinerFaults(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) { + return *new(bitfield.BitField), xerrors.New("method not supported") } -func (s *FullNodeStruct) WalletImport(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) { - return s.Internal.WalletImport(p0, p1) +func (s *FullNodeStruct) StateMinerInfo(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) { + return s.Internal.StateMinerInfo(p0, p1, p2) } -func (s *FullNodeStruct) WalletList(p0 context.Context) ([]address.Address, error) { - return s.Internal.WalletList(p0) +func (s *FullNodeStub) StateMinerInfo(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) { + return *new(miner.MinerInfo), xerrors.New("method not supported") } -func (s *FullNodeStruct) WalletNew(p0 context.Context, p1 types.KeyType) (address.Address, error) { - return s.Internal.WalletNew(p0, p1) +func (s *FullNodeStruct) StateMinerInitialPledgeCollateral(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) { + return s.Internal.StateMinerInitialPledgeCollateral(p0, p1, p2, p3) } -func (s *FullNodeStruct) WalletSetDefault(p0 context.Context, p1 address.Address) error { - return s.Internal.WalletSetDefault(p0, p1) +func (s *FullNodeStub) StateMinerInitialPledgeCollateral(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") } -func (s *FullNodeStruct) WalletSign(p0 context.Context, p1 address.Address, p2 []byte) (*crypto.Signature, error) { - return s.Internal.WalletSign(p0, p1, p2) +func (s *FullNodeStruct) StateMinerPartitions(p0 context.Context, p1 address.Address, p2 uint64, p3 types.TipSetKey) ([]api.Partition, error) { + return s.Internal.StateMinerPartitions(p0, p1, p2, p3) } -func (s *FullNodeStruct) WalletSignMessage(p0 context.Context, p1 address.Address, p2 *types.Message) (*types.SignedMessage, error) { - return s.Internal.WalletSignMessage(p0, p1, p2) +func (s *FullNodeStub) StateMinerPartitions(p0 context.Context, p1 address.Address, p2 uint64, p3 types.TipSetKey) ([]api.Partition, error) { + return *new([]api.Partition), xerrors.New("method not supported") } -func (s *FullNodeStruct) WalletValidateAddress(p0 context.Context, p1 string) (address.Address, error) { - return s.Internal.WalletValidateAddress(p0, p1) +func (s *FullNodeStruct) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.MinerPower, error) { + return s.Internal.StateMinerPower(p0, p1, p2) } -func (s *FullNodeStruct) WalletVerify(p0 context.Context, p1 address.Address, p2 []byte, p3 *crypto.Signature) (bool, error) { - return s.Internal.WalletVerify(p0, p1, p2, p3) +func (s *FullNodeStub) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.MinerPower, error) { + return nil, xerrors.New("method not supported") } -func (s *GatewayStruct) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*api.BlockMessages, error) { - return s.Internal.ChainGetBlockMessages(p0, p1) +func (s *FullNodeStruct) StateMinerPreCommitDepositForPower(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) { + return s.Internal.StateMinerPreCommitDepositForPower(p0, p1, p2, p3) } -func (s *GatewayStruct) ChainGetMessage(p0 context.Context, p1 cid.Cid) (*types.Message, error) { - return s.Internal.ChainGetMessage(p0, p1) +func (s *FullNodeStub) StateMinerPreCommitDepositForPower(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") } -func (s *GatewayStruct) ChainGetTipSet(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) { - return s.Internal.ChainGetTipSet(p0, p1) +func (s *FullNodeStruct) StateMinerProvingDeadline(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) { + return s.Internal.StateMinerProvingDeadline(p0, p1, p2) } -func (s *GatewayStruct) ChainGetTipSetByHeight(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) { - return s.Internal.ChainGetTipSetByHeight(p0, p1, p2) +func (s *FullNodeStub) StateMinerProvingDeadline(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) { + return nil, xerrors.New("method not supported") } -func (s *GatewayStruct) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { - return s.Internal.ChainHasObj(p0, p1) +func (s *FullNodeStruct) StateMinerRecoveries(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) { + return s.Internal.StateMinerRecoveries(p0, p1, p2) } -func (s *GatewayStruct) ChainHead(p0 context.Context) (*types.TipSet, error) { - return s.Internal.ChainHead(p0) +func (s *FullNodeStub) StateMinerRecoveries(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) { + return *new(bitfield.BitField), xerrors.New("method not supported") } -func (s *GatewayStruct) ChainNotify(p0 context.Context) (<-chan []*api.HeadChange, error) { - return s.Internal.ChainNotify(p0) +func (s *FullNodeStruct) StateMinerSectorAllocated(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (bool, error) { + return s.Internal.StateMinerSectorAllocated(p0, p1, p2, p3) } -func (s *GatewayStruct) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { - return s.Internal.ChainReadObj(p0, p1) +func (s *FullNodeStub) StateMinerSectorAllocated(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (bool, error) { + return false, xerrors.New("method not supported") } -func (s *GatewayStruct) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { - return s.Internal.GasEstimateMessageGas(p0, p1, p2, p3) +func (s *FullNodeStruct) StateMinerSectorCount(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MinerSectors, error) { + return s.Internal.StateMinerSectorCount(p0, p1, p2) } -func (s *GatewayStruct) MpoolPush(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { - return s.Internal.MpoolPush(p0, p1) +func (s *FullNodeStub) StateMinerSectorCount(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MinerSectors, error) { + return *new(api.MinerSectors), xerrors.New("method not supported") } -func (s *GatewayStruct) MsigGetAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { - return s.Internal.MsigGetAvailableBalance(p0, p1, p2) +func (s *FullNodeStruct) StateMinerSectors(p0 context.Context, p1 address.Address, p2 *bitfield.BitField, p3 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { + return s.Internal.StateMinerSectors(p0, p1, p2, p3) } -func (s *GatewayStruct) MsigGetPending(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*api.MsigTransaction, error) { - return s.Internal.MsigGetPending(p0, p1, p2) +func (s *FullNodeStub) StateMinerSectors(p0 context.Context, p1 address.Address, p2 *bitfield.BitField, p3 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { + return *new([]*miner.SectorOnChainInfo), xerrors.New("method not supported") } -func (s *GatewayStruct) MsigGetVested(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) { - return s.Internal.MsigGetVested(p0, p1, p2, p3) +func (s *FullNodeStruct) StateNetworkName(p0 context.Context) (dtypes.NetworkName, error) { + return s.Internal.StateNetworkName(p0) } -func (s *GatewayStruct) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { - return s.Internal.StateAccountKey(p0, p1, p2) +func (s *FullNodeStub) StateNetworkName(p0 context.Context) (dtypes.NetworkName, error) { + return *new(dtypes.NetworkName), xerrors.New("method not supported") } -func (s *GatewayStruct) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) { - return s.Internal.StateDealProviderCollateralBounds(p0, p1, p2, p3) +func (s *FullNodeStruct) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) { + return s.Internal.StateNetworkVersion(p0, p1) } -func (s *GatewayStruct) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) { - return s.Internal.StateGetActor(p0, p1, p2) +func (s *FullNodeStub) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) { + return *new(apitypes.NetworkVersion), xerrors.New("method not supported") } -func (s *GatewayStruct) StateGetReceipt(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) { - return s.Internal.StateGetReceipt(p0, p1, p2) +func (s *FullNodeStruct) StateReadState(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.ActorState, error) { + return s.Internal.StateReadState(p0, p1, p2) } -func (s *GatewayStruct) StateListMiners(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { - return s.Internal.StateListMiners(p0, p1) +func (s *FullNodeStub) StateReadState(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.ActorState, error) { + return nil, xerrors.New("method not supported") } -func (s *GatewayStruct) StateLookupID(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { - return s.Internal.StateLookupID(p0, p1, p2) +func (s *FullNodeStruct) StateReplay(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*api.InvocResult, error) { + return s.Internal.StateReplay(p0, p1, p2) } -func (s *GatewayStruct) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MarketBalance, error) { - return s.Internal.StateMarketBalance(p0, p1, p2) +func (s *FullNodeStub) StateReplay(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*api.InvocResult, error) { + return nil, xerrors.New("method not supported") } -func (s *GatewayStruct) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*api.MarketDeal, error) { - return s.Internal.StateMarketStorageDeal(p0, p1, p2) +func (s *FullNodeStruct) StateSearchMsg(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) { + return s.Internal.StateSearchMsg(p0, p1) } -func (s *GatewayStruct) StateMinerInfo(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) { - return s.Internal.StateMinerInfo(p0, p1, p2) +func (s *FullNodeStub) StateSearchMsg(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) { + return nil, xerrors.New("method not supported") } -func (s *GatewayStruct) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.MinerPower, error) { - return s.Internal.StateMinerPower(p0, p1, p2) +func (s *FullNodeStruct) StateSearchMsgLimited(p0 context.Context, p1 cid.Cid, p2 abi.ChainEpoch) (*api.MsgLookup, error) { + return s.Internal.StateSearchMsgLimited(p0, p1, p2) } -func (s *GatewayStruct) StateMinerProvingDeadline(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) { - return s.Internal.StateMinerProvingDeadline(p0, p1, p2) +func (s *FullNodeStub) StateSearchMsgLimited(p0 context.Context, p1 cid.Cid, p2 abi.ChainEpoch) (*api.MsgLookup, error) { + return nil, xerrors.New("method not supported") } -func (s *GatewayStruct) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) { - return s.Internal.StateNetworkVersion(p0, p1) +func (s *FullNodeStruct) StateSectorExpiration(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorExpiration, error) { + return s.Internal.StateSectorExpiration(p0, p1, p2, p3) } -func (s *GatewayStruct) StateSearchMsg(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) { - return s.Internal.StateSearchMsg(p0, p1) +func (s *FullNodeStub) StateSectorExpiration(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorExpiration, error) { + return nil, xerrors.New("method not supported") } -func (s *GatewayStruct) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { +func (s *FullNodeStruct) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { return s.Internal.StateSectorGetInfo(p0, p1, p2, p3) } -func (s *GatewayStruct) StateVerifiedClientStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { - return s.Internal.StateVerifiedClientStatus(p0, p1, p2) +func (s *FullNodeStub) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { + return nil, xerrors.New("method not supported") } -func (s *GatewayStruct) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) { - return s.Internal.StateWaitMsg(p0, p1, p2) +func (s *FullNodeStruct) StateSectorPartition(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorLocation, error) { + return s.Internal.StateSectorPartition(p0, p1, p2, p3) } -func (s *SignableStruct) Sign(p0 context.Context, p1 api.SignFunc) error { - return s.Internal.Sign(p0, p1) +func (s *FullNodeStub) StateSectorPartition(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorLocation, error) { + return nil, xerrors.New("method not supported") } -func (s *StorageMinerStruct) ActorAddress(p0 context.Context) (address.Address, error) { - return s.Internal.ActorAddress(p0) +func (s *FullNodeStruct) StateSectorPreCommitInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) { + return s.Internal.StateSectorPreCommitInfo(p0, p1, p2, p3) } -func (s *StorageMinerStruct) ActorAddressConfig(p0 context.Context) (api.AddressConfig, error) { - return s.Internal.ActorAddressConfig(p0) +func (s *FullNodeStub) StateSectorPreCommitInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) { + return *new(miner.SectorPreCommitOnChainInfo), xerrors.New("method not supported") } -func (s *StorageMinerStruct) ActorSectorSize(p0 context.Context, p1 address.Address) (abi.SectorSize, error) { - return s.Internal.ActorSectorSize(p0, p1) +func (s *FullNodeStruct) StateVMCirculatingSupplyInternal(p0 context.Context, p1 types.TipSetKey) (api.CirculatingSupply, error) { + return s.Internal.StateVMCirculatingSupplyInternal(p0, p1) } -func (s *StorageMinerStruct) CheckProvable(p0 context.Context, p1 abi.RegisteredPoStProof, p2 []storage.SectorRef, p3 bool) (map[abi.SectorNumber]string, error) { - return s.Internal.CheckProvable(p0, p1, p2, p3) +func (s *FullNodeStub) StateVMCirculatingSupplyInternal(p0 context.Context, p1 types.TipSetKey) (api.CirculatingSupply, error) { + return *new(api.CirculatingSupply), xerrors.New("method not supported") } -func (s *StorageMinerStruct) CreateBackup(p0 context.Context, p1 string) error { - return s.Internal.CreateBackup(p0, p1) +func (s *FullNodeStruct) StateVerifiedClientStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { + return s.Internal.StateVerifiedClientStatus(p0, p1, p2) } -func (s *StorageMinerStruct) DealsConsiderOfflineRetrievalDeals(p0 context.Context) (bool, error) { - return s.Internal.DealsConsiderOfflineRetrievalDeals(p0) +func (s *FullNodeStub) StateVerifiedClientStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { + return nil, xerrors.New("method not supported") } -func (s *StorageMinerStruct) DealsConsiderOfflineStorageDeals(p0 context.Context) (bool, error) { - return s.Internal.DealsConsiderOfflineStorageDeals(p0) +func (s *FullNodeStruct) StateVerifiedRegistryRootKey(p0 context.Context, p1 types.TipSetKey) (address.Address, error) { + return s.Internal.StateVerifiedRegistryRootKey(p0, p1) } -func (s *StorageMinerStruct) DealsConsiderOnlineRetrievalDeals(p0 context.Context) (bool, error) { - return s.Internal.DealsConsiderOnlineRetrievalDeals(p0) +func (s *FullNodeStub) StateVerifiedRegistryRootKey(p0 context.Context, p1 types.TipSetKey) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") } -func (s *StorageMinerStruct) DealsConsiderOnlineStorageDeals(p0 context.Context) (bool, error) { - return s.Internal.DealsConsiderOnlineStorageDeals(p0) +func (s *FullNodeStruct) StateVerifierStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { + return s.Internal.StateVerifierStatus(p0, p1, p2) } -func (s *StorageMinerStruct) DealsConsiderUnverifiedStorageDeals(p0 context.Context) (bool, error) { - return s.Internal.DealsConsiderUnverifiedStorageDeals(p0) +func (s *FullNodeStub) StateVerifierStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { + return nil, xerrors.New("method not supported") } -func (s *StorageMinerStruct) DealsConsiderVerifiedStorageDeals(p0 context.Context) (bool, error) { - return s.Internal.DealsConsiderVerifiedStorageDeals(p0) +func (s *FullNodeStruct) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) { + return s.Internal.StateWaitMsg(p0, p1, p2) } -func (s *StorageMinerStruct) DealsImportData(p0 context.Context, p1 cid.Cid, p2 string) error { - return s.Internal.DealsImportData(p0, p1, p2) +func (s *FullNodeStub) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) { + return nil, xerrors.New("method not supported") } -func (s *StorageMinerStruct) DealsList(p0 context.Context) ([]api.MarketDeal, error) { - return s.Internal.DealsList(p0) +func (s *FullNodeStruct) StateWaitMsgLimited(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch) (*api.MsgLookup, error) { + return s.Internal.StateWaitMsgLimited(p0, p1, p2, p3) } -func (s *StorageMinerStruct) DealsPieceCidBlocklist(p0 context.Context) ([]cid.Cid, error) { - return s.Internal.DealsPieceCidBlocklist(p0) +func (s *FullNodeStub) StateWaitMsgLimited(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch) (*api.MsgLookup, error) { + return nil, xerrors.New("method not supported") } -func (s *StorageMinerStruct) DealsSetConsiderOfflineRetrievalDeals(p0 context.Context, p1 bool) error { - return s.Internal.DealsSetConsiderOfflineRetrievalDeals(p0, p1) +func (s *FullNodeStruct) SyncCheckBad(p0 context.Context, p1 cid.Cid) (string, error) { + return s.Internal.SyncCheckBad(p0, p1) } -func (s *StorageMinerStruct) DealsSetConsiderOfflineStorageDeals(p0 context.Context, p1 bool) error { - return s.Internal.DealsSetConsiderOfflineStorageDeals(p0, p1) +func (s *FullNodeStub) SyncCheckBad(p0 context.Context, p1 cid.Cid) (string, error) { + return "", xerrors.New("method not supported") } -func (s *StorageMinerStruct) DealsSetConsiderOnlineRetrievalDeals(p0 context.Context, p1 bool) error { - return s.Internal.DealsSetConsiderOnlineRetrievalDeals(p0, p1) +func (s *FullNodeStruct) SyncCheckpoint(p0 context.Context, p1 types.TipSetKey) error { + return s.Internal.SyncCheckpoint(p0, p1) } -func (s *StorageMinerStruct) DealsSetConsiderOnlineStorageDeals(p0 context.Context, p1 bool) error { - return s.Internal.DealsSetConsiderOnlineStorageDeals(p0, p1) +func (s *FullNodeStub) SyncCheckpoint(p0 context.Context, p1 types.TipSetKey) error { + return xerrors.New("method not supported") } -func (s *StorageMinerStruct) DealsSetConsiderUnverifiedStorageDeals(p0 context.Context, p1 bool) error { - return s.Internal.DealsSetConsiderUnverifiedStorageDeals(p0, p1) +func (s *FullNodeStruct) SyncIncomingBlocks(p0 context.Context) (<-chan *types.BlockHeader, error) { + return s.Internal.SyncIncomingBlocks(p0) } -func (s *StorageMinerStruct) DealsSetConsiderVerifiedStorageDeals(p0 context.Context, p1 bool) error { - return s.Internal.DealsSetConsiderVerifiedStorageDeals(p0, p1) +func (s *FullNodeStub) SyncIncomingBlocks(p0 context.Context) (<-chan *types.BlockHeader, error) { + return nil, xerrors.New("method not supported") } -func (s *StorageMinerStruct) DealsSetPieceCidBlocklist(p0 context.Context, p1 []cid.Cid) error { - return s.Internal.DealsSetPieceCidBlocklist(p0, p1) +func (s *FullNodeStruct) SyncMarkBad(p0 context.Context, p1 cid.Cid) error { + return s.Internal.SyncMarkBad(p0, p1) } -func (s *StorageMinerStruct) MarketCancelDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { - return s.Internal.MarketCancelDataTransfer(p0, p1, p2, p3) +func (s *FullNodeStub) SyncMarkBad(p0 context.Context, p1 cid.Cid) error { + return xerrors.New("method not supported") } -func (s *StorageMinerStruct) MarketDataTransferUpdates(p0 context.Context) (<-chan api.DataTransferChannel, error) { - return s.Internal.MarketDataTransferUpdates(p0) +func (s *FullNodeStruct) SyncState(p0 context.Context) (*api.SyncState, error) { + return s.Internal.SyncState(p0) } -func (s *StorageMinerStruct) MarketGetAsk(p0 context.Context) (*storagemarket.SignedStorageAsk, error) { - return s.Internal.MarketGetAsk(p0) +func (s *FullNodeStub) SyncState(p0 context.Context) (*api.SyncState, error) { + return nil, xerrors.New("method not supported") } -func (s *StorageMinerStruct) MarketGetDealUpdates(p0 context.Context) (<-chan storagemarket.MinerDeal, error) { - return s.Internal.MarketGetDealUpdates(p0) +func (s *FullNodeStruct) SyncSubmitBlock(p0 context.Context, p1 *types.BlockMsg) error { + return s.Internal.SyncSubmitBlock(p0, p1) } -func (s *StorageMinerStruct) MarketGetRetrievalAsk(p0 context.Context) (*retrievalmarket.Ask, error) { - return s.Internal.MarketGetRetrievalAsk(p0) +func (s *FullNodeStub) SyncSubmitBlock(p0 context.Context, p1 *types.BlockMsg) error { + return xerrors.New("method not supported") } -func (s *StorageMinerStruct) MarketImportDealData(p0 context.Context, p1 cid.Cid, p2 string) error { - return s.Internal.MarketImportDealData(p0, p1, p2) +func (s *FullNodeStruct) SyncUnmarkAllBad(p0 context.Context) error { + return s.Internal.SyncUnmarkAllBad(p0) } -func (s *StorageMinerStruct) MarketListDataTransfers(p0 context.Context) ([]api.DataTransferChannel, error) { - return s.Internal.MarketListDataTransfers(p0) +func (s *FullNodeStub) SyncUnmarkAllBad(p0 context.Context) error { + return xerrors.New("method not supported") } -func (s *StorageMinerStruct) MarketListDeals(p0 context.Context) ([]api.MarketDeal, error) { - return s.Internal.MarketListDeals(p0) +func (s *FullNodeStruct) SyncUnmarkBad(p0 context.Context, p1 cid.Cid) error { + return s.Internal.SyncUnmarkBad(p0, p1) } -func (s *StorageMinerStruct) MarketListIncompleteDeals(p0 context.Context) ([]storagemarket.MinerDeal, error) { - return s.Internal.MarketListIncompleteDeals(p0) +func (s *FullNodeStub) SyncUnmarkBad(p0 context.Context, p1 cid.Cid) error { + return xerrors.New("method not supported") } -func (s *StorageMinerStruct) MarketListRetrievalDeals(p0 context.Context) ([]retrievalmarket.ProviderDealState, error) { - return s.Internal.MarketListRetrievalDeals(p0) +func (s *FullNodeStruct) SyncValidateTipset(p0 context.Context, p1 types.TipSetKey) (bool, error) { + return s.Internal.SyncValidateTipset(p0, p1) } -func (s *StorageMinerStruct) MarketPendingDeals(p0 context.Context) (api.PendingDealInfo, error) { - return s.Internal.MarketPendingDeals(p0) +func (s *FullNodeStub) SyncValidateTipset(p0 context.Context, p1 types.TipSetKey) (bool, error) { + return false, xerrors.New("method not supported") } -func (s *StorageMinerStruct) MarketPublishPendingDeals(p0 context.Context) error { - return s.Internal.MarketPublishPendingDeals(p0) +func (s *FullNodeStruct) WalletBalance(p0 context.Context, p1 address.Address) (types.BigInt, error) { + return s.Internal.WalletBalance(p0, p1) } -func (s *StorageMinerStruct) MarketRestartDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { - return s.Internal.MarketRestartDataTransfer(p0, p1, p2, p3) +func (s *FullNodeStub) WalletBalance(p0 context.Context, p1 address.Address) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") } -func (s *StorageMinerStruct) MarketSetAsk(p0 context.Context, p1 types.BigInt, p2 types.BigInt, p3 abi.ChainEpoch, p4 abi.PaddedPieceSize, p5 abi.PaddedPieceSize) error { - return s.Internal.MarketSetAsk(p0, p1, p2, p3, p4, p5) +func (s *FullNodeStruct) WalletDefaultAddress(p0 context.Context) (address.Address, error) { + return s.Internal.WalletDefaultAddress(p0) } -func (s *StorageMinerStruct) MarketSetRetrievalAsk(p0 context.Context, p1 *retrievalmarket.Ask) error { - return s.Internal.MarketSetRetrievalAsk(p0, p1) +func (s *FullNodeStub) WalletDefaultAddress(p0 context.Context) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") } -func (s *StorageMinerStruct) MiningBase(p0 context.Context) (*types.TipSet, error) { - return s.Internal.MiningBase(p0) +func (s *FullNodeStruct) WalletDelete(p0 context.Context, p1 address.Address) error { + return s.Internal.WalletDelete(p0, p1) } -func (s *StorageMinerStruct) PiecesGetCIDInfo(p0 context.Context, p1 cid.Cid) (*piecestore.CIDInfo, error) { - return s.Internal.PiecesGetCIDInfo(p0, p1) +func (s *FullNodeStub) WalletDelete(p0 context.Context, p1 address.Address) error { + return xerrors.New("method not supported") } -func (s *StorageMinerStruct) PiecesGetPieceInfo(p0 context.Context, p1 cid.Cid) (*piecestore.PieceInfo, error) { - return s.Internal.PiecesGetPieceInfo(p0, p1) +func (s *FullNodeStruct) WalletExport(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) { + return s.Internal.WalletExport(p0, p1) } -func (s *StorageMinerStruct) PiecesListCidInfos(p0 context.Context) ([]cid.Cid, error) { - return s.Internal.PiecesListCidInfos(p0) +func (s *FullNodeStub) WalletExport(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) { + return nil, xerrors.New("method not supported") } -func (s *StorageMinerStruct) PiecesListPieces(p0 context.Context) ([]cid.Cid, error) { - return s.Internal.PiecesListPieces(p0) +func (s *FullNodeStruct) WalletHas(p0 context.Context, p1 address.Address) (bool, error) { + return s.Internal.WalletHas(p0, p1) } -func (s *StorageMinerStruct) PledgeSector(p0 context.Context) (abi.SectorID, error) { - return s.Internal.PledgeSector(p0) +func (s *FullNodeStub) WalletHas(p0 context.Context, p1 address.Address) (bool, error) { + return false, xerrors.New("method not supported") } -func (s *StorageMinerStruct) ReturnAddPiece(p0 context.Context, p1 storiface.CallID, p2 abi.PieceInfo, p3 *storiface.CallError) error { - return s.Internal.ReturnAddPiece(p0, p1, p2, p3) +func (s *FullNodeStruct) WalletImport(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) { + return s.Internal.WalletImport(p0, p1) } -func (s *StorageMinerStruct) ReturnFetch(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { - return s.Internal.ReturnFetch(p0, p1, p2) +func (s *FullNodeStub) WalletImport(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") } -func (s *StorageMinerStruct) ReturnFinalizeSector(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { - return s.Internal.ReturnFinalizeSector(p0, p1, p2) +func (s *FullNodeStruct) WalletList(p0 context.Context) ([]address.Address, error) { + return s.Internal.WalletList(p0) } -func (s *StorageMinerStruct) ReturnMoveStorage(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { - return s.Internal.ReturnMoveStorage(p0, p1, p2) +func (s *FullNodeStub) WalletList(p0 context.Context) ([]address.Address, error) { + return *new([]address.Address), xerrors.New("method not supported") } -func (s *StorageMinerStruct) ReturnReadPiece(p0 context.Context, p1 storiface.CallID, p2 bool, p3 *storiface.CallError) error { - return s.Internal.ReturnReadPiece(p0, p1, p2, p3) +func (s *FullNodeStruct) WalletNew(p0 context.Context, p1 types.KeyType) (address.Address, error) { + return s.Internal.WalletNew(p0, p1) } -func (s *StorageMinerStruct) ReturnReleaseUnsealed(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { - return s.Internal.ReturnReleaseUnsealed(p0, p1, p2) +func (s *FullNodeStub) WalletNew(p0 context.Context, p1 types.KeyType) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") } -func (s *StorageMinerStruct) ReturnSealCommit1(p0 context.Context, p1 storiface.CallID, p2 storage.Commit1Out, p3 *storiface.CallError) error { - return s.Internal.ReturnSealCommit1(p0, p1, p2, p3) +func (s *FullNodeStruct) WalletSetDefault(p0 context.Context, p1 address.Address) error { + return s.Internal.WalletSetDefault(p0, p1) } -func (s *StorageMinerStruct) ReturnSealCommit2(p0 context.Context, p1 storiface.CallID, p2 storage.Proof, p3 *storiface.CallError) error { - return s.Internal.ReturnSealCommit2(p0, p1, p2, p3) +func (s *FullNodeStub) WalletSetDefault(p0 context.Context, p1 address.Address) error { + return xerrors.New("method not supported") } -func (s *StorageMinerStruct) ReturnSealPreCommit1(p0 context.Context, p1 storiface.CallID, p2 storage.PreCommit1Out, p3 *storiface.CallError) error { - return s.Internal.ReturnSealPreCommit1(p0, p1, p2, p3) +func (s *FullNodeStruct) WalletSign(p0 context.Context, p1 address.Address, p2 []byte) (*crypto.Signature, error) { + return s.Internal.WalletSign(p0, p1, p2) } -func (s *StorageMinerStruct) ReturnSealPreCommit2(p0 context.Context, p1 storiface.CallID, p2 storage.SectorCids, p3 *storiface.CallError) error { - return s.Internal.ReturnSealPreCommit2(p0, p1, p2, p3) +func (s *FullNodeStub) WalletSign(p0 context.Context, p1 address.Address, p2 []byte) (*crypto.Signature, error) { + return nil, xerrors.New("method not supported") } -func (s *StorageMinerStruct) ReturnUnsealPiece(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { - return s.Internal.ReturnUnsealPiece(p0, p1, p2) +func (s *FullNodeStruct) WalletSignMessage(p0 context.Context, p1 address.Address, p2 *types.Message) (*types.SignedMessage, error) { + return s.Internal.WalletSignMessage(p0, p1, p2) } -func (s *StorageMinerStruct) SealingAbort(p0 context.Context, p1 storiface.CallID) error { - return s.Internal.SealingAbort(p0, p1) +func (s *FullNodeStub) WalletSignMessage(p0 context.Context, p1 address.Address, p2 *types.Message) (*types.SignedMessage, error) { + return nil, xerrors.New("method not supported") } -func (s *StorageMinerStruct) SealingSchedDiag(p0 context.Context, p1 bool) (interface{}, error) { - return s.Internal.SealingSchedDiag(p0, p1) +func (s *FullNodeStruct) WalletValidateAddress(p0 context.Context, p1 string) (address.Address, error) { + return s.Internal.WalletValidateAddress(p0, p1) } -func (s *StorageMinerStruct) SectorGetExpectedSealDuration(p0 context.Context) (time.Duration, error) { - return s.Internal.SectorGetExpectedSealDuration(p0) +func (s *FullNodeStub) WalletValidateAddress(p0 context.Context, p1 string) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") } -func (s *StorageMinerStruct) SectorGetSealDelay(p0 context.Context) (time.Duration, error) { - return s.Internal.SectorGetSealDelay(p0) +func (s *FullNodeStruct) WalletVerify(p0 context.Context, p1 address.Address, p2 []byte, p3 *crypto.Signature) (bool, error) { + return s.Internal.WalletVerify(p0, p1, p2, p3) } -func (s *StorageMinerStruct) SectorMarkForUpgrade(p0 context.Context, p1 abi.SectorNumber) error { - return s.Internal.SectorMarkForUpgrade(p0, p1) +func (s *FullNodeStub) WalletVerify(p0 context.Context, p1 address.Address, p2 []byte, p3 *crypto.Signature) (bool, error) { + return false, xerrors.New("method not supported") } -func (s *StorageMinerStruct) SectorRemove(p0 context.Context, p1 abi.SectorNumber) error { - return s.Internal.SectorRemove(p0, p1) +func (s *GatewayStruct) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*api.BlockMessages, error) { + return s.Internal.ChainGetBlockMessages(p0, p1) } -func (s *StorageMinerStruct) SectorSetExpectedSealDuration(p0 context.Context, p1 time.Duration) error { - return s.Internal.SectorSetExpectedSealDuration(p0, p1) +func (s *GatewayStub) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*api.BlockMessages, error) { + return nil, xerrors.New("method not supported") } -func (s *StorageMinerStruct) SectorSetSealDelay(p0 context.Context, p1 time.Duration) error { - return s.Internal.SectorSetSealDelay(p0, p1) +func (s *GatewayStruct) ChainGetMessage(p0 context.Context, p1 cid.Cid) (*types.Message, error) { + return s.Internal.ChainGetMessage(p0, p1) } -func (s *StorageMinerStruct) SectorStartSealing(p0 context.Context, p1 abi.SectorNumber) error { - return s.Internal.SectorStartSealing(p0, p1) +func (s *GatewayStub) ChainGetMessage(p0 context.Context, p1 cid.Cid) (*types.Message, error) { + return nil, xerrors.New("method not supported") } -func (s *StorageMinerStruct) SectorTerminate(p0 context.Context, p1 abi.SectorNumber) error { - return s.Internal.SectorTerminate(p0, p1) +func (s *GatewayStruct) ChainGetTipSet(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) { + return s.Internal.ChainGetTipSet(p0, p1) } -func (s *StorageMinerStruct) SectorTerminateFlush(p0 context.Context) (*cid.Cid, error) { - return s.Internal.SectorTerminateFlush(p0) +func (s *GatewayStub) ChainGetTipSet(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) { + return nil, xerrors.New("method not supported") } -func (s *StorageMinerStruct) SectorTerminatePending(p0 context.Context) ([]abi.SectorID, error) { - return s.Internal.SectorTerminatePending(p0) +func (s *GatewayStruct) ChainGetTipSetByHeight(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) { + return s.Internal.ChainGetTipSetByHeight(p0, p1, p2) } -func (s *StorageMinerStruct) SectorsList(p0 context.Context) ([]abi.SectorNumber, error) { - return s.Internal.SectorsList(p0) +func (s *GatewayStub) ChainGetTipSetByHeight(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) { + return nil, xerrors.New("method not supported") } -func (s *StorageMinerStruct) SectorsListInStates(p0 context.Context, p1 []api.SectorState) ([]abi.SectorNumber, error) { - return s.Internal.SectorsListInStates(p0, p1) +func (s *GatewayStruct) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { + return s.Internal.ChainHasObj(p0, p1) } -func (s *StorageMinerStruct) SectorsRefs(p0 context.Context) (map[string][]api.SealedRef, error) { - return s.Internal.SectorsRefs(p0) +func (s *GatewayStub) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { + return false, xerrors.New("method not supported") } -func (s *StorageMinerStruct) SectorsStatus(p0 context.Context, p1 abi.SectorNumber, p2 bool) (api.SectorInfo, error) { - return s.Internal.SectorsStatus(p0, p1, p2) +func (s *GatewayStruct) ChainHead(p0 context.Context) (*types.TipSet, error) { + return s.Internal.ChainHead(p0) } -func (s *StorageMinerStruct) SectorsSummary(p0 context.Context) (map[api.SectorState]int, error) { - return s.Internal.SectorsSummary(p0) +func (s *GatewayStub) ChainHead(p0 context.Context) (*types.TipSet, error) { + return nil, xerrors.New("method not supported") } -func (s *StorageMinerStruct) SectorsUpdate(p0 context.Context, p1 abi.SectorNumber, p2 api.SectorState) error { - return s.Internal.SectorsUpdate(p0, p1, p2) +func (s *GatewayStruct) ChainNotify(p0 context.Context) (<-chan []*api.HeadChange, error) { + return s.Internal.ChainNotify(p0) } -func (s *StorageMinerStruct) StorageAddLocal(p0 context.Context, p1 string) error { - return s.Internal.StorageAddLocal(p0, p1) +func (s *GatewayStub) ChainNotify(p0 context.Context) (<-chan []*api.HeadChange, error) { + return nil, xerrors.New("method not supported") } -func (s *StorageMinerStruct) StorageAttach(p0 context.Context, p1 stores.StorageInfo, p2 fsutil.FsStat) error { - return s.Internal.StorageAttach(p0, p1, p2) +func (s *GatewayStruct) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { + return s.Internal.ChainReadObj(p0, p1) } -func (s *StorageMinerStruct) StorageBestAlloc(p0 context.Context, p1 storiface.SectorFileType, p2 abi.SectorSize, p3 storiface.PathType) ([]stores.StorageInfo, error) { - return s.Internal.StorageBestAlloc(p0, p1, p2, p3) +func (s *GatewayStub) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { + return *new([]byte), xerrors.New("method not supported") } -func (s *StorageMinerStruct) StorageDeclareSector(p0 context.Context, p1 stores.ID, p2 abi.SectorID, p3 storiface.SectorFileType, p4 bool) error { - return s.Internal.StorageDeclareSector(p0, p1, p2, p3, p4) +func (s *GatewayStruct) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { + return s.Internal.GasEstimateMessageGas(p0, p1, p2, p3) } -func (s *StorageMinerStruct) StorageDropSector(p0 context.Context, p1 stores.ID, p2 abi.SectorID, p3 storiface.SectorFileType) error { - return s.Internal.StorageDropSector(p0, p1, p2, p3) +func (s *GatewayStub) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { + return nil, xerrors.New("method not supported") } -func (s *StorageMinerStruct) StorageFindSector(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 abi.SectorSize, p4 bool) ([]stores.SectorStorageInfo, error) { - return s.Internal.StorageFindSector(p0, p1, p2, p3, p4) +func (s *GatewayStruct) MpoolPush(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { + return s.Internal.MpoolPush(p0, p1) } -func (s *StorageMinerStruct) StorageInfo(p0 context.Context, p1 stores.ID) (stores.StorageInfo, error) { - return s.Internal.StorageInfo(p0, p1) +func (s *GatewayStub) MpoolPush(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { + return *new(cid.Cid), xerrors.New("method not supported") } -func (s *StorageMinerStruct) StorageList(p0 context.Context) (map[stores.ID][]stores.Decl, error) { - return s.Internal.StorageList(p0) +func (s *GatewayStruct) MsigGetAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { + return s.Internal.MsigGetAvailableBalance(p0, p1, p2) } -func (s *StorageMinerStruct) StorageLocal(p0 context.Context) (map[stores.ID]string, error) { - return s.Internal.StorageLocal(p0) +func (s *GatewayStub) MsigGetAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") } -func (s *StorageMinerStruct) StorageLock(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 storiface.SectorFileType) error { - return s.Internal.StorageLock(p0, p1, p2, p3) +func (s *GatewayStruct) MsigGetPending(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*api.MsigTransaction, error) { + return s.Internal.MsigGetPending(p0, p1, p2) } -func (s *StorageMinerStruct) StorageReportHealth(p0 context.Context, p1 stores.ID, p2 stores.HealthReport) error { - return s.Internal.StorageReportHealth(p0, p1, p2) +func (s *GatewayStub) MsigGetPending(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*api.MsigTransaction, error) { + return *new([]*api.MsigTransaction), xerrors.New("method not supported") } -func (s *StorageMinerStruct) StorageStat(p0 context.Context, p1 stores.ID) (fsutil.FsStat, error) { - return s.Internal.StorageStat(p0, p1) +func (s *GatewayStruct) MsigGetVested(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) { + return s.Internal.MsigGetVested(p0, p1, p2, p3) } -func (s *StorageMinerStruct) StorageTryLock(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 storiface.SectorFileType) (bool, error) { - return s.Internal.StorageTryLock(p0, p1, p2, p3) +func (s *GatewayStub) MsigGetVested(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") } -func (s *StorageMinerStruct) WorkerConnect(p0 context.Context, p1 string) error { - return s.Internal.WorkerConnect(p0, p1) +func (s *GatewayStruct) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + return s.Internal.StateAccountKey(p0, p1, p2) } -func (s *StorageMinerStruct) WorkerJobs(p0 context.Context) (map[uuid.UUID][]storiface.WorkerJob, error) { - return s.Internal.WorkerJobs(p0) +func (s *GatewayStub) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") } -func (s *StorageMinerStruct) WorkerStats(p0 context.Context) (map[uuid.UUID]storiface.WorkerStats, error) { - return s.Internal.WorkerStats(p0) +func (s *GatewayStruct) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) { + return s.Internal.StateDealProviderCollateralBounds(p0, p1, p2, p3) } -func (s *WalletStruct) WalletDelete(p0 context.Context, p1 address.Address) error { - return s.Internal.WalletDelete(p0, p1) +func (s *GatewayStub) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) { + return *new(api.DealCollateralBounds), xerrors.New("method not supported") } -func (s *WalletStruct) WalletExport(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) { - return s.Internal.WalletExport(p0, p1) +func (s *GatewayStruct) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) { + return s.Internal.StateGetActor(p0, p1, p2) } -func (s *WalletStruct) WalletHas(p0 context.Context, p1 address.Address) (bool, error) { - return s.Internal.WalletHas(p0, p1) +func (s *GatewayStub) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) { + return nil, xerrors.New("method not supported") } -func (s *WalletStruct) WalletImport(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) { - return s.Internal.WalletImport(p0, p1) +func (s *GatewayStruct) StateGetReceipt(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) { + return s.Internal.StateGetReceipt(p0, p1, p2) } -func (s *WalletStruct) WalletList(p0 context.Context) ([]address.Address, error) { - return s.Internal.WalletList(p0) +func (s *GatewayStub) StateGetReceipt(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) { + return nil, xerrors.New("method not supported") } -func (s *WalletStruct) WalletNew(p0 context.Context, p1 types.KeyType) (address.Address, error) { - return s.Internal.WalletNew(p0, p1) +func (s *GatewayStruct) StateListMiners(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { + return s.Internal.StateListMiners(p0, p1) } -func (s *WalletStruct) WalletSign(p0 context.Context, p1 address.Address, p2 []byte, p3 api.MsgMeta) (*crypto.Signature, error) { - return s.Internal.WalletSign(p0, p1, p2, p3) +func (s *GatewayStub) StateListMiners(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { + return *new([]address.Address), xerrors.New("method not supported") } -func (s *WorkerStruct) AddPiece(p0 context.Context, p1 storage.SectorRef, p2 []abi.UnpaddedPieceSize, p3 abi.UnpaddedPieceSize, p4 storage.Data) (storiface.CallID, error) { - return s.Internal.AddPiece(p0, p1, p2, p3, p4) +func (s *GatewayStruct) StateLookupID(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + return s.Internal.StateLookupID(p0, p1, p2) } -func (s *WorkerStruct) Enabled(p0 context.Context) (bool, error) { - return s.Internal.Enabled(p0) +func (s *GatewayStub) StateLookupID(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + return *new(address.Address), xerrors.New("method not supported") } -func (s *WorkerStruct) Fetch(p0 context.Context, p1 storage.SectorRef, p2 storiface.SectorFileType, p3 storiface.PathType, p4 storiface.AcquireMode) (storiface.CallID, error) { - return s.Internal.Fetch(p0, p1, p2, p3, p4) +func (s *GatewayStruct) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MarketBalance, error) { + return s.Internal.StateMarketBalance(p0, p1, p2) } -func (s *WorkerStruct) FinalizeSector(p0 context.Context, p1 storage.SectorRef, p2 []storage.Range) (storiface.CallID, error) { - return s.Internal.FinalizeSector(p0, p1, p2) +func (s *GatewayStub) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MarketBalance, error) { + return *new(api.MarketBalance), xerrors.New("method not supported") } -func (s *WorkerStruct) Info(p0 context.Context) (storiface.WorkerInfo, error) { - return s.Internal.Info(p0) +func (s *GatewayStruct) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*api.MarketDeal, error) { + return s.Internal.StateMarketStorageDeal(p0, p1, p2) } -func (s *WorkerStruct) MoveStorage(p0 context.Context, p1 storage.SectorRef, p2 storiface.SectorFileType) (storiface.CallID, error) { - return s.Internal.MoveStorage(p0, p1, p2) +func (s *GatewayStub) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*api.MarketDeal, error) { + return nil, xerrors.New("method not supported") } -func (s *WorkerStruct) Paths(p0 context.Context) ([]stores.StoragePath, error) { - return s.Internal.Paths(p0) +func (s *GatewayStruct) StateMinerInfo(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) { + return s.Internal.StateMinerInfo(p0, p1, p2) } -func (s *WorkerStruct) ProcessSession(p0 context.Context) (uuid.UUID, error) { - return s.Internal.ProcessSession(p0) +func (s *GatewayStub) StateMinerInfo(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) { + return *new(miner.MinerInfo), xerrors.New("method not supported") } -func (s *WorkerStruct) ReadPiece(p0 context.Context, p1 io.Writer, p2 storage.SectorRef, p3 storiface.UnpaddedByteIndex, p4 abi.UnpaddedPieceSize) (storiface.CallID, error) { - return s.Internal.ReadPiece(p0, p1, p2, p3, p4) +func (s *GatewayStruct) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.MinerPower, error) { + return s.Internal.StateMinerPower(p0, p1, p2) } -func (s *WorkerStruct) ReleaseUnsealed(p0 context.Context, p1 storage.SectorRef, p2 []storage.Range) (storiface.CallID, error) { - return s.Internal.ReleaseUnsealed(p0, p1, p2) +func (s *GatewayStub) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.MinerPower, error) { + return nil, xerrors.New("method not supported") } -func (s *WorkerStruct) Remove(p0 context.Context, p1 abi.SectorID) error { - return s.Internal.Remove(p0, p1) +func (s *GatewayStruct) StateMinerProvingDeadline(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) { + return s.Internal.StateMinerProvingDeadline(p0, p1, p2) } -func (s *WorkerStruct) SealCommit1(p0 context.Context, p1 storage.SectorRef, p2 abi.SealRandomness, p3 abi.InteractiveSealRandomness, p4 []abi.PieceInfo, p5 storage.SectorCids) (storiface.CallID, error) { - return s.Internal.SealCommit1(p0, p1, p2, p3, p4, p5) +func (s *GatewayStub) StateMinerProvingDeadline(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) { + return nil, xerrors.New("method not supported") } -func (s *WorkerStruct) SealCommit2(p0 context.Context, p1 storage.SectorRef, p2 storage.Commit1Out) (storiface.CallID, error) { - return s.Internal.SealCommit2(p0, p1, p2) +func (s *GatewayStruct) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (network.Version, error) { + return s.Internal.StateNetworkVersion(p0, p1) } -func (s *WorkerStruct) SealPreCommit1(p0 context.Context, p1 storage.SectorRef, p2 abi.SealRandomness, p3 []abi.PieceInfo) (storiface.CallID, error) { - return s.Internal.SealPreCommit1(p0, p1, p2, p3) +func (s *GatewayStub) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (network.Version, error) { + return *new(network.Version), xerrors.New("method not supported") } -func (s *WorkerStruct) SealPreCommit2(p0 context.Context, p1 storage.SectorRef, p2 storage.PreCommit1Out) (storiface.CallID, error) { - return s.Internal.SealPreCommit2(p0, p1, p2) +func (s *GatewayStruct) StateSearchMsg(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) { + return s.Internal.StateSearchMsg(p0, p1) } -func (s *WorkerStruct) Session(p0 context.Context) (uuid.UUID, error) { - return s.Internal.Session(p0) +func (s *GatewayStub) StateSearchMsg(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) { + return nil, xerrors.New("method not supported") } -func (s *WorkerStruct) SetEnabled(p0 context.Context, p1 bool) error { - return s.Internal.SetEnabled(p0, p1) +func (s *GatewayStruct) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { + return s.Internal.StateSectorGetInfo(p0, p1, p2, p3) } -func (s *WorkerStruct) StorageAddLocal(p0 context.Context, p1 string) error { - return s.Internal.StorageAddLocal(p0, p1) +func (s *GatewayStub) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { + return nil, xerrors.New("method not supported") } -func (s *WorkerStruct) TaskDisable(p0 context.Context, p1 sealtasks.TaskType) error { - return s.Internal.TaskDisable(p0, p1) +func (s *GatewayStruct) StateVerifiedClientStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { + return s.Internal.StateVerifiedClientStatus(p0, p1, p2) } -func (s *WorkerStruct) TaskEnable(p0 context.Context, p1 sealtasks.TaskType) error { - return s.Internal.TaskEnable(p0, p1) +func (s *GatewayStub) StateVerifiedClientStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { + return nil, xerrors.New("method not supported") } -func (s *WorkerStruct) TaskTypes(p0 context.Context) (map[sealtasks.TaskType]struct{}, error) { - return s.Internal.TaskTypes(p0) +func (s *GatewayStruct) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) { + return s.Internal.StateWaitMsg(p0, p1, p2) } -func (s *WorkerStruct) UnsealPiece(p0 context.Context, p1 storage.SectorRef, p2 storiface.UnpaddedByteIndex, p3 abi.UnpaddedPieceSize, p4 abi.SealRandomness, p5 cid.Cid) (storiface.CallID, error) { - return s.Internal.UnsealPiece(p0, p1, p2, p3, p4, p5) +func (s *GatewayStub) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) { + return nil, xerrors.New("method not supported") } -func (s *WorkerStruct) Version(p0 context.Context) (api.Version, error) { - return s.Internal.Version(p0) +func (s *GatewayStruct) WalletBalance(p0 context.Context, p1 address.Address) (types.BigInt, error) { + return s.Internal.WalletBalance(p0, p1) } -func (s *WorkerStruct) WaitQuiet(p0 context.Context) error { - return s.Internal.WaitQuiet(p0) +func (s *GatewayStub) WalletBalance(p0 context.Context, p1 address.Address) (types.BigInt, error) { + return *new(types.BigInt), xerrors.New("method not supported") } -var _ api.ChainIO = new(ChainIOStruct) -var _ api.Common = new(CommonStruct) -var _ api.FullNode = new(FullNodeStruct) -var _ api.Gateway = new(GatewayStruct) -var _ api.Signable = new(SignableStruct) -var _ api.StorageMiner = new(StorageMinerStruct) -var _ api.Wallet = new(WalletStruct) -var _ api.Worker = new(WorkerStruct) +var _ FullNode = new(FullNodeStruct) +var _ Gateway = new(GatewayStruct) diff --git a/api/v0api/v0mocks/mock_full.go b/api/v0api/v0mocks/mock_full.go new file mode 100644 index 00000000000..165b07165b7 --- /dev/null +++ b/api/v0api/v0mocks/mock_full.go @@ -0,0 +1,3019 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/filecoin-project/lotus/api/v0api (interfaces: FullNode) + +// Package v0mocks is a generated GoMock package. +package v0mocks + +import ( + context "context" + reflect "reflect" + + address "github.com/filecoin-project/go-address" + bitfield "github.com/filecoin-project/go-bitfield" + datatransfer "github.com/filecoin-project/go-data-transfer" + retrievalmarket "github.com/filecoin-project/go-fil-markets/retrievalmarket" + storagemarket "github.com/filecoin-project/go-fil-markets/storagemarket" + auth "github.com/filecoin-project/go-jsonrpc/auth" + multistore "github.com/filecoin-project/go-multistore" + abi "github.com/filecoin-project/go-state-types/abi" + big "github.com/filecoin-project/go-state-types/big" + crypto "github.com/filecoin-project/go-state-types/crypto" + dline "github.com/filecoin-project/go-state-types/dline" + network "github.com/filecoin-project/go-state-types/network" + api "github.com/filecoin-project/lotus/api" + apitypes "github.com/filecoin-project/lotus/api/types" + miner "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + types "github.com/filecoin-project/lotus/chain/types" + marketevents "github.com/filecoin-project/lotus/markets/loggers" + dtypes "github.com/filecoin-project/lotus/node/modules/dtypes" + miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" + paych "github.com/filecoin-project/specs-actors/actors/builtin/paych" + gomock "github.com/golang/mock/gomock" + uuid "github.com/google/uuid" + cid "github.com/ipfs/go-cid" + metrics "github.com/libp2p/go-libp2p-core/metrics" + network0 "github.com/libp2p/go-libp2p-core/network" + peer "github.com/libp2p/go-libp2p-core/peer" + protocol "github.com/libp2p/go-libp2p-core/protocol" +) + +// MockFullNode is a mock of FullNode interface +type MockFullNode struct { + ctrl *gomock.Controller + recorder *MockFullNodeMockRecorder +} + +// MockFullNodeMockRecorder is the mock recorder for MockFullNode +type MockFullNodeMockRecorder struct { + mock *MockFullNode +} + +// NewMockFullNode creates a new mock instance +func NewMockFullNode(ctrl *gomock.Controller) *MockFullNode { + mock := &MockFullNode{ctrl: ctrl} + mock.recorder = &MockFullNodeMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockFullNode) EXPECT() *MockFullNodeMockRecorder { + return m.recorder +} + +// AuthNew mocks base method +func (m *MockFullNode) AuthNew(arg0 context.Context, arg1 []auth.Permission) ([]byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AuthNew", arg0, arg1) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// AuthNew indicates an expected call of AuthNew +func (mr *MockFullNodeMockRecorder) AuthNew(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthNew", reflect.TypeOf((*MockFullNode)(nil).AuthNew), arg0, arg1) +} + +// AuthVerify mocks base method +func (m *MockFullNode) AuthVerify(arg0 context.Context, arg1 string) ([]auth.Permission, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AuthVerify", arg0, arg1) + ret0, _ := ret[0].([]auth.Permission) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// AuthVerify indicates an expected call of AuthVerify +func (mr *MockFullNodeMockRecorder) AuthVerify(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthVerify", reflect.TypeOf((*MockFullNode)(nil).AuthVerify), arg0, arg1) +} + +// BeaconGetEntry mocks base method +func (m *MockFullNode) BeaconGetEntry(arg0 context.Context, arg1 abi.ChainEpoch) (*types.BeaconEntry, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BeaconGetEntry", arg0, arg1) + ret0, _ := ret[0].(*types.BeaconEntry) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// BeaconGetEntry indicates an expected call of BeaconGetEntry +func (mr *MockFullNodeMockRecorder) BeaconGetEntry(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeaconGetEntry", reflect.TypeOf((*MockFullNode)(nil).BeaconGetEntry), arg0, arg1) +} + +// ChainDeleteObj mocks base method +func (m *MockFullNode) ChainDeleteObj(arg0 context.Context, arg1 cid.Cid) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainDeleteObj", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ChainDeleteObj indicates an expected call of ChainDeleteObj +func (mr *MockFullNodeMockRecorder) ChainDeleteObj(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainDeleteObj", reflect.TypeOf((*MockFullNode)(nil).ChainDeleteObj), arg0, arg1) +} + +// ChainExport mocks base method +func (m *MockFullNode) ChainExport(arg0 context.Context, arg1 abi.ChainEpoch, arg2 bool, arg3 types.TipSetKey) (<-chan []byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainExport", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(<-chan []byte) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainExport indicates an expected call of ChainExport +func (mr *MockFullNodeMockRecorder) ChainExport(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainExport", reflect.TypeOf((*MockFullNode)(nil).ChainExport), arg0, arg1, arg2, arg3) +} + +// ChainGetBlock mocks base method +func (m *MockFullNode) ChainGetBlock(arg0 context.Context, arg1 cid.Cid) (*types.BlockHeader, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainGetBlock", arg0, arg1) + ret0, _ := ret[0].(*types.BlockHeader) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainGetBlock indicates an expected call of ChainGetBlock +func (mr *MockFullNodeMockRecorder) ChainGetBlock(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetBlock", reflect.TypeOf((*MockFullNode)(nil).ChainGetBlock), arg0, arg1) +} + +// ChainGetBlockMessages mocks base method +func (m *MockFullNode) ChainGetBlockMessages(arg0 context.Context, arg1 cid.Cid) (*api.BlockMessages, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainGetBlockMessages", arg0, arg1) + ret0, _ := ret[0].(*api.BlockMessages) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainGetBlockMessages indicates an expected call of ChainGetBlockMessages +func (mr *MockFullNodeMockRecorder) ChainGetBlockMessages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetBlockMessages", reflect.TypeOf((*MockFullNode)(nil).ChainGetBlockMessages), arg0, arg1) +} + +// ChainGetGenesis mocks base method +func (m *MockFullNode) ChainGetGenesis(arg0 context.Context) (*types.TipSet, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainGetGenesis", arg0) + ret0, _ := ret[0].(*types.TipSet) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainGetGenesis indicates an expected call of ChainGetGenesis +func (mr *MockFullNodeMockRecorder) ChainGetGenesis(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetGenesis", reflect.TypeOf((*MockFullNode)(nil).ChainGetGenesis), arg0) +} + +// ChainGetMessage mocks base method +func (m *MockFullNode) ChainGetMessage(arg0 context.Context, arg1 cid.Cid) (*types.Message, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainGetMessage", arg0, arg1) + ret0, _ := ret[0].(*types.Message) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainGetMessage indicates an expected call of ChainGetMessage +func (mr *MockFullNodeMockRecorder) ChainGetMessage(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetMessage", reflect.TypeOf((*MockFullNode)(nil).ChainGetMessage), arg0, arg1) +} + +// ChainGetNode mocks base method +func (m *MockFullNode) ChainGetNode(arg0 context.Context, arg1 string) (*api.IpldObject, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainGetNode", arg0, arg1) + ret0, _ := ret[0].(*api.IpldObject) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainGetNode indicates an expected call of ChainGetNode +func (mr *MockFullNodeMockRecorder) ChainGetNode(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetNode", reflect.TypeOf((*MockFullNode)(nil).ChainGetNode), arg0, arg1) +} + +// ChainGetParentMessages mocks base method +func (m *MockFullNode) ChainGetParentMessages(arg0 context.Context, arg1 cid.Cid) ([]api.Message, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainGetParentMessages", arg0, arg1) + ret0, _ := ret[0].([]api.Message) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainGetParentMessages indicates an expected call of ChainGetParentMessages +func (mr *MockFullNodeMockRecorder) ChainGetParentMessages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetParentMessages", reflect.TypeOf((*MockFullNode)(nil).ChainGetParentMessages), arg0, arg1) +} + +// ChainGetParentReceipts mocks base method +func (m *MockFullNode) ChainGetParentReceipts(arg0 context.Context, arg1 cid.Cid) ([]*types.MessageReceipt, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainGetParentReceipts", arg0, arg1) + ret0, _ := ret[0].([]*types.MessageReceipt) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainGetParentReceipts indicates an expected call of ChainGetParentReceipts +func (mr *MockFullNodeMockRecorder) ChainGetParentReceipts(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetParentReceipts", reflect.TypeOf((*MockFullNode)(nil).ChainGetParentReceipts), arg0, arg1) +} + +// ChainGetPath mocks base method +func (m *MockFullNode) ChainGetPath(arg0 context.Context, arg1, arg2 types.TipSetKey) ([]*api.HeadChange, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainGetPath", arg0, arg1, arg2) + ret0, _ := ret[0].([]*api.HeadChange) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainGetPath indicates an expected call of ChainGetPath +func (mr *MockFullNodeMockRecorder) ChainGetPath(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetPath", reflect.TypeOf((*MockFullNode)(nil).ChainGetPath), arg0, arg1, arg2) +} + +// ChainGetRandomnessFromBeacon mocks base method +func (m *MockFullNode) ChainGetRandomnessFromBeacon(arg0 context.Context, arg1 types.TipSetKey, arg2 crypto.DomainSeparationTag, arg3 abi.ChainEpoch, arg4 []byte) (abi.Randomness, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainGetRandomnessFromBeacon", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(abi.Randomness) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainGetRandomnessFromBeacon indicates an expected call of ChainGetRandomnessFromBeacon +func (mr *MockFullNodeMockRecorder) ChainGetRandomnessFromBeacon(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetRandomnessFromBeacon", reflect.TypeOf((*MockFullNode)(nil).ChainGetRandomnessFromBeacon), arg0, arg1, arg2, arg3, arg4) +} + +// ChainGetRandomnessFromTickets mocks base method +func (m *MockFullNode) ChainGetRandomnessFromTickets(arg0 context.Context, arg1 types.TipSetKey, arg2 crypto.DomainSeparationTag, arg3 abi.ChainEpoch, arg4 []byte) (abi.Randomness, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainGetRandomnessFromTickets", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(abi.Randomness) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainGetRandomnessFromTickets indicates an expected call of ChainGetRandomnessFromTickets +func (mr *MockFullNodeMockRecorder) ChainGetRandomnessFromTickets(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetRandomnessFromTickets", reflect.TypeOf((*MockFullNode)(nil).ChainGetRandomnessFromTickets), arg0, arg1, arg2, arg3, arg4) +} + +// ChainGetTipSet mocks base method +func (m *MockFullNode) ChainGetTipSet(arg0 context.Context, arg1 types.TipSetKey) (*types.TipSet, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainGetTipSet", arg0, arg1) + ret0, _ := ret[0].(*types.TipSet) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainGetTipSet indicates an expected call of ChainGetTipSet +func (mr *MockFullNodeMockRecorder) ChainGetTipSet(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetTipSet", reflect.TypeOf((*MockFullNode)(nil).ChainGetTipSet), arg0, arg1) +} + +// ChainGetTipSetByHeight mocks base method +func (m *MockFullNode) ChainGetTipSetByHeight(arg0 context.Context, arg1 abi.ChainEpoch, arg2 types.TipSetKey) (*types.TipSet, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainGetTipSetByHeight", arg0, arg1, arg2) + ret0, _ := ret[0].(*types.TipSet) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainGetTipSetByHeight indicates an expected call of ChainGetTipSetByHeight +func (mr *MockFullNodeMockRecorder) ChainGetTipSetByHeight(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetTipSetByHeight", reflect.TypeOf((*MockFullNode)(nil).ChainGetTipSetByHeight), arg0, arg1, arg2) +} + +// ChainHasObj mocks base method +func (m *MockFullNode) ChainHasObj(arg0 context.Context, arg1 cid.Cid) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainHasObj", arg0, arg1) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainHasObj indicates an expected call of ChainHasObj +func (mr *MockFullNodeMockRecorder) ChainHasObj(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainHasObj", reflect.TypeOf((*MockFullNode)(nil).ChainHasObj), arg0, arg1) +} + +// ChainHead mocks base method +func (m *MockFullNode) ChainHead(arg0 context.Context) (*types.TipSet, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainHead", arg0) + ret0, _ := ret[0].(*types.TipSet) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainHead indicates an expected call of ChainHead +func (mr *MockFullNodeMockRecorder) ChainHead(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainHead", reflect.TypeOf((*MockFullNode)(nil).ChainHead), arg0) +} + +// ChainNotify mocks base method +func (m *MockFullNode) ChainNotify(arg0 context.Context) (<-chan []*api.HeadChange, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainNotify", arg0) + ret0, _ := ret[0].(<-chan []*api.HeadChange) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainNotify indicates an expected call of ChainNotify +func (mr *MockFullNodeMockRecorder) ChainNotify(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainNotify", reflect.TypeOf((*MockFullNode)(nil).ChainNotify), arg0) +} + +// ChainReadObj mocks base method +func (m *MockFullNode) ChainReadObj(arg0 context.Context, arg1 cid.Cid) ([]byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainReadObj", arg0, arg1) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainReadObj indicates an expected call of ChainReadObj +func (mr *MockFullNodeMockRecorder) ChainReadObj(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainReadObj", reflect.TypeOf((*MockFullNode)(nil).ChainReadObj), arg0, arg1) +} + +// ChainSetHead mocks base method +func (m *MockFullNode) ChainSetHead(arg0 context.Context, arg1 types.TipSetKey) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainSetHead", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ChainSetHead indicates an expected call of ChainSetHead +func (mr *MockFullNodeMockRecorder) ChainSetHead(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainSetHead", reflect.TypeOf((*MockFullNode)(nil).ChainSetHead), arg0, arg1) +} + +// ChainStatObj mocks base method +func (m *MockFullNode) ChainStatObj(arg0 context.Context, arg1, arg2 cid.Cid) (api.ObjStat, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainStatObj", arg0, arg1, arg2) + ret0, _ := ret[0].(api.ObjStat) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainStatObj indicates an expected call of ChainStatObj +func (mr *MockFullNodeMockRecorder) ChainStatObj(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainStatObj", reflect.TypeOf((*MockFullNode)(nil).ChainStatObj), arg0, arg1, arg2) +} + +// ChainTipSetWeight mocks base method +func (m *MockFullNode) ChainTipSetWeight(arg0 context.Context, arg1 types.TipSetKey) (big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainTipSetWeight", arg0, arg1) + ret0, _ := ret[0].(big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainTipSetWeight indicates an expected call of ChainTipSetWeight +func (mr *MockFullNodeMockRecorder) ChainTipSetWeight(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainTipSetWeight", reflect.TypeOf((*MockFullNode)(nil).ChainTipSetWeight), arg0, arg1) +} + +// ClientCalcCommP mocks base method +func (m *MockFullNode) ClientCalcCommP(arg0 context.Context, arg1 string) (*api.CommPRet, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientCalcCommP", arg0, arg1) + ret0, _ := ret[0].(*api.CommPRet) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientCalcCommP indicates an expected call of ClientCalcCommP +func (mr *MockFullNodeMockRecorder) ClientCalcCommP(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientCalcCommP", reflect.TypeOf((*MockFullNode)(nil).ClientCalcCommP), arg0, arg1) +} + +// ClientCancelDataTransfer mocks base method +func (m *MockFullNode) ClientCancelDataTransfer(arg0 context.Context, arg1 datatransfer.TransferID, arg2 peer.ID, arg3 bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientCancelDataTransfer", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(error) + return ret0 +} + +// ClientCancelDataTransfer indicates an expected call of ClientCancelDataTransfer +func (mr *MockFullNodeMockRecorder) ClientCancelDataTransfer(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientCancelDataTransfer", reflect.TypeOf((*MockFullNode)(nil).ClientCancelDataTransfer), arg0, arg1, arg2, arg3) +} + +// ClientCancelRetrievalDeal mocks base method +func (m *MockFullNode) ClientCancelRetrievalDeal(arg0 context.Context, arg1 retrievalmarket.DealID) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientCancelRetrievalDeal", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ClientCancelRetrievalDeal indicates an expected call of ClientCancelRetrievalDeal +func (mr *MockFullNodeMockRecorder) ClientCancelRetrievalDeal(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientCancelRetrievalDeal", reflect.TypeOf((*MockFullNode)(nil).ClientCancelRetrievalDeal), arg0, arg1) +} + +// ClientDataTransferUpdates mocks base method +func (m *MockFullNode) ClientDataTransferUpdates(arg0 context.Context) (<-chan api.DataTransferChannel, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientDataTransferUpdates", arg0) + ret0, _ := ret[0].(<-chan api.DataTransferChannel) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientDataTransferUpdates indicates an expected call of ClientDataTransferUpdates +func (mr *MockFullNodeMockRecorder) ClientDataTransferUpdates(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientDataTransferUpdates", reflect.TypeOf((*MockFullNode)(nil).ClientDataTransferUpdates), arg0) +} + +// ClientDealPieceCID mocks base method +func (m *MockFullNode) ClientDealPieceCID(arg0 context.Context, arg1 cid.Cid) (api.DataCIDSize, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientDealPieceCID", arg0, arg1) + ret0, _ := ret[0].(api.DataCIDSize) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientDealPieceCID indicates an expected call of ClientDealPieceCID +func (mr *MockFullNodeMockRecorder) ClientDealPieceCID(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientDealPieceCID", reflect.TypeOf((*MockFullNode)(nil).ClientDealPieceCID), arg0, arg1) +} + +// ClientDealSize mocks base method +func (m *MockFullNode) ClientDealSize(arg0 context.Context, arg1 cid.Cid) (api.DataSize, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientDealSize", arg0, arg1) + ret0, _ := ret[0].(api.DataSize) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientDealSize indicates an expected call of ClientDealSize +func (mr *MockFullNodeMockRecorder) ClientDealSize(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientDealSize", reflect.TypeOf((*MockFullNode)(nil).ClientDealSize), arg0, arg1) +} + +// ClientFindData mocks base method +func (m *MockFullNode) ClientFindData(arg0 context.Context, arg1 cid.Cid, arg2 *cid.Cid) ([]api.QueryOffer, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientFindData", arg0, arg1, arg2) + ret0, _ := ret[0].([]api.QueryOffer) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientFindData indicates an expected call of ClientFindData +func (mr *MockFullNodeMockRecorder) ClientFindData(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientFindData", reflect.TypeOf((*MockFullNode)(nil).ClientFindData), arg0, arg1, arg2) +} + +// ClientGenCar mocks base method +func (m *MockFullNode) ClientGenCar(arg0 context.Context, arg1 api.FileRef, arg2 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientGenCar", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// ClientGenCar indicates an expected call of ClientGenCar +func (mr *MockFullNodeMockRecorder) ClientGenCar(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientGenCar", reflect.TypeOf((*MockFullNode)(nil).ClientGenCar), arg0, arg1, arg2) +} + +// ClientGetDealInfo mocks base method +func (m *MockFullNode) ClientGetDealInfo(arg0 context.Context, arg1 cid.Cid) (*api.DealInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientGetDealInfo", arg0, arg1) + ret0, _ := ret[0].(*api.DealInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientGetDealInfo indicates an expected call of ClientGetDealInfo +func (mr *MockFullNodeMockRecorder) ClientGetDealInfo(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientGetDealInfo", reflect.TypeOf((*MockFullNode)(nil).ClientGetDealInfo), arg0, arg1) +} + +// ClientGetDealStatus mocks base method +func (m *MockFullNode) ClientGetDealStatus(arg0 context.Context, arg1 uint64) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientGetDealStatus", arg0, arg1) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientGetDealStatus indicates an expected call of ClientGetDealStatus +func (mr *MockFullNodeMockRecorder) ClientGetDealStatus(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientGetDealStatus", reflect.TypeOf((*MockFullNode)(nil).ClientGetDealStatus), arg0, arg1) +} + +// ClientGetDealUpdates mocks base method +func (m *MockFullNode) ClientGetDealUpdates(arg0 context.Context) (<-chan api.DealInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientGetDealUpdates", arg0) + ret0, _ := ret[0].(<-chan api.DealInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientGetDealUpdates indicates an expected call of ClientGetDealUpdates +func (mr *MockFullNodeMockRecorder) ClientGetDealUpdates(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientGetDealUpdates", reflect.TypeOf((*MockFullNode)(nil).ClientGetDealUpdates), arg0) +} + +// ClientHasLocal mocks base method +func (m *MockFullNode) ClientHasLocal(arg0 context.Context, arg1 cid.Cid) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientHasLocal", arg0, arg1) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientHasLocal indicates an expected call of ClientHasLocal +func (mr *MockFullNodeMockRecorder) ClientHasLocal(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientHasLocal", reflect.TypeOf((*MockFullNode)(nil).ClientHasLocal), arg0, arg1) +} + +// ClientImport mocks base method +func (m *MockFullNode) ClientImport(arg0 context.Context, arg1 api.FileRef) (*api.ImportRes, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientImport", arg0, arg1) + ret0, _ := ret[0].(*api.ImportRes) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientImport indicates an expected call of ClientImport +func (mr *MockFullNodeMockRecorder) ClientImport(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientImport", reflect.TypeOf((*MockFullNode)(nil).ClientImport), arg0, arg1) +} + +// ClientListDataTransfers mocks base method +func (m *MockFullNode) ClientListDataTransfers(arg0 context.Context) ([]api.DataTransferChannel, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientListDataTransfers", arg0) + ret0, _ := ret[0].([]api.DataTransferChannel) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientListDataTransfers indicates an expected call of ClientListDataTransfers +func (mr *MockFullNodeMockRecorder) ClientListDataTransfers(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientListDataTransfers", reflect.TypeOf((*MockFullNode)(nil).ClientListDataTransfers), arg0) +} + +// ClientListDeals mocks base method +func (m *MockFullNode) ClientListDeals(arg0 context.Context) ([]api.DealInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientListDeals", arg0) + ret0, _ := ret[0].([]api.DealInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientListDeals indicates an expected call of ClientListDeals +func (mr *MockFullNodeMockRecorder) ClientListDeals(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientListDeals", reflect.TypeOf((*MockFullNode)(nil).ClientListDeals), arg0) +} + +// ClientListImports mocks base method +func (m *MockFullNode) ClientListImports(arg0 context.Context) ([]api.Import, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientListImports", arg0) + ret0, _ := ret[0].([]api.Import) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientListImports indicates an expected call of ClientListImports +func (mr *MockFullNodeMockRecorder) ClientListImports(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientListImports", reflect.TypeOf((*MockFullNode)(nil).ClientListImports), arg0) +} + +// ClientMinerQueryOffer mocks base method +func (m *MockFullNode) ClientMinerQueryOffer(arg0 context.Context, arg1 address.Address, arg2 cid.Cid, arg3 *cid.Cid) (api.QueryOffer, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientMinerQueryOffer", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(api.QueryOffer) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientMinerQueryOffer indicates an expected call of ClientMinerQueryOffer +func (mr *MockFullNodeMockRecorder) ClientMinerQueryOffer(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientMinerQueryOffer", reflect.TypeOf((*MockFullNode)(nil).ClientMinerQueryOffer), arg0, arg1, arg2, arg3) +} + +// ClientQueryAsk mocks base method +func (m *MockFullNode) ClientQueryAsk(arg0 context.Context, arg1 peer.ID, arg2 address.Address) (*storagemarket.StorageAsk, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientQueryAsk", arg0, arg1, arg2) + ret0, _ := ret[0].(*storagemarket.StorageAsk) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientQueryAsk indicates an expected call of ClientQueryAsk +func (mr *MockFullNodeMockRecorder) ClientQueryAsk(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientQueryAsk", reflect.TypeOf((*MockFullNode)(nil).ClientQueryAsk), arg0, arg1, arg2) +} + +// ClientRemoveImport mocks base method +func (m *MockFullNode) ClientRemoveImport(arg0 context.Context, arg1 multistore.StoreID) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientRemoveImport", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ClientRemoveImport indicates an expected call of ClientRemoveImport +func (mr *MockFullNodeMockRecorder) ClientRemoveImport(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientRemoveImport", reflect.TypeOf((*MockFullNode)(nil).ClientRemoveImport), arg0, arg1) +} + +// ClientRestartDataTransfer mocks base method +func (m *MockFullNode) ClientRestartDataTransfer(arg0 context.Context, arg1 datatransfer.TransferID, arg2 peer.ID, arg3 bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientRestartDataTransfer", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(error) + return ret0 +} + +// ClientRestartDataTransfer indicates an expected call of ClientRestartDataTransfer +func (mr *MockFullNodeMockRecorder) ClientRestartDataTransfer(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientRestartDataTransfer", reflect.TypeOf((*MockFullNode)(nil).ClientRestartDataTransfer), arg0, arg1, arg2, arg3) +} + +// ClientRetrieve mocks base method +func (m *MockFullNode) ClientRetrieve(arg0 context.Context, arg1 api.RetrievalOrder, arg2 *api.FileRef) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientRetrieve", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// ClientRetrieve indicates an expected call of ClientRetrieve +func (mr *MockFullNodeMockRecorder) ClientRetrieve(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientRetrieve", reflect.TypeOf((*MockFullNode)(nil).ClientRetrieve), arg0, arg1, arg2) +} + +// ClientRetrieveTryRestartInsufficientFunds mocks base method +func (m *MockFullNode) ClientRetrieveTryRestartInsufficientFunds(arg0 context.Context, arg1 address.Address) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientRetrieveTryRestartInsufficientFunds", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ClientRetrieveTryRestartInsufficientFunds indicates an expected call of ClientRetrieveTryRestartInsufficientFunds +func (mr *MockFullNodeMockRecorder) ClientRetrieveTryRestartInsufficientFunds(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientRetrieveTryRestartInsufficientFunds", reflect.TypeOf((*MockFullNode)(nil).ClientRetrieveTryRestartInsufficientFunds), arg0, arg1) +} + +// ClientRetrieveWithEvents mocks base method +func (m *MockFullNode) ClientRetrieveWithEvents(arg0 context.Context, arg1 api.RetrievalOrder, arg2 *api.FileRef) (<-chan marketevents.RetrievalEvent, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientRetrieveWithEvents", arg0, arg1, arg2) + ret0, _ := ret[0].(<-chan marketevents.RetrievalEvent) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientRetrieveWithEvents indicates an expected call of ClientRetrieveWithEvents +func (mr *MockFullNodeMockRecorder) ClientRetrieveWithEvents(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientRetrieveWithEvents", reflect.TypeOf((*MockFullNode)(nil).ClientRetrieveWithEvents), arg0, arg1, arg2) +} + +// ClientStartDeal mocks base method +func (m *MockFullNode) ClientStartDeal(arg0 context.Context, arg1 *api.StartDealParams) (*cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientStartDeal", arg0, arg1) + ret0, _ := ret[0].(*cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientStartDeal indicates an expected call of ClientStartDeal +func (mr *MockFullNodeMockRecorder) ClientStartDeal(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientStartDeal", reflect.TypeOf((*MockFullNode)(nil).ClientStartDeal), arg0, arg1) +} + +// Closing mocks base method +func (m *MockFullNode) Closing(arg0 context.Context) (<-chan struct{}, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Closing", arg0) + ret0, _ := ret[0].(<-chan struct{}) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Closing indicates an expected call of Closing +func (mr *MockFullNodeMockRecorder) Closing(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Closing", reflect.TypeOf((*MockFullNode)(nil).Closing), arg0) +} + +// CreateBackup mocks base method +func (m *MockFullNode) CreateBackup(arg0 context.Context, arg1 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateBackup", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// CreateBackup indicates an expected call of CreateBackup +func (mr *MockFullNodeMockRecorder) CreateBackup(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateBackup", reflect.TypeOf((*MockFullNode)(nil).CreateBackup), arg0, arg1) +} + +// Discover mocks base method +func (m *MockFullNode) Discover(arg0 context.Context) (apitypes.OpenRPCDocument, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Discover", arg0) + ret0, _ := ret[0].(apitypes.OpenRPCDocument) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Discover indicates an expected call of Discover +func (mr *MockFullNodeMockRecorder) Discover(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Discover", reflect.TypeOf((*MockFullNode)(nil).Discover), arg0) +} + +// GasEstimateFeeCap mocks base method +func (m *MockFullNode) GasEstimateFeeCap(arg0 context.Context, arg1 *types.Message, arg2 int64, arg3 types.TipSetKey) (big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GasEstimateFeeCap", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GasEstimateFeeCap indicates an expected call of GasEstimateFeeCap +func (mr *MockFullNodeMockRecorder) GasEstimateFeeCap(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GasEstimateFeeCap", reflect.TypeOf((*MockFullNode)(nil).GasEstimateFeeCap), arg0, arg1, arg2, arg3) +} + +// GasEstimateGasLimit mocks base method +func (m *MockFullNode) GasEstimateGasLimit(arg0 context.Context, arg1 *types.Message, arg2 types.TipSetKey) (int64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GasEstimateGasLimit", arg0, arg1, arg2) + ret0, _ := ret[0].(int64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GasEstimateGasLimit indicates an expected call of GasEstimateGasLimit +func (mr *MockFullNodeMockRecorder) GasEstimateGasLimit(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GasEstimateGasLimit", reflect.TypeOf((*MockFullNode)(nil).GasEstimateGasLimit), arg0, arg1, arg2) +} + +// GasEstimateGasPremium mocks base method +func (m *MockFullNode) GasEstimateGasPremium(arg0 context.Context, arg1 uint64, arg2 address.Address, arg3 int64, arg4 types.TipSetKey) (big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GasEstimateGasPremium", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GasEstimateGasPremium indicates an expected call of GasEstimateGasPremium +func (mr *MockFullNodeMockRecorder) GasEstimateGasPremium(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GasEstimateGasPremium", reflect.TypeOf((*MockFullNode)(nil).GasEstimateGasPremium), arg0, arg1, arg2, arg3, arg4) +} + +// GasEstimateMessageGas mocks base method +func (m *MockFullNode) GasEstimateMessageGas(arg0 context.Context, arg1 *types.Message, arg2 *api.MessageSendSpec, arg3 types.TipSetKey) (*types.Message, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GasEstimateMessageGas", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(*types.Message) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GasEstimateMessageGas indicates an expected call of GasEstimateMessageGas +func (mr *MockFullNodeMockRecorder) GasEstimateMessageGas(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GasEstimateMessageGas", reflect.TypeOf((*MockFullNode)(nil).GasEstimateMessageGas), arg0, arg1, arg2, arg3) +} + +// ID mocks base method +func (m *MockFullNode) ID(arg0 context.Context) (peer.ID, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ID", arg0) + ret0, _ := ret[0].(peer.ID) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ID indicates an expected call of ID +func (mr *MockFullNodeMockRecorder) ID(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ID", reflect.TypeOf((*MockFullNode)(nil).ID), arg0) +} + +// LogList mocks base method +func (m *MockFullNode) LogList(arg0 context.Context) ([]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "LogList", arg0) + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// LogList indicates an expected call of LogList +func (mr *MockFullNodeMockRecorder) LogList(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LogList", reflect.TypeOf((*MockFullNode)(nil).LogList), arg0) +} + +// LogSetLevel mocks base method +func (m *MockFullNode) LogSetLevel(arg0 context.Context, arg1, arg2 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "LogSetLevel", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// LogSetLevel indicates an expected call of LogSetLevel +func (mr *MockFullNodeMockRecorder) LogSetLevel(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LogSetLevel", reflect.TypeOf((*MockFullNode)(nil).LogSetLevel), arg0, arg1, arg2) +} + +// MarketAddBalance mocks base method +func (m *MockFullNode) MarketAddBalance(arg0 context.Context, arg1, arg2 address.Address, arg3 big.Int) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MarketAddBalance", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MarketAddBalance indicates an expected call of MarketAddBalance +func (mr *MockFullNodeMockRecorder) MarketAddBalance(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarketAddBalance", reflect.TypeOf((*MockFullNode)(nil).MarketAddBalance), arg0, arg1, arg2, arg3) +} + +// MarketGetReserved mocks base method +func (m *MockFullNode) MarketGetReserved(arg0 context.Context, arg1 address.Address) (big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MarketGetReserved", arg0, arg1) + ret0, _ := ret[0].(big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MarketGetReserved indicates an expected call of MarketGetReserved +func (mr *MockFullNodeMockRecorder) MarketGetReserved(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarketGetReserved", reflect.TypeOf((*MockFullNode)(nil).MarketGetReserved), arg0, arg1) +} + +// MarketReleaseFunds mocks base method +func (m *MockFullNode) MarketReleaseFunds(arg0 context.Context, arg1 address.Address, arg2 big.Int) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MarketReleaseFunds", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// MarketReleaseFunds indicates an expected call of MarketReleaseFunds +func (mr *MockFullNodeMockRecorder) MarketReleaseFunds(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarketReleaseFunds", reflect.TypeOf((*MockFullNode)(nil).MarketReleaseFunds), arg0, arg1, arg2) +} + +// MarketReserveFunds mocks base method +func (m *MockFullNode) MarketReserveFunds(arg0 context.Context, arg1, arg2 address.Address, arg3 big.Int) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MarketReserveFunds", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MarketReserveFunds indicates an expected call of MarketReserveFunds +func (mr *MockFullNodeMockRecorder) MarketReserveFunds(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarketReserveFunds", reflect.TypeOf((*MockFullNode)(nil).MarketReserveFunds), arg0, arg1, arg2, arg3) +} + +// MarketWithdraw mocks base method +func (m *MockFullNode) MarketWithdraw(arg0 context.Context, arg1, arg2 address.Address, arg3 big.Int) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MarketWithdraw", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MarketWithdraw indicates an expected call of MarketWithdraw +func (mr *MockFullNodeMockRecorder) MarketWithdraw(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarketWithdraw", reflect.TypeOf((*MockFullNode)(nil).MarketWithdraw), arg0, arg1, arg2, arg3) +} + +// MinerCreateBlock mocks base method +func (m *MockFullNode) MinerCreateBlock(arg0 context.Context, arg1 *api.BlockTemplate) (*types.BlockMsg, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MinerCreateBlock", arg0, arg1) + ret0, _ := ret[0].(*types.BlockMsg) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MinerCreateBlock indicates an expected call of MinerCreateBlock +func (mr *MockFullNodeMockRecorder) MinerCreateBlock(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MinerCreateBlock", reflect.TypeOf((*MockFullNode)(nil).MinerCreateBlock), arg0, arg1) +} + +// MinerGetBaseInfo mocks base method +func (m *MockFullNode) MinerGetBaseInfo(arg0 context.Context, arg1 address.Address, arg2 abi.ChainEpoch, arg3 types.TipSetKey) (*api.MiningBaseInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MinerGetBaseInfo", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(*api.MiningBaseInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MinerGetBaseInfo indicates an expected call of MinerGetBaseInfo +func (mr *MockFullNodeMockRecorder) MinerGetBaseInfo(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MinerGetBaseInfo", reflect.TypeOf((*MockFullNode)(nil).MinerGetBaseInfo), arg0, arg1, arg2, arg3) +} + +// MpoolBatchPush mocks base method +func (m *MockFullNode) MpoolBatchPush(arg0 context.Context, arg1 []*types.SignedMessage) ([]cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolBatchPush", arg0, arg1) + ret0, _ := ret[0].([]cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MpoolBatchPush indicates an expected call of MpoolBatchPush +func (mr *MockFullNodeMockRecorder) MpoolBatchPush(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolBatchPush", reflect.TypeOf((*MockFullNode)(nil).MpoolBatchPush), arg0, arg1) +} + +// MpoolBatchPushMessage mocks base method +func (m *MockFullNode) MpoolBatchPushMessage(arg0 context.Context, arg1 []*types.Message, arg2 *api.MessageSendSpec) ([]*types.SignedMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolBatchPushMessage", arg0, arg1, arg2) + ret0, _ := ret[0].([]*types.SignedMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MpoolBatchPushMessage indicates an expected call of MpoolBatchPushMessage +func (mr *MockFullNodeMockRecorder) MpoolBatchPushMessage(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolBatchPushMessage", reflect.TypeOf((*MockFullNode)(nil).MpoolBatchPushMessage), arg0, arg1, arg2) +} + +// MpoolBatchPushUntrusted mocks base method +func (m *MockFullNode) MpoolBatchPushUntrusted(arg0 context.Context, arg1 []*types.SignedMessage) ([]cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolBatchPushUntrusted", arg0, arg1) + ret0, _ := ret[0].([]cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MpoolBatchPushUntrusted indicates an expected call of MpoolBatchPushUntrusted +func (mr *MockFullNodeMockRecorder) MpoolBatchPushUntrusted(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolBatchPushUntrusted", reflect.TypeOf((*MockFullNode)(nil).MpoolBatchPushUntrusted), arg0, arg1) +} + +// MpoolClear mocks base method +func (m *MockFullNode) MpoolClear(arg0 context.Context, arg1 bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolClear", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// MpoolClear indicates an expected call of MpoolClear +func (mr *MockFullNodeMockRecorder) MpoolClear(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolClear", reflect.TypeOf((*MockFullNode)(nil).MpoolClear), arg0, arg1) +} + +// MpoolGetConfig mocks base method +func (m *MockFullNode) MpoolGetConfig(arg0 context.Context) (*types.MpoolConfig, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolGetConfig", arg0) + ret0, _ := ret[0].(*types.MpoolConfig) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MpoolGetConfig indicates an expected call of MpoolGetConfig +func (mr *MockFullNodeMockRecorder) MpoolGetConfig(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolGetConfig", reflect.TypeOf((*MockFullNode)(nil).MpoolGetConfig), arg0) +} + +// MpoolGetNonce mocks base method +func (m *MockFullNode) MpoolGetNonce(arg0 context.Context, arg1 address.Address) (uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolGetNonce", arg0, arg1) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MpoolGetNonce indicates an expected call of MpoolGetNonce +func (mr *MockFullNodeMockRecorder) MpoolGetNonce(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolGetNonce", reflect.TypeOf((*MockFullNode)(nil).MpoolGetNonce), arg0, arg1) +} + +// MpoolPending mocks base method +func (m *MockFullNode) MpoolPending(arg0 context.Context, arg1 types.TipSetKey) ([]*types.SignedMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolPending", arg0, arg1) + ret0, _ := ret[0].([]*types.SignedMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MpoolPending indicates an expected call of MpoolPending +func (mr *MockFullNodeMockRecorder) MpoolPending(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolPending", reflect.TypeOf((*MockFullNode)(nil).MpoolPending), arg0, arg1) +} + +// MpoolPush mocks base method +func (m *MockFullNode) MpoolPush(arg0 context.Context, arg1 *types.SignedMessage) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolPush", arg0, arg1) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MpoolPush indicates an expected call of MpoolPush +func (mr *MockFullNodeMockRecorder) MpoolPush(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolPush", reflect.TypeOf((*MockFullNode)(nil).MpoolPush), arg0, arg1) +} + +// MpoolPushMessage mocks base method +func (m *MockFullNode) MpoolPushMessage(arg0 context.Context, arg1 *types.Message, arg2 *api.MessageSendSpec) (*types.SignedMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolPushMessage", arg0, arg1, arg2) + ret0, _ := ret[0].(*types.SignedMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MpoolPushMessage indicates an expected call of MpoolPushMessage +func (mr *MockFullNodeMockRecorder) MpoolPushMessage(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolPushMessage", reflect.TypeOf((*MockFullNode)(nil).MpoolPushMessage), arg0, arg1, arg2) +} + +// MpoolPushUntrusted mocks base method +func (m *MockFullNode) MpoolPushUntrusted(arg0 context.Context, arg1 *types.SignedMessage) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolPushUntrusted", arg0, arg1) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MpoolPushUntrusted indicates an expected call of MpoolPushUntrusted +func (mr *MockFullNodeMockRecorder) MpoolPushUntrusted(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolPushUntrusted", reflect.TypeOf((*MockFullNode)(nil).MpoolPushUntrusted), arg0, arg1) +} + +// MpoolSelect mocks base method +func (m *MockFullNode) MpoolSelect(arg0 context.Context, arg1 types.TipSetKey, arg2 float64) ([]*types.SignedMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolSelect", arg0, arg1, arg2) + ret0, _ := ret[0].([]*types.SignedMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MpoolSelect indicates an expected call of MpoolSelect +func (mr *MockFullNodeMockRecorder) MpoolSelect(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolSelect", reflect.TypeOf((*MockFullNode)(nil).MpoolSelect), arg0, arg1, arg2) +} + +// MpoolSetConfig mocks base method +func (m *MockFullNode) MpoolSetConfig(arg0 context.Context, arg1 *types.MpoolConfig) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolSetConfig", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// MpoolSetConfig indicates an expected call of MpoolSetConfig +func (mr *MockFullNodeMockRecorder) MpoolSetConfig(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolSetConfig", reflect.TypeOf((*MockFullNode)(nil).MpoolSetConfig), arg0, arg1) +} + +// MpoolSub mocks base method +func (m *MockFullNode) MpoolSub(arg0 context.Context) (<-chan api.MpoolUpdate, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolSub", arg0) + ret0, _ := ret[0].(<-chan api.MpoolUpdate) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MpoolSub indicates an expected call of MpoolSub +func (mr *MockFullNodeMockRecorder) MpoolSub(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolSub", reflect.TypeOf((*MockFullNode)(nil).MpoolSub), arg0) +} + +// MsigAddApprove mocks base method +func (m *MockFullNode) MsigAddApprove(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4, arg5 address.Address, arg6 bool) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigAddApprove", arg0, arg1, arg2, arg3, arg4, arg5, arg6) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigAddApprove indicates an expected call of MsigAddApprove +func (mr *MockFullNodeMockRecorder) MsigAddApprove(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigAddApprove", reflect.TypeOf((*MockFullNode)(nil).MsigAddApprove), arg0, arg1, arg2, arg3, arg4, arg5, arg6) +} + +// MsigAddCancel mocks base method +func (m *MockFullNode) MsigAddCancel(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4 address.Address, arg5 bool) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigAddCancel", arg0, arg1, arg2, arg3, arg4, arg5) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigAddCancel indicates an expected call of MsigAddCancel +func (mr *MockFullNodeMockRecorder) MsigAddCancel(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigAddCancel", reflect.TypeOf((*MockFullNode)(nil).MsigAddCancel), arg0, arg1, arg2, arg3, arg4, arg5) +} + +// MsigAddPropose mocks base method +func (m *MockFullNode) MsigAddPropose(arg0 context.Context, arg1, arg2, arg3 address.Address, arg4 bool) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigAddPropose", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigAddPropose indicates an expected call of MsigAddPropose +func (mr *MockFullNodeMockRecorder) MsigAddPropose(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigAddPropose", reflect.TypeOf((*MockFullNode)(nil).MsigAddPropose), arg0, arg1, arg2, arg3, arg4) +} + +// MsigApprove mocks base method +func (m *MockFullNode) MsigApprove(arg0 context.Context, arg1 address.Address, arg2 uint64, arg3 address.Address) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigApprove", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigApprove indicates an expected call of MsigApprove +func (mr *MockFullNodeMockRecorder) MsigApprove(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigApprove", reflect.TypeOf((*MockFullNode)(nil).MsigApprove), arg0, arg1, arg2, arg3) +} + +// MsigApproveTxnHash mocks base method +func (m *MockFullNode) MsigApproveTxnHash(arg0 context.Context, arg1 address.Address, arg2 uint64, arg3, arg4 address.Address, arg5 big.Int, arg6 address.Address, arg7 uint64, arg8 []byte) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigApproveTxnHash", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigApproveTxnHash indicates an expected call of MsigApproveTxnHash +func (mr *MockFullNodeMockRecorder) MsigApproveTxnHash(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigApproveTxnHash", reflect.TypeOf((*MockFullNode)(nil).MsigApproveTxnHash), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) +} + +// MsigCancel mocks base method +func (m *MockFullNode) MsigCancel(arg0 context.Context, arg1 address.Address, arg2 uint64, arg3 address.Address, arg4 big.Int, arg5 address.Address, arg6 uint64, arg7 []byte) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigCancel", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigCancel indicates an expected call of MsigCancel +func (mr *MockFullNodeMockRecorder) MsigCancel(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigCancel", reflect.TypeOf((*MockFullNode)(nil).MsigCancel), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +} + +// MsigCreate mocks base method +func (m *MockFullNode) MsigCreate(arg0 context.Context, arg1 uint64, arg2 []address.Address, arg3 abi.ChainEpoch, arg4 big.Int, arg5 address.Address, arg6 big.Int) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigCreate", arg0, arg1, arg2, arg3, arg4, arg5, arg6) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigCreate indicates an expected call of MsigCreate +func (mr *MockFullNodeMockRecorder) MsigCreate(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigCreate", reflect.TypeOf((*MockFullNode)(nil).MsigCreate), arg0, arg1, arg2, arg3, arg4, arg5, arg6) +} + +// MsigGetAvailableBalance mocks base method +func (m *MockFullNode) MsigGetAvailableBalance(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigGetAvailableBalance", arg0, arg1, arg2) + ret0, _ := ret[0].(big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigGetAvailableBalance indicates an expected call of MsigGetAvailableBalance +func (mr *MockFullNodeMockRecorder) MsigGetAvailableBalance(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigGetAvailableBalance", reflect.TypeOf((*MockFullNode)(nil).MsigGetAvailableBalance), arg0, arg1, arg2) +} + +// MsigGetPending mocks base method +func (m *MockFullNode) MsigGetPending(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) ([]*api.MsigTransaction, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigGetPending", arg0, arg1, arg2) + ret0, _ := ret[0].([]*api.MsigTransaction) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigGetPending indicates an expected call of MsigGetPending +func (mr *MockFullNodeMockRecorder) MsigGetPending(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigGetPending", reflect.TypeOf((*MockFullNode)(nil).MsigGetPending), arg0, arg1, arg2) +} + +// MsigGetVested mocks base method +func (m *MockFullNode) MsigGetVested(arg0 context.Context, arg1 address.Address, arg2, arg3 types.TipSetKey) (big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigGetVested", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigGetVested indicates an expected call of MsigGetVested +func (mr *MockFullNodeMockRecorder) MsigGetVested(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigGetVested", reflect.TypeOf((*MockFullNode)(nil).MsigGetVested), arg0, arg1, arg2, arg3) +} + +// MsigGetVestingSchedule mocks base method +func (m *MockFullNode) MsigGetVestingSchedule(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (api.MsigVesting, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigGetVestingSchedule", arg0, arg1, arg2) + ret0, _ := ret[0].(api.MsigVesting) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigGetVestingSchedule indicates an expected call of MsigGetVestingSchedule +func (mr *MockFullNodeMockRecorder) MsigGetVestingSchedule(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigGetVestingSchedule", reflect.TypeOf((*MockFullNode)(nil).MsigGetVestingSchedule), arg0, arg1, arg2) +} + +// MsigPropose mocks base method +func (m *MockFullNode) MsigPropose(arg0 context.Context, arg1, arg2 address.Address, arg3 big.Int, arg4 address.Address, arg5 uint64, arg6 []byte) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigPropose", arg0, arg1, arg2, arg3, arg4, arg5, arg6) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigPropose indicates an expected call of MsigPropose +func (mr *MockFullNodeMockRecorder) MsigPropose(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigPropose", reflect.TypeOf((*MockFullNode)(nil).MsigPropose), arg0, arg1, arg2, arg3, arg4, arg5, arg6) +} + +// MsigRemoveSigner mocks base method +func (m *MockFullNode) MsigRemoveSigner(arg0 context.Context, arg1, arg2, arg3 address.Address, arg4 bool) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigRemoveSigner", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigRemoveSigner indicates an expected call of MsigRemoveSigner +func (mr *MockFullNodeMockRecorder) MsigRemoveSigner(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigRemoveSigner", reflect.TypeOf((*MockFullNode)(nil).MsigRemoveSigner), arg0, arg1, arg2, arg3, arg4) +} + +// MsigSwapApprove mocks base method +func (m *MockFullNode) MsigSwapApprove(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4, arg5, arg6 address.Address) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigSwapApprove", arg0, arg1, arg2, arg3, arg4, arg5, arg6) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigSwapApprove indicates an expected call of MsigSwapApprove +func (mr *MockFullNodeMockRecorder) MsigSwapApprove(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigSwapApprove", reflect.TypeOf((*MockFullNode)(nil).MsigSwapApprove), arg0, arg1, arg2, arg3, arg4, arg5, arg6) +} + +// MsigSwapCancel mocks base method +func (m *MockFullNode) MsigSwapCancel(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4, arg5 address.Address) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigSwapCancel", arg0, arg1, arg2, arg3, arg4, arg5) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigSwapCancel indicates an expected call of MsigSwapCancel +func (mr *MockFullNodeMockRecorder) MsigSwapCancel(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigSwapCancel", reflect.TypeOf((*MockFullNode)(nil).MsigSwapCancel), arg0, arg1, arg2, arg3, arg4, arg5) +} + +// MsigSwapPropose mocks base method +func (m *MockFullNode) MsigSwapPropose(arg0 context.Context, arg1, arg2, arg3, arg4 address.Address) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsigSwapPropose", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MsigSwapPropose indicates an expected call of MsigSwapPropose +func (mr *MockFullNodeMockRecorder) MsigSwapPropose(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsigSwapPropose", reflect.TypeOf((*MockFullNode)(nil).MsigSwapPropose), arg0, arg1, arg2, arg3, arg4) +} + +// NetAddrsListen mocks base method +func (m *MockFullNode) NetAddrsListen(arg0 context.Context) (peer.AddrInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetAddrsListen", arg0) + ret0, _ := ret[0].(peer.AddrInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NetAddrsListen indicates an expected call of NetAddrsListen +func (mr *MockFullNodeMockRecorder) NetAddrsListen(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetAddrsListen", reflect.TypeOf((*MockFullNode)(nil).NetAddrsListen), arg0) +} + +// NetAgentVersion mocks base method +func (m *MockFullNode) NetAgentVersion(arg0 context.Context, arg1 peer.ID) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetAgentVersion", arg0, arg1) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NetAgentVersion indicates an expected call of NetAgentVersion +func (mr *MockFullNodeMockRecorder) NetAgentVersion(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetAgentVersion", reflect.TypeOf((*MockFullNode)(nil).NetAgentVersion), arg0, arg1) +} + +// NetAutoNatStatus mocks base method +func (m *MockFullNode) NetAutoNatStatus(arg0 context.Context) (api.NatInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetAutoNatStatus", arg0) + ret0, _ := ret[0].(api.NatInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NetAutoNatStatus indicates an expected call of NetAutoNatStatus +func (mr *MockFullNodeMockRecorder) NetAutoNatStatus(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetAutoNatStatus", reflect.TypeOf((*MockFullNode)(nil).NetAutoNatStatus), arg0) +} + +// NetBandwidthStats mocks base method +func (m *MockFullNode) NetBandwidthStats(arg0 context.Context) (metrics.Stats, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetBandwidthStats", arg0) + ret0, _ := ret[0].(metrics.Stats) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NetBandwidthStats indicates an expected call of NetBandwidthStats +func (mr *MockFullNodeMockRecorder) NetBandwidthStats(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetBandwidthStats", reflect.TypeOf((*MockFullNode)(nil).NetBandwidthStats), arg0) +} + +// NetBandwidthStatsByPeer mocks base method +func (m *MockFullNode) NetBandwidthStatsByPeer(arg0 context.Context) (map[string]metrics.Stats, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetBandwidthStatsByPeer", arg0) + ret0, _ := ret[0].(map[string]metrics.Stats) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NetBandwidthStatsByPeer indicates an expected call of NetBandwidthStatsByPeer +func (mr *MockFullNodeMockRecorder) NetBandwidthStatsByPeer(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetBandwidthStatsByPeer", reflect.TypeOf((*MockFullNode)(nil).NetBandwidthStatsByPeer), arg0) +} + +// NetBandwidthStatsByProtocol mocks base method +func (m *MockFullNode) NetBandwidthStatsByProtocol(arg0 context.Context) (map[protocol.ID]metrics.Stats, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetBandwidthStatsByProtocol", arg0) + ret0, _ := ret[0].(map[protocol.ID]metrics.Stats) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NetBandwidthStatsByProtocol indicates an expected call of NetBandwidthStatsByProtocol +func (mr *MockFullNodeMockRecorder) NetBandwidthStatsByProtocol(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetBandwidthStatsByProtocol", reflect.TypeOf((*MockFullNode)(nil).NetBandwidthStatsByProtocol), arg0) +} + +// NetBlockAdd mocks base method +func (m *MockFullNode) NetBlockAdd(arg0 context.Context, arg1 api.NetBlockList) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetBlockAdd", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// NetBlockAdd indicates an expected call of NetBlockAdd +func (mr *MockFullNodeMockRecorder) NetBlockAdd(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetBlockAdd", reflect.TypeOf((*MockFullNode)(nil).NetBlockAdd), arg0, arg1) +} + +// NetBlockList mocks base method +func (m *MockFullNode) NetBlockList(arg0 context.Context) (api.NetBlockList, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetBlockList", arg0) + ret0, _ := ret[0].(api.NetBlockList) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NetBlockList indicates an expected call of NetBlockList +func (mr *MockFullNodeMockRecorder) NetBlockList(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetBlockList", reflect.TypeOf((*MockFullNode)(nil).NetBlockList), arg0) +} + +// NetBlockRemove mocks base method +func (m *MockFullNode) NetBlockRemove(arg0 context.Context, arg1 api.NetBlockList) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetBlockRemove", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// NetBlockRemove indicates an expected call of NetBlockRemove +func (mr *MockFullNodeMockRecorder) NetBlockRemove(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetBlockRemove", reflect.TypeOf((*MockFullNode)(nil).NetBlockRemove), arg0, arg1) +} + +// NetConnect mocks base method +func (m *MockFullNode) NetConnect(arg0 context.Context, arg1 peer.AddrInfo) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetConnect", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// NetConnect indicates an expected call of NetConnect +func (mr *MockFullNodeMockRecorder) NetConnect(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetConnect", reflect.TypeOf((*MockFullNode)(nil).NetConnect), arg0, arg1) +} + +// NetConnectedness mocks base method +func (m *MockFullNode) NetConnectedness(arg0 context.Context, arg1 peer.ID) (network0.Connectedness, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetConnectedness", arg0, arg1) + ret0, _ := ret[0].(network0.Connectedness) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NetConnectedness indicates an expected call of NetConnectedness +func (mr *MockFullNodeMockRecorder) NetConnectedness(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetConnectedness", reflect.TypeOf((*MockFullNode)(nil).NetConnectedness), arg0, arg1) +} + +// NetDisconnect mocks base method +func (m *MockFullNode) NetDisconnect(arg0 context.Context, arg1 peer.ID) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetDisconnect", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// NetDisconnect indicates an expected call of NetDisconnect +func (mr *MockFullNodeMockRecorder) NetDisconnect(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetDisconnect", reflect.TypeOf((*MockFullNode)(nil).NetDisconnect), arg0, arg1) +} + +// NetFindPeer mocks base method +func (m *MockFullNode) NetFindPeer(arg0 context.Context, arg1 peer.ID) (peer.AddrInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetFindPeer", arg0, arg1) + ret0, _ := ret[0].(peer.AddrInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NetFindPeer indicates an expected call of NetFindPeer +func (mr *MockFullNodeMockRecorder) NetFindPeer(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetFindPeer", reflect.TypeOf((*MockFullNode)(nil).NetFindPeer), arg0, arg1) +} + +// NetPeerInfo mocks base method +func (m *MockFullNode) NetPeerInfo(arg0 context.Context, arg1 peer.ID) (*api.ExtendedPeerInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetPeerInfo", arg0, arg1) + ret0, _ := ret[0].(*api.ExtendedPeerInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NetPeerInfo indicates an expected call of NetPeerInfo +func (mr *MockFullNodeMockRecorder) NetPeerInfo(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetPeerInfo", reflect.TypeOf((*MockFullNode)(nil).NetPeerInfo), arg0, arg1) +} + +// NetPeers mocks base method +func (m *MockFullNode) NetPeers(arg0 context.Context) ([]peer.AddrInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetPeers", arg0) + ret0, _ := ret[0].([]peer.AddrInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NetPeers indicates an expected call of NetPeers +func (mr *MockFullNodeMockRecorder) NetPeers(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetPeers", reflect.TypeOf((*MockFullNode)(nil).NetPeers), arg0) +} + +// NetPubsubScores mocks base method +func (m *MockFullNode) NetPubsubScores(arg0 context.Context) ([]api.PubsubScore, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetPubsubScores", arg0) + ret0, _ := ret[0].([]api.PubsubScore) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NetPubsubScores indicates an expected call of NetPubsubScores +func (mr *MockFullNodeMockRecorder) NetPubsubScores(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetPubsubScores", reflect.TypeOf((*MockFullNode)(nil).NetPubsubScores), arg0) +} + +// PaychAllocateLane mocks base method +func (m *MockFullNode) PaychAllocateLane(arg0 context.Context, arg1 address.Address) (uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychAllocateLane", arg0, arg1) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PaychAllocateLane indicates an expected call of PaychAllocateLane +func (mr *MockFullNodeMockRecorder) PaychAllocateLane(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychAllocateLane", reflect.TypeOf((*MockFullNode)(nil).PaychAllocateLane), arg0, arg1) +} + +// PaychAvailableFunds mocks base method +func (m *MockFullNode) PaychAvailableFunds(arg0 context.Context, arg1 address.Address) (*api.ChannelAvailableFunds, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychAvailableFunds", arg0, arg1) + ret0, _ := ret[0].(*api.ChannelAvailableFunds) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PaychAvailableFunds indicates an expected call of PaychAvailableFunds +func (mr *MockFullNodeMockRecorder) PaychAvailableFunds(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychAvailableFunds", reflect.TypeOf((*MockFullNode)(nil).PaychAvailableFunds), arg0, arg1) +} + +// PaychAvailableFundsByFromTo mocks base method +func (m *MockFullNode) PaychAvailableFundsByFromTo(arg0 context.Context, arg1, arg2 address.Address) (*api.ChannelAvailableFunds, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychAvailableFundsByFromTo", arg0, arg1, arg2) + ret0, _ := ret[0].(*api.ChannelAvailableFunds) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PaychAvailableFundsByFromTo indicates an expected call of PaychAvailableFundsByFromTo +func (mr *MockFullNodeMockRecorder) PaychAvailableFundsByFromTo(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychAvailableFundsByFromTo", reflect.TypeOf((*MockFullNode)(nil).PaychAvailableFundsByFromTo), arg0, arg1, arg2) +} + +// PaychCollect mocks base method +func (m *MockFullNode) PaychCollect(arg0 context.Context, arg1 address.Address) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychCollect", arg0, arg1) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PaychCollect indicates an expected call of PaychCollect +func (mr *MockFullNodeMockRecorder) PaychCollect(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychCollect", reflect.TypeOf((*MockFullNode)(nil).PaychCollect), arg0, arg1) +} + +// PaychGet mocks base method +func (m *MockFullNode) PaychGet(arg0 context.Context, arg1, arg2 address.Address, arg3 big.Int) (*api.ChannelInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychGet", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(*api.ChannelInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PaychGet indicates an expected call of PaychGet +func (mr *MockFullNodeMockRecorder) PaychGet(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychGet", reflect.TypeOf((*MockFullNode)(nil).PaychGet), arg0, arg1, arg2, arg3) +} + +// PaychGetWaitReady mocks base method +func (m *MockFullNode) PaychGetWaitReady(arg0 context.Context, arg1 cid.Cid) (address.Address, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychGetWaitReady", arg0, arg1) + ret0, _ := ret[0].(address.Address) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PaychGetWaitReady indicates an expected call of PaychGetWaitReady +func (mr *MockFullNodeMockRecorder) PaychGetWaitReady(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychGetWaitReady", reflect.TypeOf((*MockFullNode)(nil).PaychGetWaitReady), arg0, arg1) +} + +// PaychList mocks base method +func (m *MockFullNode) PaychList(arg0 context.Context) ([]address.Address, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychList", arg0) + ret0, _ := ret[0].([]address.Address) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PaychList indicates an expected call of PaychList +func (mr *MockFullNodeMockRecorder) PaychList(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychList", reflect.TypeOf((*MockFullNode)(nil).PaychList), arg0) +} + +// PaychNewPayment mocks base method +func (m *MockFullNode) PaychNewPayment(arg0 context.Context, arg1, arg2 address.Address, arg3 []api.VoucherSpec) (*api.PaymentInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychNewPayment", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(*api.PaymentInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PaychNewPayment indicates an expected call of PaychNewPayment +func (mr *MockFullNodeMockRecorder) PaychNewPayment(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychNewPayment", reflect.TypeOf((*MockFullNode)(nil).PaychNewPayment), arg0, arg1, arg2, arg3) +} + +// PaychSettle mocks base method +func (m *MockFullNode) PaychSettle(arg0 context.Context, arg1 address.Address) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychSettle", arg0, arg1) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PaychSettle indicates an expected call of PaychSettle +func (mr *MockFullNodeMockRecorder) PaychSettle(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychSettle", reflect.TypeOf((*MockFullNode)(nil).PaychSettle), arg0, arg1) +} + +// PaychStatus mocks base method +func (m *MockFullNode) PaychStatus(arg0 context.Context, arg1 address.Address) (*api.PaychStatus, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychStatus", arg0, arg1) + ret0, _ := ret[0].(*api.PaychStatus) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PaychStatus indicates an expected call of PaychStatus +func (mr *MockFullNodeMockRecorder) PaychStatus(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychStatus", reflect.TypeOf((*MockFullNode)(nil).PaychStatus), arg0, arg1) +} + +// PaychVoucherAdd mocks base method +func (m *MockFullNode) PaychVoucherAdd(arg0 context.Context, arg1 address.Address, arg2 *paych.SignedVoucher, arg3 []byte, arg4 big.Int) (big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychVoucherAdd", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PaychVoucherAdd indicates an expected call of PaychVoucherAdd +func (mr *MockFullNodeMockRecorder) PaychVoucherAdd(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychVoucherAdd", reflect.TypeOf((*MockFullNode)(nil).PaychVoucherAdd), arg0, arg1, arg2, arg3, arg4) +} + +// PaychVoucherCheckSpendable mocks base method +func (m *MockFullNode) PaychVoucherCheckSpendable(arg0 context.Context, arg1 address.Address, arg2 *paych.SignedVoucher, arg3, arg4 []byte) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychVoucherCheckSpendable", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PaychVoucherCheckSpendable indicates an expected call of PaychVoucherCheckSpendable +func (mr *MockFullNodeMockRecorder) PaychVoucherCheckSpendable(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychVoucherCheckSpendable", reflect.TypeOf((*MockFullNode)(nil).PaychVoucherCheckSpendable), arg0, arg1, arg2, arg3, arg4) +} + +// PaychVoucherCheckValid mocks base method +func (m *MockFullNode) PaychVoucherCheckValid(arg0 context.Context, arg1 address.Address, arg2 *paych.SignedVoucher) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychVoucherCheckValid", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// PaychVoucherCheckValid indicates an expected call of PaychVoucherCheckValid +func (mr *MockFullNodeMockRecorder) PaychVoucherCheckValid(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychVoucherCheckValid", reflect.TypeOf((*MockFullNode)(nil).PaychVoucherCheckValid), arg0, arg1, arg2) +} + +// PaychVoucherCreate mocks base method +func (m *MockFullNode) PaychVoucherCreate(arg0 context.Context, arg1 address.Address, arg2 big.Int, arg3 uint64) (*api.VoucherCreateResult, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychVoucherCreate", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(*api.VoucherCreateResult) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PaychVoucherCreate indicates an expected call of PaychVoucherCreate +func (mr *MockFullNodeMockRecorder) PaychVoucherCreate(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychVoucherCreate", reflect.TypeOf((*MockFullNode)(nil).PaychVoucherCreate), arg0, arg1, arg2, arg3) +} + +// PaychVoucherList mocks base method +func (m *MockFullNode) PaychVoucherList(arg0 context.Context, arg1 address.Address) ([]*paych.SignedVoucher, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychVoucherList", arg0, arg1) + ret0, _ := ret[0].([]*paych.SignedVoucher) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PaychVoucherList indicates an expected call of PaychVoucherList +func (mr *MockFullNodeMockRecorder) PaychVoucherList(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychVoucherList", reflect.TypeOf((*MockFullNode)(nil).PaychVoucherList), arg0, arg1) +} + +// PaychVoucherSubmit mocks base method +func (m *MockFullNode) PaychVoucherSubmit(arg0 context.Context, arg1 address.Address, arg2 *paych.SignedVoucher, arg3, arg4 []byte) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PaychVoucherSubmit", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PaychVoucherSubmit indicates an expected call of PaychVoucherSubmit +func (mr *MockFullNodeMockRecorder) PaychVoucherSubmit(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychVoucherSubmit", reflect.TypeOf((*MockFullNode)(nil).PaychVoucherSubmit), arg0, arg1, arg2, arg3, arg4) +} + +// Session mocks base method +func (m *MockFullNode) Session(arg0 context.Context) (uuid.UUID, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Session", arg0) + ret0, _ := ret[0].(uuid.UUID) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Session indicates an expected call of Session +func (mr *MockFullNodeMockRecorder) Session(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Session", reflect.TypeOf((*MockFullNode)(nil).Session), arg0) +} + +// Shutdown mocks base method +func (m *MockFullNode) Shutdown(arg0 context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Shutdown", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// Shutdown indicates an expected call of Shutdown +func (mr *MockFullNodeMockRecorder) Shutdown(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Shutdown", reflect.TypeOf((*MockFullNode)(nil).Shutdown), arg0) +} + +// StateAccountKey mocks base method +func (m *MockFullNode) StateAccountKey(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (address.Address, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateAccountKey", arg0, arg1, arg2) + ret0, _ := ret[0].(address.Address) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateAccountKey indicates an expected call of StateAccountKey +func (mr *MockFullNodeMockRecorder) StateAccountKey(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateAccountKey", reflect.TypeOf((*MockFullNode)(nil).StateAccountKey), arg0, arg1, arg2) +} + +// StateAllMinerFaults mocks base method +func (m *MockFullNode) StateAllMinerFaults(arg0 context.Context, arg1 abi.ChainEpoch, arg2 types.TipSetKey) ([]*api.Fault, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateAllMinerFaults", arg0, arg1, arg2) + ret0, _ := ret[0].([]*api.Fault) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateAllMinerFaults indicates an expected call of StateAllMinerFaults +func (mr *MockFullNodeMockRecorder) StateAllMinerFaults(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateAllMinerFaults", reflect.TypeOf((*MockFullNode)(nil).StateAllMinerFaults), arg0, arg1, arg2) +} + +// StateCall mocks base method +func (m *MockFullNode) StateCall(arg0 context.Context, arg1 *types.Message, arg2 types.TipSetKey) (*api.InvocResult, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateCall", arg0, arg1, arg2) + ret0, _ := ret[0].(*api.InvocResult) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateCall indicates an expected call of StateCall +func (mr *MockFullNodeMockRecorder) StateCall(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateCall", reflect.TypeOf((*MockFullNode)(nil).StateCall), arg0, arg1, arg2) +} + +// StateChangedActors mocks base method +func (m *MockFullNode) StateChangedActors(arg0 context.Context, arg1, arg2 cid.Cid) (map[string]types.Actor, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateChangedActors", arg0, arg1, arg2) + ret0, _ := ret[0].(map[string]types.Actor) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateChangedActors indicates an expected call of StateChangedActors +func (mr *MockFullNodeMockRecorder) StateChangedActors(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateChangedActors", reflect.TypeOf((*MockFullNode)(nil).StateChangedActors), arg0, arg1, arg2) +} + +// StateCirculatingSupply mocks base method +func (m *MockFullNode) StateCirculatingSupply(arg0 context.Context, arg1 types.TipSetKey) (big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateCirculatingSupply", arg0, arg1) + ret0, _ := ret[0].(big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateCirculatingSupply indicates an expected call of StateCirculatingSupply +func (mr *MockFullNodeMockRecorder) StateCirculatingSupply(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateCirculatingSupply", reflect.TypeOf((*MockFullNode)(nil).StateCirculatingSupply), arg0, arg1) +} + +// StateCompute mocks base method +func (m *MockFullNode) StateCompute(arg0 context.Context, arg1 abi.ChainEpoch, arg2 []*types.Message, arg3 types.TipSetKey) (*api.ComputeStateOutput, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateCompute", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(*api.ComputeStateOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateCompute indicates an expected call of StateCompute +func (mr *MockFullNodeMockRecorder) StateCompute(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateCompute", reflect.TypeOf((*MockFullNode)(nil).StateCompute), arg0, arg1, arg2, arg3) +} + +// StateDealProviderCollateralBounds mocks base method +func (m *MockFullNode) StateDealProviderCollateralBounds(arg0 context.Context, arg1 abi.PaddedPieceSize, arg2 bool, arg3 types.TipSetKey) (api.DealCollateralBounds, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateDealProviderCollateralBounds", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(api.DealCollateralBounds) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateDealProviderCollateralBounds indicates an expected call of StateDealProviderCollateralBounds +func (mr *MockFullNodeMockRecorder) StateDealProviderCollateralBounds(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateDealProviderCollateralBounds", reflect.TypeOf((*MockFullNode)(nil).StateDealProviderCollateralBounds), arg0, arg1, arg2, arg3) +} + +// StateDecodeParams mocks base method +func (m *MockFullNode) StateDecodeParams(arg0 context.Context, arg1 address.Address, arg2 abi.MethodNum, arg3 []byte, arg4 types.TipSetKey) (interface{}, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateDecodeParams", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(interface{}) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateDecodeParams indicates an expected call of StateDecodeParams +func (mr *MockFullNodeMockRecorder) StateDecodeParams(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateDecodeParams", reflect.TypeOf((*MockFullNode)(nil).StateDecodeParams), arg0, arg1, arg2, arg3, arg4) +} + +// StateGetActor mocks base method +func (m *MockFullNode) StateGetActor(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (*types.Actor, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateGetActor", arg0, arg1, arg2) + ret0, _ := ret[0].(*types.Actor) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateGetActor indicates an expected call of StateGetActor +func (mr *MockFullNodeMockRecorder) StateGetActor(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateGetActor", reflect.TypeOf((*MockFullNode)(nil).StateGetActor), arg0, arg1, arg2) +} + +// StateGetReceipt mocks base method +func (m *MockFullNode) StateGetReceipt(arg0 context.Context, arg1 cid.Cid, arg2 types.TipSetKey) (*types.MessageReceipt, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateGetReceipt", arg0, arg1, arg2) + ret0, _ := ret[0].(*types.MessageReceipt) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateGetReceipt indicates an expected call of StateGetReceipt +func (mr *MockFullNodeMockRecorder) StateGetReceipt(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateGetReceipt", reflect.TypeOf((*MockFullNode)(nil).StateGetReceipt), arg0, arg1, arg2) +} + +// StateListActors mocks base method +func (m *MockFullNode) StateListActors(arg0 context.Context, arg1 types.TipSetKey) ([]address.Address, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateListActors", arg0, arg1) + ret0, _ := ret[0].([]address.Address) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateListActors indicates an expected call of StateListActors +func (mr *MockFullNodeMockRecorder) StateListActors(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateListActors", reflect.TypeOf((*MockFullNode)(nil).StateListActors), arg0, arg1) +} + +// StateListMessages mocks base method +func (m *MockFullNode) StateListMessages(arg0 context.Context, arg1 *api.MessageMatch, arg2 types.TipSetKey, arg3 abi.ChainEpoch) ([]cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateListMessages", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].([]cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateListMessages indicates an expected call of StateListMessages +func (mr *MockFullNodeMockRecorder) StateListMessages(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateListMessages", reflect.TypeOf((*MockFullNode)(nil).StateListMessages), arg0, arg1, arg2, arg3) +} + +// StateListMiners mocks base method +func (m *MockFullNode) StateListMiners(arg0 context.Context, arg1 types.TipSetKey) ([]address.Address, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateListMiners", arg0, arg1) + ret0, _ := ret[0].([]address.Address) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateListMiners indicates an expected call of StateListMiners +func (mr *MockFullNodeMockRecorder) StateListMiners(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateListMiners", reflect.TypeOf((*MockFullNode)(nil).StateListMiners), arg0, arg1) +} + +// StateLookupID mocks base method +func (m *MockFullNode) StateLookupID(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (address.Address, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateLookupID", arg0, arg1, arg2) + ret0, _ := ret[0].(address.Address) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateLookupID indicates an expected call of StateLookupID +func (mr *MockFullNodeMockRecorder) StateLookupID(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateLookupID", reflect.TypeOf((*MockFullNode)(nil).StateLookupID), arg0, arg1, arg2) +} + +// StateMarketBalance mocks base method +func (m *MockFullNode) StateMarketBalance(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (api.MarketBalance, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMarketBalance", arg0, arg1, arg2) + ret0, _ := ret[0].(api.MarketBalance) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMarketBalance indicates an expected call of StateMarketBalance +func (mr *MockFullNodeMockRecorder) StateMarketBalance(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMarketBalance", reflect.TypeOf((*MockFullNode)(nil).StateMarketBalance), arg0, arg1, arg2) +} + +// StateMarketDeals mocks base method +func (m *MockFullNode) StateMarketDeals(arg0 context.Context, arg1 types.TipSetKey) (map[string]api.MarketDeal, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMarketDeals", arg0, arg1) + ret0, _ := ret[0].(map[string]api.MarketDeal) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMarketDeals indicates an expected call of StateMarketDeals +func (mr *MockFullNodeMockRecorder) StateMarketDeals(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMarketDeals", reflect.TypeOf((*MockFullNode)(nil).StateMarketDeals), arg0, arg1) +} + +// StateMarketParticipants mocks base method +func (m *MockFullNode) StateMarketParticipants(arg0 context.Context, arg1 types.TipSetKey) (map[string]api.MarketBalance, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMarketParticipants", arg0, arg1) + ret0, _ := ret[0].(map[string]api.MarketBalance) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMarketParticipants indicates an expected call of StateMarketParticipants +func (mr *MockFullNodeMockRecorder) StateMarketParticipants(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMarketParticipants", reflect.TypeOf((*MockFullNode)(nil).StateMarketParticipants), arg0, arg1) +} + +// StateMarketStorageDeal mocks base method +func (m *MockFullNode) StateMarketStorageDeal(arg0 context.Context, arg1 abi.DealID, arg2 types.TipSetKey) (*api.MarketDeal, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMarketStorageDeal", arg0, arg1, arg2) + ret0, _ := ret[0].(*api.MarketDeal) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMarketStorageDeal indicates an expected call of StateMarketStorageDeal +func (mr *MockFullNodeMockRecorder) StateMarketStorageDeal(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMarketStorageDeal", reflect.TypeOf((*MockFullNode)(nil).StateMarketStorageDeal), arg0, arg1, arg2) +} + +// StateMinerActiveSectors mocks base method +func (m *MockFullNode) StateMinerActiveSectors(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMinerActiveSectors", arg0, arg1, arg2) + ret0, _ := ret[0].([]*miner.SectorOnChainInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMinerActiveSectors indicates an expected call of StateMinerActiveSectors +func (mr *MockFullNodeMockRecorder) StateMinerActiveSectors(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerActiveSectors", reflect.TypeOf((*MockFullNode)(nil).StateMinerActiveSectors), arg0, arg1, arg2) +} + +// StateMinerAvailableBalance mocks base method +func (m *MockFullNode) StateMinerAvailableBalance(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMinerAvailableBalance", arg0, arg1, arg2) + ret0, _ := ret[0].(big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMinerAvailableBalance indicates an expected call of StateMinerAvailableBalance +func (mr *MockFullNodeMockRecorder) StateMinerAvailableBalance(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerAvailableBalance", reflect.TypeOf((*MockFullNode)(nil).StateMinerAvailableBalance), arg0, arg1, arg2) +} + +// StateMinerDeadlines mocks base method +func (m *MockFullNode) StateMinerDeadlines(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) ([]api.Deadline, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMinerDeadlines", arg0, arg1, arg2) + ret0, _ := ret[0].([]api.Deadline) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMinerDeadlines indicates an expected call of StateMinerDeadlines +func (mr *MockFullNodeMockRecorder) StateMinerDeadlines(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerDeadlines", reflect.TypeOf((*MockFullNode)(nil).StateMinerDeadlines), arg0, arg1, arg2) +} + +// StateMinerFaults mocks base method +func (m *MockFullNode) StateMinerFaults(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (bitfield.BitField, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMinerFaults", arg0, arg1, arg2) + ret0, _ := ret[0].(bitfield.BitField) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMinerFaults indicates an expected call of StateMinerFaults +func (mr *MockFullNodeMockRecorder) StateMinerFaults(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerFaults", reflect.TypeOf((*MockFullNode)(nil).StateMinerFaults), arg0, arg1, arg2) +} + +// StateMinerInfo mocks base method +func (m *MockFullNode) StateMinerInfo(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (miner.MinerInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMinerInfo", arg0, arg1, arg2) + ret0, _ := ret[0].(miner.MinerInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMinerInfo indicates an expected call of StateMinerInfo +func (mr *MockFullNodeMockRecorder) StateMinerInfo(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerInfo", reflect.TypeOf((*MockFullNode)(nil).StateMinerInfo), arg0, arg1, arg2) +} + +// StateMinerInitialPledgeCollateral mocks base method +func (m *MockFullNode) StateMinerInitialPledgeCollateral(arg0 context.Context, arg1 address.Address, arg2 miner0.SectorPreCommitInfo, arg3 types.TipSetKey) (big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMinerInitialPledgeCollateral", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMinerInitialPledgeCollateral indicates an expected call of StateMinerInitialPledgeCollateral +func (mr *MockFullNodeMockRecorder) StateMinerInitialPledgeCollateral(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerInitialPledgeCollateral", reflect.TypeOf((*MockFullNode)(nil).StateMinerInitialPledgeCollateral), arg0, arg1, arg2, arg3) +} + +// StateMinerPartitions mocks base method +func (m *MockFullNode) StateMinerPartitions(arg0 context.Context, arg1 address.Address, arg2 uint64, arg3 types.TipSetKey) ([]api.Partition, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMinerPartitions", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].([]api.Partition) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMinerPartitions indicates an expected call of StateMinerPartitions +func (mr *MockFullNodeMockRecorder) StateMinerPartitions(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerPartitions", reflect.TypeOf((*MockFullNode)(nil).StateMinerPartitions), arg0, arg1, arg2, arg3) +} + +// StateMinerPower mocks base method +func (m *MockFullNode) StateMinerPower(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (*api.MinerPower, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMinerPower", arg0, arg1, arg2) + ret0, _ := ret[0].(*api.MinerPower) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMinerPower indicates an expected call of StateMinerPower +func (mr *MockFullNodeMockRecorder) StateMinerPower(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerPower", reflect.TypeOf((*MockFullNode)(nil).StateMinerPower), arg0, arg1, arg2) +} + +// StateMinerPreCommitDepositForPower mocks base method +func (m *MockFullNode) StateMinerPreCommitDepositForPower(arg0 context.Context, arg1 address.Address, arg2 miner0.SectorPreCommitInfo, arg3 types.TipSetKey) (big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMinerPreCommitDepositForPower", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMinerPreCommitDepositForPower indicates an expected call of StateMinerPreCommitDepositForPower +func (mr *MockFullNodeMockRecorder) StateMinerPreCommitDepositForPower(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerPreCommitDepositForPower", reflect.TypeOf((*MockFullNode)(nil).StateMinerPreCommitDepositForPower), arg0, arg1, arg2, arg3) +} + +// StateMinerProvingDeadline mocks base method +func (m *MockFullNode) StateMinerProvingDeadline(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (*dline.Info, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMinerProvingDeadline", arg0, arg1, arg2) + ret0, _ := ret[0].(*dline.Info) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMinerProvingDeadline indicates an expected call of StateMinerProvingDeadline +func (mr *MockFullNodeMockRecorder) StateMinerProvingDeadline(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerProvingDeadline", reflect.TypeOf((*MockFullNode)(nil).StateMinerProvingDeadline), arg0, arg1, arg2) +} + +// StateMinerRecoveries mocks base method +func (m *MockFullNode) StateMinerRecoveries(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (bitfield.BitField, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMinerRecoveries", arg0, arg1, arg2) + ret0, _ := ret[0].(bitfield.BitField) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMinerRecoveries indicates an expected call of StateMinerRecoveries +func (mr *MockFullNodeMockRecorder) StateMinerRecoveries(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerRecoveries", reflect.TypeOf((*MockFullNode)(nil).StateMinerRecoveries), arg0, arg1, arg2) +} + +// StateMinerSectorAllocated mocks base method +func (m *MockFullNode) StateMinerSectorAllocated(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types.TipSetKey) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMinerSectorAllocated", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMinerSectorAllocated indicates an expected call of StateMinerSectorAllocated +func (mr *MockFullNodeMockRecorder) StateMinerSectorAllocated(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerSectorAllocated", reflect.TypeOf((*MockFullNode)(nil).StateMinerSectorAllocated), arg0, arg1, arg2, arg3) +} + +// StateMinerSectorCount mocks base method +func (m *MockFullNode) StateMinerSectorCount(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (api.MinerSectors, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMinerSectorCount", arg0, arg1, arg2) + ret0, _ := ret[0].(api.MinerSectors) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMinerSectorCount indicates an expected call of StateMinerSectorCount +func (mr *MockFullNodeMockRecorder) StateMinerSectorCount(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerSectorCount", reflect.TypeOf((*MockFullNode)(nil).StateMinerSectorCount), arg0, arg1, arg2) +} + +// StateMinerSectors mocks base method +func (m *MockFullNode) StateMinerSectors(arg0 context.Context, arg1 address.Address, arg2 *bitfield.BitField, arg3 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateMinerSectors", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].([]*miner.SectorOnChainInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateMinerSectors indicates an expected call of StateMinerSectors +func (mr *MockFullNodeMockRecorder) StateMinerSectors(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerSectors", reflect.TypeOf((*MockFullNode)(nil).StateMinerSectors), arg0, arg1, arg2, arg3) +} + +// StateNetworkName mocks base method +func (m *MockFullNode) StateNetworkName(arg0 context.Context) (dtypes.NetworkName, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateNetworkName", arg0) + ret0, _ := ret[0].(dtypes.NetworkName) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateNetworkName indicates an expected call of StateNetworkName +func (mr *MockFullNodeMockRecorder) StateNetworkName(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateNetworkName", reflect.TypeOf((*MockFullNode)(nil).StateNetworkName), arg0) +} + +// StateNetworkVersion mocks base method +func (m *MockFullNode) StateNetworkVersion(arg0 context.Context, arg1 types.TipSetKey) (network.Version, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateNetworkVersion", arg0, arg1) + ret0, _ := ret[0].(network.Version) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateNetworkVersion indicates an expected call of StateNetworkVersion +func (mr *MockFullNodeMockRecorder) StateNetworkVersion(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateNetworkVersion", reflect.TypeOf((*MockFullNode)(nil).StateNetworkVersion), arg0, arg1) +} + +// StateReadState mocks base method +func (m *MockFullNode) StateReadState(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (*api.ActorState, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateReadState", arg0, arg1, arg2) + ret0, _ := ret[0].(*api.ActorState) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateReadState indicates an expected call of StateReadState +func (mr *MockFullNodeMockRecorder) StateReadState(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateReadState", reflect.TypeOf((*MockFullNode)(nil).StateReadState), arg0, arg1, arg2) +} + +// StateReplay mocks base method +func (m *MockFullNode) StateReplay(arg0 context.Context, arg1 types.TipSetKey, arg2 cid.Cid) (*api.InvocResult, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateReplay", arg0, arg1, arg2) + ret0, _ := ret[0].(*api.InvocResult) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateReplay indicates an expected call of StateReplay +func (mr *MockFullNodeMockRecorder) StateReplay(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateReplay", reflect.TypeOf((*MockFullNode)(nil).StateReplay), arg0, arg1, arg2) +} + +// StateSearchMsg mocks base method +func (m *MockFullNode) StateSearchMsg(arg0 context.Context, arg1 cid.Cid) (*api.MsgLookup, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateSearchMsg", arg0, arg1) + ret0, _ := ret[0].(*api.MsgLookup) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateSearchMsg indicates an expected call of StateSearchMsg +func (mr *MockFullNodeMockRecorder) StateSearchMsg(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSearchMsg", reflect.TypeOf((*MockFullNode)(nil).StateSearchMsg), arg0, arg1) +} + +// StateSearchMsgLimited mocks base method +func (m *MockFullNode) StateSearchMsgLimited(arg0 context.Context, arg1 cid.Cid, arg2 abi.ChainEpoch) (*api.MsgLookup, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateSearchMsgLimited", arg0, arg1, arg2) + ret0, _ := ret[0].(*api.MsgLookup) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateSearchMsgLimited indicates an expected call of StateSearchMsgLimited +func (mr *MockFullNodeMockRecorder) StateSearchMsgLimited(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSearchMsgLimited", reflect.TypeOf((*MockFullNode)(nil).StateSearchMsgLimited), arg0, arg1, arg2) +} + +// StateSectorExpiration mocks base method +func (m *MockFullNode) StateSectorExpiration(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types.TipSetKey) (*miner.SectorExpiration, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateSectorExpiration", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(*miner.SectorExpiration) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateSectorExpiration indicates an expected call of StateSectorExpiration +func (mr *MockFullNodeMockRecorder) StateSectorExpiration(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSectorExpiration", reflect.TypeOf((*MockFullNode)(nil).StateSectorExpiration), arg0, arg1, arg2, arg3) +} + +// StateSectorGetInfo mocks base method +func (m *MockFullNode) StateSectorGetInfo(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateSectorGetInfo", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(*miner.SectorOnChainInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateSectorGetInfo indicates an expected call of StateSectorGetInfo +func (mr *MockFullNodeMockRecorder) StateSectorGetInfo(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSectorGetInfo", reflect.TypeOf((*MockFullNode)(nil).StateSectorGetInfo), arg0, arg1, arg2, arg3) +} + +// StateSectorPartition mocks base method +func (m *MockFullNode) StateSectorPartition(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types.TipSetKey) (*miner.SectorLocation, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateSectorPartition", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(*miner.SectorLocation) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateSectorPartition indicates an expected call of StateSectorPartition +func (mr *MockFullNodeMockRecorder) StateSectorPartition(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSectorPartition", reflect.TypeOf((*MockFullNode)(nil).StateSectorPartition), arg0, arg1, arg2, arg3) +} + +// StateSectorPreCommitInfo mocks base method +func (m *MockFullNode) StateSectorPreCommitInfo(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateSectorPreCommitInfo", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(miner.SectorPreCommitOnChainInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateSectorPreCommitInfo indicates an expected call of StateSectorPreCommitInfo +func (mr *MockFullNodeMockRecorder) StateSectorPreCommitInfo(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSectorPreCommitInfo", reflect.TypeOf((*MockFullNode)(nil).StateSectorPreCommitInfo), arg0, arg1, arg2, arg3) +} + +// StateVMCirculatingSupplyInternal mocks base method +func (m *MockFullNode) StateVMCirculatingSupplyInternal(arg0 context.Context, arg1 types.TipSetKey) (api.CirculatingSupply, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateVMCirculatingSupplyInternal", arg0, arg1) + ret0, _ := ret[0].(api.CirculatingSupply) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateVMCirculatingSupplyInternal indicates an expected call of StateVMCirculatingSupplyInternal +func (mr *MockFullNodeMockRecorder) StateVMCirculatingSupplyInternal(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateVMCirculatingSupplyInternal", reflect.TypeOf((*MockFullNode)(nil).StateVMCirculatingSupplyInternal), arg0, arg1) +} + +// StateVerifiedClientStatus mocks base method +func (m *MockFullNode) StateVerifiedClientStatus(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (*big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateVerifiedClientStatus", arg0, arg1, arg2) + ret0, _ := ret[0].(*big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateVerifiedClientStatus indicates an expected call of StateVerifiedClientStatus +func (mr *MockFullNodeMockRecorder) StateVerifiedClientStatus(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateVerifiedClientStatus", reflect.TypeOf((*MockFullNode)(nil).StateVerifiedClientStatus), arg0, arg1, arg2) +} + +// StateVerifiedRegistryRootKey mocks base method +func (m *MockFullNode) StateVerifiedRegistryRootKey(arg0 context.Context, arg1 types.TipSetKey) (address.Address, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateVerifiedRegistryRootKey", arg0, arg1) + ret0, _ := ret[0].(address.Address) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateVerifiedRegistryRootKey indicates an expected call of StateVerifiedRegistryRootKey +func (mr *MockFullNodeMockRecorder) StateVerifiedRegistryRootKey(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateVerifiedRegistryRootKey", reflect.TypeOf((*MockFullNode)(nil).StateVerifiedRegistryRootKey), arg0, arg1) +} + +// StateVerifierStatus mocks base method +func (m *MockFullNode) StateVerifierStatus(arg0 context.Context, arg1 address.Address, arg2 types.TipSetKey) (*big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateVerifierStatus", arg0, arg1, arg2) + ret0, _ := ret[0].(*big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateVerifierStatus indicates an expected call of StateVerifierStatus +func (mr *MockFullNodeMockRecorder) StateVerifierStatus(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateVerifierStatus", reflect.TypeOf((*MockFullNode)(nil).StateVerifierStatus), arg0, arg1, arg2) +} + +// StateWaitMsg mocks base method +func (m *MockFullNode) StateWaitMsg(arg0 context.Context, arg1 cid.Cid, arg2 uint64) (*api.MsgLookup, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateWaitMsg", arg0, arg1, arg2) + ret0, _ := ret[0].(*api.MsgLookup) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateWaitMsg indicates an expected call of StateWaitMsg +func (mr *MockFullNodeMockRecorder) StateWaitMsg(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateWaitMsg", reflect.TypeOf((*MockFullNode)(nil).StateWaitMsg), arg0, arg1, arg2) +} + +// StateWaitMsgLimited mocks base method +func (m *MockFullNode) StateWaitMsgLimited(arg0 context.Context, arg1 cid.Cid, arg2 uint64, arg3 abi.ChainEpoch) (*api.MsgLookup, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateWaitMsgLimited", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(*api.MsgLookup) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateWaitMsgLimited indicates an expected call of StateWaitMsgLimited +func (mr *MockFullNodeMockRecorder) StateWaitMsgLimited(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateWaitMsgLimited", reflect.TypeOf((*MockFullNode)(nil).StateWaitMsgLimited), arg0, arg1, arg2, arg3) +} + +// SyncCheckBad mocks base method +func (m *MockFullNode) SyncCheckBad(arg0 context.Context, arg1 cid.Cid) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SyncCheckBad", arg0, arg1) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SyncCheckBad indicates an expected call of SyncCheckBad +func (mr *MockFullNodeMockRecorder) SyncCheckBad(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncCheckBad", reflect.TypeOf((*MockFullNode)(nil).SyncCheckBad), arg0, arg1) +} + +// SyncCheckpoint mocks base method +func (m *MockFullNode) SyncCheckpoint(arg0 context.Context, arg1 types.TipSetKey) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SyncCheckpoint", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// SyncCheckpoint indicates an expected call of SyncCheckpoint +func (mr *MockFullNodeMockRecorder) SyncCheckpoint(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncCheckpoint", reflect.TypeOf((*MockFullNode)(nil).SyncCheckpoint), arg0, arg1) +} + +// SyncIncomingBlocks mocks base method +func (m *MockFullNode) SyncIncomingBlocks(arg0 context.Context) (<-chan *types.BlockHeader, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SyncIncomingBlocks", arg0) + ret0, _ := ret[0].(<-chan *types.BlockHeader) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SyncIncomingBlocks indicates an expected call of SyncIncomingBlocks +func (mr *MockFullNodeMockRecorder) SyncIncomingBlocks(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncIncomingBlocks", reflect.TypeOf((*MockFullNode)(nil).SyncIncomingBlocks), arg0) +} + +// SyncMarkBad mocks base method +func (m *MockFullNode) SyncMarkBad(arg0 context.Context, arg1 cid.Cid) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SyncMarkBad", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// SyncMarkBad indicates an expected call of SyncMarkBad +func (mr *MockFullNodeMockRecorder) SyncMarkBad(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncMarkBad", reflect.TypeOf((*MockFullNode)(nil).SyncMarkBad), arg0, arg1) +} + +// SyncState mocks base method +func (m *MockFullNode) SyncState(arg0 context.Context) (*api.SyncState, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SyncState", arg0) + ret0, _ := ret[0].(*api.SyncState) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SyncState indicates an expected call of SyncState +func (mr *MockFullNodeMockRecorder) SyncState(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncState", reflect.TypeOf((*MockFullNode)(nil).SyncState), arg0) +} + +// SyncSubmitBlock mocks base method +func (m *MockFullNode) SyncSubmitBlock(arg0 context.Context, arg1 *types.BlockMsg) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SyncSubmitBlock", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// SyncSubmitBlock indicates an expected call of SyncSubmitBlock +func (mr *MockFullNodeMockRecorder) SyncSubmitBlock(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncSubmitBlock", reflect.TypeOf((*MockFullNode)(nil).SyncSubmitBlock), arg0, arg1) +} + +// SyncUnmarkAllBad mocks base method +func (m *MockFullNode) SyncUnmarkAllBad(arg0 context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SyncUnmarkAllBad", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// SyncUnmarkAllBad indicates an expected call of SyncUnmarkAllBad +func (mr *MockFullNodeMockRecorder) SyncUnmarkAllBad(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncUnmarkAllBad", reflect.TypeOf((*MockFullNode)(nil).SyncUnmarkAllBad), arg0) +} + +// SyncUnmarkBad mocks base method +func (m *MockFullNode) SyncUnmarkBad(arg0 context.Context, arg1 cid.Cid) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SyncUnmarkBad", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// SyncUnmarkBad indicates an expected call of SyncUnmarkBad +func (mr *MockFullNodeMockRecorder) SyncUnmarkBad(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncUnmarkBad", reflect.TypeOf((*MockFullNode)(nil).SyncUnmarkBad), arg0, arg1) +} + +// SyncValidateTipset mocks base method +func (m *MockFullNode) SyncValidateTipset(arg0 context.Context, arg1 types.TipSetKey) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SyncValidateTipset", arg0, arg1) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SyncValidateTipset indicates an expected call of SyncValidateTipset +func (mr *MockFullNodeMockRecorder) SyncValidateTipset(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncValidateTipset", reflect.TypeOf((*MockFullNode)(nil).SyncValidateTipset), arg0, arg1) +} + +// Version mocks base method +func (m *MockFullNode) Version(arg0 context.Context) (api.APIVersion, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Version", arg0) + ret0, _ := ret[0].(api.APIVersion) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Version indicates an expected call of Version +func (mr *MockFullNodeMockRecorder) Version(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Version", reflect.TypeOf((*MockFullNode)(nil).Version), arg0) +} + +// WalletBalance mocks base method +func (m *MockFullNode) WalletBalance(arg0 context.Context, arg1 address.Address) (big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WalletBalance", arg0, arg1) + ret0, _ := ret[0].(big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// WalletBalance indicates an expected call of WalletBalance +func (mr *MockFullNodeMockRecorder) WalletBalance(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletBalance", reflect.TypeOf((*MockFullNode)(nil).WalletBalance), arg0, arg1) +} + +// WalletDefaultAddress mocks base method +func (m *MockFullNode) WalletDefaultAddress(arg0 context.Context) (address.Address, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WalletDefaultAddress", arg0) + ret0, _ := ret[0].(address.Address) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// WalletDefaultAddress indicates an expected call of WalletDefaultAddress +func (mr *MockFullNodeMockRecorder) WalletDefaultAddress(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletDefaultAddress", reflect.TypeOf((*MockFullNode)(nil).WalletDefaultAddress), arg0) +} + +// WalletDelete mocks base method +func (m *MockFullNode) WalletDelete(arg0 context.Context, arg1 address.Address) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WalletDelete", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// WalletDelete indicates an expected call of WalletDelete +func (mr *MockFullNodeMockRecorder) WalletDelete(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletDelete", reflect.TypeOf((*MockFullNode)(nil).WalletDelete), arg0, arg1) +} + +// WalletExport mocks base method +func (m *MockFullNode) WalletExport(arg0 context.Context, arg1 address.Address) (*types.KeyInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WalletExport", arg0, arg1) + ret0, _ := ret[0].(*types.KeyInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// WalletExport indicates an expected call of WalletExport +func (mr *MockFullNodeMockRecorder) WalletExport(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletExport", reflect.TypeOf((*MockFullNode)(nil).WalletExport), arg0, arg1) +} + +// WalletHas mocks base method +func (m *MockFullNode) WalletHas(arg0 context.Context, arg1 address.Address) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WalletHas", arg0, arg1) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// WalletHas indicates an expected call of WalletHas +func (mr *MockFullNodeMockRecorder) WalletHas(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletHas", reflect.TypeOf((*MockFullNode)(nil).WalletHas), arg0, arg1) +} + +// WalletImport mocks base method +func (m *MockFullNode) WalletImport(arg0 context.Context, arg1 *types.KeyInfo) (address.Address, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WalletImport", arg0, arg1) + ret0, _ := ret[0].(address.Address) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// WalletImport indicates an expected call of WalletImport +func (mr *MockFullNodeMockRecorder) WalletImport(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletImport", reflect.TypeOf((*MockFullNode)(nil).WalletImport), arg0, arg1) +} + +// WalletList mocks base method +func (m *MockFullNode) WalletList(arg0 context.Context) ([]address.Address, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WalletList", arg0) + ret0, _ := ret[0].([]address.Address) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// WalletList indicates an expected call of WalletList +func (mr *MockFullNodeMockRecorder) WalletList(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletList", reflect.TypeOf((*MockFullNode)(nil).WalletList), arg0) +} + +// WalletNew mocks base method +func (m *MockFullNode) WalletNew(arg0 context.Context, arg1 types.KeyType) (address.Address, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WalletNew", arg0, arg1) + ret0, _ := ret[0].(address.Address) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// WalletNew indicates an expected call of WalletNew +func (mr *MockFullNodeMockRecorder) WalletNew(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletNew", reflect.TypeOf((*MockFullNode)(nil).WalletNew), arg0, arg1) +} + +// WalletSetDefault mocks base method +func (m *MockFullNode) WalletSetDefault(arg0 context.Context, arg1 address.Address) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WalletSetDefault", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// WalletSetDefault indicates an expected call of WalletSetDefault +func (mr *MockFullNodeMockRecorder) WalletSetDefault(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletSetDefault", reflect.TypeOf((*MockFullNode)(nil).WalletSetDefault), arg0, arg1) +} + +// WalletSign mocks base method +func (m *MockFullNode) WalletSign(arg0 context.Context, arg1 address.Address, arg2 []byte) (*crypto.Signature, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WalletSign", arg0, arg1, arg2) + ret0, _ := ret[0].(*crypto.Signature) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// WalletSign indicates an expected call of WalletSign +func (mr *MockFullNodeMockRecorder) WalletSign(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletSign", reflect.TypeOf((*MockFullNode)(nil).WalletSign), arg0, arg1, arg2) +} + +// WalletSignMessage mocks base method +func (m *MockFullNode) WalletSignMessage(arg0 context.Context, arg1 address.Address, arg2 *types.Message) (*types.SignedMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WalletSignMessage", arg0, arg1, arg2) + ret0, _ := ret[0].(*types.SignedMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// WalletSignMessage indicates an expected call of WalletSignMessage +func (mr *MockFullNodeMockRecorder) WalletSignMessage(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletSignMessage", reflect.TypeOf((*MockFullNode)(nil).WalletSignMessage), arg0, arg1, arg2) +} + +// WalletValidateAddress mocks base method +func (m *MockFullNode) WalletValidateAddress(arg0 context.Context, arg1 string) (address.Address, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WalletValidateAddress", arg0, arg1) + ret0, _ := ret[0].(address.Address) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// WalletValidateAddress indicates an expected call of WalletValidateAddress +func (mr *MockFullNodeMockRecorder) WalletValidateAddress(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletValidateAddress", reflect.TypeOf((*MockFullNode)(nil).WalletValidateAddress), arg0, arg1) +} + +// WalletVerify mocks base method +func (m *MockFullNode) WalletVerify(arg0 context.Context, arg1 address.Address, arg2 []byte, arg3 *crypto.Signature) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WalletVerify", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// WalletVerify indicates an expected call of WalletVerify +func (mr *MockFullNodeMockRecorder) WalletVerify(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletVerify", reflect.TypeOf((*MockFullNode)(nil).WalletVerify), arg0, arg1, arg2, arg3) +} diff --git a/api/v0api/v1_wrapper.go b/api/v0api/v1_wrapper.go new file mode 100644 index 00000000000..ff4474fe57a --- /dev/null +++ b/api/v0api/v1_wrapper.go @@ -0,0 +1,187 @@ +package v0api + +import ( + "context" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/lotus/chain/types" + "golang.org/x/xerrors" + + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/go-state-types/abi" + + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v1api" +) + +type WrapperV1Full struct { + v1api.FullNode +} + +func (w *WrapperV1Full) StateSearchMsg(ctx context.Context, msg cid.Cid) (*api.MsgLookup, error) { + return w.FullNode.StateSearchMsg(ctx, types.EmptyTSK, msg, api.LookbackNoLimit, true) +} + +func (w *WrapperV1Full) StateSearchMsgLimited(ctx context.Context, msg cid.Cid, limit abi.ChainEpoch) (*api.MsgLookup, error) { + return w.FullNode.StateSearchMsg(ctx, types.EmptyTSK, msg, limit, true) +} + +func (w *WrapperV1Full) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error) { + return w.FullNode.StateWaitMsg(ctx, msg, confidence, api.LookbackNoLimit, true) +} + +func (w *WrapperV1Full) StateWaitMsgLimited(ctx context.Context, msg cid.Cid, confidence uint64, limit abi.ChainEpoch) (*api.MsgLookup, error) { + return w.FullNode.StateWaitMsg(ctx, msg, confidence, limit, true) +} + +func (w *WrapperV1Full) StateGetReceipt(ctx context.Context, msg cid.Cid, from types.TipSetKey) (*types.MessageReceipt, error) { + ml, err := w.FullNode.StateSearchMsg(ctx, from, msg, api.LookbackNoLimit, true) + if err != nil { + return nil, err + } + + if ml == nil { + return nil, nil + } + + return &ml.Receipt, nil +} + +func (w *WrapperV1Full) Version(ctx context.Context) (api.APIVersion, error) { + ver, err := w.FullNode.Version(ctx) + if err != nil { + return api.APIVersion{}, err + } + + ver.APIVersion = api.FullAPIVersion0 + + return ver, nil +} + +func (w *WrapperV1Full) executePrototype(ctx context.Context, p *api.MessagePrototype) (cid.Cid, error) { + sm, err := w.FullNode.MpoolPushMessage(ctx, &p.Message, nil) + if err != nil { + return cid.Undef, xerrors.Errorf("pushing message: %w", err) + } + + return sm.Cid(), nil +} +func (w *WrapperV1Full) MsigCreate(ctx context.Context, req uint64, addrs []address.Address, duration abi.ChainEpoch, val types.BigInt, src address.Address, gp types.BigInt) (cid.Cid, error) { + + p, err := w.FullNode.MsigCreate(ctx, req, addrs, duration, val, src, gp) + if err != nil { + return cid.Undef, xerrors.Errorf("creating prototype: %w", err) + } + + return w.executePrototype(ctx, p) +} + +func (w *WrapperV1Full) MsigPropose(ctx context.Context, msig address.Address, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (cid.Cid, error) { + + p, err := w.FullNode.MsigPropose(ctx, msig, to, amt, src, method, params) + if err != nil { + return cid.Undef, xerrors.Errorf("creating prototype: %w", err) + } + + return w.executePrototype(ctx, p) +} +func (w *WrapperV1Full) MsigApprove(ctx context.Context, msig address.Address, txID uint64, src address.Address) (cid.Cid, error) { + + p, err := w.FullNode.MsigApprove(ctx, msig, txID, src) + if err != nil { + return cid.Undef, xerrors.Errorf("creating prototype: %w", err) + } + + return w.executePrototype(ctx, p) +} + +func (w *WrapperV1Full) MsigApproveTxnHash(ctx context.Context, msig address.Address, txID uint64, proposer address.Address, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (cid.Cid, error) { + p, err := w.FullNode.MsigApproveTxnHash(ctx, msig, txID, proposer, to, amt, src, method, params) + if err != nil { + return cid.Undef, xerrors.Errorf("creating prototype: %w", err) + } + + return w.executePrototype(ctx, p) +} + +func (w *WrapperV1Full) MsigCancel(ctx context.Context, msig address.Address, txID uint64, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (cid.Cid, error) { + p, err := w.FullNode.MsigCancel(ctx, msig, txID, to, amt, src, method, params) + if err != nil { + return cid.Undef, xerrors.Errorf("creating prototype: %w", err) + } + + return w.executePrototype(ctx, p) +} + +func (w *WrapperV1Full) MsigAddPropose(ctx context.Context, msig address.Address, src address.Address, newAdd address.Address, inc bool) (cid.Cid, error) { + + p, err := w.FullNode.MsigAddPropose(ctx, msig, src, newAdd, inc) + if err != nil { + return cid.Undef, xerrors.Errorf("creating prototype: %w", err) + } + + return w.executePrototype(ctx, p) +} + +func (w *WrapperV1Full) MsigAddApprove(ctx context.Context, msig address.Address, src address.Address, txID uint64, proposer address.Address, newAdd address.Address, inc bool) (cid.Cid, error) { + + p, err := w.FullNode.MsigAddApprove(ctx, msig, src, txID, proposer, newAdd, inc) + if err != nil { + return cid.Undef, xerrors.Errorf("creating prototype: %w", err) + } + + return w.executePrototype(ctx, p) +} + +func (w *WrapperV1Full) MsigAddCancel(ctx context.Context, msig address.Address, src address.Address, txID uint64, newAdd address.Address, inc bool) (cid.Cid, error) { + + p, err := w.FullNode.MsigAddCancel(ctx, msig, src, txID, newAdd, inc) + if err != nil { + return cid.Undef, xerrors.Errorf("creating prototype: %w", err) + } + + return w.executePrototype(ctx, p) +} + +func (w *WrapperV1Full) MsigSwapPropose(ctx context.Context, msig address.Address, src address.Address, oldAdd address.Address, newAdd address.Address) (cid.Cid, error) { + + p, err := w.FullNode.MsigSwapPropose(ctx, msig, src, oldAdd, newAdd) + if err != nil { + return cid.Undef, xerrors.Errorf("creating prototype: %w", err) + } + + return w.executePrototype(ctx, p) +} + +func (w *WrapperV1Full) MsigSwapApprove(ctx context.Context, msig address.Address, src address.Address, txID uint64, proposer address.Address, oldAdd address.Address, newAdd address.Address) (cid.Cid, error) { + + p, err := w.FullNode.MsigSwapApprove(ctx, msig, src, txID, proposer, oldAdd, newAdd) + if err != nil { + return cid.Undef, xerrors.Errorf("creating prototype: %w", err) + } + + return w.executePrototype(ctx, p) +} + +func (w *WrapperV1Full) MsigSwapCancel(ctx context.Context, msig address.Address, src address.Address, txID uint64, oldAdd address.Address, newAdd address.Address) (cid.Cid, error) { + + p, err := w.FullNode.MsigSwapCancel(ctx, msig, src, txID, oldAdd, newAdd) + if err != nil { + return cid.Undef, xerrors.Errorf("creating prototype: %w", err) + } + + return w.executePrototype(ctx, p) +} + +func (w *WrapperV1Full) MsigRemoveSigner(ctx context.Context, msig address.Address, proposer address.Address, toRemove address.Address, decrease bool) (cid.Cid, error) { + + p, err := w.FullNode.MsigRemoveSigner(ctx, msig, proposer, toRemove, decrease) + if err != nil { + return cid.Undef, xerrors.Errorf("creating prototype: %w", err) + } + + return w.executePrototype(ctx, p) +} + +var _ FullNode = &WrapperV1Full{} diff --git a/api/v1api/latest.go b/api/v1api/latest.go new file mode 100644 index 00000000000..6f57d88262c --- /dev/null +++ b/api/v1api/latest.go @@ -0,0 +1,12 @@ +package v1api + +import ( + "github.com/filecoin-project/lotus/api" +) + +type FullNode = api.FullNode +type FullNodeStruct = api.FullNodeStruct + +func PermissionedFullAPI(a FullNode) FullNode { + return api.PermissionedFullAPI(a) +} diff --git a/api/version.go b/api/version.go index 17605b518a6..743170f049f 100644 --- a/api/version.go +++ b/api/version.go @@ -42,11 +42,11 @@ var RunningNodeType NodeType func VersionForType(nodeType NodeType) (Version, error) { switch nodeType { case NodeFull: - return FullAPIVersion, nil + return FullAPIVersion1, nil case NodeMiner: - return MinerAPIVersion, nil + return MinerAPIVersion0, nil case NodeWorker: - return WorkerAPIVersion, nil + return WorkerAPIVersion0, nil default: return Version(0), xerrors.Errorf("unknown node type %d", nodeType) } @@ -54,9 +54,11 @@ func VersionForType(nodeType NodeType) (Version, error) { // semver versions of the rpc api exposed var ( - FullAPIVersion = newVer(1, 1, 0) - MinerAPIVersion = newVer(1, 0, 1) - WorkerAPIVersion = newVer(1, 0, 0) + FullAPIVersion0 = newVer(1, 3, 0) + FullAPIVersion1 = newVer(2, 1, 0) + + MinerAPIVersion0 = newVer(1, 0, 1) + WorkerAPIVersion0 = newVer(1, 0, 0) ) //nolint:varcheck,deadcode diff --git a/api/wrap.go b/api/wrap.go new file mode 100644 index 00000000000..1ded6713296 --- /dev/null +++ b/api/wrap.go @@ -0,0 +1,32 @@ +package api + +import ( + "reflect" +) + +// Wrap adapts partial api impl to another version +// proxyT is the proxy type used as input in wrapperT +// Usage: Wrap(new(v1api.FullNodeStruct), new(v0api.WrapperV1Full), eventsApi).(EventAPI) +func Wrap(proxyT, wrapperT, impl interface{}) interface{} { + proxy := reflect.New(reflect.TypeOf(proxyT).Elem()) + proxyMethods := proxy.Elem().FieldByName("Internal") + ri := reflect.ValueOf(impl) + + for i := 0; i < ri.NumMethod(); i++ { + mt := ri.Type().Method(i) + if proxyMethods.FieldByName(mt.Name).Kind() == reflect.Invalid { + continue + } + + fn := ri.Method(i) + of := proxyMethods.FieldByName(mt.Name) + + proxyMethods.FieldByName(mt.Name).Set(reflect.MakeFunc(of.Type(), func(args []reflect.Value) (results []reflect.Value) { + return fn.Call(args) + })) + } + + wp := reflect.New(reflect.TypeOf(wrapperT).Elem()) + wp.Elem().Field(0).Set(proxy) + return wp.Interface() +} diff --git a/blockstore/cached.go b/blockstore/cached.go deleted file mode 100644 index f2bb3ed57a4..00000000000 --- a/blockstore/cached.go +++ /dev/null @@ -1,25 +0,0 @@ -package blockstore - -import ( - "context" - - blockstore "github.com/ipfs/go-ipfs-blockstore" -) - -type CacheOpts = blockstore.CacheOpts - -func DefaultCacheOpts() CacheOpts { - return CacheOpts{ - HasBloomFilterSize: 0, - HasBloomFilterHashes: 0, - HasARCCacheSize: 512 << 10, - } -} - -func CachedBlockstore(ctx context.Context, bs Blockstore, opts CacheOpts) (Blockstore, error) { - cached, err := blockstore.CachedBlockstore(ctx, bs, opts) - if err != nil { - return nil, err - } - return WrapIDStore(cached), nil -} diff --git a/blockstore/splitstore/splitstore.go b/blockstore/splitstore/splitstore.go index 23b2d342720..f6d26bbdd60 100644 --- a/blockstore/splitstore/splitstore.go +++ b/blockstore/splitstore/splitstore.go @@ -406,6 +406,11 @@ func (s *SplitStore) Close() error { } func (s *SplitStore) HeadChange(_, apply []*types.TipSet) error { + // Revert only. + if len(apply) == 0 { + return nil + } + s.mx.Lock() curTs := apply[len(apply)-1] epoch := curTs.Height() diff --git a/blockstore/splitstore/splitstore_test.go b/blockstore/splitstore/splitstore_test.go index e5314b80f3b..dcaf276474d 100644 --- a/blockstore/splitstore/splitstore_test.go +++ b/blockstore/splitstore/splitstore_test.go @@ -27,7 +27,7 @@ func init() { } func testSplitStore(t *testing.T, cfg *Config) { - chain := &mockChain{} + chain := &mockChain{t: t} // genesis genBlock := mock.MkBlock(nil, 0, 0) genTs := mock.TipSet(genBlock) @@ -169,6 +169,9 @@ func testSplitStore(t *testing.T, cfg *Config) { t.Errorf("expected %d hot blocks, but got %d", 7, hotCnt) } } + + // Make sure we can revert without panicking. + chain.revert(2) } func TestSplitStoreSimpleCompaction(t *testing.T) { @@ -191,6 +194,8 @@ func TestSplitStoreFullCompactionWithGC(t *testing.T) { } type mockChain struct { + t testing.TB + sync.Mutex tipsets []*types.TipSet listener func(revert []*types.TipSet, apply []*types.TipSet) error @@ -204,7 +209,26 @@ func (c *mockChain) push(ts *types.TipSet) { if c.listener != nil { err := c.listener(nil, []*types.TipSet{ts}) if err != nil { - log.Errorf("mockchain: error dispatching listener: %s", err) + c.t.Errorf("mockchain: error dispatching listener: %s", err) + } + } +} + +func (c *mockChain) revert(count int) { + c.Lock() + revert := make([]*types.TipSet, count) + if count > len(c.tipsets) { + c.Unlock() + c.t.Fatalf("not enough tipsets to revert") + } + copy(revert, c.tipsets[len(c.tipsets)-count:]) + c.tipsets = c.tipsets[:len(c.tipsets)-count] + c.Unlock() + + if c.listener != nil { + err := c.listener(revert, nil) + if err != nil { + c.t.Errorf("mockchain: error dispatching listener: %s", err) } } } diff --git a/build/bootstrap/butterflynet.pi b/build/bootstrap/butterflynet.pi index dc49bdf0eea..0de3043a3ef 100644 --- a/build/bootstrap/butterflynet.pi +++ b/build/bootstrap/butterflynet.pi @@ -1,2 +1,2 @@ -/dns4/bootstrap-0.butterfly.fildev.network/tcp/1347/p2p/12D3KooWQafkXgEWDgcVhZvF6KMhiC8ktdxjvmdQN8RarRXe9jCc -/dns4/bootstrap-1.butterfly.fildev.network/tcp/1347/p2p/12D3KooWE7UmZ4DLk9WBdEJUSwuSCPiSqjoCv3wPeoe8Tq3yMa77 +/dns4/bootstrap-0.butterfly.fildev.network/tcp/1347/p2p/12D3KooWRkaF18SR3E6qL6dkGrozT8QJUV5VbhE9E7BZtPmHqdWJ +/dns4/bootstrap-1.butterfly.fildev.network/tcp/1347/p2p/12D3KooWJcJUc23WJjJHGSboGcU3t76z9Lb7CghrH2tiBiDCY4ux diff --git a/build/genesis/butterflynet.car b/build/genesis/butterflynet.car index 1f5185c1af8..6654d7195a7 100644 Binary files a/build/genesis/butterflynet.car and b/build/genesis/butterflynet.car differ diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 42d7e5b954d..d628685e572 100644 Binary files a/build/openrpc/full.json.gz and b/build/openrpc/full.json.gz differ diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz index faab78eb76c..0d52dac870e 100644 Binary files a/build/openrpc/miner.json.gz and b/build/openrpc/miner.json.gz differ diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz index 7bf6216a75f..5f024f24c2b 100644 Binary files a/build/openrpc/worker.json.gz and b/build/openrpc/worker.json.gz differ diff --git a/build/params_2k.go b/build/params_2k.go index 63f7e70b49c..12d497c4b6e 100644 --- a/build/params_2k.go +++ b/build/params_2k.go @@ -3,6 +3,11 @@ package build import ( + "os" + "strconv" + + "github.com/ipfs/go-cid" + "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/lotus/chain/actors/policy" ) @@ -10,24 +15,29 @@ import ( const BootstrappersFile = "" const GenesisFile = "" -const UpgradeBreezeHeight = -1 +var UpgradeBreezeHeight = abi.ChainEpoch(-1) + const BreezeGasTampingDuration = 0 -const UpgradeSmokeHeight = -1 -const UpgradeIgnitionHeight = -2 -const UpgradeRefuelHeight = -3 -const UpgradeTapeHeight = -4 +var UpgradeSmokeHeight = abi.ChainEpoch(-1) +var UpgradeIgnitionHeight = abi.ChainEpoch(-2) +var UpgradeRefuelHeight = abi.ChainEpoch(-3) +var UpgradeTapeHeight = abi.ChainEpoch(-4) -const UpgradeActorsV2Height = 10 -const UpgradeLiftoffHeight = -5 +var UpgradeActorsV2Height = abi.ChainEpoch(10) +var UpgradeLiftoffHeight = abi.ChainEpoch(-5) -const UpgradeKumquatHeight = 15 -const UpgradeCalicoHeight = 20 -const UpgradePersianHeight = 25 -const UpgradeOrangeHeight = 27 -const UpgradeClausHeight = 30 +var UpgradeKumquatHeight = abi.ChainEpoch(15) +var UpgradeCalicoHeight = abi.ChainEpoch(20) +var UpgradePersianHeight = abi.ChainEpoch(25) +var UpgradeOrangeHeight = abi.ChainEpoch(27) +var UpgradeClausHeight = abi.ChainEpoch(30) -const UpgradeActorsV3Height = 35 +var UpgradeActorsV3Height = abi.ChainEpoch(35) + +var UpgradeNorwegianHeight = abi.ChainEpoch(40) + +var UpgradeActorsV4Height = abi.ChainEpoch(45) var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandMainnet, @@ -37,6 +47,37 @@ func init() { policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1) policy.SetConsensusMinerMinPower(abi.NewStoragePower(2048)) policy.SetMinVerifiedDealSize(abi.NewStoragePower(256)) + policy.SetPreCommitChallengeDelay(abi.ChainEpoch(10)) + + getUpgradeHeight := func(ev string, def abi.ChainEpoch) abi.ChainEpoch { + hs, found := os.LookupEnv(ev) + if found { + h, err := strconv.Atoi(hs) + if err != nil { + log.Panicf("failed to parse %s env var", ev) + } + + return abi.ChainEpoch(h) + } + + return def + } + + UpgradeBreezeHeight = getUpgradeHeight("LOTUS_BREEZE_HEIGHT", UpgradeBreezeHeight) + UpgradeSmokeHeight = getUpgradeHeight("LOTUS_SMOKE_HEIGHT", UpgradeSmokeHeight) + UpgradeIgnitionHeight = getUpgradeHeight("LOTUS_IGNITION_HEIGHT", UpgradeIgnitionHeight) + UpgradeRefuelHeight = getUpgradeHeight("LOTUS_REFUEL_HEIGHT", UpgradeRefuelHeight) + UpgradeTapeHeight = getUpgradeHeight("LOTUS_TAPE_HEIGHT", UpgradeTapeHeight) + UpgradeActorsV2Height = getUpgradeHeight("LOTUS_ACTORSV2_HEIGHT", UpgradeActorsV2Height) + UpgradeLiftoffHeight = getUpgradeHeight("LOTUS_LIFTOFF_HEIGHT", UpgradeLiftoffHeight) + UpgradeKumquatHeight = getUpgradeHeight("LOTUS_KUMQUAT_HEIGHT", UpgradeKumquatHeight) + UpgradeCalicoHeight = getUpgradeHeight("LOTUS_CALICO_HEIGHT", UpgradeCalicoHeight) + UpgradePersianHeight = getUpgradeHeight("LOTUS_PERSIAN_HEIGHT", UpgradePersianHeight) + UpgradeOrangeHeight = getUpgradeHeight("LOTUS_ORANGE_HEIGHT", UpgradeOrangeHeight) + UpgradeClausHeight = getUpgradeHeight("LOTUS_CLAUS_HEIGHT", UpgradeClausHeight) + UpgradeActorsV3Height = getUpgradeHeight("LOTUS_ACTORSV3_HEIGHT", UpgradeActorsV3Height) + UpgradeNorwegianHeight = getUpgradeHeight("LOTUS_NORWEGIAN_HEIGHT", UpgradeNorwegianHeight) + UpgradeActorsV4Height = getUpgradeHeight("LOTUS_ACTORSV4_HEIGHT", UpgradeActorsV4Height) BuildType |= Build2k } @@ -55,3 +96,5 @@ const SlashablePowerDelay = 20 const InteractivePoRepConfidence = 6 const BootstrapPeerThreshold = 1 + +var WhitelistedBlock = cid.Undef diff --git a/build/params_butterfly.go b/build/params_butterfly.go index f7bf8aa10b1..6daeca50215 100644 --- a/build/params_butterfly.go +++ b/build/params_butterfly.go @@ -7,6 +7,7 @@ import ( "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" + "github.com/ipfs/go-cid" ) var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ @@ -32,6 +33,8 @@ const UpgradePersianHeight = 150 const UpgradeClausHeight = 180 const UpgradeOrangeHeight = 210 const UpgradeActorsV3Height = 240 +const UpgradeNorwegianHeight = UpgradeActorsV3Height + (builtin2.EpochsInHour * 12) +const UpgradeActorsV4Height = 8922 func init() { policy.SetConsensusMinerMinPower(abi.NewStoragePower(2 << 30)) @@ -50,3 +53,5 @@ const PropagationDelaySecs = uint64(6) // BootstrapPeerThreshold is the minimum number peers we need to track for a sync worker to start const BootstrapPeerThreshold = 2 + +var WhitelistedBlock = cid.Undef diff --git a/build/params_calibnet.go b/build/params_calibnet.go index 976cffd22bd..997bb395bac 100644 --- a/build/params_calibnet.go +++ b/build/params_calibnet.go @@ -7,6 +7,7 @@ import ( "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" + "github.com/ipfs/go-cid" ) var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ @@ -40,6 +41,9 @@ const UpgradeClausHeight = 250 const UpgradeOrangeHeight = 300 const UpgradeActorsV3Height = 600 +const UpgradeNorwegianHeight = 114000 + +const UpgradeActorsV4Height = 193789 func init() { policy.SetConsensusMinerMinPower(abi.NewStoragePower(32 << 30)) @@ -61,3 +65,5 @@ const PropagationDelaySecs = uint64(6) // BootstrapPeerThreshold is the minimum number peers we need to track for a sync worker to start const BootstrapPeerThreshold = 4 + +var WhitelistedBlock = cid.Undef diff --git a/build/params_mainnet.go b/build/params_mainnet.go index cc929978b63..ea4ae7d75ef 100644 --- a/build/params_mainnet.go +++ b/build/params_mainnet.go @@ -56,6 +56,12 @@ const UpgradeClausHeight = 343200 // 2021-03-04T00:00:30Z var UpgradeActorsV3Height = abi.ChainEpoch(550321) +// 2021-04-12T22:00:00Z +const UpgradeNorwegianHeight = 665280 + +// 2021-04-29T06:00:00Z +var UpgradeActorsV4Height = abi.ChainEpoch(712320) + func init() { policy.SetConsensusMinerMinPower(abi.NewStoragePower(10 << 40)) @@ -67,6 +73,10 @@ func init() { UpgradeActorsV3Height = math.MaxInt64 } + if os.Getenv("LOTUS_DISABLE_V4_ACTOR_MIGRATION") == "1" { + UpgradeActorsV4Height = math.MaxInt64 + } + Devnet = false BuildType = BuildMainnet @@ -78,3 +88,6 @@ const PropagationDelaySecs = uint64(6) // BootstrapPeerThreshold is the minimum number peers we need to track for a sync worker to start const BootstrapPeerThreshold = 4 + +// we skip checks on message validity in this block to sidestep the zero-bls signature +var WhitelistedBlock = MustParseCid("bafy2bzaceapyg2uyzk7vueh3xccxkuwbz3nxewjyguoxvhx77malc2lzn2ybi") diff --git a/build/params_nerpanet.go b/build/params_nerpanet.go index 20ecab4e276..fb6cfc47ab7 100644 --- a/build/params_nerpanet.go +++ b/build/params_nerpanet.go @@ -5,6 +5,7 @@ package build import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/lotus/chain/actors/policy" + "github.com/ipfs/go-cid" builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" ) @@ -39,6 +40,8 @@ const UpgradeClausHeight = 250 const UpgradeOrangeHeight = 300 const UpgradeActorsV3Height = 600 +const UpgradeNorwegianHeight = 999999 +const UpgradeActorsV4Height = 99999999 func init() { // Minimum block production power is set to 4 TiB @@ -70,3 +73,5 @@ const PropagationDelaySecs = uint64(6) // BootstrapPeerThreshold is the minimum number peers we need to track for a sync worker to start const BootstrapPeerThreshold = 4 + +var WhitelistedBlock = cid.Undef diff --git a/build/params_shared_funcs.go b/build/params_shared_funcs.go index bcd82bb4821..f59fee653e9 100644 --- a/build/params_shared_funcs.go +++ b/build/params_shared_funcs.go @@ -2,6 +2,7 @@ package build import ( "github.com/filecoin-project/go-address" + "github.com/ipfs/go-cid" "github.com/libp2p/go-libp2p-core/protocol" @@ -28,3 +29,12 @@ func MustParseAddress(addr string) address.Address { return ret } + +func MustParseCid(c string) cid.Cid { + ret, err := cid.Decode(c) + if err != nil { + panic(err) + } + + return ret +} diff --git a/build/params_shared_vals.go b/build/params_shared_vals.go index 5e2d18ff154..92bbc5db915 100644 --- a/build/params_shared_vals.go +++ b/build/params_shared_vals.go @@ -25,7 +25,7 @@ const UnixfsLinksPerLevel = 1024 // Consensus / Network const AllowableClockDriftSecs = uint64(1) -const NewestNetworkVersion = network.Version9 +const NewestNetworkVersion = network.Version11 const ActorUpgradeNetworkVersion = network.Version4 // Epochs @@ -118,5 +118,5 @@ const PackingEfficiencyNum = 4 const PackingEfficiencyDenom = 5 // Actor consts -// TODO: Pull from actors when its made not private -var MinDealDuration = abi.ChainEpoch(180 * builtin2.EpochsInDay) +// TODO: pieceSize unused from actors +var MinDealDuration, MaxDealDuration = policy.DealDurationBounds(0) diff --git a/build/params_testground.go b/build/params_testground.go index 759b2969233..7da3c2272b7 100644 --- a/build/params_testground.go +++ b/build/params_testground.go @@ -12,6 +12,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/network" + "github.com/ipfs/go-cid" builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" @@ -72,8 +73,8 @@ var ( }() // Actor consts - // TODO: Pull from actors when its made not private - MinDealDuration = abi.ChainEpoch(180 * builtin2.EpochsInDay) + // TODO: pieceSize unused from actors + MinDealDuration, MaxDealDuration = policy.DealDurationBounds(0) PackingEfficiencyNum int64 = 4 PackingEfficiencyDenom int64 = 5 @@ -81,29 +82,32 @@ var ( UpgradeBreezeHeight abi.ChainEpoch = -1 BreezeGasTampingDuration abi.ChainEpoch = 0 - UpgradeSmokeHeight abi.ChainEpoch = -1 - UpgradeIgnitionHeight abi.ChainEpoch = -2 - UpgradeRefuelHeight abi.ChainEpoch = -3 - UpgradeTapeHeight abi.ChainEpoch = -4 - UpgradeActorsV2Height abi.ChainEpoch = 10 - UpgradeLiftoffHeight abi.ChainEpoch = -5 - UpgradeKumquatHeight abi.ChainEpoch = -6 - UpgradeCalicoHeight abi.ChainEpoch = -7 - UpgradePersianHeight abi.ChainEpoch = -8 - UpgradeOrangeHeight abi.ChainEpoch = -9 - UpgradeClausHeight abi.ChainEpoch = -10 - UpgradeActorsV3Height abi.ChainEpoch = -11 + UpgradeSmokeHeight abi.ChainEpoch = -1 + UpgradeIgnitionHeight abi.ChainEpoch = -2 + UpgradeRefuelHeight abi.ChainEpoch = -3 + UpgradeTapeHeight abi.ChainEpoch = -4 + UpgradeActorsV2Height abi.ChainEpoch = 10 + UpgradeLiftoffHeight abi.ChainEpoch = -5 + UpgradeKumquatHeight abi.ChainEpoch = -6 + UpgradeCalicoHeight abi.ChainEpoch = -7 + UpgradePersianHeight abi.ChainEpoch = -8 + UpgradeOrangeHeight abi.ChainEpoch = -9 + UpgradeClausHeight abi.ChainEpoch = -10 + UpgradeActorsV3Height abi.ChainEpoch = -11 + UpgradeNorwegianHeight abi.ChainEpoch = -12 + UpgradeActorsV4Height abi.ChainEpoch = -13 DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandMainnet, } - NewestNetworkVersion = network.Version9 + NewestNetworkVersion = network.Version11 ActorUpgradeNetworkVersion = network.Version4 Devnet = true ZeroAddress = MustParseAddress("f3yaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaby2smx7a") + WhitelistedBlock = cid.Undef BootstrappersFile = "" GenesisFile = "" ) diff --git a/build/tools.go b/build/tools.go index ad45397bb37..57b6e7d1f36 100644 --- a/build/tools.go +++ b/build/tools.go @@ -6,4 +6,5 @@ import ( _ "github.com/GeertJohan/go.rice/rice" _ "github.com/golang/mock/mockgen" _ "github.com/whyrusleeping/bencher" + _ "golang.org/x/tools/cmd/stringer" ) diff --git a/build/version.go b/build/version.go index f5e85783ac7..12b1058b314 100644 --- a/build/version.go +++ b/build/version.go @@ -1,5 +1,7 @@ package build +import "os" + var CurrentCommit string var BuildType int @@ -29,8 +31,12 @@ func buildType() string { } // BuildVersion is the local build version, set by build system -const BuildVersion = "1.6.0-dev" +const BuildVersion = "1.11.0-dev" func UserVersion() string { + if os.Getenv("LOTUS_VERSION_IGNORE_COMMIT") == "1" { + return BuildVersion + } + return BuildVersion + buildType() + CurrentCommit } diff --git a/chain/actors/agen/main.go b/chain/actors/agen/main.go new file mode 100644 index 00000000000..7269d9ae592 --- /dev/null +++ b/chain/actors/agen/main.go @@ -0,0 +1,218 @@ +package main + +import ( + "bytes" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "text/template" + + "golang.org/x/xerrors" +) + +var latestVersion = 4 + +var versions = []int{0, 2, 3, latestVersion} + +var versionImports = map[int]string{ + 0: "/", + 2: "/v2/", + 3: "/v3/", + latestVersion: "/v4/", +} + +var actors = map[string][]int{ + "account": versions, + "cron": versions, + "init": versions, + "market": versions, + "miner": versions, + "multisig": versions, + "paych": versions, + "power": versions, + "reward": versions, + "verifreg": versions, +} + +func main() { + if err := generateAdapters(); err != nil { + fmt.Println(err) + return + } + + if err := generatePolicy("chain/actors/policy/policy.go"); err != nil { + fmt.Println(err) + return + } + + if err := generateBuiltin("chain/actors/builtin/builtin.go"); err != nil { + fmt.Println(err) + return + } +} + +func generateAdapters() error { + for act, versions := range actors { + actDir := filepath.Join("chain/actors/builtin", act) + + if err := generateState(actDir); err != nil { + return err + } + + if err := generateMessages(actDir); err != nil { + return err + } + + { + af, err := ioutil.ReadFile(filepath.Join(actDir, "actor.go.template")) + if err != nil { + return xerrors.Errorf("loading actor template: %w", err) + } + + tpl := template.Must(template.New("").Funcs(template.FuncMap{ + "import": func(v int) string { return versionImports[v] }, + }).Parse(string(af))) + + var b bytes.Buffer + + err = tpl.Execute(&b, map[string]interface{}{ + "versions": versions, + "latestVersion": latestVersion, + }) + if err != nil { + return err + } + + if err := ioutil.WriteFile(filepath.Join(actDir, fmt.Sprintf("%s.go", act)), b.Bytes(), 0666); err != nil { + return err + } + } + } + + return nil +} + +func generateState(actDir string) error { + af, err := ioutil.ReadFile(filepath.Join(actDir, "state.go.template")) + if err != nil { + if os.IsNotExist(err) { + return nil // skip + } + + return xerrors.Errorf("loading state adapter template: %w", err) + } + + for _, version := range versions { + tpl := template.Must(template.New("").Funcs(template.FuncMap{}).Parse(string(af))) + + var b bytes.Buffer + + err := tpl.Execute(&b, map[string]interface{}{ + "v": version, + "import": versionImports[version], + }) + if err != nil { + return err + } + + if err := ioutil.WriteFile(filepath.Join(actDir, fmt.Sprintf("v%d.go", version)), b.Bytes(), 0666); err != nil { + return err + } + } + + return nil +} + +func generateMessages(actDir string) error { + af, err := ioutil.ReadFile(filepath.Join(actDir, "message.go.template")) + if err != nil { + if os.IsNotExist(err) { + return nil // skip + } + + return xerrors.Errorf("loading message adapter template: %w", err) + } + + for _, version := range versions { + tpl := template.Must(template.New("").Funcs(template.FuncMap{}).Parse(string(af))) + + var b bytes.Buffer + + err := tpl.Execute(&b, map[string]interface{}{ + "v": version, + "import": versionImports[version], + }) + if err != nil { + return err + } + + if err := ioutil.WriteFile(filepath.Join(actDir, fmt.Sprintf("message%d.go", version)), b.Bytes(), 0666); err != nil { + return err + } + } + + return nil +} + +func generatePolicy(policyPath string) error { + + pf, err := ioutil.ReadFile(policyPath + ".template") + if err != nil { + if os.IsNotExist(err) { + return nil // skip + } + + return xerrors.Errorf("loading policy template file: %w", err) + } + + tpl := template.Must(template.New("").Funcs(template.FuncMap{ + "import": func(v int) string { return versionImports[v] }, + }).Parse(string(pf))) + var b bytes.Buffer + + err = tpl.Execute(&b, map[string]interface{}{ + "versions": versions, + "latestVersion": latestVersion, + }) + if err != nil { + return err + } + + if err := ioutil.WriteFile(policyPath, b.Bytes(), 0666); err != nil { + return err + } + + return nil +} + +func generateBuiltin(builtinPath string) error { + + bf, err := ioutil.ReadFile(builtinPath + ".template") + if err != nil { + if os.IsNotExist(err) { + return nil // skip + } + + return xerrors.Errorf("loading builtin template file: %w", err) + } + + tpl := template.Must(template.New("").Funcs(template.FuncMap{ + "import": func(v int) string { return versionImports[v] }, + }).Parse(string(bf))) + var b bytes.Buffer + + err = tpl.Execute(&b, map[string]interface{}{ + "versions": versions, + "latestVersion": latestVersion, + }) + if err != nil { + return err + } + + if err := ioutil.WriteFile(builtinPath, b.Bytes(), 0666); err != nil { + return err + } + + return nil +} diff --git a/chain/actors/builtin/account/account.go b/chain/actors/builtin/account/account.go index 53a03e6f323..8242e300dae 100644 --- a/chain/actors/builtin/account/account.go +++ b/chain/actors/builtin/account/account.go @@ -12,32 +12,50 @@ import ( "github.com/filecoin-project/lotus/chain/types" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" + + builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" ) func init() { + builtin.RegisterActorState(builtin0.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load0(store, root) }) + builtin.RegisterActorState(builtin2.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load2(store, root) }) + builtin.RegisterActorState(builtin3.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load3(store, root) }) + + builtin.RegisterActorState(builtin4.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load4(store, root) + }) } -var Methods = builtin3.MethodsAccount +var Methods = builtin4.MethodsAccount func Load(store adt.Store, act *types.Actor) (State, error) { switch act.Code { + case builtin0.AccountActorCodeID: return load0(store, act.Head) + case builtin2.AccountActorCodeID: return load2(store, act.Head) + case builtin3.AccountActorCodeID: return load3(store, act.Head) + + case builtin4.AccountActorCodeID: + return load4(store, act.Head) + } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } diff --git a/chain/actors/builtin/account/actor.go.template b/chain/actors/builtin/account/actor.go.template new file mode 100644 index 00000000000..f75af3dfb88 --- /dev/null +++ b/chain/actors/builtin/account/actor.go.template @@ -0,0 +1,41 @@ +package account + +import ( + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/cbor" + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/chain/types" +{{range .versions}} + builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin" +{{end}} +) + +func init() { +{{range .versions}} + builtin.RegisterActorState(builtin{{.}}.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load{{.}}(store, root) + }) +{{end}}} + +var Methods = builtin4.MethodsAccount + +func Load(store adt.Store, act *types.Actor) (State, error) { + switch act.Code { +{{range .versions}} + case builtin{{.}}.AccountActorCodeID: + return load{{.}}(store, act.Head) +{{end}} + } + return nil, xerrors.Errorf("unknown actor code %s", act.Code) +} + +type State interface { + cbor.Marshaler + + PubkeyAddress() (address.Address, error) +} diff --git a/chain/actors/builtin/account/state.go.template b/chain/actors/builtin/account/state.go.template new file mode 100644 index 00000000000..65d874c80a3 --- /dev/null +++ b/chain/actors/builtin/account/state.go.template @@ -0,0 +1,30 @@ +package account + +import ( + "github.com/filecoin-project/go-address" + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + account{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/account" +) + +var _ State = (*state{{.v}})(nil) + +func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { + out := state{{.v}}{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +type state{{.v}} struct { + account{{.v}}.State + store adt.Store +} + +func (s *state{{.v}}) PubkeyAddress() (address.Address, error) { + return s.Address, nil +} diff --git a/chain/actors/builtin/account/v4.go b/chain/actors/builtin/account/v4.go new file mode 100644 index 00000000000..1a24007d899 --- /dev/null +++ b/chain/actors/builtin/account/v4.go @@ -0,0 +1,30 @@ +package account + +import ( + "github.com/filecoin-project/go-address" + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + account4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/account" +) + +var _ State = (*state4)(nil) + +func load4(store adt.Store, root cid.Cid) (State, error) { + out := state4{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +type state4 struct { + account4.State + store adt.Store +} + +func (s *state4) PubkeyAddress() (address.Address, error) { + return s.Address, nil +} diff --git a/chain/actors/builtin/builtin.go b/chain/actors/builtin/builtin.go index 1e535dca462..5e34c015a9d 100644 --- a/chain/actors/builtin/builtin.go +++ b/chain/actors/builtin/builtin.go @@ -6,8 +6,16 @@ import ( "golang.org/x/xerrors" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + 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" + builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" + smoothing3 "github.com/filecoin-project/specs-actors/v3/actors/util/smoothing" + + builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" + smoothing4 "github.com/filecoin-project/specs-actors/v4/actors/util/smoothing" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/cbor" @@ -15,57 +23,64 @@ import ( "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/types" - smoothing0 "github.com/filecoin-project/specs-actors/actors/util/smoothing" - smoothing2 "github.com/filecoin-project/specs-actors/v2/actors/util/smoothing" - smoothing3 "github.com/filecoin-project/specs-actors/v3/actors/util/smoothing" - - miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" - proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof" + miner4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/miner" + proof4 "github.com/filecoin-project/specs-actors/v4/actors/runtime/proof" ) -var SystemActorAddr = builtin0.SystemActorAddr -var BurntFundsActorAddr = builtin0.BurntFundsActorAddr -var CronActorAddr = builtin0.CronActorAddr +var SystemActorAddr = builtin4.SystemActorAddr +var BurntFundsActorAddr = builtin4.BurntFundsActorAddr +var CronActorAddr = builtin4.CronActorAddr var SaftAddress = makeAddress("t0122") var ReserveAddress = makeAddress("t090") var RootVerifierAddress = makeAddress("t080") var ( - ExpectedLeadersPerEpoch = builtin0.ExpectedLeadersPerEpoch + ExpectedLeadersPerEpoch = builtin4.ExpectedLeadersPerEpoch ) const ( - EpochDurationSeconds = builtin0.EpochDurationSeconds - EpochsInDay = builtin0.EpochsInDay - SecondsInDay = builtin0.SecondsInDay + EpochDurationSeconds = builtin4.EpochDurationSeconds + EpochsInDay = builtin4.EpochsInDay + SecondsInDay = builtin4.SecondsInDay ) const ( - MethodSend = builtin3.MethodSend - MethodConstructor = builtin3.MethodConstructor + MethodSend = builtin4.MethodSend + MethodConstructor = builtin4.MethodConstructor ) -// These are all just type aliases across actor versions 0, 2, & 3. In the future, that might change +// These are all just type aliases across actor versions. In the future, that might change // and we might need to do something fancier. -type SectorInfo = proof0.SectorInfo -type PoStProof = proof0.PoStProof +type SectorInfo = proof4.SectorInfo +type PoStProof = proof4.PoStProof type FilterEstimate = smoothing0.FilterEstimate -func FromV0FilterEstimate(v0 smoothing0.FilterEstimate) FilterEstimate { - return (FilterEstimate)(v0) +func QAPowerForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight, verifiedWeight abi.DealWeight) abi.StoragePower { + return miner4.QAPowerForWeight(size, duration, dealWeight, verifiedWeight) } -// Doesn't change between actors v0, v2, and v3. -func QAPowerForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight, verifiedWeight abi.DealWeight) abi.StoragePower { - return miner0.QAPowerForWeight(size, duration, dealWeight, verifiedWeight) +func FromV0FilterEstimate(v0 smoothing0.FilterEstimate) FilterEstimate { + + return (FilterEstimate)(v0) //nolint:unconvert + } func FromV2FilterEstimate(v2 smoothing2.FilterEstimate) FilterEstimate { + return (FilterEstimate)(v2) + } func FromV3FilterEstimate(v3 smoothing3.FilterEstimate) FilterEstimate { + return (FilterEstimate)(v3) + +} + +func FromV4FilterEstimate(v4 smoothing4.FilterEstimate) FilterEstimate { + + return (FilterEstimate)(v4) + } type ActorStateLoader func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) @@ -86,46 +101,127 @@ func Load(store adt.Store, act *types.Actor) (cbor.Marshaler, error) { func ActorNameByCode(c cid.Cid) string { switch { + case builtin0.IsBuiltinActor(c): return builtin0.ActorNameByCode(c) + case builtin2.IsBuiltinActor(c): return builtin2.ActorNameByCode(c) + case builtin3.IsBuiltinActor(c): return builtin3.ActorNameByCode(c) + + case builtin4.IsBuiltinActor(c): + return builtin4.ActorNameByCode(c) + default: return "" } } func IsBuiltinActor(c cid.Cid) bool { - return builtin0.IsBuiltinActor(c) || - builtin2.IsBuiltinActor(c) || - builtin3.IsBuiltinActor(c) + + if builtin0.IsBuiltinActor(c) { + return true + } + + if builtin2.IsBuiltinActor(c) { + return true + } + + if builtin3.IsBuiltinActor(c) { + return true + } + + if builtin4.IsBuiltinActor(c) { + return true + } + + return false } func IsAccountActor(c cid.Cid) bool { - return c == builtin0.AccountActorCodeID || - c == builtin2.AccountActorCodeID || - c == builtin3.AccountActorCodeID + + if c == builtin0.AccountActorCodeID { + return true + } + + if c == builtin2.AccountActorCodeID { + return true + } + + if c == builtin3.AccountActorCodeID { + return true + } + + if c == builtin4.AccountActorCodeID { + return true + } + + return false } func IsStorageMinerActor(c cid.Cid) bool { - return c == builtin0.StorageMinerActorCodeID || - c == builtin2.StorageMinerActorCodeID || - c == builtin3.StorageMinerActorCodeID + + if c == builtin0.StorageMinerActorCodeID { + return true + } + + if c == builtin2.StorageMinerActorCodeID { + return true + } + + if c == builtin3.StorageMinerActorCodeID { + return true + } + + if c == builtin4.StorageMinerActorCodeID { + return true + } + + return false } func IsMultisigActor(c cid.Cid) bool { - return c == builtin0.MultisigActorCodeID || - c == builtin2.MultisigActorCodeID || - c == builtin3.MultisigActorCodeID + if c == builtin0.MultisigActorCodeID { + return true + } + + if c == builtin2.MultisigActorCodeID { + return true + } + + if c == builtin3.MultisigActorCodeID { + return true + } + + if c == builtin4.MultisigActorCodeID { + return true + } + + return false } func IsPaymentChannelActor(c cid.Cid) bool { - return c == builtin0.PaymentChannelActorCodeID || - c == builtin2.PaymentChannelActorCodeID || - c == builtin3.PaymentChannelActorCodeID + + if c == builtin0.PaymentChannelActorCodeID { + return true + } + + if c == builtin2.PaymentChannelActorCodeID { + return true + } + + if c == builtin3.PaymentChannelActorCodeID { + return true + } + + if c == builtin4.PaymentChannelActorCodeID { + return true + } + + return false } func makeAddress(addr string) address.Address { diff --git a/chain/actors/builtin/builtin.go.template b/chain/actors/builtin/builtin.go.template new file mode 100644 index 00000000000..9b89b13f56e --- /dev/null +++ b/chain/actors/builtin/builtin.go.template @@ -0,0 +1,144 @@ +package builtin + +import ( + "github.com/filecoin-project/go-address" + "github.com/ipfs/go-cid" + "golang.org/x/xerrors" + + {{range .versions}} + builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin" + smoothing{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/util/smoothing" + {{end}} + + "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" + + miner{{.latestVersion}} "github.com/filecoin-project/specs-actors{{import .latestVersion}}actors/builtin/miner" + proof{{.latestVersion}} "github.com/filecoin-project/specs-actors{{import .latestVersion}}actors/runtime/proof" +) + +var SystemActorAddr = builtin{{.latestVersion}}.SystemActorAddr +var BurntFundsActorAddr = builtin{{.latestVersion}}.BurntFundsActorAddr +var CronActorAddr = builtin{{.latestVersion}}.CronActorAddr +var SaftAddress = makeAddress("t0122") +var ReserveAddress = makeAddress("t090") +var RootVerifierAddress = makeAddress("t080") + +var ( + ExpectedLeadersPerEpoch = builtin{{.latestVersion}}.ExpectedLeadersPerEpoch +) + +const ( + EpochDurationSeconds = builtin{{.latestVersion}}.EpochDurationSeconds + EpochsInDay = builtin{{.latestVersion}}.EpochsInDay + SecondsInDay = builtin{{.latestVersion}}.SecondsInDay +) + +const ( + MethodSend = builtin{{.latestVersion}}.MethodSend + MethodConstructor = builtin{{.latestVersion}}.MethodConstructor +) + +// These are all just type aliases across actor versions. In the future, that might change +// and we might need to do something fancier. +type SectorInfo = proof{{.latestVersion}}.SectorInfo +type PoStProof = proof{{.latestVersion}}.PoStProof +type FilterEstimate = smoothing0.FilterEstimate + +func QAPowerForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight, verifiedWeight abi.DealWeight) abi.StoragePower { + return miner{{.latestVersion}}.QAPowerForWeight(size, duration, dealWeight, verifiedWeight) +} + +{{range .versions}} + func FromV{{.}}FilterEstimate(v{{.}} smoothing{{.}}.FilterEstimate) FilterEstimate { + {{if (eq . 0)}} + return (FilterEstimate)(v{{.}}) //nolint:unconvert + {{else}} + return (FilterEstimate)(v{{.}}) + {{end}} + } +{{end}} + +type ActorStateLoader func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) + +var ActorStateLoaders = make(map[cid.Cid]ActorStateLoader) + +func RegisterActorState(code cid.Cid, loader ActorStateLoader) { + ActorStateLoaders[code] = loader +} + +func Load(store adt.Store, act *types.Actor) (cbor.Marshaler, error) { + loader, found := ActorStateLoaders[act.Code] + if !found { + return nil, xerrors.Errorf("unknown actor code %s", act.Code) + } + return loader(store, act.Head) +} + +func ActorNameByCode(c cid.Cid) string { + switch { + {{range .versions}} + case builtin{{.}}.IsBuiltinActor(c): + return builtin{{.}}.ActorNameByCode(c) + {{end}} + default: + return "" + } +} + +func IsBuiltinActor(c cid.Cid) bool { + {{range .versions}} + if builtin{{.}}.IsBuiltinActor(c) { + return true + } + {{end}} + return false +} + +func IsAccountActor(c cid.Cid) bool { + {{range .versions}} + if c == builtin{{.}}.AccountActorCodeID { + return true + } + {{end}} + return false +} + +func IsStorageMinerActor(c cid.Cid) bool { + {{range .versions}} + if c == builtin{{.}}.StorageMinerActorCodeID { + return true + } + {{end}} + return false +} + +func IsMultisigActor(c cid.Cid) bool { + {{range .versions}} + if c == builtin{{.}}.MultisigActorCodeID { + return true + } + {{end}} + return false +} + +func IsPaymentChannelActor(c cid.Cid) bool { + {{range .versions}} + if c == builtin{{.}}.PaymentChannelActorCodeID { + return true + } + {{end}} + return false +} + +func makeAddress(addr string) address.Address { + ret, err := address.NewFromString(addr) + if err != nil { + panic(err) + } + + return ret +} diff --git a/chain/actors/builtin/cron/actor.go.template b/chain/actors/builtin/cron/actor.go.template new file mode 100644 index 00000000000..6b7449617fe --- /dev/null +++ b/chain/actors/builtin/cron/actor.go.template @@ -0,0 +1,10 @@ +package cron + +import ( + builtin{{.latestVersion}} "github.com/filecoin-project/specs-actors{{import .latestVersion}}actors/builtin" +) + +var ( + Address = builtin{{.latestVersion}}.CronActorAddr + Methods = builtin{{.latestVersion}}.MethodsCron +) diff --git a/chain/actors/builtin/cron/cron.go b/chain/actors/builtin/cron/cron.go index 284aad82e22..52a9fab0708 100644 --- a/chain/actors/builtin/cron/cron.go +++ b/chain/actors/builtin/cron/cron.go @@ -1,10 +1,10 @@ package cron import ( - builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" + builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" ) var ( - Address = builtin3.CronActorAddr - Methods = builtin3.MethodsCron + Address = builtin4.CronActorAddr + Methods = builtin4.MethodsCron ) diff --git a/chain/actors/builtin/init/actor.go.template b/chain/actors/builtin/init/actor.go.template new file mode 100644 index 00000000000..5b700cec863 --- /dev/null +++ b/chain/actors/builtin/init/actor.go.template @@ -0,0 +1,60 @@ +package init + +import ( + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/cbor" + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/node/modules/dtypes" +{{range .versions}} + builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin" +{{end}} +) + +func init() { +{{range .versions}} + builtin.RegisterActorState(builtin{{.}}.InitActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load{{.}}(store, root) + }) +{{end}}} + +var ( + Address = builtin{{.latestVersion}}.InitActorAddr + Methods = builtin{{.latestVersion}}.MethodsInit +) + +func Load(store adt.Store, act *types.Actor) (State, error) { + switch act.Code { +{{range .versions}} + case builtin{{.}}.InitActorCodeID: + return load{{.}}(store, act.Head) +{{end}} + } + return nil, xerrors.Errorf("unknown actor code %s", act.Code) +} + +type State interface { + cbor.Marshaler + + ResolveAddress(address address.Address) (address.Address, bool, error) + MapAddressToNewID(address address.Address) (address.Address, error) + NetworkName() (dtypes.NetworkName, error) + + ForEachActor(func(id abi.ActorID, address address.Address) error) error + + // Remove exists to support tooling that manipulates state for testing. + // It should not be used in production code, as init actor entries are + // immutable. + Remove(addrs ...address.Address) error + + // Sets the network's name. This should only be used on upgrade/fork. + SetNetworkName(name string) error + + addressMap() (adt.Map, error) +} diff --git a/chain/actors/builtin/init/init.go b/chain/actors/builtin/init/init.go index f9e91276847..730d21fd83f 100644 --- a/chain/actors/builtin/init/init.go +++ b/chain/actors/builtin/init/init.go @@ -14,35 +14,53 @@ import ( "github.com/filecoin-project/lotus/node/modules/dtypes" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" + + builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" ) func init() { + builtin.RegisterActorState(builtin0.InitActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load0(store, root) }) + builtin.RegisterActorState(builtin2.InitActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load2(store, root) }) + builtin.RegisterActorState(builtin3.InitActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load3(store, root) }) + + builtin.RegisterActorState(builtin4.InitActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load4(store, root) + }) } var ( - Address = builtin3.InitActorAddr - Methods = builtin3.MethodsInit + Address = builtin4.InitActorAddr + Methods = builtin4.MethodsInit ) func Load(store adt.Store, act *types.Actor) (State, error) { switch act.Code { + case builtin0.InitActorCodeID: return load0(store, act.Head) + case builtin2.InitActorCodeID: return load2(store, act.Head) + case builtin3.InitActorCodeID: return load3(store, act.Head) + + case builtin4.InitActorCodeID: + return load4(store, act.Head) + } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } diff --git a/chain/actors/builtin/init/state.go.template b/chain/actors/builtin/init/state.go.template new file mode 100644 index 00000000000..95f052bdaaf --- /dev/null +++ b/chain/actors/builtin/init/state.go.template @@ -0,0 +1,89 @@ +package init + +import ( + "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" + "github.com/filecoin-project/lotus/node/modules/dtypes" + +{{if (ge .v 3)}} + builtin{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin" +{{end}} + + init{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/init" + adt{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/util/adt" +) + +var _ State = (*state{{.v}})(nil) + +func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { + out := state{{.v}}{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +type state{{.v}} struct { + init{{.v}}.State + store adt.Store +} + +func (s *state{{.v}}) ResolveAddress(address address.Address) (address.Address, bool, error) { + return s.State.ResolveAddress(s.store, address) +} + +func (s *state{{.v}}) MapAddressToNewID(address address.Address) (address.Address, error) { + return s.State.MapAddressToNewID(s.store, address) +} + +func (s *state{{.v}}) ForEachActor(cb func(id abi.ActorID, address address.Address) error) error { + addrs, err := adt{{.v}}.AsMap(s.store, s.State.AddressMap{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}}) + if err != nil { + return err + } + var actorID cbg.CborInt + return addrs.ForEach(&actorID, func(key string) error { + addr, err := address.NewFromBytes([]byte(key)) + if err != nil { + return err + } + return cb(abi.ActorID(actorID), addr) + }) +} + +func (s *state{{.v}}) NetworkName() (dtypes.NetworkName, error) { + return dtypes.NetworkName(s.State.NetworkName), nil +} + +func (s *state{{.v}}) SetNetworkName(name string) error { + s.State.NetworkName = name + return nil +} + +func (s *state{{.v}}) Remove(addrs ...address.Address) (err error) { + m, err := adt{{.v}}.AsMap(s.store, s.State.AddressMap{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}}) + if err != nil { + return err + } + for _, addr := range addrs { + if err = m.Delete(abi.AddrKey(addr)); err != nil { + return xerrors.Errorf("failed to delete entry for address: %s; err: %w", addr, err) + } + } + amr, err := m.Root() + if err != nil { + return xerrors.Errorf("failed to get address map root: %w", err) + } + s.State.AddressMap = amr + return nil +} + +func (s *state{{.v}}) addressMap() (adt.Map, error) { + return adt{{.v}}.AsMap(s.store, s.AddressMap{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}}) +} diff --git a/chain/actors/builtin/init/v3.go b/chain/actors/builtin/init/v3.go index e586b3b1103..eaa54dfd4a3 100644 --- a/chain/actors/builtin/init/v3.go +++ b/chain/actors/builtin/init/v3.go @@ -3,7 +3,6 @@ package init import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" - builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" @@ -11,6 +10,8 @@ import ( "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/node/modules/dtypes" + builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" + init3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/init" adt3 "github.com/filecoin-project/specs-actors/v3/actors/util/adt" ) diff --git a/chain/actors/builtin/init/v4.go b/chain/actors/builtin/init/v4.go new file mode 100644 index 00000000000..38749eed55b --- /dev/null +++ b/chain/actors/builtin/init/v4.go @@ -0,0 +1,87 @@ +package init + +import ( + "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" + "github.com/filecoin-project/lotus/node/modules/dtypes" + + builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" + + init4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/init" + adt4 "github.com/filecoin-project/specs-actors/v4/actors/util/adt" +) + +var _ State = (*state4)(nil) + +func load4(store adt.Store, root cid.Cid) (State, error) { + out := state4{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +type state4 struct { + init4.State + store adt.Store +} + +func (s *state4) ResolveAddress(address address.Address) (address.Address, bool, error) { + return s.State.ResolveAddress(s.store, address) +} + +func (s *state4) MapAddressToNewID(address address.Address) (address.Address, error) { + return s.State.MapAddressToNewID(s.store, address) +} + +func (s *state4) ForEachActor(cb func(id abi.ActorID, address address.Address) error) error { + addrs, err := adt4.AsMap(s.store, s.State.AddressMap, builtin4.DefaultHamtBitwidth) + if err != nil { + return err + } + var actorID cbg.CborInt + return addrs.ForEach(&actorID, func(key string) error { + addr, err := address.NewFromBytes([]byte(key)) + if err != nil { + return err + } + return cb(abi.ActorID(actorID), addr) + }) +} + +func (s *state4) NetworkName() (dtypes.NetworkName, error) { + return dtypes.NetworkName(s.State.NetworkName), nil +} + +func (s *state4) SetNetworkName(name string) error { + s.State.NetworkName = name + return nil +} + +func (s *state4) Remove(addrs ...address.Address) (err error) { + m, err := adt4.AsMap(s.store, s.State.AddressMap, builtin4.DefaultHamtBitwidth) + if err != nil { + return err + } + for _, addr := range addrs { + if err = m.Delete(abi.AddrKey(addr)); err != nil { + return xerrors.Errorf("failed to delete entry for address: %s; err: %w", addr, err) + } + } + amr, err := m.Root() + if err != nil { + return xerrors.Errorf("failed to get address map root: %w", err) + } + s.State.AddressMap = amr + return nil +} + +func (s *state4) addressMap() (adt.Map, error) { + return adt4.AsMap(s.store, s.AddressMap, builtin4.DefaultHamtBitwidth) +} diff --git a/chain/actors/builtin/market/actor.go.template b/chain/actors/builtin/market/actor.go.template new file mode 100644 index 00000000000..39cfe1be7f0 --- /dev/null +++ b/chain/actors/builtin/market/actor.go.template @@ -0,0 +1,159 @@ +package market + +import ( + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/go-state-types/cbor" + "github.com/ipfs/go-cid" + cbg "github.com/whyrusleeping/cbor-gen" + + market0 "github.com/filecoin-project/specs-actors/actors/builtin/market" +{{range .versions}} + builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin" +{{end}} + + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/chain/types" +) + +func init() { +{{range .versions}} + builtin.RegisterActorState(builtin{{.}}.StorageMarketActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load{{.}}(store, root) + }) +{{end}}} + +var ( + Address = builtin{{.latestVersion}}.StorageMarketActorAddr + Methods = builtin{{.latestVersion}}.MethodsMarket +) + +func Load(store adt.Store, act *types.Actor) (State, error) { + switch act.Code { +{{range .versions}} + case builtin{{.}}.StorageMarketActorCodeID: + return load{{.}}(store, act.Head) +{{end}} + } + return nil, xerrors.Errorf("unknown actor code %s", act.Code) +} + +type State interface { + cbor.Marshaler + BalancesChanged(State) (bool, error) + EscrowTable() (BalanceTable, error) + LockedTable() (BalanceTable, error) + TotalLocked() (abi.TokenAmount, error) + StatesChanged(State) (bool, error) + States() (DealStates, error) + ProposalsChanged(State) (bool, error) + Proposals() (DealProposals, error) + VerifyDealsForActivation( + minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch, + ) (weight, verifiedWeight abi.DealWeight, err error) + NextID() (abi.DealID, error) +} + +type BalanceTable interface { + ForEach(cb func(address.Address, abi.TokenAmount) error) error + Get(key address.Address) (abi.TokenAmount, error) +} + +type DealStates interface { + ForEach(cb func(id abi.DealID, ds DealState) error) error + Get(id abi.DealID) (*DealState, bool, error) + + array() adt.Array + decode(*cbg.Deferred) (*DealState, error) +} + +type DealProposals interface { + ForEach(cb func(id abi.DealID, dp DealProposal) error) error + Get(id abi.DealID) (*DealProposal, bool, error) + + array() adt.Array + decode(*cbg.Deferred) (*DealProposal, error) +} + +type PublishStorageDealsParams = market0.PublishStorageDealsParams +type PublishStorageDealsReturn = market0.PublishStorageDealsReturn +type VerifyDealsForActivationParams = market0.VerifyDealsForActivationParams +type WithdrawBalanceParams = market0.WithdrawBalanceParams + +type ClientDealProposal = market0.ClientDealProposal + +type DealState struct { + SectorStartEpoch abi.ChainEpoch // -1 if not yet included in proven sector + LastUpdatedEpoch abi.ChainEpoch // -1 if deal state never updated + SlashEpoch abi.ChainEpoch // -1 if deal never slashed +} + +type DealProposal struct { + PieceCID cid.Cid + PieceSize abi.PaddedPieceSize + VerifiedDeal bool + Client address.Address + Provider address.Address + Label string + StartEpoch abi.ChainEpoch + EndEpoch abi.ChainEpoch + StoragePricePerEpoch abi.TokenAmount + ProviderCollateral abi.TokenAmount + ClientCollateral abi.TokenAmount +} + +type DealStateChanges struct { + Added []DealIDState + Modified []DealStateChange + Removed []DealIDState +} + +type DealIDState struct { + ID abi.DealID + Deal DealState +} + +// DealStateChange is a change in deal state from -> to +type DealStateChange struct { + ID abi.DealID + From *DealState + To *DealState +} + +type DealProposalChanges struct { + Added []ProposalIDState + Removed []ProposalIDState +} + +type ProposalIDState struct { + ID abi.DealID + Proposal DealProposal +} + +func EmptyDealState() *DealState { + return &DealState{ + SectorStartEpoch: -1, + SlashEpoch: -1, + LastUpdatedEpoch: -1, + } +} + +// returns the earned fees and pending fees for a given deal +func (deal DealProposal) GetDealFees(height abi.ChainEpoch) (abi.TokenAmount, abi.TokenAmount) { + tf := big.Mul(deal.StoragePricePerEpoch, big.NewInt(int64(deal.EndEpoch-deal.StartEpoch))) + + ef := big.Mul(deal.StoragePricePerEpoch, big.NewInt(int64(height-deal.StartEpoch))) + if ef.LessThan(big.Zero()) { + ef = big.Zero() + } + + if ef.GreaterThan(tf) { + ef = tf + } + + return ef, big.Sub(tf, ef) +} diff --git a/chain/actors/builtin/market/market.go b/chain/actors/builtin/market/market.go index 0e4d9e01b78..adf7ce33db0 100644 --- a/chain/actors/builtin/market/market.go +++ b/chain/actors/builtin/market/market.go @@ -5,45 +5,65 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/cbor" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" market0 "github.com/filecoin-project/specs-actors/actors/builtin/market" + + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" + builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/types" ) func init() { + builtin.RegisterActorState(builtin0.StorageMarketActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load0(store, root) }) + builtin.RegisterActorState(builtin2.StorageMarketActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load2(store, root) }) + builtin.RegisterActorState(builtin3.StorageMarketActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load3(store, root) }) + + builtin.RegisterActorState(builtin4.StorageMarketActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load4(store, root) + }) } var ( - Address = builtin3.StorageMarketActorAddr - Methods = builtin3.MethodsMarket + Address = builtin4.StorageMarketActorAddr + Methods = builtin4.MethodsMarket ) -func Load(store adt.Store, act *types.Actor) (st State, err error) { +func Load(store adt.Store, act *types.Actor) (State, error) { switch act.Code { + case builtin0.StorageMarketActorCodeID: return load0(store, act.Head) + case builtin2.StorageMarketActorCodeID: return load2(store, act.Head) + case builtin3.StorageMarketActorCodeID: return load3(store, act.Head) + + case builtin4.StorageMarketActorCodeID: + return load4(store, act.Head) + } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } @@ -147,3 +167,19 @@ func EmptyDealState() *DealState { LastUpdatedEpoch: -1, } } + +// returns the earned fees and pending fees for a given deal +func (deal DealProposal) GetDealFees(height abi.ChainEpoch) (abi.TokenAmount, abi.TokenAmount) { + tf := big.Mul(deal.StoragePricePerEpoch, big.NewInt(int64(deal.EndEpoch-deal.StartEpoch))) + + ef := big.Mul(deal.StoragePricePerEpoch, big.NewInt(int64(height-deal.StartEpoch))) + if ef.LessThan(big.Zero()) { + ef = big.Zero() + } + + if ef.GreaterThan(tf) { + ef = tf + } + + return ef, big.Sub(tf, ef) +} diff --git a/chain/actors/builtin/market/state.go.template b/chain/actors/builtin/market/state.go.template new file mode 100644 index 00000000000..a55743ce553 --- /dev/null +++ b/chain/actors/builtin/market/state.go.template @@ -0,0 +1,209 @@ +package market + +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/types" + + market{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/market" + adt{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/util/adt" +) + +var _ State = (*state{{.v}})(nil) + +func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { + out := state{{.v}}{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +type state{{.v}} struct { + market{{.v}}.State + store adt.Store +} + +func (s *state{{.v}}) TotalLocked() (abi.TokenAmount, error) { + fml := types.BigAdd(s.TotalClientLockedCollateral, s.TotalProviderLockedCollateral) + fml = types.BigAdd(fml, s.TotalClientStorageFee) + return fml, nil +} + +func (s *state{{.v}}) BalancesChanged(otherState State) (bool, error) { + otherState{{.v}}, ok := otherState.(*state{{.v}}) + if !ok { + // there's no way to compare different versions of the state, so let's + // just say that means the state of balances has changed + return true, nil + } + return !s.State.EscrowTable.Equals(otherState{{.v}}.State.EscrowTable) || !s.State.LockedTable.Equals(otherState{{.v}}.State.LockedTable), nil +} + +func (s *state{{.v}}) StatesChanged(otherState State) (bool, error) { + otherState{{.v}}, ok := otherState.(*state{{.v}}) + if !ok { + // there's no way to compare different versions of the state, so let's + // just say that means the state of balances has changed + return true, nil + } + return !s.State.States.Equals(otherState{{.v}}.State.States), nil +} + +func (s *state{{.v}}) States() (DealStates, error) { + stateArray, err := adt{{.v}}.AsArray(s.store, s.State.States{{if (ge .v 3)}}, market{{.v}}.StatesAmtBitwidth{{end}}) + if err != nil { + return nil, err + } + return &dealStates{{.v}}{stateArray}, nil +} + +func (s *state{{.v}}) ProposalsChanged(otherState State) (bool, error) { + otherState{{.v}}, ok := otherState.(*state{{.v}}) + if !ok { + // there's no way to compare different versions of the state, so let's + // just say that means the state of balances has changed + return true, nil + } + return !s.State.Proposals.Equals(otherState{{.v}}.State.Proposals), nil +} + +func (s *state{{.v}}) Proposals() (DealProposals, error) { + proposalArray, err := adt{{.v}}.AsArray(s.store, s.State.Proposals{{if (ge .v 3)}}, market{{.v}}.ProposalsAmtBitwidth{{end}}) + if err != nil { + return nil, err + } + return &dealProposals{{.v}}{proposalArray}, nil +} + +func (s *state{{.v}}) EscrowTable() (BalanceTable, error) { + bt, err := adt{{.v}}.AsBalanceTable(s.store, s.State.EscrowTable) + if err != nil { + return nil, err + } + return &balanceTable{{.v}}{bt}, nil +} + +func (s *state{{.v}}) LockedTable() (BalanceTable, error) { + bt, err := adt{{.v}}.AsBalanceTable(s.store, s.State.LockedTable) + if err != nil { + return nil, err + } + return &balanceTable{{.v}}{bt}, nil +} + +func (s *state{{.v}}) VerifyDealsForActivation( + minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch, +) (weight, verifiedWeight abi.DealWeight, err error) { + w, vw{{if (ge .v 2)}}, _{{end}}, err := market{{.v}}.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch) + return w, vw, err +} + +func (s *state{{.v}}) NextID() (abi.DealID, error) { + return s.State.NextID, nil +} + +type balanceTable{{.v}} struct { + *adt{{.v}}.BalanceTable +} + +func (bt *balanceTable{{.v}}) ForEach(cb func(address.Address, abi.TokenAmount) error) error { + asMap := (*adt{{.v}}.Map)(bt.BalanceTable) + var ta abi.TokenAmount + return asMap.ForEach(&ta, func(key string) error { + a, err := address.NewFromBytes([]byte(key)) + if err != nil { + return err + } + return cb(a, ta) + }) +} + +type dealStates{{.v}} struct { + adt.Array +} + +func (s *dealStates{{.v}}) Get(dealID abi.DealID) (*DealState, bool, error) { + var deal{{.v}} market{{.v}}.DealState + found, err := s.Array.Get(uint64(dealID), &deal{{.v}}) + if err != nil { + return nil, false, err + } + if !found { + return nil, false, nil + } + deal := fromV{{.v}}DealState(deal{{.v}}) + return &deal, true, nil +} + +func (s *dealStates{{.v}}) ForEach(cb func(dealID abi.DealID, ds DealState) error) error { + var ds{{.v}} market{{.v}}.DealState + return s.Array.ForEach(&ds{{.v}}, func(idx int64) error { + return cb(abi.DealID(idx), fromV{{.v}}DealState(ds{{.v}})) + }) +} + +func (s *dealStates{{.v}}) decode(val *cbg.Deferred) (*DealState, error) { + var ds{{.v}} market{{.v}}.DealState + if err := ds{{.v}}.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { + return nil, err + } + ds := fromV{{.v}}DealState(ds{{.v}}) + return &ds, nil +} + +func (s *dealStates{{.v}}) array() adt.Array { + return s.Array +} + +func fromV{{.v}}DealState(v{{.v}} market{{.v}}.DealState) DealState { + return (DealState)(v{{.v}}) +} + +type dealProposals{{.v}} struct { + adt.Array +} + +func (s *dealProposals{{.v}}) Get(dealID abi.DealID) (*DealProposal, bool, error) { + var proposal{{.v}} market{{.v}}.DealProposal + found, err := s.Array.Get(uint64(dealID), &proposal{{.v}}) + if err != nil { + return nil, false, err + } + if !found { + return nil, false, nil + } + proposal := fromV{{.v}}DealProposal(proposal{{.v}}) + return &proposal, true, nil +} + +func (s *dealProposals{{.v}}) ForEach(cb func(dealID abi.DealID, dp DealProposal) error) error { + var dp{{.v}} market{{.v}}.DealProposal + return s.Array.ForEach(&dp{{.v}}, func(idx int64) error { + return cb(abi.DealID(idx), fromV{{.v}}DealProposal(dp{{.v}})) + }) +} + +func (s *dealProposals{{.v}}) decode(val *cbg.Deferred) (*DealProposal, error) { + var dp{{.v}} market{{.v}}.DealProposal + if err := dp{{.v}}.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { + return nil, err + } + dp := fromV{{.v}}DealProposal(dp{{.v}}) + return &dp, nil +} + +func (s *dealProposals{{.v}}) array() adt.Array { + return s.Array +} + +func fromV{{.v}}DealProposal(v{{.v}} market{{.v}}.DealProposal) DealProposal { + return (DealProposal)(v{{.v}}) +} diff --git a/chain/actors/builtin/market/v0.go b/chain/actors/builtin/market/v0.go index f3b885995b3..175c0a2ea9c 100644 --- a/chain/actors/builtin/market/v0.go +++ b/chain/actors/builtin/market/v0.go @@ -102,7 +102,8 @@ func (s *state0) LockedTable() (BalanceTable, error) { func (s *state0) VerifyDealsForActivation( minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch, ) (weight, verifiedWeight abi.DealWeight, err error) { - return market0.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch) + w, vw, err := market0.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch) + return w, vw, err } func (s *state0) NextID() (abi.DealID, error) { diff --git a/chain/actors/builtin/market/v2.go b/chain/actors/builtin/market/v2.go index 1ce051c387b..dafae8feb95 100644 --- a/chain/actors/builtin/market/v2.go +++ b/chain/actors/builtin/market/v2.go @@ -144,18 +144,18 @@ func (s *dealStates2) Get(dealID abi.DealID) (*DealState, bool, error) { } func (s *dealStates2) ForEach(cb func(dealID abi.DealID, ds DealState) error) error { - var ds1 market2.DealState - return s.Array.ForEach(&ds1, func(idx int64) error { - return cb(abi.DealID(idx), fromV2DealState(ds1)) + var ds2 market2.DealState + return s.Array.ForEach(&ds2, func(idx int64) error { + return cb(abi.DealID(idx), fromV2DealState(ds2)) }) } func (s *dealStates2) decode(val *cbg.Deferred) (*DealState, error) { - var ds1 market2.DealState - if err := ds1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { + var ds2 market2.DealState + if err := ds2.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { return nil, err } - ds := fromV2DealState(ds1) + ds := fromV2DealState(ds2) return &ds, nil } @@ -163,8 +163,8 @@ func (s *dealStates2) array() adt.Array { return s.Array } -func fromV2DealState(v1 market2.DealState) DealState { - return (DealState)(v1) +func fromV2DealState(v2 market2.DealState) DealState { + return (DealState)(v2) } type dealProposals2 struct { @@ -185,18 +185,18 @@ func (s *dealProposals2) Get(dealID abi.DealID) (*DealProposal, bool, error) { } func (s *dealProposals2) ForEach(cb func(dealID abi.DealID, dp DealProposal) error) error { - var dp1 market2.DealProposal - return s.Array.ForEach(&dp1, func(idx int64) error { - return cb(abi.DealID(idx), fromV2DealProposal(dp1)) + var dp2 market2.DealProposal + return s.Array.ForEach(&dp2, func(idx int64) error { + return cb(abi.DealID(idx), fromV2DealProposal(dp2)) }) } func (s *dealProposals2) decode(val *cbg.Deferred) (*DealProposal, error) { - var dp1 market2.DealProposal - if err := dp1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { + var dp2 market2.DealProposal + if err := dp2.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { return nil, err } - dp := fromV2DealProposal(dp1) + dp := fromV2DealProposal(dp2) return &dp, nil } @@ -204,6 +204,6 @@ func (s *dealProposals2) array() adt.Array { return s.Array } -func fromV2DealProposal(v1 market2.DealProposal) DealProposal { - return (DealProposal)(v1) +func fromV2DealProposal(v2 market2.DealProposal) DealProposal { + return (DealProposal)(v2) } diff --git a/chain/actors/builtin/market/v3.go b/chain/actors/builtin/market/v3.go index 15251985be9..dec8d6e2513 100644 --- a/chain/actors/builtin/market/v3.go +++ b/chain/actors/builtin/market/v3.go @@ -38,23 +38,23 @@ func (s *state3) TotalLocked() (abi.TokenAmount, error) { } func (s *state3) BalancesChanged(otherState State) (bool, error) { - otherState2, ok := otherState.(*state3) + otherState3, ok := otherState.(*state3) if !ok { // there's no way to compare different versions of the state, so let's // just say that means the state of balances has changed return true, nil } - return !s.State.EscrowTable.Equals(otherState2.State.EscrowTable) || !s.State.LockedTable.Equals(otherState2.State.LockedTable), nil + return !s.State.EscrowTable.Equals(otherState3.State.EscrowTable) || !s.State.LockedTable.Equals(otherState3.State.LockedTable), nil } func (s *state3) StatesChanged(otherState State) (bool, error) { - otherState2, ok := otherState.(*state3) + otherState3, ok := otherState.(*state3) if !ok { // there's no way to compare different versions of the state, so let's // just say that means the state of balances has changed return true, nil } - return !s.State.States.Equals(otherState2.State.States), nil + return !s.State.States.Equals(otherState3.State.States), nil } func (s *state3) States() (DealStates, error) { @@ -66,13 +66,13 @@ func (s *state3) States() (DealStates, error) { } func (s *state3) ProposalsChanged(otherState State) (bool, error) { - otherState2, ok := otherState.(*state3) + otherState3, ok := otherState.(*state3) if !ok { // there's no way to compare different versions of the state, so let's // just say that means the state of balances has changed return true, nil } - return !s.State.Proposals.Equals(otherState2.State.Proposals), nil + return !s.State.Proposals.Equals(otherState3.State.Proposals), nil } func (s *state3) Proposals() (DealProposals, error) { @@ -131,31 +131,31 @@ type dealStates3 struct { } func (s *dealStates3) Get(dealID abi.DealID) (*DealState, bool, error) { - var deal2 market3.DealState - found, err := s.Array.Get(uint64(dealID), &deal2) + var deal3 market3.DealState + found, err := s.Array.Get(uint64(dealID), &deal3) if err != nil { return nil, false, err } if !found { return nil, false, nil } - deal := fromV3DealState(deal2) + deal := fromV3DealState(deal3) return &deal, true, nil } func (s *dealStates3) ForEach(cb func(dealID abi.DealID, ds DealState) error) error { - var ds1 market3.DealState - return s.Array.ForEach(&ds1, func(idx int64) error { - return cb(abi.DealID(idx), fromV3DealState(ds1)) + var ds3 market3.DealState + return s.Array.ForEach(&ds3, func(idx int64) error { + return cb(abi.DealID(idx), fromV3DealState(ds3)) }) } func (s *dealStates3) decode(val *cbg.Deferred) (*DealState, error) { - var ds1 market3.DealState - if err := ds1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { + var ds3 market3.DealState + if err := ds3.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { return nil, err } - ds := fromV3DealState(ds1) + ds := fromV3DealState(ds3) return &ds, nil } @@ -163,8 +163,8 @@ func (s *dealStates3) array() adt.Array { return s.Array } -func fromV3DealState(v1 market3.DealState) DealState { - return (DealState)(v1) +func fromV3DealState(v3 market3.DealState) DealState { + return (DealState)(v3) } type dealProposals3 struct { @@ -172,31 +172,31 @@ type dealProposals3 struct { } func (s *dealProposals3) Get(dealID abi.DealID) (*DealProposal, bool, error) { - var proposal2 market3.DealProposal - found, err := s.Array.Get(uint64(dealID), &proposal2) + var proposal3 market3.DealProposal + found, err := s.Array.Get(uint64(dealID), &proposal3) if err != nil { return nil, false, err } if !found { return nil, false, nil } - proposal := fromV3DealProposal(proposal2) + proposal := fromV3DealProposal(proposal3) return &proposal, true, nil } func (s *dealProposals3) ForEach(cb func(dealID abi.DealID, dp DealProposal) error) error { - var dp1 market3.DealProposal - return s.Array.ForEach(&dp1, func(idx int64) error { - return cb(abi.DealID(idx), fromV3DealProposal(dp1)) + var dp3 market3.DealProposal + return s.Array.ForEach(&dp3, func(idx int64) error { + return cb(abi.DealID(idx), fromV3DealProposal(dp3)) }) } func (s *dealProposals3) decode(val *cbg.Deferred) (*DealProposal, error) { - var dp1 market3.DealProposal - if err := dp1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { + var dp3 market3.DealProposal + if err := dp3.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { return nil, err } - dp := fromV3DealProposal(dp1) + dp := fromV3DealProposal(dp3) return &dp, nil } @@ -204,6 +204,6 @@ func (s *dealProposals3) array() adt.Array { return s.Array } -func fromV3DealProposal(v1 market3.DealProposal) DealProposal { - return (DealProposal)(v1) +func fromV3DealProposal(v3 market3.DealProposal) DealProposal { + return (DealProposal)(v3) } diff --git a/chain/actors/builtin/market/v4.go b/chain/actors/builtin/market/v4.go new file mode 100644 index 00000000000..22514395c00 --- /dev/null +++ b/chain/actors/builtin/market/v4.go @@ -0,0 +1,209 @@ +package market + +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/types" + + market4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/market" + adt4 "github.com/filecoin-project/specs-actors/v4/actors/util/adt" +) + +var _ State = (*state4)(nil) + +func load4(store adt.Store, root cid.Cid) (State, error) { + out := state4{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +type state4 struct { + market4.State + store adt.Store +} + +func (s *state4) TotalLocked() (abi.TokenAmount, error) { + fml := types.BigAdd(s.TotalClientLockedCollateral, s.TotalProviderLockedCollateral) + fml = types.BigAdd(fml, s.TotalClientStorageFee) + return fml, nil +} + +func (s *state4) BalancesChanged(otherState State) (bool, error) { + otherState4, ok := otherState.(*state4) + if !ok { + // there's no way to compare different versions of the state, so let's + // just say that means the state of balances has changed + return true, nil + } + return !s.State.EscrowTable.Equals(otherState4.State.EscrowTable) || !s.State.LockedTable.Equals(otherState4.State.LockedTable), nil +} + +func (s *state4) StatesChanged(otherState State) (bool, error) { + otherState4, ok := otherState.(*state4) + if !ok { + // there's no way to compare different versions of the state, so let's + // just say that means the state of balances has changed + return true, nil + } + return !s.State.States.Equals(otherState4.State.States), nil +} + +func (s *state4) States() (DealStates, error) { + stateArray, err := adt4.AsArray(s.store, s.State.States, market4.StatesAmtBitwidth) + if err != nil { + return nil, err + } + return &dealStates4{stateArray}, nil +} + +func (s *state4) ProposalsChanged(otherState State) (bool, error) { + otherState4, ok := otherState.(*state4) + if !ok { + // there's no way to compare different versions of the state, so let's + // just say that means the state of balances has changed + return true, nil + } + return !s.State.Proposals.Equals(otherState4.State.Proposals), nil +} + +func (s *state4) Proposals() (DealProposals, error) { + proposalArray, err := adt4.AsArray(s.store, s.State.Proposals, market4.ProposalsAmtBitwidth) + if err != nil { + return nil, err + } + return &dealProposals4{proposalArray}, nil +} + +func (s *state4) EscrowTable() (BalanceTable, error) { + bt, err := adt4.AsBalanceTable(s.store, s.State.EscrowTable) + if err != nil { + return nil, err + } + return &balanceTable4{bt}, nil +} + +func (s *state4) LockedTable() (BalanceTable, error) { + bt, err := adt4.AsBalanceTable(s.store, s.State.LockedTable) + if err != nil { + return nil, err + } + return &balanceTable4{bt}, nil +} + +func (s *state4) VerifyDealsForActivation( + minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch, +) (weight, verifiedWeight abi.DealWeight, err error) { + w, vw, _, err := market4.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch) + return w, vw, err +} + +func (s *state4) NextID() (abi.DealID, error) { + return s.State.NextID, nil +} + +type balanceTable4 struct { + *adt4.BalanceTable +} + +func (bt *balanceTable4) ForEach(cb func(address.Address, abi.TokenAmount) error) error { + asMap := (*adt4.Map)(bt.BalanceTable) + var ta abi.TokenAmount + return asMap.ForEach(&ta, func(key string) error { + a, err := address.NewFromBytes([]byte(key)) + if err != nil { + return err + } + return cb(a, ta) + }) +} + +type dealStates4 struct { + adt.Array +} + +func (s *dealStates4) Get(dealID abi.DealID) (*DealState, bool, error) { + var deal4 market4.DealState + found, err := s.Array.Get(uint64(dealID), &deal4) + if err != nil { + return nil, false, err + } + if !found { + return nil, false, nil + } + deal := fromV4DealState(deal4) + return &deal, true, nil +} + +func (s *dealStates4) ForEach(cb func(dealID abi.DealID, ds DealState) error) error { + var ds4 market4.DealState + return s.Array.ForEach(&ds4, func(idx int64) error { + return cb(abi.DealID(idx), fromV4DealState(ds4)) + }) +} + +func (s *dealStates4) decode(val *cbg.Deferred) (*DealState, error) { + var ds4 market4.DealState + if err := ds4.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { + return nil, err + } + ds := fromV4DealState(ds4) + return &ds, nil +} + +func (s *dealStates4) array() adt.Array { + return s.Array +} + +func fromV4DealState(v4 market4.DealState) DealState { + return (DealState)(v4) +} + +type dealProposals4 struct { + adt.Array +} + +func (s *dealProposals4) Get(dealID abi.DealID) (*DealProposal, bool, error) { + var proposal4 market4.DealProposal + found, err := s.Array.Get(uint64(dealID), &proposal4) + if err != nil { + return nil, false, err + } + if !found { + return nil, false, nil + } + proposal := fromV4DealProposal(proposal4) + return &proposal, true, nil +} + +func (s *dealProposals4) ForEach(cb func(dealID abi.DealID, dp DealProposal) error) error { + var dp4 market4.DealProposal + return s.Array.ForEach(&dp4, func(idx int64) error { + return cb(abi.DealID(idx), fromV4DealProposal(dp4)) + }) +} + +func (s *dealProposals4) decode(val *cbg.Deferred) (*DealProposal, error) { + var dp4 market4.DealProposal + if err := dp4.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { + return nil, err + } + dp := fromV4DealProposal(dp4) + return &dp, nil +} + +func (s *dealProposals4) array() adt.Array { + return s.Array +} + +func fromV4DealProposal(v4 market4.DealProposal) DealProposal { + return (DealProposal)(v4) +} diff --git a/chain/actors/builtin/miner/actor.go.template b/chain/actors/builtin/miner/actor.go.template new file mode 100644 index 00000000000..4b3d8db5e6f --- /dev/null +++ b/chain/actors/builtin/miner/actor.go.template @@ -0,0 +1,270 @@ +package miner + +import ( + "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/go-state-types/network" + "github.com/ipfs/go-cid" + "github.com/libp2p/go-libp2p-core/peer" + cbg "github.com/whyrusleeping/cbor-gen" + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-bitfield" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/cbor" + "github.com/filecoin-project/go-state-types/dline" + + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/chain/types" + + miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" + miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" + miner3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/miner" +{{range .versions}} + builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin" +{{end}} +) + +func init() { +{{range .versions}} + builtin.RegisterActorState(builtin{{.}}.StorageMinerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load{{.}}(store, root) + }) +{{end}} +} + +var Methods = builtin{{.latestVersion}}.MethodsMiner + +// Unchanged between v0, v2, v3, and v4 actors +var WPoStProvingPeriod = miner0.WPoStProvingPeriod +var WPoStPeriodDeadlines = miner0.WPoStPeriodDeadlines +var WPoStChallengeWindow = miner0.WPoStChallengeWindow +var WPoStChallengeLookback = miner0.WPoStChallengeLookback +var FaultDeclarationCutoff = miner0.FaultDeclarationCutoff + +const MinSectorExpiration = miner0.MinSectorExpiration + +// Not used / checked in v0 +// TODO: Abstract over network versions +var DeclarationsMax = miner2.DeclarationsMax +var AddressedSectorsMax = miner2.AddressedSectorsMax + +func Load(store adt.Store, act *types.Actor) (State, error) { + switch act.Code { +{{range .versions}} + case builtin{{.}}.StorageMinerActorCodeID: + return load{{.}}(store, act.Head) +{{end}} +} + return nil, xerrors.Errorf("unknown actor code %s", act.Code) +} + +type State interface { + cbor.Marshaler + + // Total available balance to spend. + AvailableBalance(abi.TokenAmount) (abi.TokenAmount, error) + // Funds that will vest by the given epoch. + VestedFunds(abi.ChainEpoch) (abi.TokenAmount, error) + // Funds locked for various reasons. + LockedFunds() (LockedFunds, error) + FeeDebt() (abi.TokenAmount, error) + + GetSector(abi.SectorNumber) (*SectorOnChainInfo, error) + FindSector(abi.SectorNumber) (*SectorLocation, error) + GetSectorExpiration(abi.SectorNumber) (*SectorExpiration, error) + GetPrecommittedSector(abi.SectorNumber) (*SectorPreCommitOnChainInfo, error) + LoadSectors(sectorNos *bitfield.BitField) ([]*SectorOnChainInfo, error) + NumLiveSectors() (uint64, error) + IsAllocated(abi.SectorNumber) (bool, error) + + LoadDeadline(idx uint64) (Deadline, error) + ForEachDeadline(cb func(idx uint64, dl Deadline) error) error + NumDeadlines() (uint64, error) + DeadlinesChanged(State) (bool, error) + + Info() (MinerInfo, error) + MinerInfoChanged(State) (bool, error) + + DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error) + DeadlineCronActive() (bool, error) + + // Diff helpers. Used by Diff* functions internally. + sectors() (adt.Array, error) + decodeSectorOnChainInfo(*cbg.Deferred) (SectorOnChainInfo, error) + precommits() (adt.Map, error) + decodeSectorPreCommitOnChainInfo(*cbg.Deferred) (SectorPreCommitOnChainInfo, error) +} + +type Deadline interface { + LoadPartition(idx uint64) (Partition, error) + ForEachPartition(cb func(idx uint64, part Partition) error) error + PartitionsPoSted() (bitfield.BitField, error) + + PartitionsChanged(Deadline) (bool, error) + DisputableProofCount() (uint64, error) +} + +type Partition interface { + AllSectors() (bitfield.BitField, error) + FaultySectors() (bitfield.BitField, error) + RecoveringSectors() (bitfield.BitField, error) + LiveSectors() (bitfield.BitField, error) + ActiveSectors() (bitfield.BitField, error) +} + +type SectorOnChainInfo struct { + SectorNumber abi.SectorNumber + SealProof abi.RegisteredSealProof + SealedCID cid.Cid + DealIDs []abi.DealID + Activation abi.ChainEpoch + Expiration abi.ChainEpoch + DealWeight abi.DealWeight + VerifiedDealWeight abi.DealWeight + InitialPledge abi.TokenAmount + ExpectedDayReward abi.TokenAmount + ExpectedStoragePledge abi.TokenAmount +} + +type SectorPreCommitInfo = miner0.SectorPreCommitInfo + +type SectorPreCommitOnChainInfo struct { + Info SectorPreCommitInfo + PreCommitDeposit abi.TokenAmount + PreCommitEpoch abi.ChainEpoch + DealWeight abi.DealWeight + VerifiedDealWeight abi.DealWeight +} + +type PoStPartition = miner0.PoStPartition +type RecoveryDeclaration = miner0.RecoveryDeclaration +type FaultDeclaration = miner0.FaultDeclaration + +// Params +type DeclareFaultsParams = miner0.DeclareFaultsParams +type DeclareFaultsRecoveredParams = miner0.DeclareFaultsRecoveredParams +type SubmitWindowedPoStParams = miner0.SubmitWindowedPoStParams +type ProveCommitSectorParams = miner0.ProveCommitSectorParams +type DisputeWindowedPoStParams = miner3.DisputeWindowedPoStParams + +func PreferredSealProofTypeFromWindowPoStType(nver network.Version, proof abi.RegisteredPoStProof) (abi.RegisteredSealProof, error) { + // We added support for the new proofs in network version 7, and removed support for the old + // ones in network version 8. + if nver < network.Version7 { + switch proof { + case abi.RegisteredPoStProof_StackedDrgWindow2KiBV1: + return abi.RegisteredSealProof_StackedDrg2KiBV1, nil + case abi.RegisteredPoStProof_StackedDrgWindow8MiBV1: + return abi.RegisteredSealProof_StackedDrg8MiBV1, nil + case abi.RegisteredPoStProof_StackedDrgWindow512MiBV1: + return abi.RegisteredSealProof_StackedDrg512MiBV1, nil + case abi.RegisteredPoStProof_StackedDrgWindow32GiBV1: + return abi.RegisteredSealProof_StackedDrg32GiBV1, nil + case abi.RegisteredPoStProof_StackedDrgWindow64GiBV1: + return abi.RegisteredSealProof_StackedDrg64GiBV1, nil + default: + return -1, xerrors.Errorf("unrecognized window post type: %d", proof) + } + } + + switch proof { + case abi.RegisteredPoStProof_StackedDrgWindow2KiBV1: + return abi.RegisteredSealProof_StackedDrg2KiBV1_1, nil + case abi.RegisteredPoStProof_StackedDrgWindow8MiBV1: + return abi.RegisteredSealProof_StackedDrg8MiBV1_1, nil + case abi.RegisteredPoStProof_StackedDrgWindow512MiBV1: + return abi.RegisteredSealProof_StackedDrg512MiBV1_1, nil + case abi.RegisteredPoStProof_StackedDrgWindow32GiBV1: + return abi.RegisteredSealProof_StackedDrg32GiBV1_1, nil + case abi.RegisteredPoStProof_StackedDrgWindow64GiBV1: + return abi.RegisteredSealProof_StackedDrg64GiBV1_1, nil + default: + return -1, xerrors.Errorf("unrecognized window post type: %d", proof) + } +} + +func WinningPoStProofTypeFromWindowPoStProofType(nver network.Version, proof abi.RegisteredPoStProof) (abi.RegisteredPoStProof, error) { + switch proof { + case abi.RegisteredPoStProof_StackedDrgWindow2KiBV1: + return abi.RegisteredPoStProof_StackedDrgWinning2KiBV1, nil + case abi.RegisteredPoStProof_StackedDrgWindow8MiBV1: + return abi.RegisteredPoStProof_StackedDrgWinning8MiBV1, nil + case abi.RegisteredPoStProof_StackedDrgWindow512MiBV1: + return abi.RegisteredPoStProof_StackedDrgWinning512MiBV1, nil + case abi.RegisteredPoStProof_StackedDrgWindow32GiBV1: + return abi.RegisteredPoStProof_StackedDrgWinning32GiBV1, nil + case abi.RegisteredPoStProof_StackedDrgWindow64GiBV1: + return abi.RegisteredPoStProof_StackedDrgWinning64GiBV1, nil + default: + return -1, xerrors.Errorf("unknown proof type %d", proof) + } +} + +type MinerInfo struct { + Owner address.Address // Must be an ID-address. + Worker address.Address // Must be an ID-address. + NewWorker address.Address // Must be an ID-address. + ControlAddresses []address.Address // Must be an ID-addresses. + WorkerChangeEpoch abi.ChainEpoch + PeerId *peer.ID + Multiaddrs []abi.Multiaddrs + WindowPoStProofType abi.RegisteredPoStProof + SectorSize abi.SectorSize + WindowPoStPartitionSectors uint64 + 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 + + // non-zero if sector is faulty, epoch at which it will be permanently + // removed if it doesn't recover + Early abi.ChainEpoch +} + +type SectorLocation struct { + Deadline uint64 + Partition uint64 +} + +type SectorChanges struct { + Added []SectorOnChainInfo + Extended []SectorExtensions + Removed []SectorOnChainInfo +} + +type SectorExtensions struct { + From SectorOnChainInfo + To SectorOnChainInfo +} + +type PreCommitChanges struct { + Added []SectorPreCommitOnChainInfo + Removed []SectorPreCommitOnChainInfo +} + +type LockedFunds struct { + VestingFunds abi.TokenAmount + InitialPledgeRequirement abi.TokenAmount + PreCommitDeposits abi.TokenAmount +} + +func (lf LockedFunds) TotalLockedFunds() abi.TokenAmount { + return big.Add(lf.VestingFunds, big.Add(lf.InitialPledgeRequirement, lf.PreCommitDeposits)) +} diff --git a/chain/actors/builtin/miner/miner.go b/chain/actors/builtin/miner/miner.go index 49a468efbf6..a426e063b9c 100644 --- a/chain/actors/builtin/miner/miner.go +++ b/chain/actors/builtin/miner/miner.go @@ -18,29 +18,42 @@ import ( "github.com/filecoin-project/lotus/chain/actors/builtin" "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" - builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" - builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" miner3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/miner" + + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + + builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" + + builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" ) func init() { + builtin.RegisterActorState(builtin0.StorageMinerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load0(store, root) }) + builtin.RegisterActorState(builtin2.StorageMinerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load2(store, root) }) + builtin.RegisterActorState(builtin3.StorageMinerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load3(store, root) }) + + builtin.RegisterActorState(builtin4.StorageMinerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load4(store, root) + }) + } -var Methods = builtin3.MethodsMiner +var Methods = builtin4.MethodsMiner -// Unchanged between v0, v2, and v3 actors +// Unchanged between v0, v2, v3, and v4 actors var WPoStProvingPeriod = miner0.WPoStProvingPeriod var WPoStPeriodDeadlines = miner0.WPoStPeriodDeadlines var WPoStChallengeWindow = miner0.WPoStChallengeWindow @@ -50,17 +63,25 @@ var FaultDeclarationCutoff = miner0.FaultDeclarationCutoff const MinSectorExpiration = miner0.MinSectorExpiration // Not used / checked in v0 +// TODO: Abstract over network versions var DeclarationsMax = miner2.DeclarationsMax var AddressedSectorsMax = miner2.AddressedSectorsMax -func Load(store adt.Store, act *types.Actor) (st State, err error) { +func Load(store adt.Store, act *types.Actor) (State, error) { switch act.Code { + case builtin0.StorageMinerActorCodeID: return load0(store, act.Head) + case builtin2.StorageMinerActorCodeID: return load2(store, act.Head) + case builtin3.StorageMinerActorCodeID: return load3(store, act.Head) + + case builtin4.StorageMinerActorCodeID: + return load4(store, act.Head) + } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } @@ -93,6 +114,7 @@ type State interface { MinerInfoChanged(State) (bool, error) DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error) + DeadlineCronActive() (bool, error) // Diff helpers. Used by Diff* functions internally. sectors() (adt.Array, error) diff --git a/chain/actors/builtin/miner/state.go.template b/chain/actors/builtin/miner/state.go.template new file mode 100644 index 00000000000..0769eea1003 --- /dev/null +++ b/chain/actors/builtin/miner/state.go.template @@ -0,0 +1,460 @@ +package miner + +import ( + "bytes" + "errors" +{{if (le .v 1)}} + "github.com/filecoin-project/go-state-types/big" +{{end}} + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-bitfield" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/dline" + "github.com/ipfs/go-cid" + "github.com/libp2p/go-libp2p-core/peer" + cbg "github.com/whyrusleeping/cbor-gen" + "golang.org/x/xerrors" + + "github.com/filecoin-project/lotus/chain/actors/adt" + +{{if (ge .v 3)}} + builtin{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin" +{{end}} + miner{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/miner" + adt{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/util/adt" +) + +var _ State = (*state{{.v}})(nil) + +func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { + out := state{{.v}}{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +type state{{.v}} struct { + miner{{.v}}.State + store adt.Store +} + +type deadline{{.v}} struct { + miner{{.v}}.Deadline + store adt.Store +} + +type partition{{.v}} struct { + miner{{.v}}.Partition + store adt.Store +} + +func (s *state{{.v}}) 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{{if (ge .v 2)}}, err{{end}} = s.GetAvailableBalance(bal) + return available, err +} + +func (s *state{{.v}}) VestedFunds(epoch abi.ChainEpoch) (abi.TokenAmount, error) { + return s.CheckVestedFunds(s.store, epoch) +} + +func (s *state{{.v}}) LockedFunds() (LockedFunds, error) { + return LockedFunds{ + VestingFunds: s.State.LockedFunds, + InitialPledgeRequirement: s.State.InitialPledge{{if (le .v 1)}}Requirement{{end}}, + PreCommitDeposits: s.State.PreCommitDeposits, + }, nil +} + +func (s *state{{.v}}) FeeDebt() (abi.TokenAmount, error) { + return {{if (ge .v 2)}}s.State.FeeDebt{{else}}big.Zero(){{end}}, nil +} + +func (s *state{{.v}}) InitialPledge() (abi.TokenAmount, error) { + return s.State.InitialPledge{{if (le .v 1)}}Requirement{{end}}, nil +} + +func (s *state{{.v}}) PreCommitDeposits() (abi.TokenAmount, error) { + return s.State.PreCommitDeposits, nil +} + +func (s *state{{.v}}) GetSector(num abi.SectorNumber) (*SectorOnChainInfo, error) { + info, ok, err := s.State.GetSector(s.store, num) + if !ok || err != nil { + return nil, err + } + + ret := fromV{{.v}}SectorOnChainInfo(*info) + return &ret, nil +} + +func (s *state{{.v}}) FindSector(num abi.SectorNumber) (*SectorLocation, error) { + dlIdx, partIdx, err := s.State.FindSector(s.store, num) + if err != nil { + return nil, err + } + return &SectorLocation{ + Deadline: dlIdx, + Partition: partIdx, + }, nil +} + +func (s *state{{.v}}) NumLiveSectors() (uint64, error) { + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return 0, err + } + var total uint64 + if err := dls.ForEach(s.store, func(dlIdx uint64, dl *miner{{.v}}.Deadline) error { + total += dl.LiveSectors + return nil + }); err != nil { + return 0, err + } + return total, nil +} + +// GetSectorExpiration returns the effective expiration of the given sector. +// +// If the sector does not expire early, the Early expiration field is 0. +func (s *state{{.v}}) GetSectorExpiration(num abi.SectorNumber) (*SectorExpiration, error) { + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return nil, err + } + // NOTE: this can be optimized significantly. + // 1. If the sector is non-faulty, it will either expire on-time (can be + // learned from the sector info), or in the next quantized expiration + // epoch (i.e., the first element in the partition's expiration queue. + // 2. If it's faulty, it will expire early within the first 14 entries + // of the expiration queue. + stopErr := errors.New("stop") + out := SectorExpiration{} + err = dls.ForEach(s.store, func(dlIdx uint64, dl *miner{{.v}}.Deadline) error { + partitions, err := dl.PartitionsArray(s.store) + if err != nil { + return err + } + quant := s.State.QuantSpecForDeadline(dlIdx) + var part miner{{.v}}.Partition + return partitions.ForEach(&part, func(partIdx int64) error { + if found, err := part.Sectors.IsSet(uint64(num)); err != nil { + return err + } else if !found { + return nil + } + if found, err := part.Terminated.IsSet(uint64(num)); err != nil { + return err + } else if found { + // already terminated + return stopErr + } + + q, err := miner{{.v}}.LoadExpirationQueue(s.store, part.ExpirationsEpochs, quant{{if (ge .v 3)}}, miner{{.v}}.PartitionExpirationAmtBitwidth{{end}}) + if err != nil { + return err + } + var exp miner{{.v}}.ExpirationSet + return q.ForEach(&exp, func(epoch int64) error { + if early, err := exp.EarlySectors.IsSet(uint64(num)); err != nil { + return err + } else if early { + out.Early = abi.ChainEpoch(epoch) + return nil + } + if onTime, err := exp.OnTimeSectors.IsSet(uint64(num)); err != nil { + return err + } else if onTime { + out.OnTime = abi.ChainEpoch(epoch) + return stopErr + } + return nil + }) + }) + }) + if err == stopErr { + err = nil + } + if err != nil { + return nil, err + } + if out.Early == 0 && out.OnTime == 0 { + return nil, xerrors.Errorf("failed to find sector %d", num) + } + return &out, nil +} + +func (s *state{{.v}}) GetPrecommittedSector(num abi.SectorNumber) (*SectorPreCommitOnChainInfo, error) { + info, ok, err := s.State.GetPrecommittedSector(s.store, num) + if !ok || err != nil { + return nil, err + } + + ret := fromV{{.v}}SectorPreCommitOnChainInfo(*info) + + return &ret, nil +} + +func (s *state{{.v}}) LoadSectors(snos *bitfield.BitField) ([]*SectorOnChainInfo, error) { + sectors, err := miner{{.v}}.LoadSectors(s.store, s.State.Sectors) + if err != nil { + return nil, err + } + + // If no sector numbers are specified, load all. + if snos == nil { + infos := make([]*SectorOnChainInfo, 0, sectors.Length()) + var info{{.v}} miner{{.v}}.SectorOnChainInfo + if err := sectors.ForEach(&info{{.v}}, func(_ int64) error { + info := fromV{{.v}}SectorOnChainInfo(info{{.v}}) + infos = append(infos, &info) + return nil + }); err != nil { + return nil, err + } + return infos, nil + } + + // Otherwise, load selected. + infos{{.v}}, err := sectors.Load(*snos) + if err != nil { + return nil, err + } + infos := make([]*SectorOnChainInfo, len(infos{{.v}})) + for i, info{{.v}} := range infos{{.v}} { + info := fromV{{.v}}SectorOnChainInfo(*info{{.v}}) + infos[i] = &info + } + return infos, nil +} + +func (s *state{{.v}}) IsAllocated(num abi.SectorNumber) (bool, error) { + var allocatedSectors bitfield.BitField + if err := s.store.Get(s.store.Context(), s.State.AllocatedSectors, &allocatedSectors); err != nil { + return false, err + } + + return allocatedSectors.IsSet(uint64(num)) +} + +func (s *state{{.v}}) LoadDeadline(idx uint64) (Deadline, error) { + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return nil, err + } + dl, err := dls.LoadDeadline(s.store, idx) + if err != nil { + return nil, err + } + return &deadline{{.v}}{*dl, s.store}, nil +} + +func (s *state{{.v}}) ForEachDeadline(cb func(uint64, Deadline) error) error { + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return err + } + return dls.ForEach(s.store, func(i uint64, dl *miner{{.v}}.Deadline) error { + return cb(i, &deadline{{.v}}{*dl, s.store}) + }) +} + +func (s *state{{.v}}) NumDeadlines() (uint64, error) { + return miner{{.v}}.WPoStPeriodDeadlines, nil +} + +func (s *state{{.v}}) DeadlinesChanged(other State) (bool, error) { + other{{.v}}, ok := other.(*state{{.v}}) + if !ok { + // treat an upgrade as a change, always + return true, nil + } + + return !s.State.Deadlines.Equals(other{{.v}}.Deadlines), nil +} + +func (s *state{{.v}}) MinerInfoChanged(other State) (bool, error) { + other0, ok := other.(*state{{.v}}) + if !ok { + // treat an upgrade as a change, always + return true, nil + } + return !s.State.Info.Equals(other0.State.Info), nil +} + +func (s *state{{.v}}) Info() (MinerInfo, error) { + info, err := s.State.GetInfo(s.store) + if err != nil { + return MinerInfo{}, err + } + + var pid *peer.ID + if peerID, err := peer.IDFromBytes(info.PeerId); err == nil { + pid = &peerID + } +{{if (le .v 2)}} + wpp, err := info.SealProofType.RegisteredWindowPoStProof() + if err != nil { + return MinerInfo{}, err + } +{{end}} + mi := MinerInfo{ + Owner: info.Owner, + Worker: info.Worker, + ControlAddresses: info.ControlAddresses, + + NewWorker: address.Undef, + WorkerChangeEpoch: -1, + + PeerId: pid, + Multiaddrs: info.Multiaddrs, + WindowPoStProofType: {{if (ge .v 3)}}info.WindowPoStProofType{{else}}wpp{{end}}, + SectorSize: info.SectorSize, + WindowPoStPartitionSectors: info.WindowPoStPartitionSectors, + ConsensusFaultElapsed: {{if (ge .v 2)}}info.ConsensusFaultElapsed{{else}}-1{{end}}, + } + + if info.PendingWorkerKey != nil { + mi.NewWorker = info.PendingWorkerKey.NewWorker + mi.WorkerChangeEpoch = info.PendingWorkerKey.EffectiveAt + } + + return mi, nil +} + +func (s *state{{.v}}) DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error) { + return s.State.{{if (ge .v 4)}}Recorded{{end}}DeadlineInfo(epoch), nil +} + +func (s *state{{.v}}) DeadlineCronActive() (bool, error) { + return {{if (ge .v 4)}}s.State.DeadlineCronActive{{else}}true{{end}}, nil{{if (lt .v 4)}} // always active in this version{{end}} +} + +func (s *state{{.v}}) sectors() (adt.Array, error) { + return adt{{.v}}.AsArray(s.store, s.Sectors{{if (ge .v 3)}}, miner{{.v}}.SectorsAmtBitwidth{{end}}) +} + +func (s *state{{.v}}) decodeSectorOnChainInfo(val *cbg.Deferred) (SectorOnChainInfo, error) { + var si miner{{.v}}.SectorOnChainInfo + err := si.UnmarshalCBOR(bytes.NewReader(val.Raw)) + if err != nil { + return SectorOnChainInfo{}, err + } + + return fromV{{.v}}SectorOnChainInfo(si), nil +} + +func (s *state{{.v}}) precommits() (adt.Map, error) { + return adt{{.v}}.AsMap(s.store, s.PreCommittedSectors{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}}) +} + +func (s *state{{.v}}) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreCommitOnChainInfo, error) { + var sp miner{{.v}}.SectorPreCommitOnChainInfo + err := sp.UnmarshalCBOR(bytes.NewReader(val.Raw)) + if err != nil { + return SectorPreCommitOnChainInfo{}, err + } + + return fromV{{.v}}SectorPreCommitOnChainInfo(sp), nil +} + +func (d *deadline{{.v}}) LoadPartition(idx uint64) (Partition, error) { + p, err := d.Deadline.LoadPartition(d.store, idx) + if err != nil { + return nil, err + } + return &partition{{.v}}{*p, d.store}, nil +} + +func (d *deadline{{.v}}) ForEachPartition(cb func(uint64, Partition) error) error { + ps, err := d.Deadline.PartitionsArray(d.store) + if err != nil { + return err + } + var part miner{{.v}}.Partition + return ps.ForEach(&part, func(i int64) error { + return cb(uint64(i), &partition{{.v}}{part, d.store}) + }) +} + +func (d *deadline{{.v}}) PartitionsChanged(other Deadline) (bool, error) { + other{{.v}}, ok := other.(*deadline{{.v}}) + if !ok { + // treat an upgrade as a change, always + return true, nil + } + + return !d.Deadline.Partitions.Equals(other{{.v}}.Deadline.Partitions), nil +} + +func (d *deadline{{.v}}) PartitionsPoSted() (bitfield.BitField, error) { + return d.Deadline.{{if (ge .v 3)}}PartitionsPoSted{{else}}PostSubmissions{{end}}, nil +} + +func (d *deadline{{.v}}) DisputableProofCount() (uint64, error) { +{{if (ge .v 3)}} + ops, err := d.OptimisticProofsSnapshotArray(d.store) + if err != nil { + return 0, err + } + + return ops.Length(), nil +{{else}} + // field doesn't exist until v3 + return 0, nil +{{end}} +} + +func (p *partition{{.v}}) AllSectors() (bitfield.BitField, error) { + return p.Partition.Sectors, nil +} + +func (p *partition{{.v}}) FaultySectors() (bitfield.BitField, error) { + return p.Partition.Faults, nil +} + +func (p *partition{{.v}}) RecoveringSectors() (bitfield.BitField, error) { + return p.Partition.Recoveries, nil +} + +func fromV{{.v}}SectorOnChainInfo(v{{.v}} miner{{.v}}.SectorOnChainInfo) SectorOnChainInfo { +{{if (ge .v 2)}} + return SectorOnChainInfo{ + SectorNumber: v{{.v}}.SectorNumber, + SealProof: v{{.v}}.SealProof, + SealedCID: v{{.v}}.SealedCID, + DealIDs: v{{.v}}.DealIDs, + Activation: v{{.v}}.Activation, + Expiration: v{{.v}}.Expiration, + DealWeight: v{{.v}}.DealWeight, + VerifiedDealWeight: v{{.v}}.VerifiedDealWeight, + InitialPledge: v{{.v}}.InitialPledge, + ExpectedDayReward: v{{.v}}.ExpectedDayReward, + ExpectedStoragePledge: v{{.v}}.ExpectedStoragePledge, + } +{{else}} + return (SectorOnChainInfo)(v0) +{{end}} +} + +func fromV{{.v}}SectorPreCommitOnChainInfo(v{{.v}} miner{{.v}}.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo { +{{if (ge .v 2)}} + return SectorPreCommitOnChainInfo{ + Info: (SectorPreCommitInfo)(v{{.v}}.Info), + PreCommitDeposit: v{{.v}}.PreCommitDeposit, + PreCommitEpoch: v{{.v}}.PreCommitEpoch, + DealWeight: v{{.v}}.DealWeight, + VerifiedDealWeight: v{{.v}}.VerifiedDealWeight, + } +{{else}} + return (SectorPreCommitOnChainInfo)(v0) +{{end}} +} diff --git a/chain/actors/builtin/miner/v0.go b/chain/actors/builtin/miner/v0.go index ebe5cf08518..2dc8ae23e75 100644 --- a/chain/actors/builtin/miner/v0.go +++ b/chain/actors/builtin/miner/v0.go @@ -196,6 +196,7 @@ func (s *state0) GetPrecommittedSector(num abi.SectorNumber) (*SectorPreCommitOn } ret := fromV0SectorPreCommitOnChainInfo(*info) + return &ret, nil } @@ -330,6 +331,10 @@ func (s *state0) DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error) { return s.State.DeadlineInfo(epoch), nil } +func (s *state0) DeadlineCronActive() (bool, error) { + return true, nil // always active in this version +} + func (s *state0) sectors() (adt.Array, error) { return adt0.AsArray(s.store, s.Sectors) } @@ -392,8 +397,10 @@ func (d *deadline0) PartitionsPoSted() (bitfield.BitField, error) { } func (d *deadline0) DisputableProofCount() (uint64, error) { + // field doesn't exist until v3 return 0, nil + } func (p *partition0) AllSectors() (bitfield.BitField, error) { @@ -409,9 +416,13 @@ func (p *partition0) RecoveringSectors() (bitfield.BitField, error) { } func fromV0SectorOnChainInfo(v0 miner0.SectorOnChainInfo) SectorOnChainInfo { + return (SectorOnChainInfo)(v0) + } func fromV0SectorPreCommitOnChainInfo(v0 miner0.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo { + return (SectorPreCommitOnChainInfo)(v0) + } diff --git a/chain/actors/builtin/miner/v2.go b/chain/actors/builtin/miner/v2.go index 79f9842136c..7564dd8b8ea 100644 --- a/chain/actors/builtin/miner/v2.go +++ b/chain/actors/builtin/miner/v2.go @@ -329,6 +329,10 @@ func (s *state2) DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error) { return s.State.DeadlineInfo(epoch), nil } +func (s *state2) DeadlineCronActive() (bool, error) { + return true, nil // always active in this version +} + func (s *state2) sectors() (adt.Array, error) { return adt2.AsArray(s.store, s.Sectors) } @@ -391,8 +395,10 @@ func (d *deadline2) PartitionsPoSted() (bitfield.BitField, error) { } func (d *deadline2) DisputableProofCount() (uint64, error) { + // field doesn't exist until v3 return 0, nil + } func (p *partition2) AllSectors() (bitfield.BitField, error) { @@ -408,6 +414,7 @@ func (p *partition2) RecoveringSectors() (bitfield.BitField, error) { } func fromV2SectorOnChainInfo(v2 miner2.SectorOnChainInfo) SectorOnChainInfo { + return SectorOnChainInfo{ SectorNumber: v2.SectorNumber, SealProof: v2.SealProof, @@ -421,9 +428,11 @@ func fromV2SectorOnChainInfo(v2 miner2.SectorOnChainInfo) SectorOnChainInfo { ExpectedDayReward: v2.ExpectedDayReward, ExpectedStoragePledge: v2.ExpectedStoragePledge, } + } func fromV2SectorPreCommitOnChainInfo(v2 miner2.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo { + return SectorPreCommitOnChainInfo{ Info: (SectorPreCommitInfo)(v2.Info), PreCommitDeposit: v2.PreCommitDeposit, @@ -431,4 +440,5 @@ func fromV2SectorPreCommitOnChainInfo(v2 miner2.SectorPreCommitOnChainInfo) Sect DealWeight: v2.DealWeight, VerifiedDealWeight: v2.VerifiedDealWeight, } + } diff --git a/chain/actors/builtin/miner/v3.go b/chain/actors/builtin/miner/v3.go index 3379e720ed0..72a080f73c2 100644 --- a/chain/actors/builtin/miner/v3.go +++ b/chain/actors/builtin/miner/v3.go @@ -16,6 +16,7 @@ import ( "github.com/filecoin-project/lotus/chain/actors/adt" builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" + miner3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/miner" adt3 "github.com/filecoin-project/specs-actors/v3/actors/util/adt" ) @@ -208,9 +209,9 @@ func (s *state3) LoadSectors(snos *bitfield.BitField) ([]*SectorOnChainInfo, err // If no sector numbers are specified, load all. if snos == nil { infos := make([]*SectorOnChainInfo, 0, sectors.Length()) - var info2 miner3.SectorOnChainInfo - if err := sectors.ForEach(&info2, func(_ int64) error { - info := fromV3SectorOnChainInfo(info2) + var info3 miner3.SectorOnChainInfo + if err := sectors.ForEach(&info3, func(_ int64) error { + info := fromV3SectorOnChainInfo(info3) infos = append(infos, &info) return nil }); err != nil { @@ -220,13 +221,13 @@ func (s *state3) LoadSectors(snos *bitfield.BitField) ([]*SectorOnChainInfo, err } // Otherwise, load selected. - infos2, err := sectors.Load(*snos) + infos3, err := sectors.Load(*snos) if err != nil { return nil, err } - infos := make([]*SectorOnChainInfo, len(infos2)) - for i, info2 := range infos2 { - info := fromV3SectorOnChainInfo(*info2) + infos := make([]*SectorOnChainInfo, len(infos3)) + for i, info3 := range infos3 { + info := fromV3SectorOnChainInfo(*info3) infos[i] = &info } return infos, nil @@ -268,13 +269,13 @@ func (s *state3) NumDeadlines() (uint64, error) { } func (s *state3) DeadlinesChanged(other State) (bool, error) { - other2, ok := other.(*state3) + other3, ok := other.(*state3) if !ok { // treat an upgrade as a change, always return true, nil } - return !s.State.Deadlines.Equals(other2.Deadlines), nil + return !s.State.Deadlines.Equals(other3.Deadlines), nil } func (s *state3) MinerInfoChanged(other State) (bool, error) { @@ -325,6 +326,10 @@ func (s *state3) DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error) { return s.State.DeadlineInfo(epoch), nil } +func (s *state3) DeadlineCronActive() (bool, error) { + return true, nil // always active in this version +} + func (s *state3) sectors() (adt.Array, error) { return adt3.AsArray(s.store, s.Sectors, miner3.SectorsAmtBitwidth) } @@ -373,13 +378,13 @@ func (d *deadline3) ForEachPartition(cb func(uint64, Partition) error) error { } func (d *deadline3) PartitionsChanged(other Deadline) (bool, error) { - other2, ok := other.(*deadline3) + other3, ok := other.(*deadline3) if !ok { // treat an upgrade as a change, always return true, nil } - return !d.Deadline.Partitions.Equals(other2.Deadline.Partitions), nil + return !d.Deadline.Partitions.Equals(other3.Deadline.Partitions), nil } func (d *deadline3) PartitionsPoSted() (bitfield.BitField, error) { @@ -387,12 +392,14 @@ func (d *deadline3) PartitionsPoSted() (bitfield.BitField, error) { } func (d *deadline3) DisputableProofCount() (uint64, error) { + ops, err := d.OptimisticProofsSnapshotArray(d.store) if err != nil { return 0, err } return ops.Length(), nil + } func (p *partition3) AllSectors() (bitfield.BitField, error) { @@ -408,6 +415,7 @@ func (p *partition3) RecoveringSectors() (bitfield.BitField, error) { } func fromV3SectorOnChainInfo(v3 miner3.SectorOnChainInfo) SectorOnChainInfo { + return SectorOnChainInfo{ SectorNumber: v3.SectorNumber, SealProof: v3.SealProof, @@ -421,9 +429,11 @@ func fromV3SectorOnChainInfo(v3 miner3.SectorOnChainInfo) SectorOnChainInfo { ExpectedDayReward: v3.ExpectedDayReward, ExpectedStoragePledge: v3.ExpectedStoragePledge, } + } func fromV3SectorPreCommitOnChainInfo(v3 miner3.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo { + return SectorPreCommitOnChainInfo{ Info: (SectorPreCommitInfo)(v3.Info), PreCommitDeposit: v3.PreCommitDeposit, @@ -431,4 +441,5 @@ func fromV3SectorPreCommitOnChainInfo(v3 miner3.SectorPreCommitOnChainInfo) Sect DealWeight: v3.DealWeight, VerifiedDealWeight: v3.VerifiedDealWeight, } + } diff --git a/chain/actors/builtin/miner/v4.go b/chain/actors/builtin/miner/v4.go new file mode 100644 index 00000000000..698bdf2f53f --- /dev/null +++ b/chain/actors/builtin/miner/v4.go @@ -0,0 +1,445 @@ +package miner + +import ( + "bytes" + "errors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-bitfield" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/dline" + "github.com/ipfs/go-cid" + "github.com/libp2p/go-libp2p-core/peer" + cbg "github.com/whyrusleeping/cbor-gen" + "golang.org/x/xerrors" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" + + miner4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/miner" + adt4 "github.com/filecoin-project/specs-actors/v4/actors/util/adt" +) + +var _ State = (*state4)(nil) + +func load4(store adt.Store, root cid.Cid) (State, error) { + out := state4{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +type state4 struct { + miner4.State + store adt.Store +} + +type deadline4 struct { + miner4.Deadline + store adt.Store +} + +type partition4 struct { + miner4.Partition + store adt.Store +} + +func (s *state4) 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 *state4) VestedFunds(epoch abi.ChainEpoch) (abi.TokenAmount, error) { + return s.CheckVestedFunds(s.store, epoch) +} + +func (s *state4) LockedFunds() (LockedFunds, error) { + return LockedFunds{ + VestingFunds: s.State.LockedFunds, + InitialPledgeRequirement: s.State.InitialPledge, + PreCommitDeposits: s.State.PreCommitDeposits, + }, nil +} + +func (s *state4) FeeDebt() (abi.TokenAmount, error) { + return s.State.FeeDebt, nil +} + +func (s *state4) InitialPledge() (abi.TokenAmount, error) { + return s.State.InitialPledge, nil +} + +func (s *state4) PreCommitDeposits() (abi.TokenAmount, error) { + return s.State.PreCommitDeposits, nil +} + +func (s *state4) GetSector(num abi.SectorNumber) (*SectorOnChainInfo, error) { + info, ok, err := s.State.GetSector(s.store, num) + if !ok || err != nil { + return nil, err + } + + ret := fromV4SectorOnChainInfo(*info) + return &ret, nil +} + +func (s *state4) FindSector(num abi.SectorNumber) (*SectorLocation, error) { + dlIdx, partIdx, err := s.State.FindSector(s.store, num) + if err != nil { + return nil, err + } + return &SectorLocation{ + Deadline: dlIdx, + Partition: partIdx, + }, nil +} + +func (s *state4) NumLiveSectors() (uint64, error) { + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return 0, err + } + var total uint64 + if err := dls.ForEach(s.store, func(dlIdx uint64, dl *miner4.Deadline) error { + total += dl.LiveSectors + return nil + }); err != nil { + return 0, err + } + return total, nil +} + +// GetSectorExpiration returns the effective expiration of the given sector. +// +// If the sector does not expire early, the Early expiration field is 0. +func (s *state4) GetSectorExpiration(num abi.SectorNumber) (*SectorExpiration, error) { + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return nil, err + } + // NOTE: this can be optimized significantly. + // 1. If the sector is non-faulty, it will either expire on-time (can be + // learned from the sector info), or in the next quantized expiration + // epoch (i.e., the first element in the partition's expiration queue. + // 2. If it's faulty, it will expire early within the first 14 entries + // of the expiration queue. + stopErr := errors.New("stop") + out := SectorExpiration{} + err = dls.ForEach(s.store, func(dlIdx uint64, dl *miner4.Deadline) error { + partitions, err := dl.PartitionsArray(s.store) + if err != nil { + return err + } + quant := s.State.QuantSpecForDeadline(dlIdx) + var part miner4.Partition + return partitions.ForEach(&part, func(partIdx int64) error { + if found, err := part.Sectors.IsSet(uint64(num)); err != nil { + return err + } else if !found { + return nil + } + if found, err := part.Terminated.IsSet(uint64(num)); err != nil { + return err + } else if found { + // already terminated + return stopErr + } + + q, err := miner4.LoadExpirationQueue(s.store, part.ExpirationsEpochs, quant, miner4.PartitionExpirationAmtBitwidth) + if err != nil { + return err + } + var exp miner4.ExpirationSet + return q.ForEach(&exp, func(epoch int64) error { + if early, err := exp.EarlySectors.IsSet(uint64(num)); err != nil { + return err + } else if early { + out.Early = abi.ChainEpoch(epoch) + return nil + } + if onTime, err := exp.OnTimeSectors.IsSet(uint64(num)); err != nil { + return err + } else if onTime { + out.OnTime = abi.ChainEpoch(epoch) + return stopErr + } + return nil + }) + }) + }) + if err == stopErr { + err = nil + } + if err != nil { + return nil, err + } + if out.Early == 0 && out.OnTime == 0 { + return nil, xerrors.Errorf("failed to find sector %d", num) + } + return &out, nil +} + +func (s *state4) GetPrecommittedSector(num abi.SectorNumber) (*SectorPreCommitOnChainInfo, error) { + info, ok, err := s.State.GetPrecommittedSector(s.store, num) + if !ok || err != nil { + return nil, err + } + + ret := fromV4SectorPreCommitOnChainInfo(*info) + + return &ret, nil +} + +func (s *state4) LoadSectors(snos *bitfield.BitField) ([]*SectorOnChainInfo, error) { + sectors, err := miner4.LoadSectors(s.store, s.State.Sectors) + if err != nil { + return nil, err + } + + // If no sector numbers are specified, load all. + if snos == nil { + infos := make([]*SectorOnChainInfo, 0, sectors.Length()) + var info4 miner4.SectorOnChainInfo + if err := sectors.ForEach(&info4, func(_ int64) error { + info := fromV4SectorOnChainInfo(info4) + infos = append(infos, &info) + return nil + }); err != nil { + return nil, err + } + return infos, nil + } + + // Otherwise, load selected. + infos4, err := sectors.Load(*snos) + if err != nil { + return nil, err + } + infos := make([]*SectorOnChainInfo, len(infos4)) + for i, info4 := range infos4 { + info := fromV4SectorOnChainInfo(*info4) + infos[i] = &info + } + return infos, nil +} + +func (s *state4) IsAllocated(num abi.SectorNumber) (bool, error) { + var allocatedSectors bitfield.BitField + if err := s.store.Get(s.store.Context(), s.State.AllocatedSectors, &allocatedSectors); err != nil { + return false, err + } + + return allocatedSectors.IsSet(uint64(num)) +} + +func (s *state4) LoadDeadline(idx uint64) (Deadline, error) { + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return nil, err + } + dl, err := dls.LoadDeadline(s.store, idx) + if err != nil { + return nil, err + } + return &deadline4{*dl, s.store}, nil +} + +func (s *state4) ForEachDeadline(cb func(uint64, Deadline) error) error { + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return err + } + return dls.ForEach(s.store, func(i uint64, dl *miner4.Deadline) error { + return cb(i, &deadline4{*dl, s.store}) + }) +} + +func (s *state4) NumDeadlines() (uint64, error) { + return miner4.WPoStPeriodDeadlines, nil +} + +func (s *state4) DeadlinesChanged(other State) (bool, error) { + other4, ok := other.(*state4) + if !ok { + // treat an upgrade as a change, always + return true, nil + } + + return !s.State.Deadlines.Equals(other4.Deadlines), nil +} + +func (s *state4) MinerInfoChanged(other State) (bool, error) { + other0, ok := other.(*state4) + if !ok { + // treat an upgrade as a change, always + return true, nil + } + return !s.State.Info.Equals(other0.State.Info), nil +} + +func (s *state4) Info() (MinerInfo, error) { + info, err := s.State.GetInfo(s.store) + if err != nil { + return MinerInfo{}, err + } + + var pid *peer.ID + if peerID, err := peer.IDFromBytes(info.PeerId); err == nil { + pid = &peerID + } + + mi := MinerInfo{ + Owner: info.Owner, + Worker: info.Worker, + ControlAddresses: info.ControlAddresses, + + NewWorker: address.Undef, + WorkerChangeEpoch: -1, + + PeerId: pid, + Multiaddrs: info.Multiaddrs, + WindowPoStProofType: info.WindowPoStProofType, + SectorSize: info.SectorSize, + WindowPoStPartitionSectors: info.WindowPoStPartitionSectors, + ConsensusFaultElapsed: info.ConsensusFaultElapsed, + } + + if info.PendingWorkerKey != nil { + mi.NewWorker = info.PendingWorkerKey.NewWorker + mi.WorkerChangeEpoch = info.PendingWorkerKey.EffectiveAt + } + + return mi, nil +} + +func (s *state4) DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error) { + return s.State.RecordedDeadlineInfo(epoch), nil +} + +func (s *state4) DeadlineCronActive() (bool, error) { + return s.State.DeadlineCronActive, nil +} + +func (s *state4) sectors() (adt.Array, error) { + return adt4.AsArray(s.store, s.Sectors, miner4.SectorsAmtBitwidth) +} + +func (s *state4) decodeSectorOnChainInfo(val *cbg.Deferred) (SectorOnChainInfo, error) { + var si miner4.SectorOnChainInfo + err := si.UnmarshalCBOR(bytes.NewReader(val.Raw)) + if err != nil { + return SectorOnChainInfo{}, err + } + + return fromV4SectorOnChainInfo(si), nil +} + +func (s *state4) precommits() (adt.Map, error) { + return adt4.AsMap(s.store, s.PreCommittedSectors, builtin4.DefaultHamtBitwidth) +} + +func (s *state4) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreCommitOnChainInfo, error) { + var sp miner4.SectorPreCommitOnChainInfo + err := sp.UnmarshalCBOR(bytes.NewReader(val.Raw)) + if err != nil { + return SectorPreCommitOnChainInfo{}, err + } + + return fromV4SectorPreCommitOnChainInfo(sp), nil +} + +func (d *deadline4) LoadPartition(idx uint64) (Partition, error) { + p, err := d.Deadline.LoadPartition(d.store, idx) + if err != nil { + return nil, err + } + return &partition4{*p, d.store}, nil +} + +func (d *deadline4) ForEachPartition(cb func(uint64, Partition) error) error { + ps, err := d.Deadline.PartitionsArray(d.store) + if err != nil { + return err + } + var part miner4.Partition + return ps.ForEach(&part, func(i int64) error { + return cb(uint64(i), &partition4{part, d.store}) + }) +} + +func (d *deadline4) PartitionsChanged(other Deadline) (bool, error) { + other4, ok := other.(*deadline4) + if !ok { + // treat an upgrade as a change, always + return true, nil + } + + return !d.Deadline.Partitions.Equals(other4.Deadline.Partitions), nil +} + +func (d *deadline4) PartitionsPoSted() (bitfield.BitField, error) { + return d.Deadline.PartitionsPoSted, nil +} + +func (d *deadline4) DisputableProofCount() (uint64, error) { + + ops, err := d.OptimisticProofsSnapshotArray(d.store) + if err != nil { + return 0, err + } + + return ops.Length(), nil + +} + +func (p *partition4) AllSectors() (bitfield.BitField, error) { + return p.Partition.Sectors, nil +} + +func (p *partition4) FaultySectors() (bitfield.BitField, error) { + return p.Partition.Faults, nil +} + +func (p *partition4) RecoveringSectors() (bitfield.BitField, error) { + return p.Partition.Recoveries, nil +} + +func fromV4SectorOnChainInfo(v4 miner4.SectorOnChainInfo) SectorOnChainInfo { + + return SectorOnChainInfo{ + SectorNumber: v4.SectorNumber, + SealProof: v4.SealProof, + SealedCID: v4.SealedCID, + DealIDs: v4.DealIDs, + Activation: v4.Activation, + Expiration: v4.Expiration, + DealWeight: v4.DealWeight, + VerifiedDealWeight: v4.VerifiedDealWeight, + InitialPledge: v4.InitialPledge, + ExpectedDayReward: v4.ExpectedDayReward, + ExpectedStoragePledge: v4.ExpectedStoragePledge, + } + +} + +func fromV4SectorPreCommitOnChainInfo(v4 miner4.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo { + + return SectorPreCommitOnChainInfo{ + Info: (SectorPreCommitInfo)(v4.Info), + PreCommitDeposit: v4.PreCommitDeposit, + PreCommitEpoch: v4.PreCommitEpoch, + DealWeight: v4.DealWeight, + VerifiedDealWeight: v4.VerifiedDealWeight, + } + +} diff --git a/chain/actors/builtin/multisig/actor.go.template b/chain/actors/builtin/multisig/actor.go.template new file mode 100644 index 00000000000..19d99dcb729 --- /dev/null +++ b/chain/actors/builtin/multisig/actor.go.template @@ -0,0 +1,117 @@ +package multisig + +import ( + "fmt" + + "github.com/minio/blake2b-simd" + cbg "github.com/whyrusleeping/cbor-gen" + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/cbor" + "github.com/ipfs/go-cid" + + msig{{.latestVersion}} "github.com/filecoin-project/specs-actors/v4/actors/builtin/multisig" +{{range .versions}} + builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin" +{{end}} + + "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/types" +) + +func init() { +{{range .versions}} + builtin.RegisterActorState(builtin{{.}}.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load{{.}}(store, root) + }) +{{end}}} + +func Load(store adt.Store, act *types.Actor) (State, error) { + switch act.Code { +{{range .versions}} + case builtin{{.}}.MultisigActorCodeID: + return load{{.}}(store, act.Head) +{{end}} + } + return nil, xerrors.Errorf("unknown actor code %s", act.Code) +} + +type State interface { + cbor.Marshaler + + LockedBalance(epoch abi.ChainEpoch) (abi.TokenAmount, error) + StartEpoch() (abi.ChainEpoch, error) + UnlockDuration() (abi.ChainEpoch, error) + InitialBalance() (abi.TokenAmount, error) + Threshold() (uint64, error) + Signers() ([]address.Address, error) + + ForEachPendingTxn(func(id int64, txn Transaction) error) error + PendingTxnChanged(State) (bool, error) + + transactions() (adt.Map, error) + decodeTransaction(val *cbg.Deferred) (Transaction, error) +} + +type Transaction = msig{{.latestVersion}}.Transaction + +var Methods = builtin{{.latestVersion}}.MethodsMultisig + +func Message(version actors.Version, from address.Address) MessageBuilder { + switch version { +{{range .versions}} + case actors.Version{{.}}: + return message{{.}}{{"{"}}{{if (ge . 2)}}message0{from}{{else}}from{{end}}} +{{end}} default: + panic(fmt.Sprintf("unsupported actors version: %d", version)) + } +} + +type MessageBuilder interface { + // Create a new multisig with the specified parameters. + Create(signers []address.Address, threshold uint64, + vestingStart, vestingDuration abi.ChainEpoch, + initialAmount abi.TokenAmount) (*types.Message, error) + + // Propose a transaction to the given multisig. + Propose(msig, target address.Address, amt abi.TokenAmount, + method abi.MethodNum, params []byte) (*types.Message, error) + + // Approve a multisig transaction. The "hash" is optional. + Approve(msig address.Address, txID uint64, hash *ProposalHashData) (*types.Message, error) + + // Cancel a multisig transaction. The "hash" is optional. + Cancel(msig address.Address, txID uint64, hash *ProposalHashData) (*types.Message, error) +} + +// this type is the same between v0 and v2 +type ProposalHashData = msig{{.latestVersion}}.ProposalHashData +type ProposeReturn = msig{{.latestVersion}}.ProposeReturn +type ProposeParams = msig{{.latestVersion}}.ProposeParams + +func txnParams(id uint64, data *ProposalHashData) ([]byte, error) { + params := msig{{.latestVersion}}.TxnIDParams{ID: msig{{.latestVersion}}.TxnID(id)} + if data != nil { + if data.Requester.Protocol() != address.ID { + return nil, xerrors.Errorf("proposer address must be an ID address, was %s", data.Requester) + } + if data.Value.Sign() == -1 { + return nil, xerrors.Errorf("proposal value must be non-negative, was %s", data.Value) + } + if data.To == address.Undef { + return nil, xerrors.Errorf("proposed destination address must be set") + } + pser, err := data.Serialize() + if err != nil { + return nil, err + } + hash := blake2b.Sum256(pser) + params.ProposalHash = hash[:] + } + + return actors.SerializeParams(¶ms) +} diff --git a/chain/actors/builtin/multisig/message.go b/chain/actors/builtin/multisig/message.go deleted file mode 100644 index 223bc4bc500..00000000000 --- a/chain/actors/builtin/multisig/message.go +++ /dev/null @@ -1,77 +0,0 @@ -package multisig - -import ( - "fmt" - - "github.com/minio/blake2b-simd" - "golang.org/x/xerrors" - - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/go-state-types/abi" - - builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" - multisig3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/multisig" - - "github.com/filecoin-project/lotus/chain/actors" - "github.com/filecoin-project/lotus/chain/types" -) - -var Methods = builtin3.MethodsMultisig - -func Message(version actors.Version, from address.Address) MessageBuilder { - switch version { - case actors.Version0: - return message0{from} - case actors.Version2: - return message2{message0{from}} - case actors.Version3: - return message3{message0{from}} - default: - panic(fmt.Sprintf("unsupported actors version: %d", version)) - } -} - -type MessageBuilder interface { - // Create a new multisig with the specified parameters. - Create(signers []address.Address, threshold uint64, - vestingStart, vestingDuration abi.ChainEpoch, - initialAmount abi.TokenAmount) (*types.Message, error) - - // Propose a transaction to the given multisig. - Propose(msig, target address.Address, amt abi.TokenAmount, - method abi.MethodNum, params []byte) (*types.Message, error) - - // Approve a multisig transaction. The "hash" is optional. - Approve(msig address.Address, txID uint64, hash *ProposalHashData) (*types.Message, error) - - // Cancel a multisig transaction. The "hash" is optional. - Cancel(msig address.Address, txID uint64, hash *ProposalHashData) (*types.Message, error) -} - -// this type is the same between v0 and v2 -type ProposalHashData = multisig3.ProposalHashData -type ProposeReturn = multisig3.ProposeReturn -type ProposeParams = multisig3.ProposeParams - -func txnParams(id uint64, data *ProposalHashData) ([]byte, error) { - params := multisig3.TxnIDParams{ID: multisig3.TxnID(id)} - if data != nil { - if data.Requester.Protocol() != address.ID { - return nil, xerrors.Errorf("proposer address must be an ID address, was %s", data.Requester) - } - if data.Value.Sign() == -1 { - return nil, xerrors.Errorf("proposal value must be non-negative, was %s", data.Value) - } - if data.To == address.Undef { - return nil, xerrors.Errorf("proposed destination address must be set") - } - pser, err := data.Serialize() - if err != nil { - return nil, err - } - hash := blake2b.Sum256(pser) - params.ProposalHash = hash[:] - } - - return actors.SerializeParams(¶ms) -} diff --git a/chain/actors/builtin/multisig/message.go.template b/chain/actors/builtin/multisig/message.go.template new file mode 100644 index 00000000000..6bff8983ab0 --- /dev/null +++ b/chain/actors/builtin/multisig/message.go.template @@ -0,0 +1,146 @@ +package multisig + +import ( + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + + builtin{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin" + init{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/init" + multisig{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/multisig" + + "github.com/filecoin-project/lotus/chain/actors" + init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" + "github.com/filecoin-project/lotus/chain/types" +) + +type message{{.v}} struct{ {{if (ge .v 2)}}message0{{else}}from address.Address{{end}} } + +func (m message{{.v}}) Create( + signers []address.Address, threshold uint64, + unlockStart, unlockDuration abi.ChainEpoch, + initialAmount abi.TokenAmount, +) (*types.Message, error) { + + lenAddrs := uint64(len(signers)) + + if lenAddrs < threshold { + return nil, xerrors.Errorf("cannot require signing of more addresses than provided for multisig") + } + + if threshold == 0 { + threshold = lenAddrs + } + + if m.from == address.Undef { + return nil, xerrors.Errorf("must provide source address") + } +{{if (le .v 1)}} + if unlockStart != 0 { + return nil, xerrors.Errorf("actors v0 does not support a non-zero vesting start time") + } +{{end}} + // Set up constructor parameters for multisig + msigParams := &multisig{{.v}}.ConstructorParams{ + Signers: signers, + NumApprovalsThreshold: threshold, + UnlockDuration: unlockDuration,{{if (ge .v 2)}} + StartEpoch: unlockStart,{{end}} + } + + enc, actErr := actors.SerializeParams(msigParams) + if actErr != nil { + return nil, actErr + } + + // new actors are created by invoking 'exec' on the init actor with the constructor params + execParams := &init{{.v}}.ExecParams{ + CodeCID: builtin{{.v}}.MultisigActorCodeID, + ConstructorParams: enc, + } + + enc, actErr = actors.SerializeParams(execParams) + if actErr != nil { + return nil, actErr + } + + return &types.Message{ + To: init_.Address, + From: m.from, + Method: builtin{{.v}}.MethodsInit.Exec, + Params: enc, + Value: initialAmount, + }, nil +} + +{{if (le .v 1)}} + +func (m message0) Propose(msig, to address.Address, amt abi.TokenAmount, + method abi.MethodNum, params []byte) (*types.Message, error) { + + if msig == address.Undef { + return nil, xerrors.Errorf("must provide a multisig address for proposal") + } + + if to == address.Undef { + return nil, xerrors.Errorf("must provide a target address for proposal") + } + + if amt.Sign() == -1 { + return nil, xerrors.Errorf("must provide a non-negative amount for proposed send") + } + + if m.from == address.Undef { + return nil, xerrors.Errorf("must provide source address") + } + + enc, actErr := actors.SerializeParams(&multisig0.ProposeParams{ + To: to, + Value: amt, + Method: method, + Params: params, + }) + if actErr != nil { + return nil, xerrors.Errorf("failed to serialize parameters: %w", actErr) + } + + return &types.Message{ + To: msig, + From: m.from, + Value: abi.NewTokenAmount(0), + Method: builtin0.MethodsMultisig.Propose, + Params: enc, + }, nil +} + +func (m message0) Approve(msig address.Address, txID uint64, hashData *ProposalHashData) (*types.Message, error) { + enc, err := txnParams(txID, hashData) + if err != nil { + return nil, err + } + + return &types.Message{ + To: msig, + From: m.from, + Value: types.NewInt(0), + Method: builtin0.MethodsMultisig.Approve, + Params: enc, + }, nil +} + +func (m message0) Cancel(msig address.Address, txID uint64, hashData *ProposalHashData) (*types.Message, error) { + enc, err := txnParams(txID, hashData) + if err != nil { + return nil, err + } + + return &types.Message{ + To: msig, + From: m.from, + Value: types.NewInt(0), + Method: builtin0.MethodsMultisig.Cancel, + Params: enc, + }, nil +} +{{end}} diff --git a/chain/actors/builtin/multisig/message4.go b/chain/actors/builtin/multisig/message4.go new file mode 100644 index 00000000000..90885aa0715 --- /dev/null +++ b/chain/actors/builtin/multisig/message4.go @@ -0,0 +1,71 @@ +package multisig + +import ( + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + + builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" + init4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/init" + multisig4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/multisig" + + "github.com/filecoin-project/lotus/chain/actors" + init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" + "github.com/filecoin-project/lotus/chain/types" +) + +type message4 struct{ message0 } + +func (m message4) Create( + signers []address.Address, threshold uint64, + unlockStart, unlockDuration abi.ChainEpoch, + initialAmount abi.TokenAmount, +) (*types.Message, error) { + + lenAddrs := uint64(len(signers)) + + if lenAddrs < threshold { + return nil, xerrors.Errorf("cannot require signing of more addresses than provided for multisig") + } + + if threshold == 0 { + threshold = lenAddrs + } + + if m.from == address.Undef { + return nil, xerrors.Errorf("must provide source address") + } + + // Set up constructor parameters for multisig + msigParams := &multisig4.ConstructorParams{ + Signers: signers, + NumApprovalsThreshold: threshold, + UnlockDuration: unlockDuration, + StartEpoch: unlockStart, + } + + enc, actErr := actors.SerializeParams(msigParams) + if actErr != nil { + return nil, actErr + } + + // new actors are created by invoking 'exec' on the init actor with the constructor params + execParams := &init4.ExecParams{ + CodeCID: builtin4.MultisigActorCodeID, + ConstructorParams: enc, + } + + enc, actErr = actors.SerializeParams(execParams) + if actErr != nil { + return nil, actErr + } + + return &types.Message{ + To: init_.Address, + From: m.from, + Method: builtin4.MethodsInit.Exec, + Params: enc, + Value: initialAmount, + }, nil +} diff --git a/chain/actors/builtin/multisig/multisig.go b/chain/actors/builtin/multisig/multisig.go new file mode 100644 index 00000000000..d8f6fabae20 --- /dev/null +++ b/chain/actors/builtin/multisig/multisig.go @@ -0,0 +1,152 @@ +package multisig + +import ( + "fmt" + + "github.com/minio/blake2b-simd" + cbg "github.com/whyrusleeping/cbor-gen" + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/cbor" + "github.com/ipfs/go-cid" + + msig4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/multisig" + + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + + builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" + + builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" + + "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/types" +) + +func init() { + + builtin.RegisterActorState(builtin0.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load0(store, root) + }) + + builtin.RegisterActorState(builtin2.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load2(store, root) + }) + + builtin.RegisterActorState(builtin3.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load3(store, root) + }) + + builtin.RegisterActorState(builtin4.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load4(store, root) + }) +} + +func Load(store adt.Store, act *types.Actor) (State, error) { + switch act.Code { + + case builtin0.MultisigActorCodeID: + return load0(store, act.Head) + + case builtin2.MultisigActorCodeID: + return load2(store, act.Head) + + case builtin3.MultisigActorCodeID: + return load3(store, act.Head) + + case builtin4.MultisigActorCodeID: + return load4(store, act.Head) + + } + return nil, xerrors.Errorf("unknown actor code %s", act.Code) +} + +type State interface { + cbor.Marshaler + + LockedBalance(epoch abi.ChainEpoch) (abi.TokenAmount, error) + StartEpoch() (abi.ChainEpoch, error) + UnlockDuration() (abi.ChainEpoch, error) + InitialBalance() (abi.TokenAmount, error) + Threshold() (uint64, error) + Signers() ([]address.Address, error) + + ForEachPendingTxn(func(id int64, txn Transaction) error) error + PendingTxnChanged(State) (bool, error) + + transactions() (adt.Map, error) + decodeTransaction(val *cbg.Deferred) (Transaction, error) +} + +type Transaction = msig4.Transaction + +var Methods = builtin4.MethodsMultisig + +func Message(version actors.Version, from address.Address) MessageBuilder { + switch version { + + case actors.Version0: + return message0{from} + + case actors.Version2: + return message2{message0{from}} + + case actors.Version3: + return message3{message0{from}} + + case actors.Version4: + return message4{message0{from}} + default: + panic(fmt.Sprintf("unsupported actors version: %d", version)) + } +} + +type MessageBuilder interface { + // Create a new multisig with the specified parameters. + Create(signers []address.Address, threshold uint64, + vestingStart, vestingDuration abi.ChainEpoch, + initialAmount abi.TokenAmount) (*types.Message, error) + + // Propose a transaction to the given multisig. + Propose(msig, target address.Address, amt abi.TokenAmount, + method abi.MethodNum, params []byte) (*types.Message, error) + + // Approve a multisig transaction. The "hash" is optional. + Approve(msig address.Address, txID uint64, hash *ProposalHashData) (*types.Message, error) + + // Cancel a multisig transaction. The "hash" is optional. + Cancel(msig address.Address, txID uint64, hash *ProposalHashData) (*types.Message, error) +} + +// this type is the same between v0 and v2 +type ProposalHashData = msig4.ProposalHashData +type ProposeReturn = msig4.ProposeReturn +type ProposeParams = msig4.ProposeParams + +func txnParams(id uint64, data *ProposalHashData) ([]byte, error) { + params := msig4.TxnIDParams{ID: msig4.TxnID(id)} + if data != nil { + if data.Requester.Protocol() != address.ID { + return nil, xerrors.Errorf("proposer address must be an ID address, was %s", data.Requester) + } + if data.Value.Sign() == -1 { + return nil, xerrors.Errorf("proposal value must be non-negative, was %s", data.Value) + } + if data.To == address.Undef { + return nil, xerrors.Errorf("proposed destination address must be set") + } + pser, err := data.Serialize() + if err != nil { + return nil, err + } + hash := blake2b.Sum256(pser) + params.ProposalHash = hash[:] + } + + return actors.SerializeParams(¶ms) +} diff --git a/chain/actors/builtin/multisig/state.go b/chain/actors/builtin/multisig/state.go deleted file mode 100644 index 5f9fb6a52ef..00000000000 --- a/chain/actors/builtin/multisig/state.go +++ /dev/null @@ -1,63 +0,0 @@ -package multisig - -import ( - cbg "github.com/whyrusleeping/cbor-gen" - "golang.org/x/xerrors" - - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/go-state-types/cbor" - "github.com/ipfs/go-cid" - - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" - builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" - builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" - - "github.com/filecoin-project/lotus/chain/actors/adt" - "github.com/filecoin-project/lotus/chain/actors/builtin" - "github.com/filecoin-project/lotus/chain/types" -) - -func init() { - builtin.RegisterActorState(builtin0.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { - return load0(store, root) - }) - builtin.RegisterActorState(builtin2.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { - return load2(store, root) - }) - builtin.RegisterActorState(builtin3.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { - return load3(store, root) - }) -} - -func Load(store adt.Store, act *types.Actor) (State, error) { - switch act.Code { - case builtin0.MultisigActorCodeID: - return load0(store, act.Head) - case builtin2.MultisigActorCodeID: - return load2(store, act.Head) - case builtin3.MultisigActorCodeID: - return load3(store, act.Head) - } - return nil, xerrors.Errorf("unknown actor code %s", act.Code) -} - -type State interface { - cbor.Marshaler - - LockedBalance(epoch abi.ChainEpoch) (abi.TokenAmount, error) - StartEpoch() (abi.ChainEpoch, error) - UnlockDuration() (abi.ChainEpoch, error) - InitialBalance() (abi.TokenAmount, error) - Threshold() (uint64, error) - Signers() ([]address.Address, error) - - ForEachPendingTxn(func(id int64, txn Transaction) error) error - PendingTxnChanged(State) (bool, error) - - transactions() (adt.Map, error) - decodeTransaction(val *cbg.Deferred) (Transaction, error) -} - -type Transaction = msig0.Transaction diff --git a/chain/actors/builtin/multisig/state.go.template b/chain/actors/builtin/multisig/state.go.template new file mode 100644 index 00000000000..2316aadba0c --- /dev/null +++ b/chain/actors/builtin/multisig/state.go.template @@ -0,0 +1,97 @@ +package multisig + +import ( + "bytes" + "encoding/binary" + + adt{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/util/adt" + + "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" + +{{if (ge .v 3)}} + builtin{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin" +{{end}} + msig{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/multisig" +) + +var _ State = (*state{{.v}})(nil) + +func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { + out := state{{.v}}{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +type state{{.v}} struct { + msig{{.v}}.State + store adt.Store +} + +func (s *state{{.v}}) LockedBalance(currEpoch abi.ChainEpoch) (abi.TokenAmount, error) { + return s.State.AmountLocked(currEpoch - s.State.StartEpoch), nil +} + +func (s *state{{.v}}) StartEpoch() (abi.ChainEpoch, error) { + return s.State.StartEpoch, nil +} + +func (s *state{{.v}}) UnlockDuration() (abi.ChainEpoch, error) { + return s.State.UnlockDuration, nil +} + +func (s *state{{.v}}) InitialBalance() (abi.TokenAmount, error) { + return s.State.InitialBalance, nil +} + +func (s *state{{.v}}) Threshold() (uint64, error) { + return s.State.NumApprovalsThreshold, nil +} + +func (s *state{{.v}}) Signers() ([]address.Address, error) { + return s.State.Signers, nil +} + +func (s *state{{.v}}) ForEachPendingTxn(cb func(id int64, txn Transaction) error) error { + arr, err := adt{{.v}}.AsMap(s.store, s.State.PendingTxns{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}}) + if err != nil { + return err + } + var out msig{{.v}}.Transaction + return arr.ForEach(&out, func(key string) error { + txid, n := binary.Varint([]byte(key)) + if n <= 0 { + return xerrors.Errorf("invalid pending transaction key: %v", key) + } + return cb(txid, (Transaction)(out)) //nolint:unconvert + }) +} + +func (s *state{{.v}}) PendingTxnChanged(other State) (bool, error) { + other{{.v}}, ok := other.(*state{{.v}}) + if !ok { + // treat an upgrade as a change, always + return true, nil + } + return !s.State.PendingTxns.Equals(other{{.v}}.PendingTxns), nil +} + +func (s *state{{.v}}) transactions() (adt.Map, error) { + return adt{{.v}}.AsMap(s.store, s.PendingTxns{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}}) +} + +func (s *state{{.v}}) decodeTransaction(val *cbg.Deferred) (Transaction, error) { + var tx msig{{.v}}.Transaction + if err := tx.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { + return Transaction{}, err + } + return tx, nil +} diff --git a/chain/actors/builtin/multisig/state0.go b/chain/actors/builtin/multisig/v0.go similarity index 93% rename from chain/actors/builtin/multisig/state0.go rename to chain/actors/builtin/multisig/v0.go index 5548b0a5ca4..20c1557b007 100644 --- a/chain/actors/builtin/multisig/state0.go +++ b/chain/actors/builtin/multisig/v0.go @@ -4,6 +4,8 @@ import ( "bytes" "encoding/binary" + adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/ipfs/go-cid" @@ -13,8 +15,6 @@ import ( "github.com/filecoin-project/lotus/chain/actors/adt" msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" - multisig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" - adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" ) var _ State = (*state0)(nil) @@ -68,7 +68,7 @@ func (s *state0) ForEachPendingTxn(cb func(id int64, txn Transaction) error) err if n <= 0 { return xerrors.Errorf("invalid pending transaction key: %v", key) } - return cb(txid, (Transaction)(out)) + return cb(txid, (Transaction)(out)) //nolint:unconvert }) } @@ -86,7 +86,7 @@ func (s *state0) transactions() (adt.Map, error) { } func (s *state0) decodeTransaction(val *cbg.Deferred) (Transaction, error) { - var tx multisig0.Transaction + var tx msig0.Transaction if err := tx.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { return Transaction{}, err } diff --git a/chain/actors/builtin/multisig/state2.go b/chain/actors/builtin/multisig/v2.go similarity index 97% rename from chain/actors/builtin/multisig/state2.go rename to chain/actors/builtin/multisig/v2.go index 628da3f2cec..ef317f903e2 100644 --- a/chain/actors/builtin/multisig/state2.go +++ b/chain/actors/builtin/multisig/v2.go @@ -4,6 +4,8 @@ import ( "bytes" "encoding/binary" + adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/ipfs/go-cid" @@ -13,7 +15,6 @@ import ( "github.com/filecoin-project/lotus/chain/actors/adt" msig2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig" - adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" ) var _ State = (*state2)(nil) @@ -67,7 +68,7 @@ func (s *state2) ForEachPendingTxn(cb func(id int64, txn Transaction) error) err if n <= 0 { return xerrors.Errorf("invalid pending transaction key: %v", key) } - return cb(txid, (Transaction)(out)) + return cb(txid, (Transaction)(out)) //nolint:unconvert }) } diff --git a/chain/actors/builtin/multisig/state3.go b/chain/actors/builtin/multisig/v3.go similarity index 93% rename from chain/actors/builtin/multisig/state3.go rename to chain/actors/builtin/multisig/v3.go index 7ade2ab6424..8834e455348 100644 --- a/chain/actors/builtin/multisig/state3.go +++ b/chain/actors/builtin/multisig/v3.go @@ -15,6 +15,7 @@ import ( "github.com/filecoin-project/lotus/chain/actors/adt" builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" + msig3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/multisig" ) @@ -69,17 +70,17 @@ func (s *state3) ForEachPendingTxn(cb func(id int64, txn Transaction) error) err if n <= 0 { return xerrors.Errorf("invalid pending transaction key: %v", key) } - return cb(txid, (Transaction)(out)) + return cb(txid, (Transaction)(out)) //nolint:unconvert }) } func (s *state3) PendingTxnChanged(other State) (bool, error) { - other2, ok := other.(*state3) + other3, ok := other.(*state3) if !ok { // treat an upgrade as a change, always return true, nil } - return !s.State.PendingTxns.Equals(other2.PendingTxns), nil + return !s.State.PendingTxns.Equals(other3.PendingTxns), nil } func (s *state3) transactions() (adt.Map, error) { diff --git a/chain/actors/builtin/multisig/v4.go b/chain/actors/builtin/multisig/v4.go new file mode 100644 index 00000000000..9f9dc75730f --- /dev/null +++ b/chain/actors/builtin/multisig/v4.go @@ -0,0 +1,96 @@ +package multisig + +import ( + "bytes" + "encoding/binary" + + adt4 "github.com/filecoin-project/specs-actors/v4/actors/util/adt" + + "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" + + builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" + + msig4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/multisig" +) + +var _ State = (*state4)(nil) + +func load4(store adt.Store, root cid.Cid) (State, error) { + out := state4{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +type state4 struct { + msig4.State + store adt.Store +} + +func (s *state4) LockedBalance(currEpoch abi.ChainEpoch) (abi.TokenAmount, error) { + return s.State.AmountLocked(currEpoch - s.State.StartEpoch), nil +} + +func (s *state4) StartEpoch() (abi.ChainEpoch, error) { + return s.State.StartEpoch, nil +} + +func (s *state4) UnlockDuration() (abi.ChainEpoch, error) { + return s.State.UnlockDuration, nil +} + +func (s *state4) InitialBalance() (abi.TokenAmount, error) { + return s.State.InitialBalance, nil +} + +func (s *state4) Threshold() (uint64, error) { + return s.State.NumApprovalsThreshold, nil +} + +func (s *state4) Signers() ([]address.Address, error) { + return s.State.Signers, nil +} + +func (s *state4) ForEachPendingTxn(cb func(id int64, txn Transaction) error) error { + arr, err := adt4.AsMap(s.store, s.State.PendingTxns, builtin4.DefaultHamtBitwidth) + if err != nil { + return err + } + var out msig4.Transaction + return arr.ForEach(&out, func(key string) error { + txid, n := binary.Varint([]byte(key)) + if n <= 0 { + return xerrors.Errorf("invalid pending transaction key: %v", key) + } + return cb(txid, (Transaction)(out)) //nolint:unconvert + }) +} + +func (s *state4) PendingTxnChanged(other State) (bool, error) { + other4, ok := other.(*state4) + if !ok { + // treat an upgrade as a change, always + return true, nil + } + return !s.State.PendingTxns.Equals(other4.PendingTxns), nil +} + +func (s *state4) transactions() (adt.Map, error) { + return adt4.AsMap(s.store, s.PendingTxns, builtin4.DefaultHamtBitwidth) +} + +func (s *state4) decodeTransaction(val *cbg.Deferred) (Transaction, error) { + var tx msig4.Transaction + if err := tx.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { + return Transaction{}, err + } + return tx, nil +} diff --git a/chain/actors/builtin/paych/actor.go.template b/chain/actors/builtin/paych/actor.go.template new file mode 100644 index 00000000000..3f68a5cfaab --- /dev/null +++ b/chain/actors/builtin/paych/actor.go.template @@ -0,0 +1,109 @@ +package paych + +import ( + "encoding/base64" + "fmt" + + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + big "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/go-state-types/cbor" + "github.com/ipfs/go-cid" + ipldcbor "github.com/ipfs/go-ipld-cbor" + + paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych" +{{range .versions}} + builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin" +{{end}} + + "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/types" +) + +func init() { +{{range .versions}} + builtin.RegisterActorState(builtin{{.}}.PaymentChannelActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load{{.}}(store, root) + }) +{{end}}} + +// Load returns an abstract copy of payment channel state, irregardless of actor version +func Load(store adt.Store, act *types.Actor) (State, error) { + switch act.Code { +{{range .versions}} + case builtin{{.}}.PaymentChannelActorCodeID: + return load{{.}}(store, act.Head) +{{end}} + } + return nil, xerrors.Errorf("unknown actor code %s", act.Code) +} + +// State is an abstract version of payment channel state that works across +// versions +type State interface { + cbor.Marshaler + // Channel owner, who has funded the actor + From() (address.Address, error) + // Recipient of payouts from channel + To() (address.Address, error) + + // Height at which the channel can be `Collected` + SettlingAt() (abi.ChainEpoch, error) + + // Amount successfully redeemed through the payment channel, paid out on `Collect()` + ToSend() (abi.TokenAmount, error) + + // Get total number of lanes + LaneCount() (uint64, error) + + // Iterate lane states + ForEachLaneState(cb func(idx uint64, dl LaneState) error) error +} + +// LaneState is an abstract copy of the state of a single lane +type LaneState interface { + Redeemed() (big.Int, error) + Nonce() (uint64, error) +} + +type SignedVoucher = paych0.SignedVoucher +type ModVerifyParams = paych0.ModVerifyParams + +// DecodeSignedVoucher decodes base64 encoded signed voucher. +func DecodeSignedVoucher(s string) (*SignedVoucher, error) { + data, err := base64.RawURLEncoding.DecodeString(s) + if err != nil { + return nil, err + } + + var sv SignedVoucher + if err := ipldcbor.DecodeInto(data, &sv); err != nil { + return nil, err + } + + return &sv, nil +} + +var Methods = builtin{{.latestVersion}}.MethodsPaych + +func Message(version actors.Version, from address.Address) MessageBuilder { + switch version { +{{range .versions}} + case actors.Version{{.}}: + return message{{.}}{from} +{{end}} + default: + panic(fmt.Sprintf("unsupported actors version: %d", version)) + } +} + +type MessageBuilder interface { + Create(to address.Address, initialAmount abi.TokenAmount) (*types.Message, error) + Update(paych address.Address, voucher *SignedVoucher, secret []byte) (*types.Message, error) + Settle(paych address.Address) (*types.Message, error) + Collect(paych address.Address) (*types.Message, error) +} diff --git a/chain/actors/builtin/paych/message.go b/chain/actors/builtin/paych/message.go deleted file mode 100644 index 39c091d4559..00000000000 --- a/chain/actors/builtin/paych/message.go +++ /dev/null @@ -1,34 +0,0 @@ -package paych - -import ( - "fmt" - - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/lotus/chain/actors" - "github.com/filecoin-project/lotus/chain/types" - - builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" -) - -var Methods = builtin3.MethodsPaych - -func Message(version actors.Version, from address.Address) MessageBuilder { - switch version { - case actors.Version0: - return message0{from} - case actors.Version2: - return message2{from} - case actors.Version3: - return message3{from} - default: - panic(fmt.Sprintf("unsupported actors version: %d", version)) - } -} - -type MessageBuilder interface { - Create(to address.Address, initialAmount abi.TokenAmount) (*types.Message, error) - Update(paych address.Address, voucher *SignedVoucher, secret []byte) (*types.Message, error) - Settle(paych address.Address) (*types.Message, error) - Collect(paych address.Address) (*types.Message, error) -} diff --git a/chain/actors/builtin/paych/message.go.template b/chain/actors/builtin/paych/message.go.template new file mode 100644 index 00000000000..4a5ea2331e5 --- /dev/null +++ b/chain/actors/builtin/paych/message.go.template @@ -0,0 +1,74 @@ +package paych + +import ( + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + + builtin{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin" + init{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/init" + paych{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/paych" + + "github.com/filecoin-project/lotus/chain/actors" + init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" + "github.com/filecoin-project/lotus/chain/types" +) + +type message{{.v}} struct{ from address.Address } + +func (m message{{.v}}) Create(to address.Address, initialAmount abi.TokenAmount) (*types.Message, error) { + params, aerr := actors.SerializeParams(&paych{{.v}}.ConstructorParams{From: m.from, To: to}) + if aerr != nil { + return nil, aerr + } + enc, aerr := actors.SerializeParams(&init{{.v}}.ExecParams{ + CodeCID: builtin{{.v}}.PaymentChannelActorCodeID, + ConstructorParams: params, + }) + if aerr != nil { + return nil, aerr + } + + return &types.Message{ + To: init_.Address, + From: m.from, + Value: initialAmount, + Method: builtin{{.v}}.MethodsInit.Exec, + Params: enc, + }, nil +} + +func (m message{{.v}}) Update(paych address.Address, sv *SignedVoucher, secret []byte) (*types.Message, error) { + params, aerr := actors.SerializeParams(&paych{{.v}}.UpdateChannelStateParams{ + Sv: *sv, + Secret: secret, + }) + if aerr != nil { + return nil, aerr + } + + return &types.Message{ + To: paych, + From: m.from, + Value: abi.NewTokenAmount(0), + Method: builtin{{.v}}.MethodsPaych.UpdateChannelState, + Params: params, + }, nil +} + +func (m message{{.v}}) Settle(paych address.Address) (*types.Message, error) { + return &types.Message{ + To: paych, + From: m.from, + Value: abi.NewTokenAmount(0), + Method: builtin{{.v}}.MethodsPaych.Settle, + }, nil +} + +func (m message{{.v}}) Collect(paych address.Address) (*types.Message, error) { + return &types.Message{ + To: paych, + From: m.from, + Value: abi.NewTokenAmount(0), + Method: builtin{{.v}}.MethodsPaych.Collect, + }, nil +} diff --git a/chain/actors/builtin/paych/message4.go b/chain/actors/builtin/paych/message4.go new file mode 100644 index 00000000000..b2c6b612e38 --- /dev/null +++ b/chain/actors/builtin/paych/message4.go @@ -0,0 +1,74 @@ +package paych + +import ( + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + + builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" + init4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/init" + paych4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/paych" + + "github.com/filecoin-project/lotus/chain/actors" + init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" + "github.com/filecoin-project/lotus/chain/types" +) + +type message4 struct{ from address.Address } + +func (m message4) Create(to address.Address, initialAmount abi.TokenAmount) (*types.Message, error) { + params, aerr := actors.SerializeParams(&paych4.ConstructorParams{From: m.from, To: to}) + if aerr != nil { + return nil, aerr + } + enc, aerr := actors.SerializeParams(&init4.ExecParams{ + CodeCID: builtin4.PaymentChannelActorCodeID, + ConstructorParams: params, + }) + if aerr != nil { + return nil, aerr + } + + return &types.Message{ + To: init_.Address, + From: m.from, + Value: initialAmount, + Method: builtin4.MethodsInit.Exec, + Params: enc, + }, nil +} + +func (m message4) Update(paych address.Address, sv *SignedVoucher, secret []byte) (*types.Message, error) { + params, aerr := actors.SerializeParams(&paych4.UpdateChannelStateParams{ + Sv: *sv, + Secret: secret, + }) + if aerr != nil { + return nil, aerr + } + + return &types.Message{ + To: paych, + From: m.from, + Value: abi.NewTokenAmount(0), + Method: builtin4.MethodsPaych.UpdateChannelState, + Params: params, + }, nil +} + +func (m message4) Settle(paych address.Address) (*types.Message, error) { + return &types.Message{ + To: paych, + From: m.from, + Value: abi.NewTokenAmount(0), + Method: builtin4.MethodsPaych.Settle, + }, nil +} + +func (m message4) Collect(paych address.Address) (*types.Message, error) { + return &types.Message{ + To: paych, + From: m.from, + Value: abi.NewTokenAmount(0), + Method: builtin4.MethodsPaych.Collect, + }, nil +} diff --git a/chain/actors/builtin/paych/state.go b/chain/actors/builtin/paych/paych.go similarity index 72% rename from chain/actors/builtin/paych/state.go rename to chain/actors/builtin/paych/paych.go index accb9624400..30e4408d8fe 100644 --- a/chain/actors/builtin/paych/state.go +++ b/chain/actors/builtin/paych/paych.go @@ -2,6 +2,7 @@ package paych import ( "encoding/base64" + "fmt" "golang.org/x/xerrors" @@ -12,37 +13,57 @@ import ( "github.com/ipfs/go-cid" ipldcbor "github.com/ipfs/go-ipld-cbor" - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych" + + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" + builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" + + "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/types" ) func init() { + builtin.RegisterActorState(builtin0.PaymentChannelActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load0(store, root) }) + builtin.RegisterActorState(builtin2.PaymentChannelActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load2(store, root) }) + builtin.RegisterActorState(builtin3.PaymentChannelActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load3(store, root) }) + + builtin.RegisterActorState(builtin4.PaymentChannelActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load4(store, root) + }) } // Load returns an abstract copy of payment channel state, irregardless of actor version func Load(store adt.Store, act *types.Actor) (State, error) { switch act.Code { + case builtin0.PaymentChannelActorCodeID: return load0(store, act.Head) + case builtin2.PaymentChannelActorCodeID: return load2(store, act.Head) + case builtin3.PaymentChannelActorCodeID: return load3(store, act.Head) + + case builtin4.PaymentChannelActorCodeID: + return load4(store, act.Head) + } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } @@ -92,3 +113,32 @@ func DecodeSignedVoucher(s string) (*SignedVoucher, error) { return &sv, nil } + +var Methods = builtin4.MethodsPaych + +func Message(version actors.Version, from address.Address) MessageBuilder { + switch version { + + case actors.Version0: + return message0{from} + + case actors.Version2: + return message2{from} + + case actors.Version3: + return message3{from} + + case actors.Version4: + return message4{from} + + default: + panic(fmt.Sprintf("unsupported actors version: %d", version)) + } +} + +type MessageBuilder interface { + Create(to address.Address, initialAmount abi.TokenAmount) (*types.Message, error) + Update(paych address.Address, voucher *SignedVoucher, secret []byte) (*types.Message, error) + Settle(paych address.Address) (*types.Message, error) + Collect(paych address.Address) (*types.Message, error) +} diff --git a/chain/actors/builtin/paych/state.go.template b/chain/actors/builtin/paych/state.go.template new file mode 100644 index 00000000000..b4b575a3e61 --- /dev/null +++ b/chain/actors/builtin/paych/state.go.template @@ -0,0 +1,104 @@ +package paych + +import ( + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/big" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + paych{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/paych" + adt{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/util/adt" +) + +var _ State = (*state{{.v}})(nil) + +func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { + out := state{{.v}}{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +type state{{.v}} struct { + paych{{.v}}.State + store adt.Store + lsAmt *adt{{.v}}.Array +} + +// Channel owner, who has funded the actor +func (s *state{{.v}}) From() (address.Address, error) { + return s.State.From, nil +} + +// Recipient of payouts from channel +func (s *state{{.v}}) To() (address.Address, error) { + return s.State.To, nil +} + +// Height at which the channel can be `Collected` +func (s *state{{.v}}) SettlingAt() (abi.ChainEpoch, error) { + return s.State.SettlingAt, nil +} + +// Amount successfully redeemed through the payment channel, paid out on `Collect()` +func (s *state{{.v}}) ToSend() (abi.TokenAmount, error) { + return s.State.ToSend, nil +} + +func (s *state{{.v}}) getOrLoadLsAmt() (*adt{{.v}}.Array, error) { + if s.lsAmt != nil { + return s.lsAmt, nil + } + + // Get the lane state from the chain + lsamt, err := adt{{.v}}.AsArray(s.store, s.State.LaneStates{{if (ge .v 3)}}, paych{{.v}}.LaneStatesAmtBitwidth{{end}}) + if err != nil { + return nil, err + } + + s.lsAmt = lsamt + return lsamt, nil +} + +// Get total number of lanes +func (s *state{{.v}}) LaneCount() (uint64, error) { + lsamt, err := s.getOrLoadLsAmt() + if err != nil { + return 0, err + } + return lsamt.Length(), nil +} + +// Iterate lane states +func (s *state{{.v}}) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error { + // Get the lane state from the chain + lsamt, err := s.getOrLoadLsAmt() + if err != nil { + return err + } + + // Note: we use a map instead of an array to store laneStates because the + // client sets the lane ID (the index) and potentially they could use a + // very large index. + var ls paych{{.v}}.LaneState + return lsamt.ForEach(&ls, func(i int64) error { + return cb(uint64(i), &laneState{{.v}}{ls}) + }) +} + +type laneState{{.v}} struct { + paych{{.v}}.LaneState +} + +func (ls *laneState{{.v}}) Redeemed() (big.Int, error) { + return ls.LaneState.Redeemed, nil +} + +func (ls *laneState{{.v}}) Nonce() (uint64, error) { + return ls.LaneState.Nonce, nil +} diff --git a/chain/actors/builtin/paych/state0.go b/chain/actors/builtin/paych/v0.go similarity index 100% rename from chain/actors/builtin/paych/state0.go rename to chain/actors/builtin/paych/v0.go diff --git a/chain/actors/builtin/paych/state2.go b/chain/actors/builtin/paych/v2.go similarity index 100% rename from chain/actors/builtin/paych/state2.go rename to chain/actors/builtin/paych/v2.go diff --git a/chain/actors/builtin/paych/state3.go b/chain/actors/builtin/paych/v3.go similarity index 100% rename from chain/actors/builtin/paych/state3.go rename to chain/actors/builtin/paych/v3.go diff --git a/chain/actors/builtin/paych/v4.go b/chain/actors/builtin/paych/v4.go new file mode 100644 index 00000000000..cf37eea5c19 --- /dev/null +++ b/chain/actors/builtin/paych/v4.go @@ -0,0 +1,104 @@ +package paych + +import ( + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/big" + + "github.com/filecoin-project/lotus/chain/actors/adt" + + paych4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/paych" + adt4 "github.com/filecoin-project/specs-actors/v4/actors/util/adt" +) + +var _ State = (*state4)(nil) + +func load4(store adt.Store, root cid.Cid) (State, error) { + out := state4{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +type state4 struct { + paych4.State + store adt.Store + lsAmt *adt4.Array +} + +// Channel owner, who has funded the actor +func (s *state4) From() (address.Address, error) { + return s.State.From, nil +} + +// Recipient of payouts from channel +func (s *state4) To() (address.Address, error) { + return s.State.To, nil +} + +// Height at which the channel can be `Collected` +func (s *state4) SettlingAt() (abi.ChainEpoch, error) { + return s.State.SettlingAt, nil +} + +// Amount successfully redeemed through the payment channel, paid out on `Collect()` +func (s *state4) ToSend() (abi.TokenAmount, error) { + return s.State.ToSend, nil +} + +func (s *state4) getOrLoadLsAmt() (*adt4.Array, error) { + if s.lsAmt != nil { + return s.lsAmt, nil + } + + // Get the lane state from the chain + lsamt, err := adt4.AsArray(s.store, s.State.LaneStates, paych4.LaneStatesAmtBitwidth) + if err != nil { + return nil, err + } + + s.lsAmt = lsamt + return lsamt, nil +} + +// Get total number of lanes +func (s *state4) LaneCount() (uint64, error) { + lsamt, err := s.getOrLoadLsAmt() + if err != nil { + return 0, err + } + return lsamt.Length(), nil +} + +// Iterate lane states +func (s *state4) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error { + // Get the lane state from the chain + lsamt, err := s.getOrLoadLsAmt() + if err != nil { + return err + } + + // Note: we use a map instead of an array to store laneStates because the + // client sets the lane ID (the index) and potentially they could use a + // very large index. + var ls paych4.LaneState + return lsamt.ForEach(&ls, func(i int64) error { + return cb(uint64(i), &laneState4{ls}) + }) +} + +type laneState4 struct { + paych4.LaneState +} + +func (ls *laneState4) Redeemed() (big.Int, error) { + return ls.LaneState.Redeemed, nil +} + +func (ls *laneState4) Nonce() (uint64, error) { + return ls.LaneState.Nonce, nil +} diff --git a/chain/actors/builtin/power/actor.go.template b/chain/actors/builtin/power/actor.go.template new file mode 100644 index 00000000000..82f791e5805 --- /dev/null +++ b/chain/actors/builtin/power/actor.go.template @@ -0,0 +1,78 @@ +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" + "github.com/filecoin-project/go-state-types/cbor" + + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/chain/types" +{{range .versions}} + builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin" +{{end}} +) + +func init() { +{{range .versions}} + builtin.RegisterActorState(builtin{{.}}.StoragePowerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load{{.}}(store, root) + }) +{{end}}} + +var ( + Address = builtin{{.latestVersion}}.StoragePowerActorAddr + Methods = builtin{{.latestVersion}}.MethodsPower +) + +func Load(store adt.Store, act *types.Actor) (State, error) { + switch act.Code { +{{range .versions}} + case builtin{{.}}.StoragePowerActorCodeID: + return load{{.}}(store, act.Head) +{{end}} + } + return nil, xerrors.Errorf("unknown actor code %s", act.Code) +} + +type State interface { + cbor.Marshaler + + TotalLocked() (abi.TokenAmount, error) + TotalPower() (Claim, error) + TotalCommitted() (Claim, error) + TotalPowerSmoothed() (builtin.FilterEstimate, error) + + // MinerCounts returns the number of miners. Participating is the number + // with power above the minimum miner threshold. + MinerCounts() (participating, total uint64, err error) + MinerPower(address.Address) (Claim, bool, error) + 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 { + // Sum of raw byte power for a miner's sectors. + RawBytePower abi.StoragePower + + // 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), + } +} diff --git a/chain/actors/builtin/power/power.go b/chain/actors/builtin/power/power.go index 712fb0b9837..bf530a21a60 100644 --- a/chain/actors/builtin/power/power.go +++ b/chain/actors/builtin/power/power.go @@ -15,35 +15,53 @@ import ( "github.com/filecoin-project/lotus/chain/types" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" + + builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" ) func init() { + builtin.RegisterActorState(builtin0.StoragePowerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load0(store, root) }) + builtin.RegisterActorState(builtin2.StoragePowerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load2(store, root) }) + builtin.RegisterActorState(builtin3.StoragePowerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load3(store, root) }) + + builtin.RegisterActorState(builtin4.StoragePowerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load4(store, root) + }) } var ( - Address = builtin3.StoragePowerActorAddr - Methods = builtin3.MethodsPower + Address = builtin4.StoragePowerActorAddr + Methods = builtin4.MethodsPower ) -func Load(store adt.Store, act *types.Actor) (st State, err error) { +func Load(store adt.Store, act *types.Actor) (State, error) { switch act.Code { + case builtin0.StoragePowerActorCodeID: return load0(store, act.Head) + case builtin2.StoragePowerActorCodeID: return load2(store, act.Head) + case builtin3.StoragePowerActorCodeID: return load3(store, act.Head) + + case builtin4.StoragePowerActorCodeID: + return load4(store, act.Head) + } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } diff --git a/chain/actors/builtin/power/state.go.template b/chain/actors/builtin/power/state.go.template new file mode 100644 index 00000000000..4cb904a1df7 --- /dev/null +++ b/chain/actors/builtin/power/state.go.template @@ -0,0 +1,151 @@ +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" + +{{if (ge .v 3)}} + builtin{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin" +{{end}} + power{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/power" + adt{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/util/adt" +) + +var _ State = (*state{{.v}})(nil) + +func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { + out := state{{.v}}{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +type state{{.v}} struct { + power{{.v}}.State + store adt.Store +} + +func (s *state{{.v}}) TotalLocked() (abi.TokenAmount, error) { + return s.TotalPledgeCollateral, nil +} + +func (s *state{{.v}}) TotalPower() (Claim, error) { + return Claim{ + RawBytePower: s.TotalRawBytePower, + QualityAdjPower: s.TotalQualityAdjPower, + }, nil +} + +// Committed power to the network. Includes miners below the minimum threshold. +func (s *state{{.v}}) TotalCommitted() (Claim, error) { + return Claim{ + RawBytePower: s.TotalBytesCommitted, + QualityAdjPower: s.TotalQABytesCommitted, + }, nil +} + +func (s *state{{.v}}) MinerPower(addr address.Address) (Claim, bool, error) { + claims, err := s.claims() + if err != nil { + return Claim{}, false, err + } + var claim power{{.v}}.Claim + ok, err := claims.Get(abi.AddrKey(addr), &claim) + if err != nil { + return Claim{}, false, err + } + return Claim{ + RawBytePower: claim.RawBytePower, + QualityAdjPower: claim.QualityAdjPower, + }, ok, nil +} + +func (s *state{{.v}}) MinerNominalPowerMeetsConsensusMinimum(a address.Address) (bool, error) { + return s.State.MinerNominalPowerMeetsConsensusMinimum(s.store, a) +} + +func (s *state{{.v}}) TotalPowerSmoothed() (builtin.FilterEstimate, error) { + return builtin.FromV{{.v}}FilterEstimate({{if (le .v 1)}}*{{end}}s.State.ThisEpochQAPowerSmoothed), nil +} + +func (s *state{{.v}}) MinerCounts() (uint64, uint64, error) { + return uint64(s.State.MinerAboveMinPowerCount), uint64(s.State.MinerCount), nil +} + +func (s *state{{.v}}) ListAllMiners() ([]address.Address, error) { + claims, err := s.claims() + if err != nil { + return nil, err + } + + var miners []address.Address + err = claims.ForEach(nil, func(k string) error { + a, err := address.NewFromBytes([]byte(k)) + if err != nil { + return err + } + miners = append(miners, a) + return nil + }) + if err != nil { + return nil, err + } + + return miners, nil +} + +func (s *state{{.v}}) ForEachClaim(cb func(miner address.Address, claim Claim) error) error { + claims, err := s.claims() + if err != nil { + return err + } + + var claim power{{.v}}.Claim + return claims.ForEach(&claim, func(k string) error { + a, err := address.NewFromBytes([]byte(k)) + if err != nil { + return err + } + return cb(a, Claim{ + RawBytePower: claim.RawBytePower, + QualityAdjPower: claim.QualityAdjPower, + }) + }) +} + +func (s *state{{.v}}) ClaimsChanged(other State) (bool, error) { + other{{.v}}, ok := other.(*state{{.v}}) + if !ok { + // treat an upgrade as a change, always + return true, nil + } + return !s.State.Claims.Equals(other{{.v}}.State.Claims), nil +} + +func (s *state{{.v}}) claims() (adt.Map, error) { + return adt{{.v}}.AsMap(s.store, s.Claims{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}}) +} + +func (s *state{{.v}}) decodeClaim(val *cbg.Deferred) (Claim, error) { + var ci power{{.v}}.Claim + if err := ci.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { + return Claim{}, err + } + return fromV{{.v}}Claim(ci), nil +} + +func fromV{{.v}}Claim(v{{.v}} power{{.v}}.Claim) Claim { + return Claim{ + RawBytePower: v{{.v}}.RawBytePower, + QualityAdjPower: v{{.v}}.QualityAdjPower, + } +} diff --git a/chain/actors/builtin/power/v0.go b/chain/actors/builtin/power/v0.go index 7636b612b51..91fad8c57f3 100644 --- a/chain/actors/builtin/power/v0.go +++ b/chain/actors/builtin/power/v0.go @@ -51,7 +51,7 @@ func (s *state0) TotalCommitted() (Claim, error) { } func (s *state0) MinerPower(addr address.Address) (Claim, bool, error) { - claims, err := adt0.AsMap(s.store, s.Claims) + claims, err := s.claims() if err != nil { return Claim{}, false, err } @@ -79,7 +79,7 @@ func (s *state0) MinerCounts() (uint64, uint64, error) { } func (s *state0) ListAllMiners() ([]address.Address, error) { - claims, err := adt0.AsMap(s.store, s.Claims) + claims, err := s.claims() if err != nil { return nil, err } @@ -101,7 +101,7 @@ func (s *state0) ListAllMiners() ([]address.Address, error) { } func (s *state0) ForEachClaim(cb func(miner address.Address, claim Claim) error) error { - claims, err := adt0.AsMap(s.store, s.Claims) + claims, err := s.claims() if err != nil { return err } @@ -141,5 +141,8 @@ func (s *state0) decodeClaim(val *cbg.Deferred) (Claim, error) { } func fromV0Claim(v0 power0.Claim) Claim { - return (Claim)(v0) + return Claim{ + RawBytePower: v0.RawBytePower, + QualityAdjPower: v0.QualityAdjPower, + } } diff --git a/chain/actors/builtin/power/v2.go b/chain/actors/builtin/power/v2.go index 012dc2a4f01..313160a7869 100644 --- a/chain/actors/builtin/power/v2.go +++ b/chain/actors/builtin/power/v2.go @@ -51,7 +51,7 @@ func (s *state2) TotalCommitted() (Claim, error) { } func (s *state2) MinerPower(addr address.Address) (Claim, bool, error) { - claims, err := adt2.AsMap(s.store, s.Claims) + claims, err := s.claims() if err != nil { return Claim{}, false, err } @@ -79,7 +79,7 @@ func (s *state2) MinerCounts() (uint64, uint64, error) { } func (s *state2) ListAllMiners() ([]address.Address, error) { - claims, err := adt2.AsMap(s.store, s.Claims) + claims, err := s.claims() if err != nil { return nil, err } @@ -101,7 +101,7 @@ func (s *state2) ListAllMiners() ([]address.Address, error) { } func (s *state2) ForEachClaim(cb func(miner address.Address, claim Claim) error) error { - claims, err := adt2.AsMap(s.store, s.Claims) + claims, err := s.claims() if err != nil { return err } diff --git a/chain/actors/builtin/power/v3.go b/chain/actors/builtin/power/v3.go index fd161dda5f4..2ef1e28086e 100644 --- a/chain/actors/builtin/power/v3.go +++ b/chain/actors/builtin/power/v3.go @@ -12,6 +12,7 @@ import ( "github.com/filecoin-project/lotus/chain/actors/builtin" builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" + power3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/power" adt3 "github.com/filecoin-project/specs-actors/v3/actors/util/adt" ) @@ -121,12 +122,12 @@ func (s *state3) ForEachClaim(cb func(miner address.Address, claim Claim) error) } func (s *state3) ClaimsChanged(other State) (bool, error) { - other2, ok := other.(*state3) + other3, ok := other.(*state3) if !ok { // treat an upgrade as a change, always return true, nil } - return !s.State.Claims.Equals(other2.State.Claims), nil + return !s.State.Claims.Equals(other3.State.Claims), nil } func (s *state3) claims() (adt.Map, error) { diff --git a/chain/actors/builtin/power/v4.go b/chain/actors/builtin/power/v4.go new file mode 100644 index 00000000000..686550456d3 --- /dev/null +++ b/chain/actors/builtin/power/v4.go @@ -0,0 +1,150 @@ +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" + + builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" + + power4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/power" + adt4 "github.com/filecoin-project/specs-actors/v4/actors/util/adt" +) + +var _ State = (*state4)(nil) + +func load4(store adt.Store, root cid.Cid) (State, error) { + out := state4{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +type state4 struct { + power4.State + store adt.Store +} + +func (s *state4) TotalLocked() (abi.TokenAmount, error) { + return s.TotalPledgeCollateral, nil +} + +func (s *state4) TotalPower() (Claim, error) { + return Claim{ + RawBytePower: s.TotalRawBytePower, + QualityAdjPower: s.TotalQualityAdjPower, + }, nil +} + +// Committed power to the network. Includes miners below the minimum threshold. +func (s *state4) TotalCommitted() (Claim, error) { + return Claim{ + RawBytePower: s.TotalBytesCommitted, + QualityAdjPower: s.TotalQABytesCommitted, + }, nil +} + +func (s *state4) MinerPower(addr address.Address) (Claim, bool, error) { + claims, err := s.claims() + if err != nil { + return Claim{}, false, err + } + var claim power4.Claim + ok, err := claims.Get(abi.AddrKey(addr), &claim) + if err != nil { + return Claim{}, false, err + } + return Claim{ + RawBytePower: claim.RawBytePower, + QualityAdjPower: claim.QualityAdjPower, + }, ok, nil +} + +func (s *state4) MinerNominalPowerMeetsConsensusMinimum(a address.Address) (bool, error) { + return s.State.MinerNominalPowerMeetsConsensusMinimum(s.store, a) +} + +func (s *state4) TotalPowerSmoothed() (builtin.FilterEstimate, error) { + return builtin.FromV4FilterEstimate(s.State.ThisEpochQAPowerSmoothed), nil +} + +func (s *state4) MinerCounts() (uint64, uint64, error) { + return uint64(s.State.MinerAboveMinPowerCount), uint64(s.State.MinerCount), nil +} + +func (s *state4) ListAllMiners() ([]address.Address, error) { + claims, err := s.claims() + if err != nil { + return nil, err + } + + var miners []address.Address + err = claims.ForEach(nil, func(k string) error { + a, err := address.NewFromBytes([]byte(k)) + if err != nil { + return err + } + miners = append(miners, a) + return nil + }) + if err != nil { + return nil, err + } + + return miners, nil +} + +func (s *state4) ForEachClaim(cb func(miner address.Address, claim Claim) error) error { + claims, err := s.claims() + if err != nil { + return err + } + + var claim power4.Claim + return claims.ForEach(&claim, func(k string) error { + a, err := address.NewFromBytes([]byte(k)) + if err != nil { + return err + } + return cb(a, Claim{ + RawBytePower: claim.RawBytePower, + QualityAdjPower: claim.QualityAdjPower, + }) + }) +} + +func (s *state4) ClaimsChanged(other State) (bool, error) { + other4, ok := other.(*state4) + if !ok { + // treat an upgrade as a change, always + return true, nil + } + return !s.State.Claims.Equals(other4.State.Claims), nil +} + +func (s *state4) claims() (adt.Map, error) { + return adt4.AsMap(s.store, s.Claims, builtin4.DefaultHamtBitwidth) +} + +func (s *state4) decodeClaim(val *cbg.Deferred) (Claim, error) { + var ci power4.Claim + if err := ci.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { + return Claim{}, err + } + return fromV4Claim(ci), nil +} + +func fromV4Claim(v4 power4.Claim) Claim { + return Claim{ + RawBytePower: v4.RawBytePower, + QualityAdjPower: v4.QualityAdjPower, + } +} diff --git a/chain/actors/builtin/reward/actor.go.template b/chain/actors/builtin/reward/actor.go.template new file mode 100644 index 00000000000..81437d26fe6 --- /dev/null +++ b/chain/actors/builtin/reward/actor.go.template @@ -0,0 +1,60 @@ +package reward + +import ( + "github.com/filecoin-project/go-state-types/abi" + reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward" + "github.com/ipfs/go-cid" + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-state-types/cbor" +{{range .versions}} + builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin" +{{end}} + + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/chain/types" +) + +func init() { +{{range .versions}} + builtin.RegisterActorState(builtin{{.}}.RewardActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load{{.}}(store, root) + }) +{{end}}} + +var ( + Address = builtin{{.latestVersion}}.RewardActorAddr + Methods = builtin{{.latestVersion}}.MethodsReward +) + +func Load(store adt.Store, act *types.Actor) (State, error) { + switch act.Code { +{{range .versions}} + case builtin{{.}}.RewardActorCodeID: + return load{{.}}(store, act.Head) +{{end}} + } + return nil, xerrors.Errorf("unknown actor code %s", act.Code) +} + +type State interface { + cbor.Marshaler + + ThisEpochBaselinePower() (abi.StoragePower, error) + ThisEpochReward() (abi.StoragePower, error) + ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) + + EffectiveBaselinePower() (abi.StoragePower, error) + EffectiveNetworkTime() (abi.ChainEpoch, error) + + TotalStoragePowerReward() (abi.TokenAmount, error) + + CumsumBaseline() (abi.StoragePower, error) + CumsumRealized() (abi.StoragePower, error) + + InitialPledgeForPower(abi.StoragePower, abi.TokenAmount, *builtin.FilterEstimate, abi.TokenAmount) (abi.TokenAmount, error) + PreCommitDepositForPower(builtin.FilterEstimate, abi.StoragePower) (abi.TokenAmount, error) +} + +type AwardBlockRewardParams = reward0.AwardBlockRewardParams diff --git a/chain/actors/builtin/reward/reward.go b/chain/actors/builtin/reward/reward.go index 156b3ec5593..1037cf7412c 100644 --- a/chain/actors/builtin/reward/reward.go +++ b/chain/actors/builtin/reward/reward.go @@ -7,40 +7,59 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/go-state-types/cbor" + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" + builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/types" ) func init() { + builtin.RegisterActorState(builtin0.RewardActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load0(store, root) }) + builtin.RegisterActorState(builtin2.RewardActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load2(store, root) }) + builtin.RegisterActorState(builtin3.RewardActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load3(store, root) }) + + builtin.RegisterActorState(builtin4.RewardActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load4(store, root) + }) } var ( - Address = builtin3.RewardActorAddr - Methods = builtin3.MethodsReward + Address = builtin4.RewardActorAddr + Methods = builtin4.MethodsReward ) -func Load(store adt.Store, act *types.Actor) (st State, err error) { +func Load(store adt.Store, act *types.Actor) (State, error) { switch act.Code { + case builtin0.RewardActorCodeID: return load0(store, act.Head) + case builtin2.RewardActorCodeID: return load2(store, act.Head) + case builtin3.RewardActorCodeID: return load3(store, act.Head) + + case builtin4.RewardActorCodeID: + return load4(store, act.Head) + } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } diff --git a/chain/actors/builtin/reward/state.go.template b/chain/actors/builtin/reward/state.go.template new file mode 100644 index 00000000000..1758d1413b1 --- /dev/null +++ b/chain/actors/builtin/reward/state.go.template @@ -0,0 +1,103 @@ +package reward + +import ( + "github.com/filecoin-project/go-state-types/abi" + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin" + + miner{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/miner" + reward{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/reward" + smoothing{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/util/smoothing" +) + +var _ State = (*state{{.v}})(nil) + +func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { + out := state{{.v}}{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +type state{{.v}} struct { + reward{{.v}}.State + store adt.Store +} + +func (s *state{{.v}}) ThisEpochReward() (abi.TokenAmount, error) { + return s.State.ThisEpochReward, nil +} + +func (s *state{{.v}}) ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) { +{{if (ge .v 2)}} + return builtin.FilterEstimate{ + PositionEstimate: s.State.ThisEpochRewardSmoothed.PositionEstimate, + VelocityEstimate: s.State.ThisEpochRewardSmoothed.VelocityEstimate, + }, nil +{{else}} + return builtin.FromV0FilterEstimate(*s.State.ThisEpochRewardSmoothed), nil +{{end}} +} + +func (s *state{{.v}}) ThisEpochBaselinePower() (abi.StoragePower, error) { + return s.State.ThisEpochBaselinePower, nil +} + +func (s *state{{.v}}) TotalStoragePowerReward() (abi.TokenAmount, error) { + return s.State.{{if (ge .v 2)}}TotalStoragePowerReward{{else}}TotalMined{{end}}, nil +} + +func (s *state{{.v}}) EffectiveBaselinePower() (abi.StoragePower, error) { + return s.State.EffectiveBaselinePower, nil +} + +func (s *state{{.v}}) EffectiveNetworkTime() (abi.ChainEpoch, error) { + return s.State.EffectiveNetworkTime, nil +} + +func (s *state{{.v}}) CumsumBaseline() (reward{{.v}}.Spacetime, error) { + return s.State.CumsumBaseline, nil +} + +func (s *state{{.v}}) CumsumRealized() (reward{{.v}}.Spacetime, error) { + return s.State.CumsumRealized, nil +} +{{if (ge .v 2)}} +func (s *state{{.v}}) InitialPledgeForPower(qaPower abi.StoragePower, networkTotalPledge abi.TokenAmount, networkQAPower *builtin.FilterEstimate, circSupply abi.TokenAmount) (abi.TokenAmount, error) { + return miner{{.v}}.InitialPledgeForPower( + qaPower, + s.State.ThisEpochBaselinePower, + s.State.ThisEpochRewardSmoothed, + smoothing{{.v}}.FilterEstimate{ + PositionEstimate: networkQAPower.PositionEstimate, + VelocityEstimate: networkQAPower.VelocityEstimate, + }, + circSupply, + ), nil +} +{{else}} +func (s *state0) InitialPledgeForPower(sectorWeight abi.StoragePower, networkTotalPledge abi.TokenAmount, networkQAPower *builtin.FilterEstimate, circSupply abi.TokenAmount) (abi.TokenAmount, error) { + return miner0.InitialPledgeForPower( + sectorWeight, + s.State.ThisEpochBaselinePower, + networkTotalPledge, + s.State.ThisEpochRewardSmoothed, + &smoothing0.FilterEstimate{ + PositionEstimate: networkQAPower.PositionEstimate, + VelocityEstimate: networkQAPower.VelocityEstimate, + }, + circSupply), nil +} +{{end}} +func (s *state{{.v}}) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, sectorWeight abi.StoragePower) (abi.TokenAmount, error) { + return miner{{.v}}.PreCommitDepositForPower(s.State.ThisEpochRewardSmoothed, + {{if (le .v 0)}}&{{end}}smoothing{{.v}}.FilterEstimate{ + PositionEstimate: networkQAPower.PositionEstimate, + VelocityEstimate: networkQAPower.VelocityEstimate, + }, + sectorWeight), nil +} diff --git a/chain/actors/builtin/reward/v0.go b/chain/actors/builtin/reward/v0.go index 6a6e6d12e9d..fe053cc16f6 100644 --- a/chain/actors/builtin/reward/v0.go +++ b/chain/actors/builtin/reward/v0.go @@ -28,12 +28,14 @@ type state0 struct { store adt.Store } -func (s *state0) ThisEpochReward() (abi.StoragePower, error) { +func (s *state0) ThisEpochReward() (abi.TokenAmount, error) { return s.State.ThisEpochReward, nil } func (s *state0) ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) { + return builtin.FromV0FilterEstimate(*s.State.ThisEpochRewardSmoothed), nil + } func (s *state0) ThisEpochBaselinePower() (abi.StoragePower, error) { @@ -52,11 +54,11 @@ func (s *state0) EffectiveNetworkTime() (abi.ChainEpoch, error) { return s.State.EffectiveNetworkTime, nil } -func (s *state0) CumsumBaseline() (abi.StoragePower, error) { +func (s *state0) CumsumBaseline() (reward0.Spacetime, error) { return s.State.CumsumBaseline, nil } -func (s *state0) CumsumRealized() (abi.StoragePower, error) { +func (s *state0) CumsumRealized() (reward0.Spacetime, error) { return s.State.CumsumRealized, nil } diff --git a/chain/actors/builtin/reward/v2.go b/chain/actors/builtin/reward/v2.go index c9a59153290..90621e4678e 100644 --- a/chain/actors/builtin/reward/v2.go +++ b/chain/actors/builtin/reward/v2.go @@ -33,10 +33,12 @@ func (s *state2) ThisEpochReward() (abi.TokenAmount, error) { } func (s *state2) ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) { + return builtin.FilterEstimate{ PositionEstimate: s.State.ThisEpochRewardSmoothed.PositionEstimate, VelocityEstimate: s.State.ThisEpochRewardSmoothed.VelocityEstimate, }, nil + } func (s *state2) ThisEpochBaselinePower() (abi.StoragePower, error) { diff --git a/chain/actors/builtin/reward/v3.go b/chain/actors/builtin/reward/v3.go index 18bd58f8e7a..926cc085b5d 100644 --- a/chain/actors/builtin/reward/v3.go +++ b/chain/actors/builtin/reward/v3.go @@ -33,10 +33,12 @@ func (s *state3) ThisEpochReward() (abi.TokenAmount, error) { } func (s *state3) ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) { + return builtin.FilterEstimate{ PositionEstimate: s.State.ThisEpochRewardSmoothed.PositionEstimate, VelocityEstimate: s.State.ThisEpochRewardSmoothed.VelocityEstimate, }, nil + } func (s *state3) ThisEpochBaselinePower() (abi.StoragePower, error) { diff --git a/chain/actors/builtin/reward/v4.go b/chain/actors/builtin/reward/v4.go new file mode 100644 index 00000000000..f034b0018c7 --- /dev/null +++ b/chain/actors/builtin/reward/v4.go @@ -0,0 +1,88 @@ +package reward + +import ( + "github.com/filecoin-project/go-state-types/abi" + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin" + + miner4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/miner" + reward4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/reward" + smoothing4 "github.com/filecoin-project/specs-actors/v4/actors/util/smoothing" +) + +var _ State = (*state4)(nil) + +func load4(store adt.Store, root cid.Cid) (State, error) { + out := state4{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +type state4 struct { + reward4.State + store adt.Store +} + +func (s *state4) ThisEpochReward() (abi.TokenAmount, error) { + return s.State.ThisEpochReward, nil +} + +func (s *state4) ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) { + + return builtin.FilterEstimate{ + PositionEstimate: s.State.ThisEpochRewardSmoothed.PositionEstimate, + VelocityEstimate: s.State.ThisEpochRewardSmoothed.VelocityEstimate, + }, nil + +} + +func (s *state4) ThisEpochBaselinePower() (abi.StoragePower, error) { + return s.State.ThisEpochBaselinePower, nil +} + +func (s *state4) TotalStoragePowerReward() (abi.TokenAmount, error) { + return s.State.TotalStoragePowerReward, nil +} + +func (s *state4) EffectiveBaselinePower() (abi.StoragePower, error) { + return s.State.EffectiveBaselinePower, nil +} + +func (s *state4) EffectiveNetworkTime() (abi.ChainEpoch, error) { + return s.State.EffectiveNetworkTime, nil +} + +func (s *state4) CumsumBaseline() (reward4.Spacetime, error) { + return s.State.CumsumBaseline, nil +} + +func (s *state4) CumsumRealized() (reward4.Spacetime, error) { + return s.State.CumsumRealized, nil +} + +func (s *state4) InitialPledgeForPower(qaPower abi.StoragePower, networkTotalPledge abi.TokenAmount, networkQAPower *builtin.FilterEstimate, circSupply abi.TokenAmount) (abi.TokenAmount, error) { + return miner4.InitialPledgeForPower( + qaPower, + s.State.ThisEpochBaselinePower, + s.State.ThisEpochRewardSmoothed, + smoothing4.FilterEstimate{ + PositionEstimate: networkQAPower.PositionEstimate, + VelocityEstimate: networkQAPower.VelocityEstimate, + }, + circSupply, + ), nil +} + +func (s *state4) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, sectorWeight abi.StoragePower) (abi.TokenAmount, error) { + return miner4.PreCommitDepositForPower(s.State.ThisEpochRewardSmoothed, + smoothing4.FilterEstimate{ + PositionEstimate: networkQAPower.PositionEstimate, + VelocityEstimate: networkQAPower.VelocityEstimate, + }, + sectorWeight), nil +} diff --git a/chain/actors/builtin/verifreg/actor.go.template b/chain/actors/builtin/verifreg/actor.go.template new file mode 100644 index 00000000000..22e809ccf05 --- /dev/null +++ b/chain/actors/builtin/verifreg/actor.go.template @@ -0,0 +1,51 @@ +package verifreg + +import ( + "github.com/ipfs/go-cid" + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + + "github.com/filecoin-project/go-state-types/cbor" +{{range .versions}} + builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin" +{{end}} + + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/chain/types" +) + +func init() { +{{range .versions}} + builtin.RegisterActorState(builtin{{.}}.VerifiedRegistryActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load{{.}}(store, root) + }) +{{end}} +} + +var ( + Address = builtin{{.latestVersion}}.VerifiedRegistryActorAddr + Methods = builtin{{.latestVersion}}.MethodsVerifiedRegistry +) + +func Load(store adt.Store, act *types.Actor) (State, error) { + switch act.Code { +{{range .versions}} + case builtin{{.}}.VerifiedRegistryActorCodeID: + return load{{.}}(store, act.Head) +{{end}} + } + return nil, xerrors.Errorf("unknown actor code %s", act.Code) +} + +type State interface { + cbor.Marshaler + + RootKey() (address.Address, error) + VerifiedClientDataCap(address.Address) (bool, abi.StoragePower, error) + VerifierDataCap(address.Address) (bool, abi.StoragePower, error) + ForEachVerifier(func(addr address.Address, dcap abi.StoragePower) error) error + ForEachClient(func(addr address.Address, dcap abi.StoragePower) error) error +} diff --git a/chain/actors/builtin/verifreg/state.go.template b/chain/actors/builtin/verifreg/state.go.template new file mode 100644 index 00000000000..244d20932d9 --- /dev/null +++ b/chain/actors/builtin/verifreg/state.go.template @@ -0,0 +1,58 @@ +package verifreg + +import ( + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" + +{{if (ge .v 3)}} builtin{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin" +{{end}} verifreg{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/verifreg" + adt{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/util/adt" +) + +var _ State = (*state{{.v}})(nil) + +func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { + out := state{{.v}}{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +type state{{.v}} struct { + verifreg{{.v}}.State + store adt.Store +} + +func (s *state{{.v}}) RootKey() (address.Address, error) { + return s.State.RootKey, nil +} + +func (s *state{{.v}}) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) { + return getDataCap(s.store, actors.Version{{.v}}, s.verifiedClients, addr) +} + +func (s *state{{.v}}) VerifierDataCap(addr address.Address) (bool, abi.StoragePower, error) { + return getDataCap(s.store, actors.Version{{.v}}, s.verifiers, addr) +} + +func (s *state{{.v}}) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error { + return forEachCap(s.store, actors.Version{{.v}}, s.verifiers, cb) +} + +func (s *state{{.v}}) ForEachClient(cb func(addr address.Address, dcap abi.StoragePower) error) error { + return forEachCap(s.store, actors.Version{{.v}}, s.verifiedClients, cb) +} + +func (s *state{{.v}}) verifiedClients() (adt.Map, error) { + return adt{{.v}}.AsMap(s.store, s.VerifiedClients{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}}) +} + +func (s *state{{.v}}) verifiers() (adt.Map, error) { + return adt{{.v}}.AsMap(s.store, s.Verifiers{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}}) +} diff --git a/chain/actors/builtin/verifreg/v4.go b/chain/actors/builtin/verifreg/v4.go new file mode 100644 index 00000000000..2419ef7588d --- /dev/null +++ b/chain/actors/builtin/verifreg/v4.go @@ -0,0 +1,58 @@ +package verifreg + +import ( + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" + + builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" + verifreg4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/verifreg" + adt4 "github.com/filecoin-project/specs-actors/v4/actors/util/adt" +) + +var _ State = (*state4)(nil) + +func load4(store adt.Store, root cid.Cid) (State, error) { + out := state4{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +type state4 struct { + verifreg4.State + store adt.Store +} + +func (s *state4) RootKey() (address.Address, error) { + return s.State.RootKey, nil +} + +func (s *state4) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) { + return getDataCap(s.store, actors.Version4, s.verifiedClients, addr) +} + +func (s *state4) VerifierDataCap(addr address.Address) (bool, abi.StoragePower, error) { + return getDataCap(s.store, actors.Version4, s.verifiers, addr) +} + +func (s *state4) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error { + return forEachCap(s.store, actors.Version4, s.verifiers, cb) +} + +func (s *state4) ForEachClient(cb func(addr address.Address, dcap abi.StoragePower) error) error { + return forEachCap(s.store, actors.Version4, s.verifiedClients, cb) +} + +func (s *state4) verifiedClients() (adt.Map, error) { + return adt4.AsMap(s.store, s.VerifiedClients, builtin4.DefaultHamtBitwidth) +} + +func (s *state4) verifiers() (adt.Map, error) { + return adt4.AsMap(s.store, s.Verifiers, builtin4.DefaultHamtBitwidth) +} diff --git a/chain/actors/builtin/verifreg/verifreg.go b/chain/actors/builtin/verifreg/verifreg.go index 4e3f3559b36..32f50a4ae32 100644 --- a/chain/actors/builtin/verifreg/verifreg.go +++ b/chain/actors/builtin/verifreg/verifreg.go @@ -1,46 +1,67 @@ package verifreg import ( - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/go-state-types/abi" - builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" "github.com/ipfs/go-cid" "golang.org/x/xerrors" + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/cbor" + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" + + builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/types" ) func init() { + builtin.RegisterActorState(builtin0.VerifiedRegistryActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load0(store, root) }) + builtin.RegisterActorState(builtin2.VerifiedRegistryActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load2(store, root) }) + builtin.RegisterActorState(builtin3.VerifiedRegistryActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { return load3(store, root) }) + + builtin.RegisterActorState(builtin4.VerifiedRegistryActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) { + return load4(store, root) + }) + } var ( - Address = builtin3.VerifiedRegistryActorAddr - Methods = builtin3.MethodsVerifiedRegistry + Address = builtin4.VerifiedRegistryActorAddr + Methods = builtin4.MethodsVerifiedRegistry ) func Load(store adt.Store, act *types.Actor) (State, error) { switch act.Code { + case builtin0.VerifiedRegistryActorCodeID: return load0(store, act.Head) + case builtin2.VerifiedRegistryActorCodeID: return load2(store, act.Head) + case builtin3.VerifiedRegistryActorCodeID: return load3(store, act.Head) + + case builtin4.VerifiedRegistryActorCodeID: + return load4(store, act.Head) + } return nil, xerrors.Errorf("unknown actor code %s", act.Code) } diff --git a/chain/actors/policy/policy.go b/chain/actors/policy/policy.go index e32b3674310..164f19a76f2 100644 --- a/chain/actors/policy/policy.go +++ b/chain/actors/policy/policy.go @@ -20,20 +20,29 @@ import ( builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" market3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/market" miner3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/miner" - paych3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/paych" verifreg3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/verifreg" + + builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" + market4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/market" + miner4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/miner" + verifreg4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/verifreg" + + paych4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/paych" ) const ( - ChainFinality = miner3.ChainFinality - SealRandomnessLookback = ChainFinality - PaychSettleDelay = paych3.SettleDelay + ChainFinality = miner4.ChainFinality + SealRandomnessLookback = ChainFinality + PaychSettleDelay = paych4.SettleDelay + MaxPreCommitRandomnessLookback = builtin4.EpochsInDay + SealRandomnessLookback ) // SetSupportedProofTypes sets supported proof types, across all actor versions. // This should only be used for testing. func SetSupportedProofTypes(types ...abi.RegisteredSealProof) { + miner0.SupportedProofTypes = make(map[abi.RegisteredSealProof]struct{}, len(types)) + miner2.PreCommitSealProofTypesV0 = make(map[abi.RegisteredSealProof]struct{}, len(types)) miner2.PreCommitSealProofTypesV7 = make(map[abi.RegisteredSealProof]struct{}, len(types)*2) miner2.PreCommitSealProofTypesV8 = make(map[abi.RegisteredSealProof]struct{}, len(types)) @@ -42,6 +51,10 @@ func SetSupportedProofTypes(types ...abi.RegisteredSealProof) { miner3.PreCommitSealProofTypesV7 = make(map[abi.RegisteredSealProof]struct{}, len(types)*2) miner3.PreCommitSealProofTypesV8 = make(map[abi.RegisteredSealProof]struct{}, len(types)) + miner4.PreCommitSealProofTypesV0 = make(map[abi.RegisteredSealProof]struct{}, len(types)) + miner4.PreCommitSealProofTypesV7 = make(map[abi.RegisteredSealProof]struct{}, len(types)*2) + miner4.PreCommitSealProofTypesV8 = make(map[abi.RegisteredSealProof]struct{}, len(types)) + AddSupportedProofTypes(types...) } @@ -53,20 +66,24 @@ func AddSupportedProofTypes(types ...abi.RegisteredSealProof) { panic("must specify v1 proof types only") } // Set for all miner versions. + miner0.SupportedProofTypes[t] = struct{}{} - miner2.PreCommitSealProofTypesV0[t] = struct{}{} + miner2.PreCommitSealProofTypesV0[t] = struct{}{} miner2.PreCommitSealProofTypesV7[t] = struct{}{} miner2.PreCommitSealProofTypesV7[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{} - miner2.PreCommitSealProofTypesV8[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{} miner3.PreCommitSealProofTypesV0[t] = struct{}{} - miner3.PreCommitSealProofTypesV7[t] = struct{}{} miner3.PreCommitSealProofTypesV7[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{} - miner3.PreCommitSealProofTypesV8[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{} + + miner4.PreCommitSealProofTypesV0[t] = struct{}{} + miner4.PreCommitSealProofTypesV7[t] = struct{}{} + miner4.PreCommitSealProofTypesV7[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{} + miner4.PreCommitSealProofTypesV8[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{} + } } @@ -74,21 +91,29 @@ func AddSupportedProofTypes(types ...abi.RegisteredSealProof) { // actors versions. Use for testing. func SetPreCommitChallengeDelay(delay abi.ChainEpoch) { // Set for all miner versions. + miner0.PreCommitChallengeDelay = delay + miner2.PreCommitChallengeDelay = delay + miner3.PreCommitChallengeDelay = delay + + miner4.PreCommitChallengeDelay = delay + } // TODO: this function shouldn't really exist. Instead, the API should expose the precommit delay. func GetPreCommitChallengeDelay() abi.ChainEpoch { - return miner0.PreCommitChallengeDelay + return miner4.PreCommitChallengeDelay } // SetConsensusMinerMinPower sets the minimum power of an individual miner must // meet for leader election, across all actor versions. This should only be used // for testing. func SetConsensusMinerMinPower(p abi.StoragePower) { + power0.ConsensusMinerMinPower = p + for _, policy := range builtin2.SealProofPolicies { policy.ConsensusMinerMinPower = p } @@ -96,24 +121,46 @@ func SetConsensusMinerMinPower(p abi.StoragePower) { for _, policy := range builtin3.PoStProofPolicies { policy.ConsensusMinerMinPower = p } + + for _, policy := range builtin4.PoStProofPolicies { + policy.ConsensusMinerMinPower = p + } + } // SetMinVerifiedDealSize sets the minimum size of a verified deal. This should // only be used for testing. func SetMinVerifiedDealSize(size abi.StoragePower) { + verifreg0.MinVerifiedDealSize = size + verifreg2.MinVerifiedDealSize = size + verifreg3.MinVerifiedDealSize = size + + verifreg4.MinVerifiedDealSize = size + } func GetMaxProveCommitDuration(ver actors.Version, t abi.RegisteredSealProof) abi.ChainEpoch { switch ver { + case actors.Version0: + return miner0.MaxSealDuration[t] + case actors.Version2: + return miner2.MaxProveCommitDuration[t] + case actors.Version3: + return miner3.MaxProveCommitDuration[t] + + case actors.Version4: + + return miner4.MaxProveCommitDuration[t] + default: panic("unsupported actors version") } @@ -125,20 +172,36 @@ func DealProviderCollateralBounds( circulatingFil abi.TokenAmount, nwVer network.Version, ) (min, max abi.TokenAmount) { switch actors.VersionForNetwork(nwVer) { + case actors.Version0: + return market0.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil, nwVer) + case actors.Version2: + return market2.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) + case actors.Version3: + return market3.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) + + case actors.Version4: + + return market4.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) + default: - panic("unsupported network version") + panic("unsupported actors version") } } +func DealDurationBounds(pieceSize abi.PaddedPieceSize) (min, max abi.ChainEpoch) { + return market4.DealDurationBounds(pieceSize) +} + // Sets the challenge window and scales the proving period to match (such that // there are always 48 challenge windows in a proving period). func SetWPoStChallengeWindow(period abi.ChainEpoch) { + miner0.WPoStChallengeWindow = period miner0.WPoStProvingPeriod = period * abi.ChainEpoch(miner0.WPoStPeriodDeadlines) @@ -147,9 +210,18 @@ func SetWPoStChallengeWindow(period abi.ChainEpoch) { miner3.WPoStChallengeWindow = period miner3.WPoStProvingPeriod = period * abi.ChainEpoch(miner3.WPoStPeriodDeadlines) + // by default, this is 2x finality which is 30 periods. // scale it if we're scaling the challenge period. miner3.WPoStDisputeWindow = period * 30 + + miner4.WPoStChallengeWindow = period + miner4.WPoStProvingPeriod = period * abi.ChainEpoch(miner4.WPoStPeriodDeadlines) + + // by default, this is 2x finality which is 30 periods. + // scale it if we're scaling the challenge period. + miner4.WPoStDisputeWindow = period * 30 + } func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch { @@ -157,26 +229,27 @@ func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch { return 10 } + // NOTE: if this ever changes, adjust it in a (*Miner).mineOne() logline as well return ChainFinality } func GetMaxSectorExpirationExtension() abi.ChainEpoch { - return miner0.MaxSectorExpirationExtension + return miner4.MaxSectorExpirationExtension } // TODO: we'll probably need to abstract over this better in the future. func GetMaxPoStPartitions(p abi.RegisteredPoStProof) (int, error) { - sectorsPerPart, err := builtin3.PoStProofWindowPoStPartitionSectors(p) + sectorsPerPart, err := builtin4.PoStProofWindowPoStPartitionSectors(p) if err != nil { return 0, err } - return int(miner3.AddressedSectorsMax / sectorsPerPart), nil + return int(miner4.AddressedSectorsMax / sectorsPerPart), nil } func GetDefaultSectorSize() abi.SectorSize { // supported sector sizes are the same across versions. - szs := make([]abi.SectorSize, 0, len(miner3.PreCommitSealProofTypesV8)) - for spt := range miner3.PreCommitSealProofTypesV8 { + szs := make([]abi.SectorSize, 0, len(miner4.PreCommitSealProofTypesV8)) + for spt := range miner4.PreCommitSealProofTypesV8 { ss, err := spt.SectorSize() if err != nil { panic(err) @@ -191,3 +264,56 @@ func GetDefaultSectorSize() abi.SectorSize { return szs[0] } + +func GetSectorMaxLifetime(proof abi.RegisteredSealProof, nwVer network.Version) abi.ChainEpoch { + if nwVer <= network.Version10 { + return builtin4.SealProofPoliciesV0[proof].SectorMaxLifetime + } + + return builtin4.SealProofPoliciesV11[proof].SectorMaxLifetime +} + +func GetAddressedSectorsMax(nwVer network.Version) int { + switch actors.VersionForNetwork(nwVer) { + + case actors.Version0: + return miner0.AddressedSectorsMax + + case actors.Version2: + return miner2.AddressedSectorsMax + + case actors.Version3: + return miner3.AddressedSectorsMax + + case actors.Version4: + return miner4.AddressedSectorsMax + + default: + panic("unsupported network version") + } +} + +func GetDeclarationsMax(nwVer network.Version) int { + switch actors.VersionForNetwork(nwVer) { + + case actors.Version0: + + // TODO: Should we instead panic here since the concept doesn't exist yet? + return miner0.AddressedPartitionsMax + + case actors.Version2: + + return miner2.DeclarationsMax + + case actors.Version3: + + return miner3.DeclarationsMax + + case actors.Version4: + + return miner4.DeclarationsMax + + default: + panic("unsupported network version") + } +} diff --git a/chain/actors/policy/policy.go.template b/chain/actors/policy/policy.go.template new file mode 100644 index 00000000000..d395d713259 --- /dev/null +++ b/chain/actors/policy/policy.go.template @@ -0,0 +1,233 @@ +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" + + {{range .versions}} + {{if (ge . 2)}} builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin" {{end}} + market{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin/market" + miner{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin/miner" + verifreg{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin/verifreg" + {{if (eq . 0)}} power{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin/power" {{end}} + {{end}} + + paych{{.latestVersion}} "github.com/filecoin-project/specs-actors{{import .latestVersion}}actors/builtin/paych" +) + +const ( + ChainFinality = miner{{.latestVersion}}.ChainFinality + SealRandomnessLookback = ChainFinality + PaychSettleDelay = paych{{.latestVersion}}.SettleDelay + MaxPreCommitRandomnessLookback = builtin{{.latestVersion}}.EpochsInDay + SealRandomnessLookback +) + +// SetSupportedProofTypes sets supported proof types, across all actor versions. +// This should only be used for testing. +func SetSupportedProofTypes(types ...abi.RegisteredSealProof) { + {{range .versions}} + {{if (eq . 0)}} + miner{{.}}.SupportedProofTypes = make(map[abi.RegisteredSealProof]struct{}, len(types)) + {{else}} + miner{{.}}.PreCommitSealProofTypesV0 = make(map[abi.RegisteredSealProof]struct{}, len(types)) + miner{{.}}.PreCommitSealProofTypesV7 = make(map[abi.RegisteredSealProof]struct{}, len(types)*2) + miner{{.}}.PreCommitSealProofTypesV8 = make(map[abi.RegisteredSealProof]struct{}, len(types)) + {{end}} + {{end}} + + AddSupportedProofTypes(types...) +} + +// AddSupportedProofTypes sets supported proof types, across all actor versions. +// This should only be used for testing. +func AddSupportedProofTypes(types ...abi.RegisteredSealProof) { + for _, t := range types { + if t >= abi.RegisteredSealProof_StackedDrg2KiBV1_1 { + panic("must specify v1 proof types only") + } + // Set for all miner versions. + + {{range .versions}} + {{if (eq . 0)}} + miner{{.}}.SupportedProofTypes[t] = struct{}{} + {{else}} + miner{{.}}.PreCommitSealProofTypesV0[t] = struct{}{} + miner{{.}}.PreCommitSealProofTypesV7[t] = struct{}{} + miner{{.}}.PreCommitSealProofTypesV7[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{} + miner{{.}}.PreCommitSealProofTypesV8[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{} + {{end}} + {{end}} + } +} + +// SetPreCommitChallengeDelay sets the pre-commit challenge delay across all +// actors versions. Use for testing. +func SetPreCommitChallengeDelay(delay abi.ChainEpoch) { + // Set for all miner versions. + {{range .versions}} + miner{{.}}.PreCommitChallengeDelay = delay + {{end}} +} + +// TODO: this function shouldn't really exist. Instead, the API should expose the precommit delay. +func GetPreCommitChallengeDelay() abi.ChainEpoch { + return miner{{.latestVersion}}.PreCommitChallengeDelay +} + +// SetConsensusMinerMinPower sets the minimum power of an individual miner must +// meet for leader election, across all actor versions. This should only be used +// for testing. +func SetConsensusMinerMinPower(p abi.StoragePower) { + {{range .versions}} + {{if (eq . 0)}} + power{{.}}.ConsensusMinerMinPower = p + {{else if (eq . 2)}} + for _, policy := range builtin{{.}}.SealProofPolicies { + policy.ConsensusMinerMinPower = p + } + {{else}} + for _, policy := range builtin{{.}}.PoStProofPolicies { + policy.ConsensusMinerMinPower = p + } + {{end}} + {{end}} +} + +// SetMinVerifiedDealSize sets the minimum size of a verified deal. This should +// only be used for testing. +func SetMinVerifiedDealSize(size abi.StoragePower) { + {{range .versions}} + verifreg{{.}}.MinVerifiedDealSize = size + {{end}} +} + +func GetMaxProveCommitDuration(ver actors.Version, t abi.RegisteredSealProof) abi.ChainEpoch { + switch ver { + {{range .versions}} + case actors.Version{{.}}: + {{if (eq . 0)}} + return miner{{.}}.MaxSealDuration[t] + {{else}} + return miner{{.}}.MaxProveCommitDuration[t] + {{end}} + {{end}} + default: + panic("unsupported actors version") + } +} + +func DealProviderCollateralBounds( + size abi.PaddedPieceSize, verified bool, + rawBytePower, qaPower, baselinePower abi.StoragePower, + circulatingFil abi.TokenAmount, nwVer network.Version, +) (min, max abi.TokenAmount) { + switch actors.VersionForNetwork(nwVer) { + {{range .versions}} + case actors.Version{{.}}: + {{if (eq . 0)}} + return market{{.}}.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil, nwVer) + {{else}} + return market{{.}}.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) + {{end}} + {{end}} + default: + panic("unsupported actors version") + } +} + +func DealDurationBounds(pieceSize abi.PaddedPieceSize) (min, max abi.ChainEpoch) { + return market{{.latestVersion}}.DealDurationBounds(pieceSize) +} + +// Sets the challenge window and scales the proving period to match (such that +// there are always 48 challenge windows in a proving period). +func SetWPoStChallengeWindow(period abi.ChainEpoch) { + {{range .versions}} + miner{{.}}.WPoStChallengeWindow = period + miner{{.}}.WPoStProvingPeriod = period * abi.ChainEpoch(miner{{.}}.WPoStPeriodDeadlines) + {{if (ge . 3)}} + // by default, this is 2x finality which is 30 periods. + // scale it if we're scaling the challenge period. + miner{{.}}.WPoStDisputeWindow = period * 30 + {{end}} + {{end}} +} + +func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch { + if nwVer <= network.Version3 { + return 10 + } + + // NOTE: if this ever changes, adjust it in a (*Miner).mineOne() logline as well + return ChainFinality +} + +func GetMaxSectorExpirationExtension() abi.ChainEpoch { + return miner{{.latestVersion}}.MaxSectorExpirationExtension +} + +// TODO: we'll probably need to abstract over this better in the future. +func GetMaxPoStPartitions(p abi.RegisteredPoStProof) (int, error) { + sectorsPerPart, err := builtin{{.latestVersion}}.PoStProofWindowPoStPartitionSectors(p) + if err != nil { + return 0, err + } + return int(miner{{.latestVersion}}.AddressedSectorsMax / sectorsPerPart), nil +} + +func GetDefaultSectorSize() abi.SectorSize { + // supported sector sizes are the same across versions. + szs := make([]abi.SectorSize, 0, len(miner{{.latestVersion}}.PreCommitSealProofTypesV8)) + for spt := range miner{{.latestVersion}}.PreCommitSealProofTypesV8 { + 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] +} + +func GetSectorMaxLifetime(proof abi.RegisteredSealProof, nwVer network.Version) abi.ChainEpoch { + if nwVer <= network.Version10 { + return builtin{{.latestVersion}}.SealProofPoliciesV0[proof].SectorMaxLifetime + } + + return builtin{{.latestVersion}}.SealProofPoliciesV11[proof].SectorMaxLifetime +} + +func GetAddressedSectorsMax(nwVer network.Version) int { + switch actors.VersionForNetwork(nwVer) { + {{range .versions}} + case actors.Version{{.}}: + return miner{{.}}.AddressedSectorsMax + {{end}} + default: + panic("unsupported network version") + } +} + +func GetDeclarationsMax(nwVer network.Version) int { + switch actors.VersionForNetwork(nwVer) { + {{range .versions}} + case actors.Version{{.}}: + {{if (eq . 0)}} + // TODO: Should we instead panic here since the concept doesn't exist yet? + return miner{{.}}.AddressedPartitionsMax + {{else}} + return miner{{.}}.DeclarationsMax + {{end}} + {{end}} + default: + panic("unsupported network version") + } +} diff --git a/chain/actors/version.go b/chain/actors/version.go index 763c5a42ccc..bd7b708bdcd 100644 --- a/chain/actors/version.go +++ b/chain/actors/version.go @@ -12,6 +12,7 @@ const ( Version0 Version = 0 Version2 Version = 2 Version3 Version = 3 + Version4 Version = 4 ) // Converts a network version into an actors adt version. @@ -21,8 +22,10 @@ func VersionForNetwork(version network.Version) Version { return Version0 case network.Version4, network.Version5, network.Version6, network.Version7, network.Version8, network.Version9: return Version2 - case network.Version10: + case network.Version10, network.Version11: return Version3 + case network.Version12: + return Version4 default: panic(fmt.Sprintf("unsupported network version %d", version)) } diff --git a/chain/beacon/beacon.go b/chain/beacon/beacon.go index 9543bec54b3..220057282fd 100644 --- a/chain/beacon/beacon.go +++ b/chain/beacon/beacon.go @@ -4,7 +4,7 @@ import ( "context" "github.com/filecoin-project/go-state-types/abi" - logging "github.com/ipfs/go-log" + logging "github.com/ipfs/go-log/v2" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/build" diff --git a/chain/beacon/drand/drand.go b/chain/beacon/drand/drand.go index 4abc12d2902..e7f673d7f66 100644 --- a/chain/beacon/drand/drand.go +++ b/chain/beacon/drand/drand.go @@ -3,7 +3,6 @@ package drand import ( "bytes" "context" - "sync" "time" dchain "github.com/drand/drand/chain" @@ -13,10 +12,11 @@ import ( gclient "github.com/drand/drand/lp2p/client" "github.com/drand/kyber" kzap "github.com/go-kit/kit/log/zap" + lru "github.com/hashicorp/golang-lru" "go.uber.org/zap/zapcore" "golang.org/x/xerrors" - logging "github.com/ipfs/go-log" + logging "github.com/ipfs/go-log/v2" pubsub "github.com/libp2p/go-libp2p-pubsub" "github.com/filecoin-project/go-state-types/abi" @@ -61,8 +61,7 @@ type DrandBeacon struct { filGenTime uint64 filRoundTime uint64 - cacheLk sync.Mutex - localCache map[uint64]types.BeaconEntry + localCache *lru.Cache } // DrandHTTPClient interface overrides the user agent used by drand @@ -111,9 +110,14 @@ func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config dtypes return nil, xerrors.Errorf("creating drand client") } + lc, err := lru.New(1024) + if err != nil { + return nil, err + } + db := &DrandBeacon{ client: client, - localCache: make(map[uint64]types.BeaconEntry), + localCache: lc, } db.pubkey = drandChain.PublicKey @@ -156,19 +160,16 @@ func (db *DrandBeacon) Entry(ctx context.Context, round uint64) <-chan beacon.Re return out } func (db *DrandBeacon) cacheValue(e types.BeaconEntry) { - db.cacheLk.Lock() - defer db.cacheLk.Unlock() - db.localCache[e.Round] = e + db.localCache.Add(e.Round, e) } func (db *DrandBeacon) getCachedValue(round uint64) *types.BeaconEntry { - db.cacheLk.Lock() - defer db.cacheLk.Unlock() - v, ok := db.localCache[round] + v, ok := db.localCache.Get(round) if !ok { return nil } - return &v + e, _ := v.(types.BeaconEntry) + return &e } func (db *DrandBeacon) VerifyEntry(curr types.BeaconEntry, prev types.BeaconEntry) error { @@ -177,6 +178,9 @@ func (db *DrandBeacon) VerifyEntry(curr types.BeaconEntry, prev types.BeaconEntr return nil } if be := db.getCachedValue(curr.Round); be != nil { + if !bytes.Equal(curr.Data, be.Data) { + return xerrors.New("invalid beacon value, does not match cached good value") + } // return no error if the value is in the cache already return nil } diff --git a/chain/checkpoint.go b/chain/checkpoint.go index 8f99d73e43d..a3660a45ce4 100644 --- a/chain/checkpoint.go +++ b/chain/checkpoint.go @@ -1,81 +1,57 @@ package chain import ( - "encoding/json" + "context" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/node/modules/dtypes" - "github.com/ipfs/go-datastore" "golang.org/x/xerrors" ) -var CheckpointKey = datastore.NewKey("/chain/checks") - -func loadCheckpoint(ds dtypes.MetadataDS) (types.TipSetKey, error) { - haveChks, err := ds.Has(CheckpointKey) - if err != nil { - return types.EmptyTSK, err - } - - if !haveChks { - return types.EmptyTSK, nil +func (syncer *Syncer) SyncCheckpoint(ctx context.Context, tsk types.TipSetKey) error { + if tsk == types.EmptyTSK { + return xerrors.Errorf("called with empty tsk") } - tskBytes, err := ds.Get(CheckpointKey) + ts, err := syncer.ChainStore().LoadTipSet(tsk) if err != nil { - return types.EmptyTSK, err + tss, err := syncer.Exchange.GetBlocks(ctx, tsk, 1) + if err != nil { + return xerrors.Errorf("failed to fetch tipset: %w", err) + } else if len(tss) != 1 { + return xerrors.Errorf("expected 1 tipset, got %d", len(tss)) + } + ts = tss[0] } - var tsk types.TipSetKey - err = json.Unmarshal(tskBytes, &tsk) - if err != nil { - return types.EmptyTSK, err + if err := syncer.switchChain(ctx, ts); err != nil { + return xerrors.Errorf("failed to switch chain when syncing checkpoint: %w", err) } - return tsk, err -} - -func (syncer *Syncer) SetCheckpoint(tsk types.TipSetKey) error { - if tsk == types.EmptyTSK { - return xerrors.Errorf("called with empty tsk") + if err := syncer.ChainStore().SetCheckpoint(ts); err != nil { + return xerrors.Errorf("failed to set the chain checkpoint: %w", err) } - syncer.checkptLk.Lock() - defer syncer.checkptLk.Unlock() - - ts, err := syncer.ChainStore().LoadTipSet(tsk) - if err != nil { - return xerrors.Errorf("cannot find tipset: %w", err) - } + return nil +} +func (syncer *Syncer) switchChain(ctx context.Context, ts *types.TipSet) error { hts := syncer.ChainStore().GetHeaviestTipSet() - anc, err := syncer.ChainStore().IsAncestorOf(ts, hts) - if err != nil { - return xerrors.Errorf("cannot determine whether checkpoint tipset is in main-chain: %w", err) + if hts.Equals(ts) { + return nil } - if !hts.Equals(ts) && !anc { - return xerrors.Errorf("cannot mark tipset as checkpoint, since it isn't in the main-chain: %w", err) + if anc, err := syncer.store.IsAncestorOf(ts, hts); err == nil && anc { + return nil } - tskBytes, err := json.Marshal(tsk) - if err != nil { - return err + // Otherwise, sync the chain and set the head. + if err := syncer.collectChain(ctx, ts, hts, true); err != nil { + return xerrors.Errorf("failed to collect chain for checkpoint: %w", err) } - err = syncer.ds.Put(CheckpointKey, tskBytes) - if err != nil { - return err + if err := syncer.ChainStore().SetHead(ts); err != nil { + return xerrors.Errorf("failed to set the chain head: %w", err) } - - syncer.checkpt = tsk - return nil } - -func (syncer *Syncer) GetCheckpoint() types.TipSetKey { - syncer.checkptLk.Lock() - defer syncer.checkptLk.Unlock() - return syncer.checkpt -} diff --git a/chain/events/events.go b/chain/events/events.go index 8ad40f95f0c..8511de9217b 100644 --- a/chain/events/events.go +++ b/chain/events/events.go @@ -33,19 +33,19 @@ type heightHandler struct { revert RevertHandler } -type eventAPI interface { +type EventAPI interface { ChainNotify(context.Context) (<-chan []*api.HeadChange, error) ChainGetBlockMessages(context.Context, cid.Cid) (*api.BlockMessages, error) ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error) ChainHead(context.Context) (*types.TipSet, error) - StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) + StateSearchMsg(ctx context.Context, from types.TipSetKey, msg cid.Cid, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) ChainGetTipSet(context.Context, types.TipSetKey) (*types.TipSet, error) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) // optional / for CalledMsg } type Events struct { - api eventAPI + api EventAPI tsc *tipSetCache lk sync.Mutex @@ -59,7 +59,7 @@ type Events struct { observers []TipSetObserver } -func NewEventsWithConfidence(ctx context.Context, api eventAPI, gcConfidence abi.ChainEpoch) *Events { +func NewEventsWithConfidence(ctx context.Context, api EventAPI, gcConfidence abi.ChainEpoch) *Events { tsc := newTSCache(gcConfidence, api) e := &Events{ @@ -93,7 +93,7 @@ func NewEventsWithConfidence(ctx context.Context, api eventAPI, gcConfidence abi return e } -func NewEvents(ctx context.Context, api eventAPI) *Events { +func NewEvents(ctx context.Context, api EventAPI) *Events { gcConfidence := 2 * build.ForkLengthThreshold return NewEventsWithConfidence(ctx, api, gcConfidence) } diff --git a/chain/events/events_called.go b/chain/events/events_called.go index 7f39e9038a6..1a619c195de 100644 --- a/chain/events/events_called.go +++ b/chain/events/events_called.go @@ -5,6 +5,8 @@ import ( "math" "sync" + "github.com/filecoin-project/lotus/chain/stmgr" + "github.com/filecoin-project/go-state-types/abi" "github.com/ipfs/go-cid" "golang.org/x/xerrors" @@ -66,7 +68,7 @@ type queuedEvent struct { // Manages chain head change events, which may be forward (new tipset added to // chain) or backward (chain branch discarded in favour of heavier branch) type hcEvents struct { - cs eventAPI + cs EventAPI tsc *tipSetCache ctx context.Context gcConfidence uint64 @@ -93,7 +95,7 @@ type hcEvents struct { watcherEvents } -func newHCEvents(ctx context.Context, cs eventAPI, tsc *tipSetCache, gcConfidence uint64) *hcEvents { +func newHCEvents(ctx context.Context, cs EventAPI, tsc *tipSetCache, gcConfidence uint64) *hcEvents { e := hcEvents{ ctx: ctx, cs: cs, @@ -353,14 +355,14 @@ type headChangeAPI interface { // watcherEvents watches for a state change type watcherEvents struct { ctx context.Context - cs eventAPI + cs EventAPI hcAPI headChangeAPI lk sync.RWMutex matchers map[triggerID]StateMatchFunc } -func newWatcherEvents(ctx context.Context, hcAPI headChangeAPI, cs eventAPI) watcherEvents { +func newWatcherEvents(ctx context.Context, hcAPI headChangeAPI, cs EventAPI) watcherEvents { return watcherEvents{ ctx: ctx, cs: cs, @@ -455,14 +457,14 @@ func (we *watcherEvents) StateChanged(check CheckFunc, scHnd StateChangeHandler, // messageEvents watches for message calls to actors type messageEvents struct { ctx context.Context - cs eventAPI + cs EventAPI hcAPI headChangeAPI lk sync.RWMutex matchers map[triggerID]MsgMatchFunc } -func newMessageEvents(ctx context.Context, hcAPI headChangeAPI, cs eventAPI) messageEvents { +func newMessageEvents(ctx context.Context, hcAPI headChangeAPI, cs EventAPI) messageEvents { return messageEvents{ ctx: ctx, cs: cs, @@ -583,12 +585,16 @@ func (me *messageEvents) Called(check CheckFunc, msgHnd MsgHandler, rev RevertHa panic("expected msg") } - rec, err := me.cs.StateGetReceipt(me.ctx, msg.Cid(), ts.Key()) + ml, err := me.cs.StateSearchMsg(me.ctx, ts.Key(), msg.Cid(), stmgr.LookbackNoLimit, true) if err != nil { return false, err } - return msgHnd(msg, rec, ts, height) + if ml == nil { + return msgHnd(msg, nil, ts, height) + } + + return msgHnd(msg, &ml.Receipt, ts, height) } id, err := me.hcAPI.onHeadChanged(check, hnd, rev, confidence, timeout) diff --git a/chain/events/events_test.go b/chain/events/events_test.go index 3957f425ca2..0aab626dd20 100644 --- a/chain/events/events_test.go +++ b/chain/events/events_test.go @@ -54,7 +54,7 @@ func (fcs *fakeCS) ChainGetTipSet(ctx context.Context, key types.TipSetKey) (*ty return fcs.tipsets[key], nil } -func (fcs *fakeCS) StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) { +func (fcs *fakeCS) StateSearchMsg(ctx context.Context, from types.TipSetKey, msg cid.Cid, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) { return nil, nil } @@ -229,7 +229,7 @@ func (fcs *fakeCS) notifDone() { fcs.sync.Unlock() } -var _ eventAPI = &fakeCS{} +var _ EventAPI = &fakeCS{} func TestAt(t *testing.T) { fcs := &fakeCS{ diff --git a/chain/events/utils.go b/chain/events/utils.go index c26ca5b836a..91ea0cd7a07 100644 --- a/chain/events/utils.go +++ b/chain/events/utils.go @@ -3,6 +3,8 @@ package events import ( "context" + "github.com/filecoin-project/lotus/chain/stmgr" + "golang.org/x/xerrors" "github.com/filecoin-project/lotus/chain/types" @@ -22,12 +24,16 @@ func (me *messageEvents) CheckMsg(ctx context.Context, smsg types.ChainMsg, hnd return false, true, nil } - rec, err := me.cs.StateGetReceipt(ctx, smsg.VMMessage().Cid(), ts.Key()) + ml, err := me.cs.StateSearchMsg(me.ctx, ts.Key(), msg.Cid(), stmgr.LookbackNoLimit, true) if err != nil { return false, true, xerrors.Errorf("getting receipt in CheckMsg: %w", err) } - more, err = hnd(msg, rec, ts, ts.Height()) + if ml == nil { + more, err = hnd(msg, nil, ts, ts.Height()) + } else { + more, err = hnd(msg, &ml.Receipt, ts, ts.Height()) + } return true, more, err } diff --git a/chain/exchange/protocol.go b/chain/exchange/protocol.go index 2114793359f..d0977e54c79 100644 --- a/chain/exchange/protocol.go +++ b/chain/exchange/protocol.go @@ -7,7 +7,7 @@ import ( "github.com/filecoin-project/lotus/chain/store" "github.com/ipfs/go-cid" - logging "github.com/ipfs/go-log" + logging "github.com/ipfs/go-log/v2" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/chain/types" diff --git a/chain/gen/gen.go b/chain/gen/gen.go index d06c755fa34..b4e04424c11 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -3,6 +3,7 @@ package gen import ( "bytes" "context" + "encoding/base64" "fmt" "io" "io/ioutil" @@ -610,6 +611,8 @@ func (wpp *wppProvider) ComputeProof(context.Context, []proof2.SectorInfo, abi.P return ValidWpostForTesting, nil } +var b64 = base64.URLEncoding.WithPadding(base64.NoPadding) + func IsRoundWinner(ctx context.Context, ts *types.TipSet, round abi.ChainEpoch, miner address.Address, brand types.BeaconEntry, mbi *api.MiningBaseInfo, a MiningCheckAPI) (*types.ElectionProof, error) { @@ -631,6 +634,15 @@ func IsRoundWinner(ctx context.Context, ts *types.TipSet, round abi.ChainEpoch, ep := &types.ElectionProof{VRFProof: vrfout} j := ep.ComputeWinCount(mbi.MinerPower, mbi.NetworkPower) ep.WinCount = j + + log.Infow("completed winAttemptVRF", + "beaconRound", brand.Round, + "beaconDataB64", b64.EncodeToString(brand.Data), + "electionRandB64", b64.EncodeToString(electionRand), + "vrfB64", b64.EncodeToString(vrfout), + "winCount", j, + ) + if j < 1 { return nil, nil } diff --git a/chain/gen/genesis/f01_init.go b/chain/gen/genesis/f01_init.go index 9fc6cfb9e5c..718eb44807c 100644 --- a/chain/gen/genesis/f01_init.go +++ b/chain/gen/genesis/f01_init.go @@ -133,9 +133,22 @@ func SetupInitActor(bs bstore.Blockstore, netname string, initialActors []genesi } } - err := setupMsig(remainder.Meta) - if err != nil { - return 0, nil, nil, xerrors.Errorf("setting up remainder msig: %w", err) + if remainder.Type == genesis.TAccount { + var ainfo genesis.AccountMeta + if err := json.Unmarshal(remainder.Meta, &ainfo); err != nil { + return 0, nil, nil, xerrors.Errorf("unmarshaling account meta: %w", err) + } + + // TODO: Use builtin.ReserveAddress... + value := cbg.CborInt(90) + if err := amap.Put(abi.AddrKey(ainfo.Owner), &value); err != nil { + return 0, nil, nil, err + } + } else if remainder.Type == genesis.TMultisig { + err := setupMsig(remainder.Meta) + if err != nil { + return 0, nil, nil, xerrors.Errorf("setting up remainder msig: %w", err) + } } amapaddr, err := amap.Root() diff --git a/chain/gen/genesis/genesis.go b/chain/gen/genesis/genesis.go index d382e4d0dff..4b86db5501e 100644 --- a/chain/gen/genesis/genesis.go +++ b/chain/gen/genesis/genesis.go @@ -330,24 +330,18 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge if err := json.Unmarshal(template.RemainderAccount.Meta, &ainfo); err != nil { return nil, nil, xerrors.Errorf("unmarshaling account meta: %w", err) } - st, err := cst.Put(ctx, &account0.State{Address: ainfo.Owner}) - if err != nil { - return nil, nil, err - } _, ok := keyIDs[ainfo.Owner] if ok { return nil, nil, fmt.Errorf("remainder account has already been declared, cannot be assigned 90: %s", ainfo.Owner) } - err = state.SetActor(builtin.ReserveAddress, &types.Actor{ - Code: builtin0.AccountActorCodeID, - Balance: template.RemainderAccount.Balance, - Head: st, - }) + keyIDs[ainfo.Owner] = builtin.ReserveAddress + err = createAccountActor(ctx, cst, state, template.RemainderAccount, keyIDs) if err != nil { - return nil, nil, xerrors.Errorf("setting remainder account: %w", err) + return nil, nil, xerrors.Errorf("creating remainder acct: %w", err) } + case genesis.TMultisig: if err = createMultisigAccount(ctx, bs, cst, state, builtin.ReserveAddress, template.RemainderAccount, keyIDs); err != nil { return nil, nil, xerrors.Errorf("failed to set up remainder: %w", err) diff --git a/chain/market/fundmanager.go b/chain/market/fundmanager.go index e3f10fdecd5..5becfdfa717 100644 --- a/chain/market/fundmanager.go +++ b/chain/market/fundmanager.go @@ -16,7 +16,7 @@ import ( "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" - logging "github.com/ipfs/go-log" + logging "github.com/ipfs/go-log/v2" "go.uber.org/fx" "golang.org/x/xerrors" ) @@ -36,7 +36,7 @@ type FundManagerAPI struct { 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) + StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) } // FundManager keeps track of funds in a set of addresses @@ -721,6 +721,6 @@ func (env *fundManagerEnvironment) WithdrawFunds( } func (env *fundManagerEnvironment) WaitMsg(ctx context.Context, c cid.Cid) error { - _, err := env.api.StateWaitMsg(ctx, c, build.MessageConfidence) + _, err := env.api.StateWaitMsg(ctx, c, build.MessageConfidence, api.LookbackNoLimit, true) return err } diff --git a/chain/market/fundmanager_test.go b/chain/market/fundmanager_test.go index ac6b2a405c0..12530434311 100644 --- a/chain/market/fundmanager_test.go +++ b/chain/market/fundmanager_test.go @@ -793,7 +793,7 @@ func (mapi *mockFundManagerAPI) publish(addr address.Address, amt abi.TokenAmoun mapi.escrow[addr] = escrow } -func (mapi *mockFundManagerAPI) StateWaitMsg(ctx context.Context, c cid.Cid, confidence uint64) (*api.MsgLookup, error) { +func (mapi *mockFundManagerAPI) StateWaitMsg(ctx context.Context, c cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) { res := &api.MsgLookup{ Message: c, Receipt: types.MessageReceipt{ diff --git a/chain/messagepool/check.go b/chain/messagepool/check.go new file mode 100644 index 00000000000..8d64636912d --- /dev/null +++ b/chain/messagepool/check.go @@ -0,0 +1,431 @@ +package messagepool + +import ( + "context" + "fmt" + stdbig "math/big" + "sort" + + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/chain/vm" +) + +var baseFeeUpperBoundFactor = types.NewInt(10) + +// CheckMessages performs a set of logic checks for a list of messages, prior to submitting it to the mpool +func (mp *MessagePool) CheckMessages(protos []*api.MessagePrototype) ([][]api.MessageCheckStatus, error) { + flex := make([]bool, len(protos)) + msgs := make([]*types.Message, len(protos)) + for i, p := range protos { + flex[i] = !p.ValidNonce + msgs[i] = &p.Message + } + return mp.checkMessages(msgs, false, flex) +} + +// CheckPendingMessages performs a set of logical sets for all messages pending from a given actor +func (mp *MessagePool) CheckPendingMessages(from address.Address) ([][]api.MessageCheckStatus, error) { + var msgs []*types.Message + mp.lk.Lock() + mset, ok := mp.pending[from] + if ok { + for _, sm := range mset.msgs { + msgs = append(msgs, &sm.Message) + } + } + mp.lk.Unlock() + + if len(msgs) == 0 { + return nil, nil + } + + sort.Slice(msgs, func(i, j int) bool { + return msgs[i].Nonce < msgs[j].Nonce + }) + + return mp.checkMessages(msgs, true, nil) +} + +// CheckReplaceMessages performs a set of logical checks for related messages while performing a +// replacement. +func (mp *MessagePool) CheckReplaceMessages(replace []*types.Message) ([][]api.MessageCheckStatus, error) { + msgMap := make(map[address.Address]map[uint64]*types.Message) + count := 0 + + mp.lk.Lock() + for _, m := range replace { + mmap, ok := msgMap[m.From] + if !ok { + mmap = make(map[uint64]*types.Message) + msgMap[m.From] = mmap + mset, ok := mp.pending[m.From] + if ok { + count += len(mset.msgs) + for _, sm := range mset.msgs { + mmap[sm.Message.Nonce] = &sm.Message + } + } else { + count++ + } + } + mmap[m.Nonce] = m + } + mp.lk.Unlock() + + msgs := make([]*types.Message, 0, count) + start := 0 + for _, mmap := range msgMap { + end := start + len(mmap) + + for _, m := range mmap { + msgs = append(msgs, m) + } + + sort.Slice(msgs[start:end], func(i, j int) bool { + return msgs[start+i].Nonce < msgs[start+j].Nonce + }) + + start = end + } + + return mp.checkMessages(msgs, true, nil) +} + +// flexibleNonces should be either nil or of len(msgs), it signifies that message at given index +// has non-determied nonce at this point +func (mp *MessagePool) checkMessages(msgs []*types.Message, interned bool, flexibleNonces []bool) (result [][]api.MessageCheckStatus, err error) { + if mp.api.IsLite() { + return nil, nil + } + mp.curTsLk.Lock() + curTs := mp.curTs + mp.curTsLk.Unlock() + + epoch := curTs.Height() + + var baseFee big.Int + if len(curTs.Blocks()) > 0 { + baseFee = curTs.Blocks()[0].ParentBaseFee + } else { + baseFee, err = mp.api.ChainComputeBaseFee(context.Background(), curTs) + if err != nil { + return nil, xerrors.Errorf("error computing basefee: %w", err) + } + } + + baseFeeLowerBound := getBaseFeeLowerBound(baseFee, baseFeeLowerBoundFactor) + baseFeeUpperBound := types.BigMul(baseFee, baseFeeUpperBoundFactor) + + type actorState struct { + nextNonce uint64 + requiredFunds *stdbig.Int + } + + state := make(map[address.Address]*actorState) + balances := make(map[address.Address]big.Int) + + result = make([][]api.MessageCheckStatus, len(msgs)) + + for i, m := range msgs { + // pre-check: actor nonce + check := api.MessageCheckStatus{ + Cid: m.Cid(), + CheckStatus: api.CheckStatus{ + Code: api.CheckStatusMessageGetStateNonce, + }, + } + + st, ok := state[m.From] + if !ok { + mp.lk.Lock() + mset, ok := mp.pending[m.From] + if ok && !interned { + st = &actorState{nextNonce: mset.nextNonce, requiredFunds: mset.requiredFunds} + for _, m := range mset.msgs { + st.requiredFunds = new(stdbig.Int).Add(st.requiredFunds, m.Message.Value.Int) + } + state[m.From] = st + mp.lk.Unlock() + + check.OK = true + check.Hint = map[string]interface{}{ + "nonce": st.nextNonce, + } + } else { + mp.lk.Unlock() + + stateNonce, err := mp.getStateNonce(m.From, curTs) + if err != nil { + check.OK = false + check.Err = fmt.Sprintf("error retrieving state nonce: %s", err.Error()) + } else { + check.OK = true + check.Hint = map[string]interface{}{ + "nonce": stateNonce, + } + } + + st = &actorState{nextNonce: stateNonce, requiredFunds: new(stdbig.Int)} + state[m.From] = st + } + } else { + check.OK = true + } + + result[i] = append(result[i], check) + if !check.OK { + continue + } + + // pre-check: actor balance + check = api.MessageCheckStatus{ + Cid: m.Cid(), + CheckStatus: api.CheckStatus{ + Code: api.CheckStatusMessageGetStateBalance, + }, + } + + balance, ok := balances[m.From] + if !ok { + balance, err = mp.getStateBalance(m.From, curTs) + if err != nil { + check.OK = false + check.Err = fmt.Sprintf("error retrieving state balance: %s", err) + } else { + check.OK = true + check.Hint = map[string]interface{}{ + "balance": balance, + } + } + + balances[m.From] = balance + } else { + check.OK = true + check.Hint = map[string]interface{}{ + "balance": balance, + } + } + + result[i] = append(result[i], check) + if !check.OK { + continue + } + + // 1. Serialization + check = api.MessageCheckStatus{ + Cid: m.Cid(), + CheckStatus: api.CheckStatus{ + Code: api.CheckStatusMessageSerialize, + }, + } + + bytes, err := m.Serialize() + if err != nil { + check.OK = false + check.Err = err.Error() + } else { + check.OK = true + } + + result[i] = append(result[i], check) + + // 2. Message size + check = api.MessageCheckStatus{ + Cid: m.Cid(), + CheckStatus: api.CheckStatus{ + Code: api.CheckStatusMessageSize, + }, + } + + if len(bytes) > 32*1024-128 { // 128 bytes to account for signature size + check.OK = false + check.Err = "message too big" + } else { + check.OK = true + } + + result[i] = append(result[i], check) + + // 3. Syntactic validation + check = api.MessageCheckStatus{ + Cid: m.Cid(), + CheckStatus: api.CheckStatus{ + Code: api.CheckStatusMessageValidity, + }, + } + + if err := m.ValidForBlockInclusion(0, build.NewestNetworkVersion); err != nil { + check.OK = false + check.Err = fmt.Sprintf("syntactically invalid message: %s", err.Error()) + } else { + check.OK = true + } + + result[i] = append(result[i], check) + if !check.OK { + // skip remaining checks if it is a syntatically invalid message + continue + } + + // gas checks + + // 4. Min Gas + minGas := vm.PricelistByEpoch(epoch).OnChainMessage(m.ChainLength()) + + check = api.MessageCheckStatus{ + Cid: m.Cid(), + CheckStatus: api.CheckStatus{ + Code: api.CheckStatusMessageMinGas, + Hint: map[string]interface{}{ + "minGas": minGas, + }, + }, + } + + if m.GasLimit < minGas.Total() { + check.OK = false + check.Err = "GasLimit less than epoch minimum gas" + } else { + check.OK = true + } + + result[i] = append(result[i], check) + + // 5. Min Base Fee + check = api.MessageCheckStatus{ + Cid: m.Cid(), + CheckStatus: api.CheckStatus{ + Code: api.CheckStatusMessageMinBaseFee, + }, + } + + if m.GasFeeCap.LessThan(minimumBaseFee) { + check.OK = false + check.Err = "GasFeeCap less than minimum base fee" + } else { + check.OK = true + } + + result[i] = append(result[i], check) + if !check.OK { + goto checkState + } + + // 6. Base Fee + check = api.MessageCheckStatus{ + Cid: m.Cid(), + CheckStatus: api.CheckStatus{ + Code: api.CheckStatusMessageBaseFee, + Hint: map[string]interface{}{ + "baseFee": baseFee, + }, + }, + } + + if m.GasFeeCap.LessThan(baseFee) { + check.OK = false + check.Err = "GasFeeCap less than current base fee" + } else { + check.OK = true + } + + result[i] = append(result[i], check) + + // 7. Base Fee lower bound + check = api.MessageCheckStatus{ + Cid: m.Cid(), + CheckStatus: api.CheckStatus{ + Code: api.CheckStatusMessageBaseFeeLowerBound, + Hint: map[string]interface{}{ + "baseFeeLowerBound": baseFeeLowerBound, + "baseFee": baseFee, + }, + }, + } + + if m.GasFeeCap.LessThan(baseFeeLowerBound) { + check.OK = false + check.Err = "GasFeeCap less than base fee lower bound for inclusion in next 20 epochs" + } else { + check.OK = true + } + + result[i] = append(result[i], check) + + // 8. Base Fee upper bound + check = api.MessageCheckStatus{ + Cid: m.Cid(), + CheckStatus: api.CheckStatus{ + Code: api.CheckStatusMessageBaseFeeUpperBound, + Hint: map[string]interface{}{ + "baseFeeUpperBound": baseFeeUpperBound, + "baseFee": baseFee, + }, + }, + } + + if m.GasFeeCap.LessThan(baseFeeUpperBound) { + check.OK = true // on purpose, the checks is more of a warning + check.Err = "GasFeeCap less than base fee upper bound for inclusion in next 20 epochs" + } else { + check.OK = true + } + + result[i] = append(result[i], check) + + // stateful checks + checkState: + // 9. Message Nonce + check = api.MessageCheckStatus{ + Cid: m.Cid(), + CheckStatus: api.CheckStatus{ + Code: api.CheckStatusMessageNonce, + Hint: map[string]interface{}{ + "nextNonce": st.nextNonce, + }, + }, + } + + if (flexibleNonces == nil || !flexibleNonces[i]) && st.nextNonce != m.Nonce { + check.OK = false + check.Err = fmt.Sprintf("message nonce doesn't match next nonce (%d)", st.nextNonce) + } else { + check.OK = true + st.nextNonce++ + } + + result[i] = append(result[i], check) + + // check required funds -vs- balance + st.requiredFunds = new(stdbig.Int).Add(st.requiredFunds, m.RequiredFunds().Int) + st.requiredFunds.Add(st.requiredFunds, m.Value.Int) + + // 10. Balance + check = api.MessageCheckStatus{ + Cid: m.Cid(), + CheckStatus: api.CheckStatus{ + Code: api.CheckStatusMessageBalance, + Hint: map[string]interface{}{ + "requiredFunds": big.Int{Int: stdbig.NewInt(0).Set(st.requiredFunds)}, + }, + }, + } + + if balance.Int.Cmp(st.requiredFunds) < 0 { + check.OK = false + check.Err = "insufficient balance" + } else { + check.OK = true + } + + result[i] = append(result[i], check) + } + + return result, nil +} diff --git a/chain/messagepool/messagepool.go b/chain/messagepool/messagepool.go index b9d80e7e7c9..93dce1df08b 100644 --- a/chain/messagepool/messagepool.go +++ b/chain/messagepool/messagepool.go @@ -195,16 +195,6 @@ func CapGasFee(mff dtypes.DefaultMaxFeeFunc, msg *types.Message, sendSepc *api.M maxFee = mf } - 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 - } - gl := types.NewInt(uint64(msg.GasLimit)) totalFee := types.BigMul(msg.GasFeeCap, gl) @@ -805,7 +795,7 @@ func (mp *MessagePool) addLocked(m *types.SignedMessage, strict, untrusted bool) return nil } -func (mp *MessagePool) GetNonce(addr address.Address) (uint64, error) { +func (mp *MessagePool) GetNonce(_ context.Context, addr address.Address, _ types.TipSetKey) (uint64, error) { mp.curTsLk.Lock() defer mp.curTsLk.Unlock() @@ -815,6 +805,13 @@ func (mp *MessagePool) GetNonce(addr address.Address) (uint64, error) { return mp.getNonceLocked(addr, mp.curTs) } +// GetActor should not be used. It is only here to satisfy interface mess caused by lite node handling +func (mp *MessagePool) GetActor(_ context.Context, addr address.Address, _ types.TipSetKey) (*types.Actor, error) { + mp.curTsLk.Lock() + defer mp.curTsLk.Unlock() + return mp.api.GetActorAfter(addr, mp.curTs) +} + func (mp *MessagePool) getNonceLocked(addr address.Address, curTs *types.TipSet) (uint64, error) { stateNonce, err := mp.getStateNonce(addr, curTs) // sanity check if err != nil { @@ -835,8 +832,8 @@ func (mp *MessagePool) getNonceLocked(addr address.Address, curTs *types.TipSet) return stateNonce, nil } -func (mp *MessagePool) getStateNonce(addr address.Address, curTs *types.TipSet) (uint64, error) { - act, err := mp.api.GetActorAfter(addr, curTs) +func (mp *MessagePool) getStateNonce(addr address.Address, ts *types.TipSet) (uint64, error) { + act, err := mp.api.GetActorAfter(addr, ts) if err != nil { return 0, err } diff --git a/chain/messagepool/messagepool_test.go b/chain/messagepool/messagepool_test.go index e31df936c8f..925ee438ca1 100644 --- a/chain/messagepool/messagepool_test.go +++ b/chain/messagepool/messagepool_test.go @@ -103,6 +103,9 @@ func (tma *testMpoolAPI) SubscribeHeadChanges(cb func(rev, app []*types.TipSet) func (tma *testMpoolAPI) PutMessage(m types.ChainMsg) (cid.Cid, error) { return cid.Undef, nil } +func (tma *testMpoolAPI) IsLite() bool { + return false +} func (tma *testMpoolAPI) PubSubPublish(string, []byte) error { tma.published++ @@ -199,7 +202,7 @@ func (tma *testMpoolAPI) ChainComputeBaseFee(ctx context.Context, ts *types.TipS func assertNonce(t *testing.T, mp *MessagePool, addr address.Address, val uint64) { t.Helper() - n, err := mp.GetNonce(addr) + n, err := mp.GetNonce(context.Background(), addr, types.EmptyTSK) if err != nil { t.Fatal(err) } diff --git a/chain/messagepool/provider.go b/chain/messagepool/provider.go index 5a6c751bce5..56569100465 100644 --- a/chain/messagepool/provider.go +++ b/chain/messagepool/provider.go @@ -9,6 +9,7 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/lotus/chain/messagesigner" "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" @@ -30,17 +31,28 @@ type Provider interface { MessagesForTipset(*types.TipSet) ([]types.ChainMsg, error) LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error) ChainComputeBaseFee(ctx context.Context, ts *types.TipSet) (types.BigInt, error) + IsLite() bool } type mpoolProvider struct { sm *stmgr.StateManager ps *pubsub.PubSub + + lite messagesigner.MpoolNonceAPI } func NewProvider(sm *stmgr.StateManager, ps *pubsub.PubSub) Provider { return &mpoolProvider{sm: sm, ps: ps} } +func NewProviderLite(sm *stmgr.StateManager, ps *pubsub.PubSub, noncer messagesigner.MpoolNonceAPI) Provider { + return &mpoolProvider{sm: sm, ps: ps, lite: noncer} +} + +func (mpp *mpoolProvider) IsLite() bool { + return mpp.lite != nil +} + func (mpp *mpoolProvider) SubscribeHeadChanges(cb func(rev, app []*types.TipSet) error) *types.TipSet { mpp.sm.ChainStore().SubscribeHeadChanges( store.WrapHeadChangeCoalescer( @@ -61,6 +73,19 @@ func (mpp *mpoolProvider) PubSubPublish(k string, v []byte) error { } func (mpp *mpoolProvider) GetActorAfter(addr address.Address, ts *types.TipSet) (*types.Actor, error) { + if mpp.IsLite() { + n, err := mpp.lite.GetNonce(context.TODO(), addr, ts.Key()) + if err != nil { + return nil, xerrors.Errorf("getting nonce over lite: %w", err) + } + a, err := mpp.lite.GetActor(context.TODO(), addr, ts.Key()) + if err != nil { + return nil, xerrors.Errorf("getting actor over lite: %w", err) + } + a.Nonce = n + return a, nil + } + stcid, _, err := mpp.sm.TipSetState(context.TODO(), ts) if err != nil { return nil, xerrors.Errorf("computing tipset state for GetActor: %w", err) diff --git a/chain/messagepool/selection.go b/chain/messagepool/selection.go index 26b9845fcc7..05acc566705 100644 --- a/chain/messagepool/selection.go +++ b/chain/messagepool/selection.go @@ -758,6 +758,7 @@ func (mp *MessagePool) createMessageChains(actor address.Address, mset map[uint6 if balance.Cmp(required) < 0 { break } + balance = new(big.Int).Sub(balance, required) value := m.Message.Value.Int diff --git a/chain/messagepool/selection_test.go b/chain/messagepool/selection_test.go index c61e24fcf7e..e32d897c4d3 100644 --- a/chain/messagepool/selection_test.go +++ b/chain/messagepool/selection_test.go @@ -16,7 +16,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" - logging "github.com/ipfs/go-log" + logging "github.com/ipfs/go-log/v2" builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" diff --git a/chain/messagesigner/messagesigner.go b/chain/messagesigner/messagesigner.go index ce9d01b3a99..063d1aa7d1a 100644 --- a/chain/messagesigner/messagesigner.go +++ b/chain/messagesigner/messagesigner.go @@ -23,7 +23,8 @@ const dsKeyActorNonce = "ActorNextNonce" var log = logging.Logger("messagesigner") type MpoolNonceAPI interface { - GetNonce(address.Address) (uint64, error) + GetNonce(context.Context, address.Address, types.TipSetKey) (uint64, error) + GetActor(context.Context, address.Address, types.TipSetKey) (*types.Actor, error) } // MessageSigner keeps track of nonces per address, and increments the nonce @@ -51,7 +52,7 @@ func (ms *MessageSigner) SignMessage(ctx context.Context, msg *types.Message, cb defer ms.lk.Unlock() // Get the next message nonce - nonce, err := ms.nextNonce(msg.From) + nonce, err := ms.nextNonce(ctx, msg.From) if err != nil { return nil, xerrors.Errorf("failed to create nonce: %w", err) } @@ -92,12 +93,12 @@ func (ms *MessageSigner) SignMessage(ctx context.Context, msg *types.Message, cb // nextNonce gets the next nonce for the given address. // If there is no nonce in the datastore, gets the nonce from the message pool. -func (ms *MessageSigner) nextNonce(addr address.Address) (uint64, error) { +func (ms *MessageSigner) nextNonce(ctx context.Context, addr address.Address) (uint64, error) { // Nonces used to be created by the mempool and we need to support nodes // that have mempool nonces, so first check the mempool for a nonce for // this address. Note that the mempool returns the actor state's nonce // by default. - nonce, err := ms.mpool.GetNonce(addr) + nonce, err := ms.mpool.GetNonce(ctx, addr, types.EmptyTSK) if err != nil { return 0, xerrors.Errorf("failed to get nonce from mempool: %w", err) } diff --git a/chain/messagesigner/messagesigner_test.go b/chain/messagesigner/messagesigner_test.go index 5eebd36da5e..90d16b7ff08 100644 --- a/chain/messagesigner/messagesigner_test.go +++ b/chain/messagesigner/messagesigner_test.go @@ -35,12 +35,15 @@ func (mp *mockMpool) setNonce(addr address.Address, nonce uint64) { mp.nonces[addr] = nonce } -func (mp *mockMpool) GetNonce(addr address.Address) (uint64, error) { +func (mp *mockMpool) GetNonce(_ context.Context, addr address.Address, _ types.TipSetKey) (uint64, error) { mp.lk.RLock() defer mp.lk.RUnlock() return mp.nonces[addr], nil } +func (mp *mockMpool) GetActor(_ context.Context, addr address.Address, _ types.TipSetKey) (*types.Actor, error) { + panic("don't use it") +} func TestMessageSignerSignMessage(t *testing.T) { ctx := context.Background() diff --git a/chain/state/statetree.go b/chain/state/statetree.go index 46a13ccc651..2a7b436b8bd 100644 --- a/chain/state/statetree.go +++ b/chain/state/statetree.go @@ -24,6 +24,7 @@ import ( states0 "github.com/filecoin-project/specs-actors/actors/states" states2 "github.com/filecoin-project/specs-actors/v2/actors/states" states3 "github.com/filecoin-project/specs-actors/v3/actors/states" + states4 "github.com/filecoin-project/specs-actors/v4/actors/states" ) var log = logging.Logger("statetree") @@ -153,7 +154,7 @@ func NewStateTree(cst cbor.IpldStore, ver types.StateTreeVersion) (*StateTree, e switch ver { case types.StateTreeVersion0: // info is undefined - case types.StateTreeVersion1, types.StateTreeVersion2: + case types.StateTreeVersion1, types.StateTreeVersion2, types.StateTreeVersion3: var err error info, err = cst.Put(context.TODO(), new(types.StateInfo0)) if err != nil { @@ -184,6 +185,12 @@ func NewStateTree(cst cbor.IpldStore, ver types.StateTreeVersion) (*StateTree, e return nil, xerrors.Errorf("failed to create state tree: %w", err) } hamt = tree.Map + case types.StateTreeVersion3: + tree, err := states4.NewTree(store) + if err != nil { + return nil, xerrors.Errorf("failed to create state tree: %w", err) + } + hamt = tree.Map default: return nil, xerrors.Errorf("unsupported state tree version: %d", ver) } @@ -233,6 +240,12 @@ func LoadStateTree(cst cbor.IpldStore, c cid.Cid) (*StateTree, error) { if tree != nil { hamt = tree.Map } + case types.StateTreeVersion3: + var tree *states4.Tree + tree, err = states4.LoadTree(store, root.Actors) + if tree != nil { + hamt = tree.Map + } default: return nil, xerrors.Errorf("unsupported state tree version: %d", root.Version) } diff --git a/chain/stmgr/forks.go b/chain/stmgr/forks.go index cb6cb22614c..a7b56f67997 100644 --- a/chain/stmgr/forks.go +++ b/chain/stmgr/forks.go @@ -34,6 +34,7 @@ import ( "github.com/filecoin-project/specs-actors/v2/actors/migration/nv4" "github.com/filecoin-project/specs-actors/v2/actors/migration/nv7" "github.com/filecoin-project/specs-actors/v3/actors/migration/nv10" + "github.com/filecoin-project/specs-actors/v4/actors/migration/nv12" "github.com/ipfs/go-cid" cbor "github.com/ipfs/go-ipld-cbor" "golang.org/x/xerrors" @@ -186,6 +187,26 @@ func DefaultUpgradeSchedule() UpgradeSchedule { StopWithin: 5, }}, Expensive: true, + }, { + Height: build.UpgradeNorwegianHeight, + Network: network.Version11, + Migration: nil, + }, { + Height: build.UpgradeActorsV4Height, + Network: network.Version12, + Migration: UpgradeActorsV4, + PreMigrations: []PreMigration{{ + PreMigration: PreUpgradeActorsV4, + StartWithin: 120, + DontStartWithin: 60, + StopWithin: 35, + }, { + PreMigration: PreUpgradeActorsV4, + StartWithin: 30, + DontStartWithin: 15, + StopWithin: 5, + }}, + Expensive: true, }} for _, u := range updates { @@ -1059,6 +1080,92 @@ func upgradeActorsV3Common( return newRoot, nil } +func UpgradeActorsV4(ctx context.Context, sm *StateManager, cache MigrationCache, cb ExecCallback, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { + // Use all the CPUs except 3. + workerCount := runtime.NumCPU() - 3 + if workerCount <= 0 { + workerCount = 1 + } + + config := nv12.Config{ + MaxWorkers: uint(workerCount), + JobQueueSize: 1000, + ResultQueueSize: 100, + ProgressLogPeriod: 10 * time.Second, + } + + newRoot, err := upgradeActorsV4Common(ctx, sm, cache, root, epoch, ts, config) + if err != nil { + return cid.Undef, xerrors.Errorf("migrating actors v4 state: %w", err) + } + + return newRoot, nil +} + +func PreUpgradeActorsV4(ctx context.Context, sm *StateManager, cache MigrationCache, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) error { + // Use half the CPUs for pre-migration, but leave at least 3. + workerCount := runtime.NumCPU() + if workerCount <= 4 { + workerCount = 1 + } else { + workerCount /= 2 + } + config := nv12.Config{MaxWorkers: uint(workerCount)} + _, err := upgradeActorsV4Common(ctx, sm, cache, root, epoch, ts, config) + return err +} + +func upgradeActorsV4Common( + ctx context.Context, sm *StateManager, cache MigrationCache, + root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet, + config nv12.Config, +) (cid.Cid, error) { + buf := blockstore.NewTieredBstore(sm.cs.StateBlockstore(), blockstore.NewMemorySync()) + store := store.ActorStore(ctx, buf) + + // Load the state root. + var stateRoot types.StateRoot + if err := store.Get(ctx, root, &stateRoot); err != nil { + return cid.Undef, xerrors.Errorf("failed to decode state root: %w", err) + } + + if stateRoot.Version != types.StateTreeVersion2 { + return cid.Undef, xerrors.Errorf( + "expected state root version 2 for actors v4 upgrade, got %d", + stateRoot.Version, + ) + } + + // Perform the migration + newHamtRoot, err := nv12.MigrateStateTree(ctx, store, stateRoot.Actors, epoch, config, migrationLogger{}, cache) + if err != nil { + return cid.Undef, xerrors.Errorf("upgrading to actors v2: %w", err) + } + + // Persist the result. + newRoot, err := store.Put(ctx, &types.StateRoot{ + Version: types.StateTreeVersion3, + Actors: newHamtRoot, + Info: stateRoot.Info, + }) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to persist new state root: %w", err) + } + + // Persist the new tree. + + { + from := buf + to := buf.Read() + + if err := vm.Copy(ctx, from, to, newRoot); err != nil { + return cid.Undef, xerrors.Errorf("copying migrated tree: %w", err) + } + } + + return newRoot, nil +} + func setNetworkName(ctx context.Context, store adt.Store, tree *state.StateTree, name string) error { ia, err := tree.GetActor(builtin0.InitActorAddr) if err != nil { diff --git a/chain/stmgr/forks_test.go b/chain/stmgr/forks_test.go index e456dc436de..fe96ad610d0 100644 --- a/chain/stmgr/forks_test.go +++ b/chain/stmgr/forks_test.go @@ -9,7 +9,7 @@ import ( "github.com/ipfs/go-cid" ipldcbor "github.com/ipfs/go-ipld-cbor" - logging "github.com/ipfs/go-log" + logging "github.com/ipfs/go-log/v2" "github.com/stretchr/testify/require" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index ffbe08474ff..afc98a32afb 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -5,11 +5,13 @@ import ( "errors" "fmt" "sync" + "sync/atomic" "github.com/ipfs/go-cid" cbor "github.com/ipfs/go-ipld-cbor" logging "github.com/ipfs/go-log/v2" cbg "github.com/whyrusleeping/cbor-gen" + "go.opencensus.io/stats" "go.opencensus.io/trace" "golang.org/x/xerrors" @@ -43,9 +45,10 @@ import ( "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/vm" + "github.com/filecoin-project/lotus/metrics" ) -const LookbackNoLimit = abi.ChainEpoch(-1) +const LookbackNoLimit = api.LookbackNoLimit const ReceiptAmtBitwidth = 3 var log = logging.Logger("statemgr") @@ -280,6 +283,13 @@ func (sm *StateManager) ExecutionTrace(ctx context.Context, ts *types.TipSet) (c type ExecCallback func(cid.Cid, *types.Message, *vm.ApplyRet) error func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEpoch, pstate cid.Cid, bms []store.BlockMessages, epoch abi.ChainEpoch, r vm.Rand, cb ExecCallback, baseFee abi.TokenAmount, ts *types.TipSet) (cid.Cid, cid.Cid, error) { + done := metrics.Timer(ctx, metrics.VMApplyBlocksTotal) + defer done() + + partDone := metrics.Timer(ctx, metrics.VMApplyEarly) + defer func() { + partDone() + }() makeVmWithBaseState := func(base cid.Cid) (*vm.VM, error) { vmopt := &vm.VMOpts{ @@ -303,7 +313,6 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp } runCron := func(epoch abi.ChainEpoch) error { - cronMsg := &types.Message{ To: cron.Address, From: builtin.SystemActorAddr, @@ -362,6 +371,9 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp pstate = newState } + partDone() + partDone = metrics.Timer(ctx, metrics.VMApplyMessages) + var receipts []cbg.CBORMarshaler processedMsgs := make(map[cid.Cid]struct{}) for _, b := range bms { @@ -426,10 +438,16 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp } } + partDone() + partDone = metrics.Timer(ctx, metrics.VMApplyCron) + if err := runCron(epoch); err != nil { return cid.Cid{}, cid.Cid{}, err } + partDone() + partDone = metrics.Timer(ctx, metrics.VMApplyFlush) + rectarr := blockadt.MakeEmptyArray(sm.cs.ActorStore(ctx)) for i, receipt := range receipts { if err := rectarr.Set(uint64(i), receipt); err != nil { @@ -446,6 +464,9 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp return cid.Undef, cid.Undef, xerrors.Errorf("vm flush failed: %w", err) } + stats.Record(ctx, metrics.VMSends.M(int64(atomic.LoadUint64(&vm.StatSends))), + metrics.VMApplied.M(int64(atomic.LoadUint64(&vm.StatApplied)))) + return st, rectroot, nil } @@ -564,24 +585,10 @@ func (sm *StateManager) LookupID(ctx context.Context, addr address.Address, ts * return state.LookupID(addr) } -func (sm *StateManager) GetReceipt(ctx context.Context, msg cid.Cid, ts *types.TipSet) (*types.MessageReceipt, error) { - m, err := sm.cs.GetCMessage(msg) - if err != nil { - return nil, fmt.Errorf("failed to load message: %w", err) - } - - _, r, _, err := sm.searchBackForMsg(ctx, ts, m, LookbackNoLimit) - if err != nil { - return nil, fmt.Errorf("failed to look back through chain for message: %w", err) - } - - return r, nil -} - // WaitForMessage blocks until a message appears on chain. It looks backwards in the chain to see if this has already // happened, with an optional limit to how many epochs it will search. It guarantees that the message has been on // chain for at least confidence epochs without being reverted before returning. -func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confidence uint64, lookbackLimit abi.ChainEpoch) (*types.TipSet, *types.MessageReceipt, cid.Cid, error) { +func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confidence uint64, lookbackLimit abi.ChainEpoch, allowReplaced bool) (*types.TipSet, *types.MessageReceipt, cid.Cid, error) { ctx, cancel := context.WithCancel(ctx) defer cancel() @@ -605,7 +612,7 @@ func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confid return nil, nil, cid.Undef, fmt.Errorf("expected current head on SHC stream (got %s)", head[0].Type) } - r, foundMsg, err := sm.tipsetExecutedMessage(head[0].Val, mcid, msg.VMMessage()) + r, foundMsg, err := sm.tipsetExecutedMessage(head[0].Val, mcid, msg.VMMessage(), allowReplaced) if err != nil { return nil, nil, cid.Undef, err } @@ -619,7 +626,7 @@ func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confid var backFm cid.Cid backSearchWait := make(chan struct{}) go func() { - fts, r, foundMsg, err := sm.searchBackForMsg(ctx, head[0].Val, msg, lookbackLimit) + fts, r, foundMsg, err := sm.searchBackForMsg(ctx, head[0].Val, msg, lookbackLimit, allowReplaced) if err != nil { log.Warnf("failed to look back through chain for message: %v", err) return @@ -658,7 +665,7 @@ func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confid if candidateTs != nil && val.Val.Height() >= candidateTs.Height()+abi.ChainEpoch(confidence) { return candidateTs, candidateRcp, candidateFm, nil } - r, foundMsg, err := sm.tipsetExecutedMessage(val.Val, mcid, msg.VMMessage()) + r, foundMsg, err := sm.tipsetExecutedMessage(val.Val, mcid, msg.VMMessage(), allowReplaced) if err != nil { return nil, nil, cid.Undef, err } @@ -694,15 +701,13 @@ func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confid } } -func (sm *StateManager) SearchForMessage(ctx context.Context, mcid cid.Cid, lookbackLimit abi.ChainEpoch) (*types.TipSet, *types.MessageReceipt, cid.Cid, error) { +func (sm *StateManager) SearchForMessage(ctx context.Context, head *types.TipSet, mcid cid.Cid, lookbackLimit abi.ChainEpoch, allowReplaced bool) (*types.TipSet, *types.MessageReceipt, cid.Cid, error) { msg, err := sm.cs.GetCMessage(mcid) if err != nil { return nil, nil, cid.Undef, fmt.Errorf("failed to load message: %w", err) } - head := sm.cs.GetHeaviestTipSet() - - r, foundMsg, err := sm.tipsetExecutedMessage(head, mcid, msg.VMMessage()) + r, foundMsg, err := sm.tipsetExecutedMessage(head, mcid, msg.VMMessage(), allowReplaced) if err != nil { return nil, nil, cid.Undef, err } @@ -711,7 +716,7 @@ func (sm *StateManager) SearchForMessage(ctx context.Context, mcid cid.Cid, look return head, r, foundMsg, nil } - fts, r, foundMsg, err := sm.searchBackForMsg(ctx, head, msg, lookbackLimit) + fts, r, foundMsg, err := sm.searchBackForMsg(ctx, head, msg, lookbackLimit, allowReplaced) if err != nil { log.Warnf("failed to look back through chain for message %s", mcid) @@ -731,7 +736,7 @@ func (sm *StateManager) SearchForMessage(ctx context.Context, mcid cid.Cid, look // - 0 then no tipsets are searched // - 5 then five tipset are searched // - LookbackNoLimit then there is no limit -func (sm *StateManager) searchBackForMsg(ctx context.Context, from *types.TipSet, m types.ChainMsg, limit abi.ChainEpoch) (*types.TipSet, *types.MessageReceipt, cid.Cid, error) { +func (sm *StateManager) searchBackForMsg(ctx context.Context, from *types.TipSet, m types.ChainMsg, limit abi.ChainEpoch, allowReplaced bool) (*types.TipSet, *types.MessageReceipt, cid.Cid, error) { limitHeight := from.Height() - limit noLimit := limit == LookbackNoLimit @@ -781,7 +786,7 @@ func (sm *StateManager) searchBackForMsg(ctx context.Context, from *types.TipSet // check that between cur and parent tipset the nonce fell into range of our message if actorNoExist || (curActor.Nonce > mNonce && act.Nonce <= mNonce) { - r, foundMsg, err := sm.tipsetExecutedMessage(cur, m.Cid(), m.VMMessage()) + r, foundMsg, err := sm.tipsetExecutedMessage(cur, m.Cid(), m.VMMessage(), allowReplaced) if err != nil { return nil, nil, cid.Undef, xerrors.Errorf("checking for message execution during lookback: %w", err) } @@ -796,7 +801,7 @@ func (sm *StateManager) searchBackForMsg(ctx context.Context, from *types.TipSet } } -func (sm *StateManager) tipsetExecutedMessage(ts *types.TipSet, msg cid.Cid, vmm *types.Message) (*types.MessageReceipt, cid.Cid, error) { +func (sm *StateManager) tipsetExecutedMessage(ts *types.TipSet, msg cid.Cid, vmm *types.Message, allowReplaced bool) (*types.MessageReceipt, cid.Cid, error) { // The genesis block did not execute any messages if ts.Height() == 0 { return nil, cid.Undef, nil @@ -819,7 +824,7 @@ func (sm *StateManager) tipsetExecutedMessage(ts *types.TipSet, msg cid.Cid, vmm if m.VMMessage().From == vmm.From { // cheaper to just check origin first if m.VMMessage().Nonce == vmm.Nonce { - if m.VMMessage().EqualCall(vmm) { + if allowReplaced && m.VMMessage().EqualCall(vmm) { if m.Cid() != msg { log.Warnw("found message with equal nonce and call params but different CID", "wanted", msg, "found", m.Cid(), "nonce", vmm.Nonce, "from", vmm.From) @@ -849,10 +854,7 @@ func (sm *StateManager) ListAllActors(ctx context.Context, ts *types.TipSet) ([] if ts == nil { ts = sm.cs.GetHeaviestTipSet() } - st, _, err := sm.TipSetState(ctx, ts) - if err != nil { - return nil, err - } + st := ts.ParentState() stateTree, err := sm.StateTree(st) if err != nil { @@ -1295,11 +1297,12 @@ func (sm *StateManager) GetVMCirculatingSupplyDetailed(ctx context.Context, heig } return api.CirculatingSupply{ - FilVested: filVested, - FilMined: filMined, - FilBurnt: filBurnt, - FilLocked: filLocked, - FilCirculating: ret, + FilVested: filVested, + FilMined: filMined, + FilBurnt: filBurnt, + FilLocked: filLocked, + FilCirculating: ret, + FilReserveDisbursed: filReserveDisbursed, }, nil } diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index 947310c7569..11c765333b8 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -26,6 +26,7 @@ import ( exported0 "github.com/filecoin-project/specs-actors/actors/builtin/exported" exported2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/exported" exported3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/exported" + exported4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/exported" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors/builtin" @@ -104,8 +105,7 @@ func GetPowerRaw(ctx context.Context, sm *StateManager, st cid.Cid, maddr addres var found bool mpow, found, err = pas.MinerPower(maddr) if err != nil || !found { - // TODO: return an error when not found? - return power.Claim{}, power.Claim{}, false, err + return power.Claim{}, tpow, false, err } minpow, err = pas.MinerNominalPowerMeetsConsensusMinimum(maddr) @@ -548,6 +548,7 @@ func init() { actors = append(actors, exported0.BuiltinActors()...) actors = append(actors, exported2.BuiltinActors()...) actors = append(actors, exported3.BuiltinActors()...) + actors = append(actors, exported4.BuiltinActors()...) for _, actor := range actors { exports := actor.Exports() diff --git a/chain/store/checkpoint_test.go b/chain/store/checkpoint_test.go new file mode 100644 index 00000000000..320b76797a2 --- /dev/null +++ b/chain/store/checkpoint_test.go @@ -0,0 +1,89 @@ +package store_test + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/filecoin-project/lotus/chain/gen" +) + +func TestChainCheckpoint(t *testing.T) { + cg, err := gen.NewGenerator() + if err != nil { + t.Fatal(err) + } + + // Let the first miner mine some blocks. + last := cg.CurTipset.TipSet() + for i := 0; i < 4; i++ { + ts, err := cg.NextTipSetFromMiners(last, cg.Miners[:1]) + require.NoError(t, err) + + last = ts.TipSet.TipSet() + } + + cs := cg.ChainStore() + + checkpoint := last + checkpointParents, err := cs.GetTipSetFromKey(checkpoint.Parents()) + require.NoError(t, err) + + // Set the head to the block before the checkpoint. + err = cs.SetHead(checkpointParents) + require.NoError(t, err) + + // Verify it worked. + head := cs.GetHeaviestTipSet() + require.True(t, head.Equals(checkpointParents)) + + // Try to set the checkpoint in the future, it should fail. + err = cs.SetCheckpoint(checkpoint) + require.Error(t, err) + + // Then move the head back. + err = cs.SetHead(checkpoint) + require.NoError(t, err) + + // Verify it worked. + head = cs.GetHeaviestTipSet() + require.True(t, head.Equals(checkpoint)) + + // And checkpoint it. + err = cs.SetCheckpoint(checkpoint) + require.NoError(t, err) + + // Let the second miner miner mine a fork + last = checkpointParents + for i := 0; i < 4; i++ { + ts, err := cg.NextTipSetFromMiners(last, cg.Miners[1:]) + require.NoError(t, err) + + last = ts.TipSet.TipSet() + } + + // See if the chain will take the fork, it shouldn't. + err = cs.MaybeTakeHeavierTipSet(context.Background(), last) + require.NoError(t, err) + head = cs.GetHeaviestTipSet() + require.True(t, head.Equals(checkpoint)) + + // Remove the checkpoint. + err = cs.RemoveCheckpoint() + require.NoError(t, err) + + // Now switch to the other fork. + err = cs.MaybeTakeHeavierTipSet(context.Background(), last) + require.NoError(t, err) + head = cs.GetHeaviestTipSet() + require.True(t, head.Equals(last)) + + // Setting a checkpoint on the other fork should fail. + err = cs.SetCheckpoint(checkpoint) + require.Error(t, err) + + // Setting a checkpoint on this fork should succeed. + err = cs.SetCheckpoint(checkpointParents) + require.NoError(t, err) +} diff --git a/chain/store/store.go b/chain/store/store.go index e0d71f0304b..1e78ce73d3e 100644 --- a/chain/store/store.go +++ b/chain/store/store.go @@ -54,8 +54,11 @@ import ( var log = logging.Logger("chainstore") -var chainHeadKey = dstore.NewKey("head") -var blockValidationCacheKeyPrefix = dstore.NewKey("blockValidation") +var ( + chainHeadKey = dstore.NewKey("head") + checkpointKey = dstore.NewKey("/chain/checks") + blockValidationCacheKeyPrefix = dstore.NewKey("blockValidation") +) var DefaultTipSetCacheSize = 8192 var DefaultMsgMetaCacheSize = 2048 @@ -113,8 +116,9 @@ type ChainStore struct { chainLocalBlockstore bstore.Blockstore - heaviestLk sync.Mutex + heaviestLk sync.RWMutex heaviest *types.TipSet + checkpoint *types.TipSet bestTips *pubsub.PubSub pubLk sync.Mutex @@ -215,6 +219,15 @@ func (cs *ChainStore) Close() error { } func (cs *ChainStore) Load() error { + if err := cs.loadHead(); err != nil { + return err + } + if err := cs.loadCheckpoint(); err != nil { + return err + } + return nil +} +func (cs *ChainStore) loadHead() error { head, err := cs.metadataDs.Get(chainHeadKey) if err == dstore.ErrNotFound { log.Warn("no previous chain state found") @@ -239,6 +252,31 @@ func (cs *ChainStore) Load() error { return nil } +func (cs *ChainStore) loadCheckpoint() error { + tskBytes, err := cs.metadataDs.Get(checkpointKey) + if err == dstore.ErrNotFound { + return nil + } + if err != nil { + return xerrors.Errorf("failed to load checkpoint from datastore: %w", err) + } + + var tsk types.TipSetKey + err = json.Unmarshal(tskBytes, &tsk) + if err != nil { + return err + } + + ts, err := cs.LoadTipSet(tsk) + if err != nil { + return xerrors.Errorf("loading tipset: %w", err) + } + + cs.checkpoint = ts + + return nil +} + func (cs *ChainStore) writeHead(ts *types.TipSet) error { data, err := json.Marshal(ts.Cids()) if err != nil { @@ -439,6 +477,11 @@ func (cs *ChainStore) exceedsForkLength(synced, external *types.TipSet) (bool, e return false, nil } + // Now check to see if we've walked back to the checkpoint. + if synced.Equals(cs.checkpoint) { + return true, nil + } + // If we didn't, go back *one* tipset on the `synced` side (incrementing // the `forkLength`). if synced.Height() == 0 { @@ -467,6 +510,9 @@ func (cs *ChainStore) ForceHeadSilent(_ context.Context, ts *types.TipSet) error cs.heaviestLk.Lock() defer cs.heaviestLk.Unlock() + if err := cs.removeCheckpoint(); err != nil { + return err + } cs.heaviest = ts err := cs.writeHead(ts) @@ -642,13 +688,80 @@ func FlushValidationCache(ds datastore.Batching) error { } // SetHead sets the chainstores current 'best' head node. -// This should only be called if something is broken and needs fixing +// This should only be called if something is broken and needs fixing. +// +// This function will bypass and remove any checkpoints. func (cs *ChainStore) SetHead(ts *types.TipSet) error { cs.heaviestLk.Lock() defer cs.heaviestLk.Unlock() + if err := cs.removeCheckpoint(); err != nil { + return err + } return cs.takeHeaviestTipSet(context.TODO(), ts) } +// RemoveCheckpoint removes the current checkpoint. +func (cs *ChainStore) RemoveCheckpoint() error { + cs.heaviestLk.Lock() + defer cs.heaviestLk.Unlock() + return cs.removeCheckpoint() +} + +func (cs *ChainStore) removeCheckpoint() error { + if err := cs.metadataDs.Delete(checkpointKey); err != nil { + return err + } + cs.checkpoint = nil + return nil +} + +// SetCheckpoint will set a checkpoint past which the chainstore will not allow forks. +// +// NOTE: Checkpoints cannot be set beyond ForkLengthThreshold epochs in the past. +func (cs *ChainStore) SetCheckpoint(ts *types.TipSet) error { + tskBytes, err := json.Marshal(ts.Key()) + if err != nil { + return err + } + + cs.heaviestLk.Lock() + defer cs.heaviestLk.Unlock() + + if ts.Height() > cs.heaviest.Height() { + return xerrors.Errorf("cannot set a checkpoint in the future") + } + + // Otherwise, this operation could get _very_ expensive. + if cs.heaviest.Height()-ts.Height() > build.ForkLengthThreshold { + return xerrors.Errorf("cannot set a checkpoint before the fork threshold") + } + + if !ts.Equals(cs.heaviest) { + anc, err := cs.IsAncestorOf(ts, cs.heaviest) + if err != nil { + return xerrors.Errorf("cannot determine whether checkpoint tipset is in main-chain: %w", err) + } + + if !anc { + return xerrors.Errorf("cannot mark tipset as checkpoint, since it isn't in the main-chain: %w", err) + } + } + err = cs.metadataDs.Put(checkpointKey, tskBytes) + if err != nil { + return err + } + + cs.checkpoint = ts + return nil +} + +func (cs *ChainStore) GetCheckpoint() *types.TipSet { + cs.heaviestLk.RLock() + chkpt := cs.checkpoint + cs.heaviestLk.RUnlock() + return chkpt +} + // Contains returns whether our BlockStore has all blocks in the supplied TipSet. func (cs *ChainStore) Contains(ts *types.TipSet) (bool, error) { for _, c := range ts.Cids() { @@ -775,10 +888,11 @@ func ReorgOps(lts func(types.TipSetKey) (*types.TipSet, error), a, b *types.TipS } // GetHeaviestTipSet returns the current heaviest tipset known (i.e. our head). -func (cs *ChainStore) GetHeaviestTipSet() *types.TipSet { - cs.heaviestLk.Lock() - defer cs.heaviestLk.Unlock() - return cs.heaviest +func (cs *ChainStore) GetHeaviestTipSet() (ts *types.TipSet) { + cs.heaviestLk.RLock() + ts = cs.heaviest + cs.heaviestLk.RUnlock() + return } func (cs *ChainStore) AddToTipSetTracker(b *types.BlockHeader) error { diff --git a/chain/sync.go b/chain/sync.go index 88237eb5ab1..6f594024d62 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -131,10 +131,6 @@ type Syncer struct { tickerCtxCancel context.CancelFunc - checkptLk sync.Mutex - - checkpt types.TipSetKey - ds dtypes.MetadataDS } @@ -152,14 +148,8 @@ func NewSyncer(ds dtypes.MetadataDS, sm *stmgr.StateManager, exchange exchange.C return nil, err } - cp, err := loadCheckpoint(ds) - if err != nil { - return nil, xerrors.Errorf("error loading mpool config: %w", err) - } - s := &Syncer{ ds: ds, - checkpt: cp, beacon: beacon, bad: NewBadBlockCache(), Genesis: gent, @@ -561,7 +551,7 @@ func (syncer *Syncer) Sync(ctx context.Context, maybeHead *types.TipSet) error { return nil } - if err := syncer.collectChain(ctx, maybeHead, hts); err != nil { + if err := syncer.collectChain(ctx, maybeHead, hts, false); err != nil { span.AddAttributes(trace.StringAttribute("col_error", err.Error())) span.SetStatus(trace.Status{ Code: 13, @@ -751,6 +741,10 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock, use } msgsCheck := async.Err(func() error { + if b.Cid() == build.WhitelistedBlock { + return nil + } + if err := syncer.checkBlockMessages(ctx, b, baseTs); err != nil { return xerrors.Errorf("block had invalid messages: %w", err) } @@ -1243,7 +1237,7 @@ func extractSyncState(ctx context.Context) *SyncerState { // // All throughout the process, we keep checking if the received blocks are in // the deny list, and short-circuit the process if so. -func (syncer *Syncer) collectHeaders(ctx context.Context, incoming *types.TipSet, known *types.TipSet) ([]*types.TipSet, error) { +func (syncer *Syncer) collectHeaders(ctx context.Context, incoming *types.TipSet, known *types.TipSet, ignoreCheckpoint bool) ([]*types.TipSet, error) { ctx, span := trace.StartSpan(ctx, "collectHeaders") defer span.End() ss := extractSyncState(ctx) @@ -1412,7 +1406,7 @@ loop: // We have now ascertained that this is *not* a 'fast forward' log.Warnf("(fork detected) synced header chain (%s - %d) does not link to our best block (%s - %d)", incoming.Cids(), incoming.Height(), known.Cids(), known.Height()) - fork, err := syncer.syncFork(ctx, base, known) + fork, err := syncer.syncFork(ctx, base, known, ignoreCheckpoint) if err != nil { if xerrors.Is(err, ErrForkTooLong) || xerrors.Is(err, ErrForkCheckpoint) { // TODO: we're marking this block bad in the same way that we mark invalid blocks bad. Maybe distinguish? @@ -1438,11 +1432,14 @@ var ErrForkCheckpoint = fmt.Errorf("fork would require us to diverge from checkp // If the fork is too long (build.ForkLengthThreshold), or would cause us to diverge from the checkpoint (ErrForkCheckpoint), // we add the entire subchain to the denylist. Else, we find the common ancestor, and add the missing chain // fragment until the fork point to the returned []TipSet. -func (syncer *Syncer) syncFork(ctx context.Context, incoming *types.TipSet, known *types.TipSet) ([]*types.TipSet, error) { +func (syncer *Syncer) syncFork(ctx context.Context, incoming *types.TipSet, known *types.TipSet, ignoreCheckpoint bool) ([]*types.TipSet, error) { - chkpt := syncer.GetCheckpoint() - if known.Key() == chkpt { - return nil, ErrForkCheckpoint + var chkpt *types.TipSet + if !ignoreCheckpoint { + chkpt = syncer.store.GetCheckpoint() + if known.Equals(chkpt) { + return nil, ErrForkCheckpoint + } } // TODO: Does this mean we always ask for ForkLengthThreshold blocks from the network, even if we just need, like, 2? Yes. @@ -1484,7 +1481,7 @@ func (syncer *Syncer) syncFork(ctx context.Context, incoming *types.TipSet, know } // We will be forking away from nts, check that it isn't checkpointed - if nts.Key() == chkpt { + if nts.Equals(chkpt) { return nil, ErrForkCheckpoint } @@ -1695,14 +1692,14 @@ func persistMessages(ctx context.Context, bs bstore.Blockstore, bst *exchange.Co // // 3. StageMessages: having acquired the headers and found a common tipset, // we then move forward, requesting the full blocks, including the messages. -func (syncer *Syncer) collectChain(ctx context.Context, ts *types.TipSet, hts *types.TipSet) error { +func (syncer *Syncer) collectChain(ctx context.Context, ts *types.TipSet, hts *types.TipSet, ignoreCheckpoint bool) error { ctx, span := trace.StartSpan(ctx, "collectChain") defer span.End() ss := extractSyncState(ctx) ss.Init(hts, ts) - headers, err := syncer.collectHeaders(ctx, ts, hts) + headers, err := syncer.collectHeaders(ctx, ts, hts, ignoreCheckpoint) if err != nil { ss.Error(err) return err diff --git a/chain/sync_test.go b/chain/sync_test.go index 9570eda328f..3176d9ec3be 100644 --- a/chain/sync_test.go +++ b/chain/sync_test.go @@ -346,12 +346,15 @@ func (tu *syncTestUtil) checkpointTs(node int, tsk types.TipSetKey) { require.NoError(tu.t, tu.nds[node].SyncCheckpoint(context.TODO(), tsk)) } +func (tu *syncTestUtil) nodeHasTs(node int, tsk types.TipSetKey) bool { + _, err := tu.nds[node].ChainGetTipSet(context.TODO(), tsk) + return err == nil +} + func (tu *syncTestUtil) waitUntilNodeHasTs(node int, tsk types.TipSetKey) { - for { - _, err := tu.nds[node].ChainGetTipSet(context.TODO(), tsk) - if err != nil { - break - } + for !tu.nodeHasTs(node, tsk) { + // Time to allow for syncing and validation + time.Sleep(10 * time.Millisecond) } // Time to allow for syncing and validation @@ -622,17 +625,17 @@ func TestDuplicateNonce(t *testing.T) { var includedMsg cid.Cid var skippedMsg cid.Cid - r0, err0 := tu.nds[0].StateGetReceipt(context.TODO(), msgs[0][0].Cid(), ts2.TipSet().Key()) - r1, err1 := tu.nds[0].StateGetReceipt(context.TODO(), msgs[1][0].Cid(), ts2.TipSet().Key()) + r0, err0 := tu.nds[0].StateSearchMsg(context.TODO(), ts2.TipSet().Key(), msgs[0][0].Cid(), api.LookbackNoLimit, true) + r1, err1 := tu.nds[0].StateSearchMsg(context.TODO(), ts2.TipSet().Key(), msgs[1][0].Cid(), api.LookbackNoLimit, true) if err0 == nil { require.Error(t, err1, "at least one of the StateGetReceipt calls should fail") - require.True(t, r0.ExitCode.IsSuccess()) + require.True(t, r0.Receipt.ExitCode.IsSuccess()) includedMsg = msgs[0][0].Message.Cid() skippedMsg = msgs[1][0].Message.Cid() } else { require.NoError(t, err1, "both the StateGetReceipt calls should not fail") - require.True(t, r1.ExitCode.IsSuccess()) + require.True(t, r1.Receipt.ExitCode.IsSuccess()) includedMsg = msgs[1][0].Message.Cid() skippedMsg = msgs[0][0].Message.Cid() } @@ -788,8 +791,13 @@ func TestSyncCheckpointHead(t *testing.T) { tu.connect(p1, p2) tu.waitUntilNodeHasTs(p1, b.TipSet().Key()) p1Head := tu.getHead(p1) - require.Equal(tu.t, p1Head, a.TipSet()) + require.True(tu.t, p1Head.Equals(a.TipSet())) tu.assertBad(p1, b.TipSet()) + + // Should be able to switch forks. + tu.checkpointTs(p1, b.TipSet().Key()) + p1Head = tu.getHead(p1) + require.True(tu.t, p1Head.Equals(b.TipSet())) } func TestSyncCheckpointEarlierThanHead(t *testing.T) { @@ -830,6 +838,11 @@ func TestSyncCheckpointEarlierThanHead(t *testing.T) { tu.connect(p1, p2) tu.waitUntilNodeHasTs(p1, b.TipSet().Key()) p1Head := tu.getHead(p1) - require.Equal(tu.t, p1Head, a.TipSet()) + require.True(tu.t, p1Head.Equals(a.TipSet())) tu.assertBad(p1, b.TipSet()) + + // Should be able to switch forks. + tu.checkpointTs(p1, b.TipSet().Key()) + p1Head = tu.getHead(p1) + require.True(tu.t, p1Head.Equals(b.TipSet())) } diff --git a/chain/types/fil.go b/chain/types/fil.go index 223ed3c5095..7438410c8ae 100644 --- a/chain/types/fil.go +++ b/chain/types/fil.go @@ -46,6 +46,15 @@ func (f FIL) Short() string { return strings.TrimRight(strings.TrimRight(r.FloatString(3), "0"), ".") + " " + prefix + "FIL" } +func (f FIL) Nano() string { + r := new(big.Rat).SetFrac(f.Int, big.NewInt(int64(1e9))) + if r.Sign() == 0 { + return "0" + } + + return strings.TrimRight(strings.TrimRight(r.FloatString(9), "0"), ".") + " nFIL" +} + func (f FIL) Format(s fmt.State, ch rune) { switch ch { case 's', 'v': diff --git a/chain/types/state.go b/chain/types/state.go index c14836ee79c..b561aab71e2 100644 --- a/chain/types/state.go +++ b/chain/types/state.go @@ -11,8 +11,10 @@ const ( StateTreeVersion0 StateTreeVersion = iota // StateTreeVersion1 corresponds to actors v2 StateTreeVersion1 - // StateTreeVersion2 corresponds to actors >= v3. + // StateTreeVersion2 corresponds to actors v3. StateTreeVersion2 + // StateTreeVersion3 corresponds to actors >= v4. + StateTreeVersion3 ) type StateRoot struct { diff --git a/chain/types/tipset_key.go b/chain/types/tipset_key.go index e5bc7750de3..9f98877964b 100644 --- a/chain/types/tipset_key.go +++ b/chain/types/tipset_key.go @@ -47,7 +47,7 @@ func NewTipSetKey(cids ...cid.Cid) TipSetKey { func TipSetKeyFromBytes(encoded []byte) (TipSetKey, error) { _, err := decodeKey(encoded) if err != nil { - return TipSetKey{}, err + return EmptyTSK, err } return TipSetKey{string(encoded)}, nil } diff --git a/chain/types/tipset_key_test.go b/chain/types/tipset_key_test.go index 7b3ce439db9..73c1ca9df43 100644 --- a/chain/types/tipset_key_test.go +++ b/chain/types/tipset_key_test.go @@ -19,7 +19,7 @@ func TestTipSetKey(t *testing.T) { fmt.Println(len(c1.Bytes())) t.Run("zero value", func(t *testing.T) { - assert.Equal(t, TipSetKey{}, NewTipSetKey()) + assert.Equal(t, EmptyTSK, NewTipSetKey()) }) t.Run("CID extraction", func(t *testing.T) { diff --git a/chain/vm/invoker.go b/chain/vm/invoker.go index 1c1d04f1999..8e0e6edd6e7 100644 --- a/chain/vm/invoker.go +++ b/chain/vm/invoker.go @@ -18,6 +18,7 @@ import ( exported2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/exported" vmr "github.com/filecoin-project/specs-actors/v2/actors/runtime" exported3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/exported" + exported4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/exported" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/exitcode" @@ -64,6 +65,7 @@ func NewActorRegistry() *ActorRegistry { inv.Register(ActorsVersionPredicate(actors.Version0), exported0.BuiltinActors()...) inv.Register(ActorsVersionPredicate(actors.Version2), exported2.BuiltinActors()...) inv.Register(ActorsVersionPredicate(actors.Version3), exported3.BuiltinActors()...) + inv.Register(ActorsVersionPredicate(actors.Version4), exported4.BuiltinActors()...) return inv } diff --git a/chain/vm/mkactor.go b/chain/vm/mkactor.go index 0e72b0c4b54..11de7362b52 100644 --- a/chain/vm/mkactor.go +++ b/chain/vm/mkactor.go @@ -17,6 +17,7 @@ import ( builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" + builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" "github.com/filecoin-project/go-address" "github.com/filecoin-project/lotus/chain/actors/aerrors" @@ -102,6 +103,8 @@ func newAccountActor(ver actors.Version) *types.Actor { code = builtin2.AccountActorCodeID case actors.Version3: code = builtin3.AccountActorCodeID + case actors.Version4: + code = builtin4.AccountActorCodeID default: panic("unsupported actors version") } diff --git a/chain/wallet/ledger/ledger.go b/chain/wallet/ledger/ledger.go index 1b0bf1a0407..eb16f646036 100644 --- a/chain/wallet/ledger/ledger.go +++ b/chain/wallet/ledger/ledger.go @@ -9,7 +9,7 @@ import ( "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/query" - logging "github.com/ipfs/go-log" + logging "github.com/ipfs/go-log/v2" ledgerfil "github.com/whyrusleeping/ledger-filecoin-go" "golang.org/x/xerrors" diff --git a/chain/wallet/remotewallet/remote.go b/chain/wallet/remotewallet/remote.go index 262b5f9c6bd..d1734518e1b 100644 --- a/chain/wallet/remotewallet/remote.go +++ b/chain/wallet/remotewallet/remote.go @@ -20,12 +20,12 @@ func SetupRemoteWallet(info string) func(mctx helpers.MetricsCtx, lc fx.Lifecycl return func(mctx helpers.MetricsCtx, lc fx.Lifecycle) (*RemoteWallet, error) { ai := cliutil.ParseApiInfo(info) - url, err := ai.DialArgs() + url, err := ai.DialArgs("v0") if err != nil { return nil, err } - wapi, closer, err := client.NewWalletRPC(mctx, url, ai.AuthHeader()) + wapi, closer, err := client.NewWalletRPCV0(mctx, url, ai.AuthHeader()) if err != nil { return nil, xerrors.Errorf("creating jsonrpc client: %w", err) } diff --git a/cli/auth.go b/cli/auth.go index 6426a4ab681..20b9bb39428 100644 --- a/cli/auth.go +++ b/cli/auth.go @@ -8,7 +8,7 @@ import ( "github.com/filecoin-project/go-jsonrpc/auth" - "github.com/filecoin-project/lotus/api/apistruct" + "github.com/filecoin-project/lotus/api" cliutil "github.com/filecoin-project/lotus/cli/util" "github.com/filecoin-project/lotus/node/repo" ) @@ -47,18 +47,18 @@ var AuthCreateAdminToken = &cli.Command{ perm := cctx.String("perm") idx := 0 - for i, p := range apistruct.AllPermissions { + for i, p := range api.AllPermissions { if auth.Permission(perm) == p { idx = i + 1 } } if idx == 0 { - return fmt.Errorf("--perm flag has to be one of: %s", apistruct.AllPermissions) + return fmt.Errorf("--perm flag has to be one of: %s", api.AllPermissions) } // slice on [:idx] so for example: 'sign' gives you [read, write, sign] - token, err := napi.AuthNew(ctx, apistruct.AllPermissions[:idx]) + token, err := napi.AuthNew(ctx, api.AllPermissions[:idx]) if err != nil { return err } @@ -95,18 +95,18 @@ var AuthApiInfoToken = &cli.Command{ perm := cctx.String("perm") idx := 0 - for i, p := range apistruct.AllPermissions { + for i, p := range api.AllPermissions { if auth.Permission(perm) == p { idx = i + 1 } } if idx == 0 { - return fmt.Errorf("--perm flag has to be one of: %s", apistruct.AllPermissions) + return fmt.Errorf("--perm flag has to be one of: %s", api.AllPermissions) } // slice on [:idx] so for example: 'sign' gives you [read, write, sign] - token, err := napi.AuthNew(ctx, apistruct.AllPermissions[:idx]) + token, err := napi.AuthNew(ctx, api.AllPermissions[:idx]) if err != nil { return err } diff --git a/cli/chain.go b/cli/chain.go index 1574f3f6494..6651a77649e 100644 --- a/cli/chain.go +++ b/cli/chain.go @@ -31,7 +31,9 @@ import ( cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" + "github.com/filecoin-project/lotus/api" lapi "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/stmgr" @@ -722,12 +724,6 @@ var ChainGetCmd = &cli.Command{ return err } - if ts == nil { - ts, err = api.ChainHead(ctx) - if err != nil { - return err - } - } p = "/ipfs/" + ts.ParentState().String() + p if cctx.Bool("verbose") { fmt.Println(p) @@ -806,7 +802,7 @@ var ChainGetCmd = &cli.Command{ type apiIpldStore struct { ctx context.Context - api lapi.FullNode + api v0api.FullNode } func (ht *apiIpldStore) Context() context.Context { @@ -834,7 +830,7 @@ func (ht *apiIpldStore) Put(ctx context.Context, v interface{}) (cid.Cid, error) panic("No mutations allowed") } -func handleAmt(ctx context.Context, api lapi.FullNode, r cid.Cid) error { +func handleAmt(ctx context.Context, api v0api.FullNode, r cid.Cid) error { s := &apiIpldStore{ctx, api} mp, err := adt.AsArray(s, r) if err != nil { @@ -847,7 +843,7 @@ func handleAmt(ctx context.Context, api lapi.FullNode, r cid.Cid) error { }) } -func handleHamtEpoch(ctx context.Context, api lapi.FullNode, r cid.Cid) error { +func handleHamtEpoch(ctx context.Context, api v0api.FullNode, r cid.Cid) error { s := &apiIpldStore{ctx, api} mp, err := adt.AsMap(s, r) if err != nil { @@ -865,7 +861,7 @@ func handleHamtEpoch(ctx context.Context, api lapi.FullNode, r cid.Cid) error { }) } -func handleHamtAddress(ctx context.Context, api lapi.FullNode, r cid.Cid) error { +func handleHamtAddress(ctx context.Context, api v0api.FullNode, r cid.Cid) error { s := &apiIpldStore{ctx, api} mp, err := adt.AsMap(s, r) if err != nil { @@ -1121,11 +1117,13 @@ var SlashConsensusFault = &cli.Command{ }, }, Action: func(cctx *cli.Context) error { - api, closer, err := GetFullNodeAPI(cctx) + srv, err := GetFullNodeServices(cctx) if err != nil { return err } - defer closer() + defer srv.Close() //nolint:errcheck + + a := srv.FullNodeAPI() ctx := ReqContext(cctx) c1, err := cid.Parse(cctx.Args().Get(0)) @@ -1133,7 +1131,7 @@ var SlashConsensusFault = &cli.Command{ return xerrors.Errorf("parsing cid 1: %w", err) } - b1, err := api.ChainGetBlock(ctx, c1) + b1, err := a.ChainGetBlock(ctx, c1) if err != nil { return xerrors.Errorf("getting block 1: %w", err) } @@ -1143,7 +1141,7 @@ var SlashConsensusFault = &cli.Command{ return xerrors.Errorf("parsing cid 2: %w", err) } - b2, err := api.ChainGetBlock(ctx, c2) + b2, err := a.ChainGetBlock(ctx, c2) if err != nil { return xerrors.Errorf("getting block 2: %w", err) } @@ -1154,7 +1152,7 @@ var SlashConsensusFault = &cli.Command{ var fromAddr address.Address if from := cctx.String("from"); from == "" { - defaddr, err := api.WalletDefaultAddress(ctx) + defaddr, err := a.WalletDefaultAddress(ctx) if err != nil { return err } @@ -1190,7 +1188,7 @@ var SlashConsensusFault = &cli.Command{ return xerrors.Errorf("parsing cid extra: %w", err) } - bExtra, err := api.ChainGetBlock(ctx, cExtra) + bExtra, err := a.ChainGetBlock(ctx, cExtra) if err != nil { return xerrors.Errorf("getting block extra: %w", err) } @@ -1208,15 +1206,17 @@ var SlashConsensusFault = &cli.Command{ return err } - msg := &types.Message{ - To: b2.Miner, - From: fromAddr, - Value: types.NewInt(0), - Method: builtin.MethodsMiner.ReportConsensusFault, - Params: enc, + proto := &api.MessagePrototype{ + Message: types.Message{ + To: b2.Miner, + From: fromAddr, + Value: types.NewInt(0), + Method: builtin.MethodsMiner.ReportConsensusFault, + Params: enc, + }, } - smsg, err := api.MpoolPushMessage(ctx, msg, nil) + smsg, err := InteractiveSend(ctx, cctx, srv, proto) if err != nil { return err } diff --git a/cli/client.go b/cli/client.go index b3e2acd6fe8..da9524e470b 100644 --- a/cli/client.go +++ b/cli/client.go @@ -40,6 +40,7 @@ import ( "github.com/filecoin-project/lotus/api" lapi "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/builtin/market" @@ -83,12 +84,14 @@ var clientCmd = &cli.Command{ WithCategory("storage", clientGetDealCmd), WithCategory("storage", clientListAsksCmd), WithCategory("storage", clientDealStatsCmd), + WithCategory("storage", clientInspectDealCmd), WithCategory("data", clientImportCmd), WithCategory("data", clientDropCmd), WithCategory("data", clientLocalCmd), WithCategory("data", clientStat), WithCategory("retrieval", clientFindCmd), WithCategory("retrieval", clientRetrieveCmd), + WithCategory("retrieval", clientCancelRetrievalDealCmd), WithCategory("util", clientCommPCmd), WithCategory("util", clientCarGenCmd), WithCategory("util", clientBalancesCmd), @@ -299,8 +302,16 @@ var clientLocalCmd = &cli.Command{ } var clientDealCmd = &cli.Command{ - Name: "deal", - Usage: "Initialize storage deal with a miner", + Name: "deal", + Usage: "Initialize storage deal with a miner", + Description: `Make a deal with a miner. +dataCid comes from running 'lotus client import'. +miner is the address of the miner you wish to make a deal with. +price is measured in FIL/GB/Epoch. Miners usually don't accept a bid +lower than their advertised ask. You can check a miners listed price +with 'lotus client query-ask '. +duration is how long the miner should store the data for, in blocks. +The minimum value is 518400 (6 months).`, ArgsUsage: "[dataCid miner price duration]", Flags: []cli.Flag{ &cli.StringFlag{ @@ -387,6 +398,9 @@ var clientDealCmd = &cli.Command{ if abi.ChainEpoch(dur) < build.MinDealDuration { return xerrors.Errorf("minimum deal duration is %d blocks", build.MinDealDuration) } + if abi.ChainEpoch(dur) > build.MaxDealDuration { + return xerrors.Errorf("maximum deal duration is %d blocks", build.MaxDealDuration) + } var a address.Address if from := cctx.String("from"); from != "" { @@ -996,7 +1010,7 @@ var clientFindCmd = &cli.Command{ }, } -const DefaultMaxRetrievePrice = 1 +const DefaultMaxRetrievePrice = "0.01" var clientRetrieveCmd = &cli.Command{ Name: "retrieve", @@ -1017,12 +1031,15 @@ var clientRetrieveCmd = &cli.Command{ }, &cli.StringFlag{ Name: "maxPrice", - Usage: fmt.Sprintf("maximum price the client is willing to consider (default: %d FIL)", DefaultMaxRetrievePrice), + Usage: fmt.Sprintf("maximum price the client is willing to consider (default: %s FIL)", DefaultMaxRetrievePrice), }, &cli.StringFlag{ Name: "pieceCid", Usage: "require data to be retrieved from a specific Piece CID", }, + &cli.BoolFlag{ + Name: "allow-local", + }, }, Action: func(cctx *cli.Context) error { if cctx.NArg() != 2 { @@ -1052,18 +1069,6 @@ var clientRetrieveCmd = &cli.Command{ return err } - // Check if we already have this data locally - - /*has, err := api.ClientHasLocal(ctx, file) - if err != nil { - return err - } - - if has { - fmt.Println("Success: Already in local storage") - return nil - }*/ // TODO: fix - var pieceCid *cid.Cid if cctx.String("pieceCid") != "" { parsed, err := cid.Parse(cctx.String("pieceCid")) @@ -1073,69 +1078,93 @@ var clientRetrieveCmd = &cli.Command{ pieceCid = &parsed } - var offer api.QueryOffer - minerStrAddr := cctx.String("miner") - if minerStrAddr == "" { // Local discovery - offers, err := fapi.ClientFindData(ctx, file, pieceCid) + var order *lapi.RetrievalOrder + if cctx.Bool("allow-local") { + imports, err := fapi.ClientListImports(ctx) + if err != nil { + return err + } + + for _, i := range imports { + if i.Root != nil && i.Root.Equals(file) { + order = &lapi.RetrievalOrder{ + Root: file, + LocalStore: &i.Key, - var cleaned []api.QueryOffer - // filter out offers that errored - for _, o := range offers { - if o.Err == "" { - cleaned = append(cleaned, o) + Total: big.Zero(), + UnsealPrice: big.Zero(), + } + break } } + } - offers = cleaned + if order == nil { + var offer api.QueryOffer + minerStrAddr := cctx.String("miner") + if minerStrAddr == "" { // Local discovery + offers, err := fapi.ClientFindData(ctx, file, pieceCid) - // sort by price low to high - sort.Slice(offers, func(i, j int) bool { - return offers[i].MinPrice.LessThan(offers[j].MinPrice) - }) - if err != nil { - return err - } + var cleaned []api.QueryOffer + // filter out offers that errored + for _, o := range offers { + if o.Err == "" { + cleaned = append(cleaned, o) + } + } - // TODO: parse offer strings from `client find`, make this smarter - if len(offers) < 1 { - fmt.Println("Failed to find file") - return nil - } - offer = offers[0] - } else { // Directed retrieval - minerAddr, err := address.NewFromString(minerStrAddr) - if err != nil { - return err + offers = cleaned + + // sort by price low to high + sort.Slice(offers, func(i, j int) bool { + return offers[i].MinPrice.LessThan(offers[j].MinPrice) + }) + if err != nil { + return err + } + + // TODO: parse offer strings from `client find`, make this smarter + if len(offers) < 1 { + fmt.Println("Failed to find file") + return nil + } + offer = offers[0] + } else { // Directed retrieval + minerAddr, err := address.NewFromString(minerStrAddr) + if err != nil { + return err + } + offer, err = fapi.ClientMinerQueryOffer(ctx, minerAddr, file, pieceCid) + if err != nil { + return err + } } - offer, err = fapi.ClientMinerQueryOffer(ctx, minerAddr, file, pieceCid) - if err != nil { - return err + if offer.Err != "" { + return fmt.Errorf("The received offer errored: %s", offer.Err) } - } - if offer.Err != "" { - return fmt.Errorf("The received offer errored: %s", offer.Err) - } - maxPrice := types.FromFil(DefaultMaxRetrievePrice) + maxPrice := types.MustParseFIL(DefaultMaxRetrievePrice) - if cctx.String("maxPrice") != "" { - maxPriceFil, err := types.ParseFIL(cctx.String("maxPrice")) - if err != nil { - return xerrors.Errorf("parsing maxPrice: %w", err) + if cctx.String("maxPrice") != "" { + maxPrice, err = types.ParseFIL(cctx.String("maxPrice")) + if err != nil { + return xerrors.Errorf("parsing maxPrice: %w", err) + } } - maxPrice = types.BigInt(maxPriceFil) - } + if offer.MinPrice.GreaterThan(big.Int(maxPrice)) { + return xerrors.Errorf("failed to find offer satisfying maxPrice: %s", maxPrice) + } - if offer.MinPrice.GreaterThan(maxPrice) { - return xerrors.Errorf("failed to find offer satisfying maxPrice: %s", maxPrice) + o := offer.Order(payer) + order = &o } - ref := &lapi.FileRef{ Path: cctx.Args().Get(1), IsCAR: cctx.Bool("car"), } - updates, err := fapi.ClientRetrieveWithEvents(ctx, offer.Order(payer), ref) + + updates, err := fapi.ClientRetrieveWithEvents(ctx, *order, ref) if err != nil { return xerrors.Errorf("error setting up retrieval: %w", err) } @@ -1165,6 +1194,29 @@ var clientRetrieveCmd = &cli.Command{ }, } +var clientInspectDealCmd = &cli.Command{ + Name: "inspect-deal", + Usage: "Inspect detailed information about deal's lifecycle and the various stages it goes through", + Flags: []cli.Flag{ + &cli.IntFlag{ + Name: "deal-id", + }, + &cli.StringFlag{ + Name: "proposal-cid", + }, + }, + Action: func(cctx *cli.Context) error { + api, closer, err := GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer closer() + + ctx := ReqContext(cctx) + return inspectDealCmd(ctx, api, cctx.String("proposal-cid"), cctx.Int("deal-id")) + }, +} + var clientDealStatsCmd = &cli.Command{ Name: "deal-stats", Usage: "Print statistics about local storage deals", @@ -1244,7 +1296,8 @@ var clientListAsksCmd = &cli.Command{ Usage: "List asks for top miners", Flags: []cli.Flag{ &cli.BoolFlag{ - Name: "by-ping", + Name: "by-ping", + Usage: "sort by ping", }, &cli.StringFlag{ Name: "output-format", @@ -1297,7 +1350,7 @@ type QueriedAsk struct { Ping time.Duration } -func GetAsks(ctx context.Context, api lapi.FullNode) ([]QueriedAsk, error) { +func GetAsks(ctx context.Context, api v0api.FullNode) ([]QueriedAsk, error) { isTTY := true if fileInfo, _ := os.Stdout.Stat(); (fileInfo.Mode() & os.ModeCharDevice) == 0 { isTTY = false @@ -1399,17 +1452,17 @@ loop: } rt := time.Now() - _, err = api.ClientQueryAsk(ctx, *mi.PeerId, miner) if err != nil { return } + pingDuration := time.Now().Sub(rt) atomic.AddInt64(&got, 1) lk.Lock() asks = append(asks, QueriedAsk{ Ask: ask, - Ping: time.Now().Sub(rt), + Ping: pingDuration, }) lk.Unlock() }(miner) @@ -1604,7 +1657,7 @@ var clientListDeals = &cli.Command{ }, } -func dealFromDealInfo(ctx context.Context, full api.FullNode, head *types.TipSet, v api.DealInfo) deal { +func dealFromDealInfo(ctx context.Context, full v0api.FullNode, head *types.TipSet, v api.DealInfo) deal { if v.DealID == 0 { return deal{ LocalDeal: v, @@ -1623,7 +1676,7 @@ func dealFromDealInfo(ctx context.Context, full api.FullNode, head *types.TipSet } } -func outputStorageDeals(ctx context.Context, out io.Writer, full lapi.FullNode, localDeals []lapi.DealInfo, verbose bool, color bool, showFailed bool) error { +func outputStorageDeals(ctx context.Context, out io.Writer, full v0api.FullNode, localDeals []lapi.DealInfo, verbose bool, color bool, showFailed bool) error { sort.Slice(localDeals, func(i, j int) bool { return localDeals[i].CreationTime.Before(localDeals[j].CreationTime) }) @@ -2026,6 +2079,33 @@ var clientCancelTransfer = &cli.Command{ }, } +var clientCancelRetrievalDealCmd = &cli.Command{ + Name: "cancel-retrieval", + Usage: "Cancel a retrieval deal by deal ID; this also cancels the associated transfer", + Flags: []cli.Flag{ + &cli.Int64Flag{ + Name: "deal-id", + Usage: "specify retrieval deal by deal ID", + Required: true, + }, + }, + Action: func(cctx *cli.Context) error { + api, closer, err := GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer closer() + ctx := ReqContext(cctx) + + id := cctx.Int64("deal-id") + if id < 0 { + return errors.New("deal id cannot be negative") + } + + return api.ClientCancelRetrievalDeal(ctx, retrievalmarket.DealID(id)) + }, +} + var clientListTransfers = &cli.Command{ Name: "list-transfers", Usage: "List ongoing data transfers for deals", @@ -2214,3 +2294,77 @@ func ellipsis(s string, length int) string { } return s } + +func inspectDealCmd(ctx context.Context, api v0api.FullNode, proposalCid string, dealId int) error { + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + deals, err := api.ClientListDeals(ctx) + if err != nil { + return err + } + + var di *lapi.DealInfo + for i, cdi := range deals { + if proposalCid != "" && cdi.ProposalCid.String() == proposalCid { + di = &deals[i] + break + } + + if dealId != 0 && int(cdi.DealID) == dealId { + di = &deals[i] + break + } + } + + if di == nil { + if proposalCid != "" { + return fmt.Errorf("cannot find deal with proposal cid: %s", proposalCid) + } + if dealId != 0 { + return fmt.Errorf("cannot find deal with deal id: %v", dealId) + } + return errors.New("you must specify proposal cid or deal id in order to inspect a deal") + } + + // populate DealInfo.DealStages and DataTransfer.Stages + di, err = api.ClientGetDealInfo(ctx, di.ProposalCid) + if err != nil { + return fmt.Errorf("cannot get deal info for proposal cid: %v", di.ProposalCid) + } + + renderDeal(di) + + return nil +} + +func renderDeal(di *lapi.DealInfo) { + color.Blue("Deal ID: %d\n", int(di.DealID)) + color.Blue("Proposal CID: %s\n\n", di.ProposalCid.String()) + + if di.DealStages == nil { + color.Yellow("Deal was made with an older version of Lotus and Lotus did not collect detailed information about its stages") + return + } + + for _, stg := range di.DealStages.Stages { + msg := fmt.Sprintf("%s %s: %s (expected duration: %s)", color.BlueString("Stage:"), color.BlueString(strings.TrimPrefix(stg.Name, "StorageDeal")), stg.Description, color.GreenString(stg.ExpectedDuration)) + if stg.UpdatedTime.Time().IsZero() { + msg = color.YellowString(msg) + } + fmt.Println(msg) + + for _, l := range stg.Logs { + fmt.Printf(" %s %s\n", color.YellowString(l.UpdatedTime.Time().UTC().Round(time.Second).Format(time.Stamp)), l.Log) + } + + if stg.Name == "StorageDealStartDataTransfer" { + for _, dtStg := range di.DataTransfer.Stages.Stages { + fmt.Printf(" %s %s %s\n", color.YellowString(dtStg.CreatedTime.Time().UTC().Round(time.Second).Format(time.Stamp)), color.BlueString("Data transfer stage:"), color.BlueString(dtStg.Name)) + for _, l := range dtStg.Logs { + fmt.Printf(" %s %s\n", color.YellowString(l.UpdatedTime.Time().UTC().Round(time.Second).Format(time.Stamp)), l.Log) + } + } + } + } +} diff --git a/cli/cmd.go b/cli/cmd.go index efbb3b990ff..fad9ee6687b 100644 --- a/cli/cmd.go +++ b/cli/cmd.go @@ -34,7 +34,7 @@ func GetFullNodeServices(ctx *cli.Context) (ServicesAPI, error) { return tn.(ServicesAPI), nil } - api, c, err := GetFullNodeAPI(ctx) + api, c, err := GetFullNodeAPIV1(ctx) if err != nil { return nil, err } @@ -50,6 +50,7 @@ var DaemonContext = cliutil.DaemonContext var ReqContext = cliutil.ReqContext var GetFullNodeAPI = cliutil.GetFullNodeAPI +var GetFullNodeAPIV1 = cliutil.GetFullNodeAPIV1 var GetGatewayAPI = cliutil.GetGatewayAPI var GetStorageMinerAPI = cliutil.GetStorageMinerAPI @@ -80,6 +81,7 @@ var Commands = []*cli.Command{ WithCategory("developer", FetchParamCmd), WithCategory("network", NetCmd), WithCategory("network", SyncCmd), + WithCategory("status", StatusCmd), PprofCmd, VersionCmd, } diff --git a/cli/disputer.go b/cli/disputer.go index ded240a80b7..235c4cf03f4 100644 --- a/cli/disputer.go +++ b/cli/disputer.go @@ -22,6 +22,7 @@ import ( logging "github.com/ipfs/go-log/v2" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/chain/store" "github.com/urfave/cli/v2" ) @@ -356,7 +357,7 @@ var disputerStartCmd = &cli.Command{ // for a given miner, index, and maxPostIndex, tries to dispute posts from 0...postsSnapshotted-1 // returns a list of DisputeWindowedPoSt msgs that are expected to succeed if sent -func makeDisputeWindowedPosts(ctx context.Context, api lapi.FullNode, dl minerDeadline, postsSnapshotted uint64, sender address.Address) ([]*types.Message, error) { +func makeDisputeWindowedPosts(ctx context.Context, api v0api.FullNode, dl minerDeadline, postsSnapshotted uint64, sender address.Address) ([]*types.Message, error) { disputes := make([]*types.Message, 0) for i := uint64(0); i < postsSnapshotted; i++ { @@ -388,7 +389,7 @@ func makeDisputeWindowedPosts(ctx context.Context, api lapi.FullNode, dl minerDe return disputes, nil } -func makeMinerDeadline(ctx context.Context, api lapi.FullNode, mAddr address.Address) (abi.ChainEpoch, *minerDeadline, error) { +func makeMinerDeadline(ctx context.Context, api v0api.FullNode, mAddr address.Address) (abi.ChainEpoch, *minerDeadline, error) { dl, err := api.StateMinerProvingDeadline(ctx, mAddr, types.EmptyTSK) if err != nil { return -1, nil, xerrors.Errorf("getting proving index list: %w", err) @@ -400,7 +401,7 @@ func makeMinerDeadline(ctx context.Context, api lapi.FullNode, mAddr address.Add }, nil } -func getSender(ctx context.Context, api lapi.FullNode, fromStr string) (address.Address, error) { +func getSender(ctx context.Context, api v0api.FullNode, fromStr string) (address.Address, error) { if fromStr == "" { return api.WalletDefaultAddress(ctx) } diff --git a/cli/init_test.go b/cli/init_test.go new file mode 100644 index 00000000000..8c343bcfabe --- /dev/null +++ b/cli/init_test.go @@ -0,0 +1,9 @@ +package cli + +import ( + logging "github.com/ipfs/go-log/v2" +) + +func init() { + logging.SetLogLevel("watchdog", "ERROR") +} diff --git a/cli/mpool.go b/cli/mpool.go index b5a68860f10..b128ccc159f 100644 --- a/cli/mpool.go +++ b/cli/mpool.go @@ -34,6 +34,7 @@ var MpoolCmd = &cli.Command{ MpoolFindCmd, MpoolConfig, MpoolGasPerfCmd, + mpoolManage, }, } @@ -132,9 +133,11 @@ var MpoolPending = &cli.Command{ }, } +// Deprecated: MpoolClear is now available at `lotus-shed mpool clear` var MpoolClear = &cli.Command{ - Name: "clear", - Usage: "Clear all pending messages from the mpool (USE WITH CARE)", + Name: "clear", + Usage: "Clear all pending messages from the mpool (USE WITH CARE) (DEPRECATED)", + Hidden: true, Flags: []cli.Flag{ &cli.BoolFlag{ Name: "local", @@ -146,6 +149,7 @@ var MpoolClear = &cli.Command{ }, }, Action: func(cctx *cli.Context) error { + fmt.Println("DEPRECATED: This behavior is being moved to `lotus-shed mpool clear`") api, closer, err := GetFullNodeAPI(cctx) if err != nil { return err diff --git a/cli/mpool_manage.go b/cli/mpool_manage.go new file mode 100644 index 00000000000..164a0584241 --- /dev/null +++ b/cli/mpool_manage.go @@ -0,0 +1,360 @@ +package cli + +import ( + "context" + "fmt" + "sort" + + "github.com/Kubuxu/imtui" + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/chain/messagepool" + types "github.com/filecoin-project/lotus/chain/types" + "github.com/gdamore/tcell/v2" + cid "github.com/ipfs/go-cid" + "github.com/urfave/cli/v2" + "golang.org/x/xerrors" +) + +var mpoolManage = &cli.Command{ + Name: "manage", + Action: func(cctx *cli.Context) error { + srv, err := GetFullNodeServices(cctx) + if err != nil { + return err + } + defer srv.Close() //nolint:errcheck + + ctx := ReqContext(cctx) + + _, localAddr, err := srv.LocalAddresses(ctx) + if err != nil { + return xerrors.Errorf("getting local addresses: %w", err) + } + + msgs, err := srv.MpoolPendingFilter(ctx, func(sm *types.SignedMessage) bool { + if sm.Message.From.Empty() { + return false + } + for _, a := range localAddr { + if a == sm.Message.From { + return true + } + } + return false + }, types.EmptyTSK) + if err != nil { + return err + } + + t, err := imtui.NewTui() + if err != nil { + panic(err) + } + + mm := &mmUI{ + ctx: ctx, + srv: srv, + addrs: localAddr, + messages: msgs, + } + sort.Slice(mm.addrs, func(i, j int) bool { + return mm.addrs[i].String() < mm.addrs[j].String() + }) + t.PushScene(mm.addrSelect()) + + err = t.Run() + + if err != nil { + panic(err) + } + + return nil + }, +} + +type mmUI struct { + ctx context.Context + srv ServicesAPI + addrs []address.Address + messages []*types.SignedMessage +} + +func (mm *mmUI) addrSelect() func(*imtui.Tui) error { + rows := [][]string{{"Address", "No. Messages"}} + mCount := map[address.Address]int{} + for _, sm := range mm.messages { + mCount[sm.Message.From]++ + } + for _, a := range mm.addrs { + rows = append(rows, []string{a.String(), fmt.Sprintf("%d", mCount[a])}) + } + + flex := []int{4, 1} + sel := 0 + scroll := 0 + return func(t *imtui.Tui) error { + if t.CurrentKey != nil && t.CurrentKey.Key() == tcell.KeyEnter { + if sel > 0 { + t.ReplaceScene(mm.messageLising(mm.addrs[sel-1])) + } + } + t.FlexTable(0, 0, 0, &sel, &scroll, rows, flex, true) + return nil + } +} + +func errUI(err error) func(*imtui.Tui) error { + return func(t *imtui.Tui) error { + return err + } +} + +type msgInfo struct { + sm *types.SignedMessage + checks []api.MessageCheckStatus +} + +func (mi *msgInfo) Row() []string { + cidStr := mi.sm.Cid().String() + failedChecks := 0 + for _, c := range mi.checks { + if !c.OK { + failedChecks++ + } + } + shortAddr := mi.sm.Message.To.String() + if len(shortAddr) > 16 { + shortAddr = "â€Ļ" + shortAddr[len(shortAddr)-16:] + } + var fCk string + if failedChecks == 0 { + fCk = "[:green:]OK" + } else { + fCk = "[:orange:]" + fmt.Sprintf("%d", failedChecks) + } + return []string{"â€Ļ" + cidStr[len(cidStr)-32:], shortAddr, + fmt.Sprintf("%d", mi.sm.Message.Nonce), types.FIL(mi.sm.Message.Value).String(), + fmt.Sprintf("%d", mi.sm.Message.Method), fCk} + +} + +func (mm *mmUI) messageLising(a address.Address) func(*imtui.Tui) error { + genMsgInfos := func() ([]msgInfo, error) { + msgs, err := mm.srv.MpoolPendingFilter(mm.ctx, func(sm *types.SignedMessage) bool { + if sm.Message.From.Empty() { + return false + } + if a == sm.Message.From { + return true + } + return false + }, types.EmptyTSK) + + if err != nil { + return nil, xerrors.Errorf("getting pending: %w", err) + } + + msgIdx := map[cid.Cid]*types.SignedMessage{} + for _, sm := range msgs { + if sm.Message.From == a { + msgIdx[sm.Message.Cid()] = sm + msgIdx[sm.Cid()] = sm + } + } + + checks, err := mm.srv.MpoolCheckPendingMessages(mm.ctx, a) + if err != nil { + return nil, xerrors.Errorf("checking pending: %w", err) + } + msgInfos := make([]msgInfo, 0, len(checks)) + for _, msgChecks := range checks { + failingChecks := []api.MessageCheckStatus{} + for _, c := range msgChecks { + if !c.OK { + failingChecks = append(failingChecks, c) + } + } + msgInfos = append(msgInfos, msgInfo{ + sm: msgIdx[msgChecks[0].Cid], + checks: failingChecks, + }) + } + return msgInfos, nil + } + + sel := 0 + scroll := 0 + + var msgInfos []msgInfo + var rows [][]string + flex := []int{3, 2, 1, 1, 1, 1} + refresh := true + + return func(t *imtui.Tui) error { + if refresh { + var err error + msgInfos, err = genMsgInfos() + if err != nil { + return xerrors.Errorf("getting msgInfos: %w", err) + } + + rows = [][]string{{"Message Cid", "To", "Nonce", "Value", "Method", "Checks"}} + for _, mi := range msgInfos { + rows = append(rows, mi.Row()) + } + refresh = false + } + + if t.CurrentKey != nil && t.CurrentKey.Key() == tcell.KeyEnter { + if sel > 0 { + t.PushScene(mm.messageDetail(msgInfos[sel-1])) + refresh = true + return nil + } + } + + t.Label(0, 0, fmt.Sprintf("Address: %s", a), tcell.StyleDefault) + t.FlexTable(1, 0, 0, &sel, &scroll, rows, flex, true) + return nil + } +} + +func (mm *mmUI) messageDetail(mi msgInfo) func(*imtui.Tui) error { + baseFee, err := mm.srv.GetBaseFee(mm.ctx) + if err != nil { + return errUI(err) + } + _ = baseFee + + m := mi.sm.Message + maxFee := big.Mul(m.GasFeeCap, big.NewInt(m.GasLimit)) + + issues := [][]string{} + for _, c := range mi.checks { + issues = append(issues, []string{c.Code.String(), c.Err}) + } + issuesFlex := []int{1, 3} + var sel, scroll int + + executeReprice := false + executeNoop := false + return func(t *imtui.Tui) error { + if executeReprice { + m.GasFeeCap = big.Div(maxFee, big.NewInt(m.GasLimit)) + m.GasPremium = messagepool.ComputeMinRBF(m.GasPremium) + m.GasFeeCap = big.Max(m.GasFeeCap, m.GasPremium) + + _, _, err := mm.srv.PublishMessage(mm.ctx, &api.MessagePrototype{ + Message: m, + ValidNonce: true, + }, true) + if err != nil { + return err + } + t.PopScene() + return nil + } + if executeNoop { + nop := types.Message{ + To: builtin.BurntFundsActorAddr, + From: m.From, + + Nonce: m.Nonce, + Value: big.Zero(), + } + + nop.GasPremium = messagepool.ComputeMinRBF(m.GasPremium) + + _, _, err := mm.srv.PublishMessage(mm.ctx, &api.MessagePrototype{ + Message: nop, + ValidNonce: true, + }, true) + + if err != nil { + return xerrors.Errorf("publishing noop message: %w", err) + } + + t.PopScene() + return nil + } + + if t.CurrentKey != nil { + if t.CurrentKey.Key() == tcell.KeyLeft { + t.PopScene() + return nil + } + if t.CurrentKey.Key() == tcell.KeyRune { + switch t.CurrentKey.Rune() { + case 'R', 'r': + t.PushScene(feeUI(baseFee, m.GasLimit, &maxFee, &executeReprice)) + return nil + case 'N', 'n': + t.PushScene(confirmationScene( + &executeNoop, + "Are you sure you want to cancel the message by", + "replacing it with a message with no effects?")) + return nil + } + } + } + + row := 0 + defS := tcell.StyleDefault + display := func(f string, args ...interface{}) { + t.Label(0, row, fmt.Sprintf(f, args...), defS) + row++ + } + + display("Message CID: %s", m.Cid()) + display("Signed Message CID: %s", mi.sm.Cid()) + row++ + display("From: %s", m.From) + display("To: %s", m.To) + row++ + display("Nonce: %d", m.Nonce) + display("Value: %s", types.FIL(m.Value)) + row++ + display("GasLimit: %d", m.GasLimit) + display("GasPremium: %s", types.FIL(m.GasPremium).Short()) + display("GasFeeCap %s", types.FIL(m.GasFeeCap).Short()) + row++ + display("Press R to reprice this message") + display("Press N to replace this message with no-operation message") + row++ + + t.FlexTable(row, 0, 0, &sel, &scroll, issues, issuesFlex, false) + + return nil + } +} + +func confirmationScene(yes *bool, ask ...string) func(*imtui.Tui) error { + return func(t *imtui.Tui) error { + row := 0 + defS := tcell.StyleDefault + display := func(f string, args ...interface{}) { + t.Label(0, row, fmt.Sprintf(f, args...), defS) + row++ + } + + for _, a := range ask { + display(a) + } + row++ + display("Enter to confirm") + display("Esc to cancel") + + if t.CurrentKey != nil { + if t.CurrentKey.Key() == tcell.KeyEnter { + *yes = true + t.PopScene() + return nil + } + } + + return nil + } +} diff --git a/cli/multisig.go b/cli/multisig.go index f6caa6ee034..9ddfcdfc146 100644 --- a/cli/multisig.go +++ b/cli/multisig.go @@ -95,11 +95,13 @@ var msigCreateCmd = &cli.Command{ return ShowHelp(cctx, fmt.Errorf("multisigs must have at least one signer")) } - api, closer, err := GetFullNodeAPI(cctx) + srv, err := GetFullNodeServices(cctx) if err != nil { return err } - defer closer() + defer srv.Close() //nolint:errcheck + + api := srv.FullNodeAPI() ctx := ReqContext(cctx) var addrs []address.Address @@ -146,13 +148,20 @@ var msigCreateCmd = &cli.Command{ gp := types.NewInt(1) - msgCid, err := api.MsigCreate(ctx, required, addrs, d, intVal, sendAddr, gp) + proto, err := api.MsigCreate(ctx, required, addrs, d, intVal, sendAddr, gp) + if err != nil { + return err + } + + sm, err := InteractiveSend(ctx, cctx, srv, proto) if err != nil { return err } + msgCid := sm.Cid() + // wait for it to get mined into a block - wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence"))) + wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")), build.Finality, true) if err != nil { return err } @@ -364,11 +373,13 @@ var msigProposeCmd = &cli.Command{ return ShowHelp(cctx, fmt.Errorf("must either pass three or five arguments")) } - api, closer, err := GetFullNodeAPI(cctx) + srv, err := GetFullNodeServices(cctx) if err != nil { return err } - defer closer() + defer srv.Close() //nolint:errcheck + + api := srv.FullNodeAPI() ctx := ReqContext(cctx) msig, err := address.NewFromString(cctx.Args().Get(0)) @@ -426,14 +437,21 @@ var msigProposeCmd = &cli.Command{ return fmt.Errorf("actor %s is not a multisig actor", msig) } - msgCid, err := api.MsigPropose(ctx, msig, dest, types.BigInt(value), from, method, params) + proto, err := api.MsigPropose(ctx, msig, dest, types.BigInt(value), from, method, params) + if err != nil { + return err + } + + sm, err := InteractiveSend(ctx, cctx, srv, proto) if err != nil { return err } + msgCid := sm.Cid() + fmt.Println("send proposal in message: ", msgCid) - wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence"))) + wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")), build.Finality, true) if err != nil { return err } @@ -481,11 +499,13 @@ var msigApproveCmd = &cli.Command{ return ShowHelp(cctx, fmt.Errorf("usage: msig approve [ ]")) } - api, closer, err := GetFullNodeAPI(cctx) + srv, err := GetFullNodeServices(cctx) if err != nil { return err } - defer closer() + defer srv.Close() //nolint:errcheck + + api := srv.FullNodeAPI() ctx := ReqContext(cctx) msig, err := address.NewFromString(cctx.Args().Get(0)) @@ -515,10 +535,17 @@ var msigApproveCmd = &cli.Command{ var msgCid cid.Cid if cctx.Args().Len() == 2 { - msgCid, err = api.MsigApprove(ctx, msig, txid, from) + proto, err := api.MsigApprove(ctx, msig, txid, from) + if err != nil { + return err + } + + sm, err := InteractiveSend(ctx, cctx, srv, proto) if err != nil { return err } + + msgCid = sm.Cid() } else { proposer, err := address.NewFromString(cctx.Args().Get(2)) if err != nil { @@ -558,15 +585,22 @@ var msigApproveCmd = &cli.Command{ params = p } - msgCid, err = api.MsigApproveTxnHash(ctx, msig, txid, proposer, dest, types.BigInt(value), from, method, params) + proto, err := api.MsigApproveTxnHash(ctx, msig, txid, proposer, dest, types.BigInt(value), from, method, params) if err != nil { return err } + + sm, err := InteractiveSend(ctx, cctx, srv, proto) + if err != nil { + return err + } + + msgCid = sm.Cid() } fmt.Println("sent approval in message: ", msgCid) - wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence"))) + wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")), build.Finality, true) if err != nil { return err } @@ -598,11 +632,13 @@ var msigRemoveProposeCmd = &cli.Command{ return ShowHelp(cctx, fmt.Errorf("must pass multisig address and signer address")) } - api, closer, err := GetFullNodeAPI(cctx) + srv, err := GetFullNodeServices(cctx) if err != nil { return err } - defer closer() + defer srv.Close() //nolint:errcheck + + api := srv.FullNodeAPI() ctx := ReqContext(cctx) msig, err := address.NewFromString(cctx.Args().Get(0)) @@ -630,14 +666,21 @@ var msigRemoveProposeCmd = &cli.Command{ from = defaddr } - msgCid, err := api.MsigRemoveSigner(ctx, msig, from, addr, cctx.Bool("decrease-threshold")) + proto, err := api.MsigRemoveSigner(ctx, msig, from, addr, cctx.Bool("decrease-threshold")) + if err != nil { + return err + } + + sm, err := InteractiveSend(ctx, cctx, srv, proto) if err != nil { return err } + msgCid := sm.Cid() + fmt.Println("sent remove proposal in message: ", msgCid) - wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence"))) + wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")), build.Finality, true) if err != nil { return err } @@ -676,11 +719,13 @@ var msigAddProposeCmd = &cli.Command{ return ShowHelp(cctx, fmt.Errorf("must pass multisig address and signer address")) } - api, closer, err := GetFullNodeAPI(cctx) + srv, err := GetFullNodeServices(cctx) if err != nil { return err } - defer closer() + defer srv.Close() //nolint:errcheck + + api := srv.FullNodeAPI() ctx := ReqContext(cctx) msig, err := address.NewFromString(cctx.Args().Get(0)) @@ -708,14 +753,21 @@ var msigAddProposeCmd = &cli.Command{ from = defaddr } - msgCid, err := api.MsigAddPropose(ctx, msig, from, addr, cctx.Bool("increase-threshold")) + proto, err := api.MsigAddPropose(ctx, msig, from, addr, cctx.Bool("increase-threshold")) if err != nil { return err } + sm, err := InteractiveSend(ctx, cctx, srv, proto) + if err != nil { + return err + } + + msgCid := sm.Cid() + fmt.Fprintln(cctx.App.Writer, "sent add proposal in message: ", msgCid) - wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence"))) + wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")), build.Finality, true) if err != nil { return err } @@ -743,11 +795,13 @@ var msigAddApproveCmd = &cli.Command{ return ShowHelp(cctx, fmt.Errorf("must pass multisig address, proposer address, transaction id, new signer address, whether to increase threshold")) } - api, closer, err := GetFullNodeAPI(cctx) + srv, err := GetFullNodeServices(cctx) if err != nil { return err } - defer closer() + defer srv.Close() //nolint:errcheck + + api := srv.FullNodeAPI() ctx := ReqContext(cctx) msig, err := address.NewFromString(cctx.Args().Get(0)) @@ -790,14 +844,21 @@ var msigAddApproveCmd = &cli.Command{ from = defaddr } - msgCid, err := api.MsigAddApprove(ctx, msig, from, txid, prop, newAdd, inc) + proto, err := api.MsigAddApprove(ctx, msig, from, txid, prop, newAdd, inc) + if err != nil { + return err + } + + sm, err := InteractiveSend(ctx, cctx, srv, proto) if err != nil { return err } + msgCid := sm.Cid() + fmt.Println("sent add approval in message: ", msgCid) - wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence"))) + wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")), build.Finality, true) if err != nil { return err } @@ -825,11 +886,13 @@ var msigAddCancelCmd = &cli.Command{ return ShowHelp(cctx, fmt.Errorf("must pass multisig address, transaction id, new signer address, whether to increase threshold")) } - api, closer, err := GetFullNodeAPI(cctx) + srv, err := GetFullNodeServices(cctx) if err != nil { return err } - defer closer() + defer srv.Close() //nolint:errcheck + + api := srv.FullNodeAPI() ctx := ReqContext(cctx) msig, err := address.NewFromString(cctx.Args().Get(0)) @@ -867,14 +930,21 @@ var msigAddCancelCmd = &cli.Command{ from = defaddr } - msgCid, err := api.MsigAddCancel(ctx, msig, from, txid, newAdd, inc) + proto, err := api.MsigAddCancel(ctx, msig, from, txid, newAdd, inc) if err != nil { return err } + sm, err := InteractiveSend(ctx, cctx, srv, proto) + if err != nil { + return err + } + + msgCid := sm.Cid() + fmt.Println("sent add cancellation in message: ", msgCid) - wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence"))) + wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")), build.Finality, true) if err != nil { return err } @@ -902,11 +972,13 @@ var msigSwapProposeCmd = &cli.Command{ return ShowHelp(cctx, fmt.Errorf("must pass multisig address, old signer address, new signer address")) } - api, closer, err := GetFullNodeAPI(cctx) + srv, err := GetFullNodeServices(cctx) if err != nil { return err } - defer closer() + defer srv.Close() //nolint:errcheck + + api := srv.FullNodeAPI() ctx := ReqContext(cctx) msig, err := address.NewFromString(cctx.Args().Get(0)) @@ -939,14 +1011,21 @@ var msigSwapProposeCmd = &cli.Command{ from = defaddr } - msgCid, err := api.MsigSwapPropose(ctx, msig, from, oldAdd, newAdd) + proto, err := api.MsigSwapPropose(ctx, msig, from, oldAdd, newAdd) if err != nil { return err } + sm, err := InteractiveSend(ctx, cctx, srv, proto) + if err != nil { + return err + } + + msgCid := sm.Cid() + fmt.Println("sent swap proposal in message: ", msgCid) - wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence"))) + wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")), build.Finality, true) if err != nil { return err } @@ -974,11 +1053,13 @@ var msigSwapApproveCmd = &cli.Command{ return ShowHelp(cctx, fmt.Errorf("must pass multisig address, proposer address, transaction id, old signer address, new signer address")) } - api, closer, err := GetFullNodeAPI(cctx) + srv, err := GetFullNodeServices(cctx) if err != nil { return err } - defer closer() + defer srv.Close() //nolint:errcheck + + api := srv.FullNodeAPI() ctx := ReqContext(cctx) msig, err := address.NewFromString(cctx.Args().Get(0)) @@ -1021,14 +1102,21 @@ var msigSwapApproveCmd = &cli.Command{ from = defaddr } - msgCid, err := api.MsigSwapApprove(ctx, msig, from, txid, prop, oldAdd, newAdd) + proto, err := api.MsigSwapApprove(ctx, msig, from, txid, prop, oldAdd, newAdd) if err != nil { return err } + sm, err := InteractiveSend(ctx, cctx, srv, proto) + if err != nil { + return err + } + + msgCid := sm.Cid() + fmt.Println("sent swap approval in message: ", msgCid) - wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence"))) + wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")), build.Finality, true) if err != nil { return err } @@ -1056,11 +1144,13 @@ var msigSwapCancelCmd = &cli.Command{ return ShowHelp(cctx, fmt.Errorf("must pass multisig address, transaction id, old signer address, new signer address")) } - api, closer, err := GetFullNodeAPI(cctx) + srv, err := GetFullNodeServices(cctx) if err != nil { return err } - defer closer() + defer srv.Close() //nolint:errcheck + + api := srv.FullNodeAPI() ctx := ReqContext(cctx) msig, err := address.NewFromString(cctx.Args().Get(0)) @@ -1098,14 +1188,21 @@ var msigSwapCancelCmd = &cli.Command{ from = defaddr } - msgCid, err := api.MsigSwapCancel(ctx, msig, from, txid, oldAdd, newAdd) + proto, err := api.MsigSwapCancel(ctx, msig, from, txid, oldAdd, newAdd) + if err != nil { + return err + } + + sm, err := InteractiveSend(ctx, cctx, srv, proto) if err != nil { return err } + msgCid := sm.Cid() + fmt.Println("sent swap cancellation in message: ", msgCid) - wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence"))) + wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")), build.Finality, true) if err != nil { return err } @@ -1133,11 +1230,13 @@ var msigLockProposeCmd = &cli.Command{ return ShowHelp(cctx, fmt.Errorf("must pass multisig address, start epoch, unlock duration, and amount")) } - api, closer, err := GetFullNodeAPI(cctx) + srv, err := GetFullNodeServices(cctx) if err != nil { return err } - defer closer() + defer srv.Close() //nolint:errcheck + + api := srv.FullNodeAPI() ctx := ReqContext(cctx) msig, err := address.NewFromString(cctx.Args().Get(0)) @@ -1185,14 +1284,21 @@ var msigLockProposeCmd = &cli.Command{ return actErr } - msgCid, err := api.MsigPropose(ctx, msig, msig, big.Zero(), from, uint64(multisig.Methods.LockBalance), params) + proto, err := api.MsigPropose(ctx, msig, msig, big.Zero(), from, uint64(multisig.Methods.LockBalance), params) if err != nil { return err } + sm, err := InteractiveSend(ctx, cctx, srv, proto) + if err != nil { + return err + } + + msgCid := sm.Cid() + fmt.Println("sent lock proposal in message: ", msgCid) - wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence"))) + wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")), build.Finality, true) if err != nil { return err } @@ -1220,11 +1326,13 @@ var msigLockApproveCmd = &cli.Command{ return ShowHelp(cctx, fmt.Errorf("must pass multisig address, proposer address, tx id, start epoch, unlock duration, and amount")) } - api, closer, err := GetFullNodeAPI(cctx) + srv, err := GetFullNodeServices(cctx) if err != nil { return err } - defer closer() + defer srv.Close() //nolint:errcheck + + api := srv.FullNodeAPI() ctx := ReqContext(cctx) msig, err := address.NewFromString(cctx.Args().Get(0)) @@ -1282,14 +1390,21 @@ var msigLockApproveCmd = &cli.Command{ return actErr } - msgCid, err := api.MsigApproveTxnHash(ctx, msig, txid, prop, msig, big.Zero(), from, uint64(multisig.Methods.LockBalance), params) + proto, err := api.MsigApproveTxnHash(ctx, msig, txid, prop, msig, big.Zero(), from, uint64(multisig.Methods.LockBalance), params) if err != nil { return err } + sm, err := InteractiveSend(ctx, cctx, srv, proto) + if err != nil { + return err + } + + msgCid := sm.Cid() + fmt.Println("sent lock approval in message: ", msgCid) - wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence"))) + wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")), build.Finality, true) if err != nil { return err } @@ -1317,11 +1432,13 @@ var msigLockCancelCmd = &cli.Command{ return ShowHelp(cctx, fmt.Errorf("must pass multisig address, tx id, start epoch, unlock duration, and amount")) } - api, closer, err := GetFullNodeAPI(cctx) + srv, err := GetFullNodeServices(cctx) if err != nil { return err } - defer closer() + defer srv.Close() //nolint:errcheck + + api := srv.FullNodeAPI() ctx := ReqContext(cctx) msig, err := address.NewFromString(cctx.Args().Get(0)) @@ -1374,14 +1491,21 @@ var msigLockCancelCmd = &cli.Command{ return actErr } - msgCid, err := api.MsigCancel(ctx, msig, txid, msig, big.Zero(), from, uint64(multisig.Methods.LockBalance), params) + proto, err := api.MsigCancel(ctx, msig, txid, msig, big.Zero(), from, uint64(multisig.Methods.LockBalance), params) if err != nil { return err } + sm, err := InteractiveSend(ctx, cctx, srv, proto) + if err != nil { + return err + } + + msgCid := sm.Cid() + fmt.Println("sent lock cancellation in message: ", msgCid) - wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence"))) + wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")), build.Finality, true) if err != nil { return err } @@ -1471,11 +1595,13 @@ var msigProposeThresholdCmd = &cli.Command{ return ShowHelp(cctx, fmt.Errorf("must pass multisig address and new threshold value")) } - api, closer, err := GetFullNodeAPI(cctx) + srv, err := GetFullNodeServices(cctx) if err != nil { return err } - defer closer() + defer srv.Close() //nolint:errcheck + + api := srv.FullNodeAPI() ctx := ReqContext(cctx) msig, err := address.NewFromString(cctx.Args().Get(0)) @@ -1511,14 +1637,21 @@ var msigProposeThresholdCmd = &cli.Command{ return actErr } - msgCid, err := api.MsigPropose(ctx, msig, msig, types.NewInt(0), from, uint64(multisig.Methods.ChangeNumApprovalsThreshold), params) + proto, err := api.MsigPropose(ctx, msig, msig, types.NewInt(0), from, uint64(multisig.Methods.ChangeNumApprovalsThreshold), params) if err != nil { return fmt.Errorf("failed to propose change of threshold: %w", err) } + sm, err := InteractiveSend(ctx, cctx, srv, proto) + if err != nil { + return err + } + + msgCid := sm.Cid() + fmt.Println("sent change threshold proposal in message: ", msgCid) - wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence"))) + wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")), build.Finality, true) if err != nil { return err } diff --git a/cli/send.go b/cli/send.go index daf73ccad1b..a5200d3b8e0 100644 --- a/cli/send.go +++ b/cli/send.go @@ -2,7 +2,6 @@ package cli import ( "encoding/hex" - "errors" "fmt" "github.com/urfave/cli/v2" @@ -59,10 +58,14 @@ var sendCmd = &cli.Command{ }, &cli.BoolFlag{ Name: "force", - Usage: "must be specified for the action to take effect if maybe SysErrInsufficientFunds etc", + Usage: "Deprecated: use global 'force-send'", }, }, Action: func(cctx *cli.Context) error { + if cctx.IsSet("force") { + fmt.Println("'force' flag is deprecated, use global flag 'force-send'") + } + if cctx.Args().Len() != 2 { return ShowHelp(cctx, fmt.Errorf("'send' expects two arguments, target and amount")) } @@ -137,23 +140,22 @@ var sendCmd = &cli.Command{ params.Params = decparams } - params.Force = cctx.Bool("force") - if cctx.IsSet("nonce") { n := cctx.Uint64("nonce") params.Nonce = &n } - msgCid, err := srv.Send(ctx, params) + proto, err := srv.MessageForSend(ctx, params) + if err != nil { + return xerrors.Errorf("creating message prototype: %w", err) + } + sm, err := InteractiveSend(ctx, cctx, srv, proto) if err != nil { - if errors.Is(err, ErrSendBalanceTooLow) { - return fmt.Errorf("--force must be specified for this action to have an effect; you have been warned: %w", err) - } - return xerrors.Errorf("executing send: %w", err) + return err } - fmt.Fprintf(cctx.App.Writer, "%s\n", msgCid) + fmt.Fprintf(cctx.App.Writer, "%s\n", sm.Cid()) return nil }, } diff --git a/cli/send_test.go b/cli/send_test.go index ff258346aab..52eafda67a7 100644 --- a/cli/send_test.go +++ b/cli/send_test.go @@ -2,24 +2,17 @@ package cli import ( "bytes" - "errors" "testing" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/api" types "github.com/filecoin-project/lotus/chain/types" gomock "github.com/golang/mock/gomock" - cid "github.com/ipfs/go-cid" "github.com/stretchr/testify/assert" ucli "github.com/urfave/cli/v2" ) -var arbtCid = (&types.Message{ - From: mustAddr(address.NewIDAddress(2)), - To: mustAddr(address.NewIDAddress(1)), - Value: types.NewInt(1000), -}).Cid() - func mustAddr(a address.Address, err error) address.Address { if err != nil { panic(err) @@ -49,80 +42,26 @@ func TestSendCLI(t *testing.T) { app, mockSrvcs, buf, done := newMockApp(t, sendCmd) defer done() - gomock.InOrder( - mockSrvcs.EXPECT().Send(gomock.Any(), SendParams{ - To: mustAddr(address.NewIDAddress(1)), - Val: oneFil, - }).Return(arbtCid, nil), - mockSrvcs.EXPECT().Close(), - ) - err := app.Run([]string{"lotus", "send", "t01", "1"}) - assert.NoError(t, err) - assert.EqualValues(t, arbtCid.String()+"\n", buf.String()) - }) - t.Run("ErrSendBalanceTooLow", func(t *testing.T) { - app, mockSrvcs, _, done := newMockApp(t, sendCmd) - defer done() - - gomock.InOrder( - mockSrvcs.EXPECT().Send(gomock.Any(), SendParams{ - To: mustAddr(address.NewIDAddress(1)), - Val: oneFil, - }).Return(cid.Undef, ErrSendBalanceTooLow), - mockSrvcs.EXPECT().Close(), - ) - err := app.Run([]string{"lotus", "send", "t01", "1"}) - assert.ErrorIs(t, err, ErrSendBalanceTooLow) - }) - t.Run("generic-err-is-forwarded", func(t *testing.T) { - app, mockSrvcs, _, done := newMockApp(t, sendCmd) - defer done() + arbtProto := &api.MessagePrototype{ + Message: types.Message{ + From: mustAddr(address.NewIDAddress(1)), + To: mustAddr(address.NewIDAddress(1)), + Value: oneFil, + }, + } + sigMsg := fakeSign(&arbtProto.Message) - errMark := errors.New("something") gomock.InOrder( - mockSrvcs.EXPECT().Send(gomock.Any(), SendParams{ + mockSrvcs.EXPECT().MessageForSend(gomock.Any(), SendParams{ To: mustAddr(address.NewIDAddress(1)), Val: oneFil, - }).Return(cid.Undef, errMark), + }).Return(arbtProto, nil), + mockSrvcs.EXPECT().PublishMessage(gomock.Any(), arbtProto, false). + Return(sigMsg, nil, nil), mockSrvcs.EXPECT().Close(), ) err := app.Run([]string{"lotus", "send", "t01", "1"}) - assert.ErrorIs(t, err, errMark) - }) - - t.Run("from-specific", func(t *testing.T) { - app, mockSrvcs, buf, done := newMockApp(t, sendCmd) - defer done() - - gomock.InOrder( - mockSrvcs.EXPECT().Send(gomock.Any(), SendParams{ - To: mustAddr(address.NewIDAddress(1)), - From: mustAddr(address.NewIDAddress(2)), - Val: oneFil, - }).Return(arbtCid, nil), - mockSrvcs.EXPECT().Close(), - ) - err := app.Run([]string{"lotus", "send", "--from=t02", "t01", "1"}) assert.NoError(t, err) - assert.EqualValues(t, arbtCid.String()+"\n", buf.String()) + assert.EqualValues(t, sigMsg.Cid().String()+"\n", buf.String()) }) - - t.Run("nonce-specific", func(t *testing.T) { - app, mockSrvcs, buf, done := newMockApp(t, sendCmd) - defer done() - zero := uint64(0) - - gomock.InOrder( - mockSrvcs.EXPECT().Send(gomock.Any(), SendParams{ - To: mustAddr(address.NewIDAddress(1)), - Nonce: &zero, - Val: oneFil, - }).Return(arbtCid, nil), - mockSrvcs.EXPECT().Close(), - ) - err := app.Run([]string{"lotus", "send", "--nonce=0", "t01", "1"}) - assert.NoError(t, err) - assert.EqualValues(t, arbtCid.String()+"\n", buf.String()) - }) - } diff --git a/cli/sending_ui.go b/cli/sending_ui.go new file mode 100644 index 00000000000..a70abefb906 --- /dev/null +++ b/cli/sending_ui.go @@ -0,0 +1,264 @@ +package cli + +import ( + "context" + "errors" + "fmt" + "io" + "strings" + + "github.com/Kubuxu/imtui" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/build" + types "github.com/filecoin-project/lotus/chain/types" + "github.com/gdamore/tcell/v2" + cid "github.com/ipfs/go-cid" + "github.com/urfave/cli/v2" + "golang.org/x/xerrors" +) + +func InteractiveSend(ctx context.Context, cctx *cli.Context, srv ServicesAPI, + proto *api.MessagePrototype) (*types.SignedMessage, error) { + + msg, checks, err := srv.PublishMessage(ctx, proto, cctx.Bool("force") || cctx.Bool("force-send")) + printer := cctx.App.Writer + if xerrors.Is(err, ErrCheckFailed) { + if !cctx.Bool("interactive") { + fmt.Fprintf(printer, "Following checks have failed:\n") + printChecks(printer, checks, proto.Message.Cid()) + } else { + proto, err = resolveChecks(ctx, srv, cctx.App.Writer, proto, checks) + if err != nil { + return nil, xerrors.Errorf("from UI: %w", err) + } + + msg, _, err = srv.PublishMessage(ctx, proto, true) + } + } + if err != nil { + return nil, xerrors.Errorf("publishing message: %w", err) + } + + return msg, nil +} + +var interactiveSolves = map[api.CheckStatusCode]bool{ + api.CheckStatusMessageMinBaseFee: true, + api.CheckStatusMessageBaseFee: true, + api.CheckStatusMessageBaseFeeLowerBound: true, + api.CheckStatusMessageBaseFeeUpperBound: true, +} + +func baseFeeFromHints(hint map[string]interface{}) big.Int { + bHint, ok := hint["baseFee"] + if !ok { + return big.Zero() + } + bHintS, ok := bHint.(string) + if !ok { + return big.Zero() + } + + var err error + baseFee, err := big.FromString(bHintS) + if err != nil { + return big.Zero() + } + return baseFee +} + +func resolveChecks(ctx context.Context, s ServicesAPI, printer io.Writer, + proto *api.MessagePrototype, checkGroups [][]api.MessageCheckStatus, +) (*api.MessagePrototype, error) { + + fmt.Fprintf(printer, "Following checks have failed:\n") + printChecks(printer, checkGroups, proto.Message.Cid()) + + if feeCapBad, baseFee := isFeeCapProblem(checkGroups, proto.Message.Cid()); feeCapBad { + fmt.Fprintf(printer, "Fee of the message can be adjusted\n") + if askUser(printer, "Do you wish to do that? [Yes/no]: ", true) { + var err error + proto, err = runFeeCapAdjustmentUI(proto, baseFee) + if err != nil { + return nil, err + } + } + checks, err := s.RunChecksForPrototype(ctx, proto) + if err != nil { + return nil, err + } + fmt.Fprintf(printer, "Following checks still failed:\n") + printChecks(printer, checks, proto.Message.Cid()) + } + + if !askUser(printer, "Do you wish to send this message? [yes/No]: ", false) { + return nil, ErrAbortedByUser + } + return proto, nil +} + +var ErrAbortedByUser = errors.New("aborted by user") + +func printChecks(printer io.Writer, checkGroups [][]api.MessageCheckStatus, protoCid cid.Cid) { + for _, checks := range checkGroups { + for _, c := range checks { + if c.OK { + continue + } + aboutProto := c.Cid.Equals(protoCid) + msgName := "current" + if !aboutProto { + msgName = c.Cid.String() + } + fmt.Fprintf(printer, "%s message failed a check %s: %s\n", msgName, c.Code, c.Err) + } + } +} + +func askUser(printer io.Writer, q string, def bool) bool { + var resp string + fmt.Fprint(printer, q) + fmt.Scanln(&resp) + resp = strings.ToLower(resp) + if len(resp) == 0 { + return def + } + return resp[0] == 'y' +} + +func isFeeCapProblem(checkGroups [][]api.MessageCheckStatus, protoCid cid.Cid) (bool, big.Int) { + baseFee := big.Zero() + yes := false + for _, checks := range checkGroups { + for _, c := range checks { + if c.OK { + continue + } + aboutProto := c.Cid.Equals(protoCid) + if aboutProto && interactiveSolves[c.Code] { + yes = true + if baseFee.IsZero() { + baseFee = baseFeeFromHints(c.Hint) + } + } + } + } + if baseFee.IsZero() { + // this will only be the case if failing check is: MessageMinBaseFee + baseFee = big.NewInt(build.MinimumBaseFee) + } + + return yes, baseFee +} + +func runFeeCapAdjustmentUI(proto *api.MessagePrototype, baseFee abi.TokenAmount) (*api.MessagePrototype, error) { + t, err := imtui.NewTui() + if err != nil { + return nil, err + } + + maxFee := big.Mul(proto.Message.GasFeeCap, big.NewInt(proto.Message.GasLimit)) + send := false + t.PushScene(feeUI(baseFee, proto.Message.GasLimit, &maxFee, &send)) + + err = t.Run() + if err != nil { + return nil, err + } + if !send { + return nil, fmt.Errorf("aborted by user") + } + + proto.Message.GasFeeCap = big.Div(maxFee, big.NewInt(proto.Message.GasLimit)) + + return proto, nil +} + +func feeUI(baseFee abi.TokenAmount, gasLimit int64, maxFee *abi.TokenAmount, send *bool) func(*imtui.Tui) error { + orignalMaxFee := *maxFee + required := big.Mul(baseFee, big.NewInt(gasLimit)) + safe := big.Mul(required, big.NewInt(10)) + + price := fmt.Sprintf("%s", types.FIL(*maxFee).Unitless()) + + return func(t *imtui.Tui) error { + if t.CurrentKey != nil { + if t.CurrentKey.Key() == tcell.KeyRune { + pF, err := types.ParseFIL(price) + switch t.CurrentKey.Rune() { + case 's', 'S': + price = types.FIL(safe).Unitless() + case '+': + if err == nil { + p := big.Mul(big.Int(pF), types.NewInt(11)) + p = big.Div(p, types.NewInt(10)) + price = fmt.Sprintf("%s", types.FIL(p).Unitless()) + } + case '-': + if err == nil { + p := big.Mul(big.Int(pF), types.NewInt(10)) + p = big.Div(p, types.NewInt(11)) + price = fmt.Sprintf("%s", types.FIL(p).Unitless()) + } + default: + } + } + + if t.CurrentKey.Key() == tcell.KeyEnter { + *send = true + t.PopScene() + return nil + } + } + + defS := tcell.StyleDefault + + row := 0 + t.Label(0, row, "Fee of the message is too low.", defS) + row++ + + t.Label(0, row, fmt.Sprintf("Your configured maximum fee is: %s FIL", + types.FIL(orignalMaxFee).Unitless()), defS) + row++ + t.Label(0, row, fmt.Sprintf("Required maximum fee for the message: %s FIL", + types.FIL(required).Unitless()), defS) + row++ + w := t.Label(0, row, fmt.Sprintf("Safe maximum fee for the message: %s FIL", + types.FIL(safe).Unitless()), defS) + t.Label(w, row, " Press S to use it", defS) + row++ + + w = t.Label(0, row, "Current Maximum Fee: ", defS) + + w += t.EditFieldFiltered(w, row, 14, &price, imtui.FilterDecimal, defS.Foreground(tcell.ColorWhite).Background(tcell.ColorBlack)) + + w += t.Label(w, row, " FIL", defS) + + pF, err := types.ParseFIL(price) + *maxFee = abi.TokenAmount(pF) + if err != nil { + w += t.Label(w, row, " invalid price", defS.Foreground(tcell.ColorMaroon).Bold(true)) + } else if maxFee.GreaterThanEqual(safe) { + w += t.Label(w, row, " SAFE", defS.Foreground(tcell.ColorDarkGreen).Bold(true)) + } else if maxFee.GreaterThanEqual(required) { + w += t.Label(w, row, " low", defS.Foreground(tcell.ColorYellow).Bold(true)) + over := big.Div(big.Mul(*maxFee, big.NewInt(100)), required) + w += t.Label(w, row, + fmt.Sprintf(" %.1fx over the minimum", float64(over.Int64())/100.0), defS) + } else { + w += t.Label(w, row, " too low", defS.Foreground(tcell.ColorRed).Bold(true)) + } + row += 2 + + t.Label(0, row, fmt.Sprintf("Current Base Fee is: %s", types.FIL(baseFee).Nano()), defS) + row++ + t.Label(0, row, fmt.Sprintf("Resulting FeeCap is: %s", + types.FIL(big.Div(*maxFee, big.NewInt(gasLimit))).Nano()), defS) + row++ + t.Label(0, row, "You can use '+' and '-' to adjust the fee.", defS) + + return nil + } +} diff --git a/cli/services.go b/cli/services.go index 069bed81159..0923680aa08 100644 --- a/cli/services.go +++ b/cli/services.go @@ -4,13 +4,13 @@ import ( "bytes" "context" "encoding/json" - "errors" "fmt" "reflect" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-jsonrpc" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/stmgr" types "github.com/filecoin-project/lotus/chain/types" @@ -22,12 +22,30 @@ import ( //go:generate go run github.com/golang/mock/mockgen -destination=servicesmock_test.go -package=cli -self_package github.com/filecoin-project/lotus/cli . ServicesAPI type ServicesAPI interface { - // Sends executes a send given SendParams - Send(ctx context.Context, params SendParams) (cid.Cid, error) + FullNodeAPI() api.FullNode + + GetBaseFee(ctx context.Context) (abi.TokenAmount, error) + + // MessageForSend creates a prototype of a message based on SendParams + MessageForSend(ctx context.Context, params SendParams) (*api.MessagePrototype, error) + // DecodeTypedParamsFromJSON takes in information needed to identify a method and converts JSON // parameters to bytes of their CBOR encoding DecodeTypedParamsFromJSON(ctx context.Context, to address.Address, method abi.MethodNum, paramstr string) ([]byte, error) + RunChecksForPrototype(ctx context.Context, prototype *api.MessagePrototype) ([][]api.MessageCheckStatus, error) + + // PublishMessage takes in a message prototype and publishes it + // before publishing the message, it runs checks on the node, message and mpool to verify that + // message is valid and won't be stuck. + // if `force` is true, it skips the checks + PublishMessage(ctx context.Context, prototype *api.MessagePrototype, force bool) (*types.SignedMessage, [][]api.MessageCheckStatus, error) + + LocalAddresses(ctx context.Context) (address.Address, []address.Address, error) + + MpoolPendingFilter(ctx context.Context, filter func(*types.SignedMessage) bool, tsk types.TipSetKey) ([]*types.SignedMessage, error) + MpoolCheckPendingMessages(ctx context.Context, a address.Address) ([][]api.MessageCheckStatus, error) + // Close ends the session of services and disconnects from RPC, using Services after Close is called // most likely will result in an error // Should not be called concurrently @@ -39,6 +57,10 @@ type ServicesImpl struct { closer jsonrpc.ClientCloser } +func (s *ServicesImpl) FullNodeAPI() api.FullNode { + return s.api +} + func (s *ServicesImpl) Close() error { if s.closer == nil { return xerrors.Errorf("Services already closed") @@ -48,6 +70,16 @@ func (s *ServicesImpl) Close() error { return nil } +func (s *ServicesImpl) GetBaseFee(ctx context.Context) (abi.TokenAmount, error) { + // not used but useful + + ts, err := s.api.ChainHead(ctx) + if err != nil { + return big.Zero(), xerrors.Errorf("getting head: %w", err) + } + return ts.MinTicketBlock().ParentBaseFee, nil +} + func (s *ServicesImpl) DecodeTypedParamsFromJSON(ctx context.Context, to address.Address, method abi.MethodNum, paramstr string) ([]byte, error) { act, err := s.api.StateGetActor(ctx, to, types.EmptyTSK) if err != nil { @@ -72,6 +104,79 @@ func (s *ServicesImpl) DecodeTypedParamsFromJSON(ctx context.Context, to address return buf.Bytes(), nil } +type CheckInfo struct { + MessageTie cid.Cid + CurrentMessageTie bool + + Check api.MessageCheckStatus +} + +var ErrCheckFailed = fmt.Errorf("check has failed") + +func (s *ServicesImpl) RunChecksForPrototype(ctx context.Context, prototype *api.MessagePrototype) ([][]api.MessageCheckStatus, error) { + var outChecks [][]api.MessageCheckStatus + checks, err := s.api.MpoolCheckMessages(ctx, []*api.MessagePrototype{prototype}) + if err != nil { + return nil, xerrors.Errorf("message check: %w", err) + } + outChecks = append(outChecks, checks...) + + checks, err = s.api.MpoolCheckPendingMessages(ctx, prototype.Message.From) + if err != nil { + return nil, xerrors.Errorf("pending mpool check: %w", err) + } + outChecks = append(outChecks, checks...) + + return outChecks, nil +} + +// PublishMessage modifies prototype to include gas estimation +// Errors with ErrCheckFailed if any of the checks fail +// First group of checks is related to the message prototype +func (s *ServicesImpl) PublishMessage(ctx context.Context, + prototype *api.MessagePrototype, force bool) (*types.SignedMessage, [][]api.MessageCheckStatus, error) { + + gasedMsg, err := s.api.GasEstimateMessageGas(ctx, &prototype.Message, nil, types.EmptyTSK) + if err != nil { + return nil, nil, xerrors.Errorf("estimating gas: %w", err) + } + prototype.Message = *gasedMsg + + if !force { + checks, err := s.RunChecksForPrototype(ctx, prototype) + if err != nil { + return nil, nil, xerrors.Errorf("running checks: %w", err) + } + for _, chks := range checks { + for _, c := range chks { + if !c.OK { + return nil, checks, ErrCheckFailed + } + } + } + } + + if prototype.ValidNonce { + sm, err := s.api.WalletSignMessage(ctx, prototype.Message.From, &prototype.Message) + if err != nil { + return nil, nil, err + } + + _, err = s.api.MpoolPush(ctx, sm) + if err != nil { + return nil, nil, err + } + return sm, nil, nil + } + + sm, err := s.api.MpoolPushMessage(ctx, &prototype.Message, nil) + if err != nil { + return nil, nil, err + } + + return sm, nil, nil +} + type SendParams struct { To address.Address From address.Address @@ -84,26 +189,18 @@ type SendParams struct { Nonce *uint64 Method abi.MethodNum Params []byte - - Force bool } -// This is specialised Send for Send command -// There might be room for generic Send that other commands can use to send their messages -// We will see - -var ErrSendBalanceTooLow = errors.New("balance too low") - -func (s *ServicesImpl) Send(ctx context.Context, params SendParams) (cid.Cid, error) { +func (s *ServicesImpl) MessageForSend(ctx context.Context, params SendParams) (*api.MessagePrototype, error) { if params.From == address.Undef { defaddr, err := s.api.WalletDefaultAddress(ctx) if err != nil { - return cid.Undef, err + return nil, err } params.From = defaddr } - msg := &types.Message{ + msg := types.Message{ From: params.From, To: params.To, Value: params.Val, @@ -127,40 +224,53 @@ func (s *ServicesImpl) Send(ctx context.Context, params SendParams) (cid.Cid, er } else { msg.GasLimit = 0 } + validNonce := false + if params.Nonce != nil { + msg.Nonce = *params.Nonce + validNonce = true + } - if !params.Force { - // Funds insufficient check - fromBalance, err := s.api.WalletBalance(ctx, msg.From) - if err != nil { - return cid.Undef, err - } - totalCost := types.BigAdd(types.BigMul(msg.GasFeeCap, types.NewInt(uint64(msg.GasLimit))), msg.Value) - - if fromBalance.LessThan(totalCost) { - return cid.Undef, xerrors.Errorf("From balance %s less than total cost %s: %w", types.FIL(fromBalance), types.FIL(totalCost), ErrSendBalanceTooLow) - - } + prototype := &api.MessagePrototype{ + Message: msg, + ValidNonce: validNonce, } + return prototype, nil +} - if params.Nonce != nil { - msg.Nonce = *params.Nonce - sm, err := s.api.WalletSignMessage(ctx, params.From, msg) - if err != nil { - return cid.Undef, err +func (s *ServicesImpl) MpoolPendingFilter(ctx context.Context, filter func(*types.SignedMessage) bool, + tsk types.TipSetKey) ([]*types.SignedMessage, error) { + msgs, err := s.api.MpoolPending(ctx, types.EmptyTSK) + if err != nil { + return nil, xerrors.Errorf("getting pending messages: %w", err) + } + out := []*types.SignedMessage{} + for _, sm := range msgs { + if filter(sm) { + out = append(out, sm) } + } - _, err = s.api.MpoolPush(ctx, sm) - if err != nil { - return cid.Undef, err - } + return out, nil +} - return sm.Cid(), nil +func (s *ServicesImpl) LocalAddresses(ctx context.Context) (address.Address, []address.Address, error) { + def, err := s.api.WalletDefaultAddress(ctx) + if err != nil { + return address.Undef, nil, xerrors.Errorf("getting default addr: %w", err) } - sm, err := s.api.MpoolPushMessage(ctx, msg, nil) + all, err := s.api.WalletList(ctx) if err != nil { - return cid.Undef, err + return address.Undef, nil, xerrors.Errorf("getting list of addrs: %w", err) } - return sm.Cid(), nil + return def, all, nil +} + +func (s *ServicesImpl) MpoolCheckPendingMessages(ctx context.Context, a address.Address) ([][]api.MessageCheckStatus, error) { + checks, err := s.api.MpoolCheckPendingMessages(ctx, a) + if err != nil { + return nil, xerrors.Errorf("pending mpool check: %w", err) + } + return checks, nil } diff --git a/cli/services_send_test.go b/cli/services_send_test.go index 9dfc3b38a5f..b7ed78f80db 100644 --- a/cli/services_send_test.go +++ b/cli/services_send_test.go @@ -9,10 +9,9 @@ import ( "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/api/mocks" + mocks "github.com/filecoin-project/lotus/api/mocks" types "github.com/filecoin-project/lotus/chain/types" gomock "github.com/golang/mock/gomock" - cid "github.com/ipfs/go-cid" "github.com/stretchr/testify/assert" ) @@ -61,6 +60,7 @@ func setupMockSrvcs(t *testing.T) (*ServicesImpl, *mocks.MockFullNode) { return srvcs, mockApi } +// linter doesn't like dead code, so these are commented out. func fakeSign(msg *types.Message) *types.SignedMessage { return &types.SignedMessage{ Message: *msg, @@ -68,15 +68,15 @@ func fakeSign(msg *types.Message) *types.SignedMessage { } } -func makeMessageSigner() (*cid.Cid, interface{}) { - smCid := cid.Undef - return &smCid, - func(_ context.Context, msg *types.Message, _ *api.MessageSendSpec) (*types.SignedMessage, error) { - sm := fakeSign(msg) - smCid = sm.Cid() - return sm, nil - } -} +//func makeMessageSigner() (*cid.Cid, interface{}) { +//smCid := cid.Undef +//return &smCid, +//func(_ context.Context, msg *types.Message, _ *api.MessageSendSpec) (*types.SignedMessage, error) { +//sm := fakeSign(msg) +//smCid = sm.Cid() +//return sm, nil +//} +//} type MessageMatcher SendParams @@ -84,11 +84,13 @@ var _ gomock.Matcher = MessageMatcher{} // Matches returns whether x is a match. func (mm MessageMatcher) Matches(x interface{}) bool { - m, ok := x.(*types.Message) + proto, ok := x.(*api.MessagePrototype) if !ok { return false } + m := &proto.Message + if mm.From != address.Undef && mm.From != m.From { return false } @@ -151,47 +153,12 @@ func TestSendService(t *testing.T) { t.Run("happy", func(t *testing.T) { params := params - srvcs, mockApi := setupMockSrvcs(t) + srvcs, _ := setupMockSrvcs(t) defer srvcs.Close() //nolint:errcheck - msgCid, sign := makeMessageSigner() - gomock.InOrder( - mockApi.EXPECT().WalletBalance(ctxM, params.From).Return(types.NewInt(balance), nil), - mockApi.EXPECT().MpoolPushMessage(ctxM, MessageMatcher(params), nil).DoAndReturn(sign), - ) - c, err := srvcs.Send(ctx, params) + proto, err := srvcs.MessageForSend(ctx, params) assert.NoError(t, err) - assert.Equal(t, *msgCid, c) - }) - - t.Run("balance-too-low", func(t *testing.T) { - params := params - srvcs, mockApi := setupMockSrvcs(t) - defer srvcs.Close() //nolint:errcheck - gomock.InOrder( - mockApi.EXPECT().WalletBalance(ctxM, a1).Return(types.NewInt(balance-200), nil), - // no MpoolPushMessage - ) - - c, err := srvcs.Send(ctx, params) - assert.Equal(t, c, cid.Undef) - assert.ErrorIs(t, err, ErrSendBalanceTooLow) - }) - - t.Run("force", func(t *testing.T) { - params := params - params.Force = true - srvcs, mockApi := setupMockSrvcs(t) - defer srvcs.Close() //nolint:errcheck - msgCid, sign := makeMessageSigner() - gomock.InOrder( - mockApi.EXPECT().WalletBalance(ctxM, a1).Return(types.NewInt(balance-200), nil).AnyTimes(), - mockApi.EXPECT().MpoolPushMessage(ctxM, MessageMatcher(params), nil).DoAndReturn(sign), - ) - - c, err := srvcs.Send(ctx, params) - assert.NoError(t, err) - assert.Equal(t, *msgCid, c) + assert.True(t, MessageMatcher(params).Matches(proto)) }) t.Run("default-from", func(t *testing.T) { @@ -202,16 +169,14 @@ func TestSendService(t *testing.T) { srvcs, mockApi := setupMockSrvcs(t) defer srvcs.Close() //nolint:errcheck - msgCid, sign := makeMessageSigner() + gomock.InOrder( mockApi.EXPECT().WalletDefaultAddress(ctxM).Return(a1, nil), - mockApi.EXPECT().WalletBalance(ctxM, a1).Return(types.NewInt(balance), nil), - mockApi.EXPECT().MpoolPushMessage(ctxM, mm, nil).DoAndReturn(sign), ) - c, err := srvcs.Send(ctx, params) + proto, err := srvcs.MessageForSend(ctx, params) assert.NoError(t, err) - assert.Equal(t, *msgCid, c) + assert.True(t, mm.Matches(proto)) }) t.Run("set-nonce", func(t *testing.T) { @@ -220,26 +185,12 @@ func TestSendService(t *testing.T) { params.Nonce = &n mm := MessageMatcher(params) - srvcs, mockApi := setupMockSrvcs(t) + srvcs, _ := setupMockSrvcs(t) defer srvcs.Close() //nolint:errcheck - _, _ = mm, mockApi - - var sm *types.SignedMessage - gomock.InOrder( - mockApi.EXPECT().WalletBalance(ctxM, a1).Return(types.NewInt(balance), nil), - mockApi.EXPECT().WalletSignMessage(ctxM, a1, mm).DoAndReturn( - func(_ context.Context, _ address.Address, msg *types.Message) (*types.SignedMessage, error) { - sm = fakeSign(msg) - - // now we expect MpoolPush with that SignedMessage - mockApi.EXPECT().MpoolPush(ctxM, sm).Return(sm.Cid(), nil) - return sm, nil - }), - ) - c, err := srvcs.Send(ctx, params) + proto, err := srvcs.MessageForSend(ctx, params) assert.NoError(t, err) - assert.Equal(t, sm.Cid(), c) + assert.True(t, mm.Matches(proto)) }) t.Run("gas-params", func(t *testing.T) { @@ -251,16 +202,14 @@ func TestSendService(t *testing.T) { gp := big.NewInt(10) params.GasPremium = &gp - srvcs, mockApi := setupMockSrvcs(t) + mm := MessageMatcher(params) + + srvcs, _ := setupMockSrvcs(t) defer srvcs.Close() //nolint:errcheck - msgCid, sign := makeMessageSigner() - gomock.InOrder( - mockApi.EXPECT().WalletBalance(ctxM, params.From).Return(types.NewInt(balance), nil), - mockApi.EXPECT().MpoolPushMessage(ctxM, MessageMatcher(params), nil).DoAndReturn(sign), - ) - c, err := srvcs.Send(ctx, params) + proto, err := srvcs.MessageForSend(ctx, params) assert.NoError(t, err) - assert.Equal(t, *msgCid, c) + assert.True(t, mm.Matches(proto)) + }) } diff --git a/cli/servicesmock_test.go b/cli/servicesmock_test.go index 48f1a95ec19..4bd4b79c9e2 100644 --- a/cli/servicesmock_test.go +++ b/cli/servicesmock_test.go @@ -8,8 +8,10 @@ import ( context "context" go_address "github.com/filecoin-project/go-address" abi "github.com/filecoin-project/go-state-types/abi" + big "github.com/filecoin-project/go-state-types/big" + api "github.com/filecoin-project/lotus/api" + types "github.com/filecoin-project/lotus/chain/types" gomock "github.com/golang/mock/gomock" - go_cid "github.com/ipfs/go-cid" reflect "reflect" ) @@ -65,17 +67,123 @@ func (mr *MockServicesAPIMockRecorder) DecodeTypedParamsFromJSON(arg0, arg1, arg return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecodeTypedParamsFromJSON", reflect.TypeOf((*MockServicesAPI)(nil).DecodeTypedParamsFromJSON), arg0, arg1, arg2, arg3) } -// Send mocks base method -func (m *MockServicesAPI) Send(arg0 context.Context, arg1 SendParams) (go_cid.Cid, error) { +// FullNodeAPI mocks base method +func (m *MockServicesAPI) FullNodeAPI() api.FullNode { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Send", arg0, arg1) - ret0, _ := ret[0].(go_cid.Cid) + ret := m.ctrl.Call(m, "FullNodeAPI") + ret0, _ := ret[0].(api.FullNode) + return ret0 +} + +// FullNodeAPI indicates an expected call of FullNodeAPI +func (mr *MockServicesAPIMockRecorder) FullNodeAPI() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FullNodeAPI", reflect.TypeOf((*MockServicesAPI)(nil).FullNodeAPI)) +} + +// GetBaseFee mocks base method +func (m *MockServicesAPI) GetBaseFee(arg0 context.Context) (big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBaseFee", arg0) + ret0, _ := ret[0].(big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBaseFee indicates an expected call of GetBaseFee +func (mr *MockServicesAPIMockRecorder) GetBaseFee(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBaseFee", reflect.TypeOf((*MockServicesAPI)(nil).GetBaseFee), arg0) +} + +// LocalAddresses mocks base method +func (m *MockServicesAPI) LocalAddresses(arg0 context.Context) (go_address.Address, []go_address.Address, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "LocalAddresses", arg0) + ret0, _ := ret[0].(go_address.Address) + ret1, _ := ret[1].([]go_address.Address) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// LocalAddresses indicates an expected call of LocalAddresses +func (mr *MockServicesAPIMockRecorder) LocalAddresses(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LocalAddresses", reflect.TypeOf((*MockServicesAPI)(nil).LocalAddresses), arg0) +} + +// MessageForSend mocks base method +func (m *MockServicesAPI) MessageForSend(arg0 context.Context, arg1 SendParams) (*api.MessagePrototype, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MessageForSend", arg0, arg1) + ret0, _ := ret[0].(*api.MessagePrototype) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MessageForSend indicates an expected call of MessageForSend +func (mr *MockServicesAPIMockRecorder) MessageForSend(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MessageForSend", reflect.TypeOf((*MockServicesAPI)(nil).MessageForSend), arg0, arg1) +} + +// MpoolCheckPendingMessages mocks base method +func (m *MockServicesAPI) MpoolCheckPendingMessages(arg0 context.Context, arg1 go_address.Address) ([][]api.MessageCheckStatus, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolCheckPendingMessages", arg0, arg1) + ret0, _ := ret[0].([][]api.MessageCheckStatus) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MpoolCheckPendingMessages indicates an expected call of MpoolCheckPendingMessages +func (mr *MockServicesAPIMockRecorder) MpoolCheckPendingMessages(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolCheckPendingMessages", reflect.TypeOf((*MockServicesAPI)(nil).MpoolCheckPendingMessages), arg0, arg1) +} + +// MpoolPendingFilter mocks base method +func (m *MockServicesAPI) MpoolPendingFilter(arg0 context.Context, arg1 func(*types.SignedMessage) bool, arg2 types.TipSetKey) ([]*types.SignedMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MpoolPendingFilter", arg0, arg1, arg2) + ret0, _ := ret[0].([]*types.SignedMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MpoolPendingFilter indicates an expected call of MpoolPendingFilter +func (mr *MockServicesAPIMockRecorder) MpoolPendingFilter(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolPendingFilter", reflect.TypeOf((*MockServicesAPI)(nil).MpoolPendingFilter), arg0, arg1, arg2) +} + +// PublishMessage mocks base method +func (m *MockServicesAPI) PublishMessage(arg0 context.Context, arg1 *api.MessagePrototype, arg2 bool) (*types.SignedMessage, [][]api.MessageCheckStatus, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PublishMessage", arg0, arg1, arg2) + ret0, _ := ret[0].(*types.SignedMessage) + ret1, _ := ret[1].([][]api.MessageCheckStatus) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// PublishMessage indicates an expected call of PublishMessage +func (mr *MockServicesAPIMockRecorder) PublishMessage(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PublishMessage", reflect.TypeOf((*MockServicesAPI)(nil).PublishMessage), arg0, arg1, arg2) +} + +// RunChecksForPrototype mocks base method +func (m *MockServicesAPI) RunChecksForPrototype(arg0 context.Context, arg1 *api.MessagePrototype) ([][]api.MessageCheckStatus, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RunChecksForPrototype", arg0, arg1) + ret0, _ := ret[0].([][]api.MessageCheckStatus) ret1, _ := ret[1].(error) return ret0, ret1 } -// Send indicates an expected call of Send -func (mr *MockServicesAPIMockRecorder) Send(arg0, arg1 interface{}) *gomock.Call { +// RunChecksForPrototype indicates an expected call of RunChecksForPrototype +func (mr *MockServicesAPIMockRecorder) RunChecksForPrototype(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockServicesAPI)(nil).Send), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RunChecksForPrototype", reflect.TypeOf((*MockServicesAPI)(nil).RunChecksForPrototype), arg0, arg1) } diff --git a/cli/state.go b/cli/state.go index 12689c7e316..63e92348594 100644 --- a/cli/state.go +++ b/cli/state.go @@ -15,6 +15,8 @@ import ( "strings" "time" + "github.com/filecoin-project/lotus/api/v0api" + "github.com/fatih/color" "github.com/filecoin-project/lotus/chain/actors/builtin" @@ -73,6 +75,50 @@ var StateCmd = &cli.Command{ StateMarketCmd, StateExecTraceCmd, StateNtwkVersionCmd, + StateMinerProvingDeadlineCmd, + }, +} + +var StateMinerProvingDeadlineCmd = &cli.Command{ + Name: "miner-proving-deadline", + Usage: "Retrieve information about a given miner's proving deadline", + ArgsUsage: "[minerAddress]", + Action: func(cctx *cli.Context) error { + api, closer, err := GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer closer() + + ctx := ReqContext(cctx) + + if !cctx.Args().Present() { + return fmt.Errorf("must specify miner to get information for") + } + + addr, err := address.NewFromString(cctx.Args().First()) + if err != nil { + return err + } + + ts, err := LoadTipSet(ctx, cctx, api) + if err != nil { + return err + } + + cd, err := api.StateMinerProvingDeadline(ctx, addr, ts.Key()) + if err != nil { + return xerrors.Errorf("getting miner info: %w", err) + } + + fmt.Printf("Period Start:\t%s\n", cd.PeriodStart) + fmt.Printf("Index:\t\t%d\n", cd.Index) + fmt.Printf("Open:\t\t%s\n", cd.Open) + fmt.Printf("Close:\t\t%s\n", cd.Close) + fmt.Printf("Challenge:\t%s\n", cd.Challenge) + fmt.Printf("FaultCutoff:\t%s\n", cd.FaultCutoff) + + return nil }, } @@ -178,16 +224,19 @@ func ParseTipSetString(ts string) ([]cid.Cid, error) { return cids, nil } -func LoadTipSet(ctx context.Context, cctx *cli.Context, api api.FullNode) (*types.TipSet, error) { +// LoadTipSet gets the tipset from the context, or the head from the API. +// +// It always gets the head from the API so commands use a consistent tipset even if time pases. +func LoadTipSet(ctx context.Context, cctx *cli.Context, api v0api.FullNode) (*types.TipSet, error) { tss := cctx.String("tipset") if tss == "" { - return nil, nil + return api.ChainHead(ctx) } return ParseTipSetRef(ctx, api, tss) } -func ParseTipSetRef(ctx context.Context, api api.FullNode, tss string) (*types.TipSet, error) { +func ParseTipSetRef(ctx context.Context, api v0api.FullNode, tss string) (*types.TipSet, error) { if tss[0] == '@' { if tss == "@head" { return api.ChainHead(ctx) @@ -574,7 +623,7 @@ var StateListMinersCmd = &cli.Command{ }, } -func getDealsCounts(ctx context.Context, lapi api.FullNode) (map[address.Address]int, error) { +func getDealsCounts(ctx context.Context, lapi v0api.FullNode) (map[address.Address]int, error) { allDeals, err := lapi.StateMarketDeals(ctx, types.EmptyTSK) if err != nil { return nil, err @@ -848,14 +897,6 @@ var StateListMessagesCmd = &cli.Command{ return err } - if ts == nil { - head, err := api.ChainHead(ctx) - if err != nil { - return err - } - ts = head - } - windowSize := abi.ChainEpoch(100) cur := ts @@ -955,13 +996,6 @@ var StateComputeStateCmd = &cli.Command{ } h := abi.ChainEpoch(cctx.Uint64("vm-height")) - if ts == nil { - head, err := api.ChainHead(ctx) - if err != nil { - return err - } - ts = head - } if h == 0 { h = ts.Height() } @@ -1443,7 +1477,7 @@ var StateSearchMsgCmd = &cli.Command{ }, } -func printReceiptReturn(ctx context.Context, api api.FullNode, m *types.Message, r types.MessageReceipt) error { +func printReceiptReturn(ctx context.Context, api v0api.FullNode, m *types.Message, r types.MessageReceipt) error { if len(r.Return) == 0 { return nil } @@ -1463,20 +1497,20 @@ func printReceiptReturn(ctx context.Context, api api.FullNode, m *types.Message, return nil } -func printMsg(ctx context.Context, api api.FullNode, msg cid.Cid, mw *lapi.MsgLookup, m *types.Message) error { - if mw != nil { - if mw.Message != msg { - fmt.Printf("Message was replaced: %s\n", mw.Message) - } - - fmt.Printf("Executed in tipset: %s\n", mw.TipSet.Cids()) - fmt.Printf("Exit Code: %d\n", mw.Receipt.ExitCode) - fmt.Printf("Gas Used: %d\n", mw.Receipt.GasUsed) - fmt.Printf("Return: %x\n", mw.Receipt.Return) - } else { +func printMsg(ctx context.Context, api v0api.FullNode, msg cid.Cid, mw *lapi.MsgLookup, m *types.Message) error { + if mw == nil { fmt.Println("message was not found on chain") + return nil } + if mw.Message != msg { + fmt.Printf("Message was replaced: %s\n", mw.Message) + } + + fmt.Printf("Executed in tipset: %s\n", mw.TipSet.Cids()) + fmt.Printf("Exit Code: %d\n", mw.Receipt.ExitCode) + fmt.Printf("Gas Used: %d\n", mw.Receipt.GasUsed) + fmt.Printf("Return: %x\n", mw.Receipt.Return) if err := printReceiptReturn(ctx, api, m, mw.Receipt); err != nil { return err } @@ -1744,7 +1778,7 @@ var StateCircSupplyCmd = &cli.Command{ var StateSectorCmd = &cli.Command{ Name: "sector", Usage: "Get miner sector info", - ArgsUsage: "[miner address] [sector number]", + ArgsUsage: "[minerAddress] [sectorNumber]", Action: func(cctx *cli.Context) error { api, closer, err := GetFullNodeAPI(cctx) if err != nil { @@ -1755,7 +1789,7 @@ var StateSectorCmd = &cli.Command{ ctx := ReqContext(cctx) if cctx.Args().Len() != 2 { - return xerrors.Errorf("expected 2 params") + return xerrors.Errorf("expected 2 params: minerAddress and sectorNumber") } ts, err := LoadTipSet(ctx, cctx, api) @@ -1763,13 +1797,6 @@ var StateSectorCmd = &cli.Command{ return err } - if ts == nil { - ts, err = api.ChainHead(ctx) - if err != nil { - return err - } - } - maddr, err := address.NewFromString(cctx.Args().Get(0)) if err != nil { return err diff --git a/cli/status.go b/cli/status.go new file mode 100644 index 00000000000..75f91196a1c --- /dev/null +++ b/cli/status.go @@ -0,0 +1,60 @@ +package cli + +import ( + "fmt" + + "github.com/urfave/cli/v2" + + "github.com/filecoin-project/lotus/build" +) + +var StatusCmd = &cli.Command{ + Name: "status", + Usage: "Check node status", + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "chain", + Usage: "include chain health status", + }, + }, + + Action: func(cctx *cli.Context) error { + apic, closer, err := GetFullNodeAPIV1(cctx) + if err != nil { + return err + } + defer closer() + ctx := ReqContext(cctx) + + inclChainStatus := cctx.Bool("chain") + + status, err := apic.NodeStatus(ctx, inclChainStatus) + if err != nil { + return err + } + + fmt.Printf("Sync Epoch: %d\n", status.SyncStatus.Epoch) + fmt.Printf("Epochs Behind: %d\n", status.SyncStatus.Behind) + fmt.Printf("Peers to Publish Messages: %d\n", status.PeerStatus.PeersToPublishMsgs) + fmt.Printf("Peers to Publish Blocks: %d\n", status.PeerStatus.PeersToPublishBlocks) + + if inclChainStatus && status.SyncStatus.Epoch > uint64(build.Finality) { + var ok100, okFin string + if status.ChainStatus.BlocksPerTipsetLast100 >= 4.75 { + ok100 = "[OK]" + } else { + ok100 = "[UNHEALTHY]" + } + if status.ChainStatus.BlocksPerTipsetLastFinality >= 4.75 { + okFin = "[OK]" + } else { + okFin = "[UNHEALTHY]" + } + + fmt.Printf("Blocks per TipSet in last 100 epochs: %f %s\n", status.ChainStatus.BlocksPerTipsetLast100, ok100) + fmt.Printf("Blocks per TipSet in last finality: %f %s\n", status.ChainStatus.BlocksPerTipsetLastFinality, okFin) + } + + return nil + }, +} diff --git a/cli/sync.go b/cli/sync.go index 223d50337ac..c7b010111c3 100644 --- a/cli/sync.go +++ b/cli/sync.go @@ -12,6 +12,7 @@ import ( "github.com/urfave/cli/v2" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/build" ) @@ -240,7 +241,7 @@ var SyncCheckpointCmd = &cli.Command{ }, } -func SyncWait(ctx context.Context, napi api.FullNode, watch bool) error { +func SyncWait(ctx context.Context, napi v0api.FullNode, watch bool) error { tick := time.Second / 4 lastLines := 0 diff --git a/cli/test/mockcli.go b/cli/test/mockcli.go index e8eb78f1b4c..aef7808c8c3 100644 --- a/cli/test/mockcli.go +++ b/cli/test/mockcli.go @@ -56,7 +56,7 @@ type MockCLIClient struct { func (c *MockCLIClient) RunCmd(input ...string) string { out, err := c.RunCmdRaw(input...) - require.NoError(c.t, err) + require.NoError(c.t, err, "output:\n%s", out) return out } diff --git a/cli/test/util.go b/cli/test/util.go index e3930dc832a..d7959b9d572 100644 --- a/cli/test/util.go +++ b/cli/test/util.go @@ -9,4 +9,6 @@ func QuietMiningLogs() { _ = log.SetLogLevel("sub", "ERROR") _ = log.SetLogLevel("storageminer", "ERROR") _ = log.SetLogLevel("pubsub", "ERROR") + _ = log.SetLogLevel("gen", "ERROR") + _ = log.SetLogLevel("dht/RtRefreshManager", "ERROR") } diff --git a/cli/util.go b/cli/util.go index fb555e320f0..3183e21cff8 100644 --- a/cli/util.go +++ b/cli/util.go @@ -10,12 +10,12 @@ import ( "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" ) -func parseTipSet(ctx context.Context, api api.FullNode, vals []string) (*types.TipSet, error) { +func parseTipSet(ctx context.Context, api v0api.FullNode, vals []string) (*types.TipSet, error) { var headers []*types.BlockHeader for _, c := range vals { blkc, err := cid.Decode(c) diff --git a/cli/util/api.go b/cli/util/api.go index ce5945f2ebf..ec826160423 100644 --- a/cli/util/api.go +++ b/cli/util/api.go @@ -18,6 +18,8 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/client" + "github.com/filecoin-project/lotus/api/v0api" + "github.com/filecoin-project/lotus/api/v1api" "github.com/filecoin-project/lotus/node/repo" ) @@ -133,13 +135,13 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { }, nil } -func GetRawAPI(ctx *cli.Context, t repo.RepoType) (string, http.Header, error) { +func GetRawAPI(ctx *cli.Context, t repo.RepoType, version string) (string, http.Header, error) { ainfo, err := GetAPIInfo(ctx, t) if err != nil { return "", nil, xerrors.Errorf("could not get API info: %w", err) } - addr, err := ainfo.DialArgs() + addr, err := ainfo.DialArgs(version) if err != nil { return "", nil, xerrors.Errorf("could not get DialArgs: %w", err) } @@ -165,25 +167,38 @@ func GetAPI(ctx *cli.Context) (api.Common, jsonrpc.ClientCloser, error) { return tn.(api.FullNode), func() {}, nil } - addr, headers, err := GetRawAPI(ctx, t) + addr, headers, err := GetRawAPI(ctx, t, "v0") if err != nil { return nil, nil, err } - return client.NewCommonRPC(ctx.Context, addr, headers) + return client.NewCommonRPCV0(ctx.Context, addr, headers) } -func GetFullNodeAPI(ctx *cli.Context) (api.FullNode, jsonrpc.ClientCloser, error) { +func GetFullNodeAPI(ctx *cli.Context) (v0api.FullNode, jsonrpc.ClientCloser, error) { if tn, ok := ctx.App.Metadata["testnode-full"]; ok { - return tn.(api.FullNode), func() {}, nil + return &v0api.WrapperV1Full{FullNode: tn.(v1api.FullNode)}, func() {}, nil + } + + addr, headers, err := GetRawAPI(ctx, repo.FullNode, "v0") + if err != nil { + return nil, nil, err + } + + return client.NewFullNodeRPCV0(ctx.Context, addr, headers) +} + +func GetFullNodeAPIV1(ctx *cli.Context) (v1api.FullNode, jsonrpc.ClientCloser, error) { + if tn, ok := ctx.App.Metadata["testnode-full"]; ok { + return tn.(v1api.FullNode), func() {}, nil } - addr, headers, err := GetRawAPI(ctx, repo.FullNode) + addr, headers, err := GetRawAPI(ctx, repo.FullNode, "v1") if err != nil { return nil, nil, err } - return client.NewFullNodeRPC(ctx.Context, addr, headers) + return client.NewFullNodeRPCV1(ctx.Context, addr, headers) } type GetStorageMinerOptions struct { @@ -206,7 +221,7 @@ func GetStorageMinerAPI(ctx *cli.Context, opts ...GetStorageMinerOption) (api.St return tn.(api.StorageMiner), func() {}, nil } - addr, headers, err := GetRawAPI(ctx, repo.StorageMiner) + addr, headers, err := GetRawAPI(ctx, repo.StorageMiner, "v0") if err != nil { return nil, nil, err } @@ -227,25 +242,34 @@ func GetStorageMinerAPI(ctx *cli.Context, opts ...GetStorageMinerOption) (api.St addr = u.String() } - return client.NewStorageMinerRPC(ctx.Context, addr, headers) + return client.NewStorageMinerRPCV0(ctx.Context, addr, headers) } func GetWorkerAPI(ctx *cli.Context) (api.Worker, jsonrpc.ClientCloser, error) { - addr, headers, err := GetRawAPI(ctx, repo.Worker) + addr, headers, err := GetRawAPI(ctx, repo.Worker, "v0") if err != nil { return nil, nil, err } - return client.NewWorkerRPC(ctx.Context, addr, headers) + return client.NewWorkerRPCV0(ctx.Context, addr, headers) } func GetGatewayAPI(ctx *cli.Context) (api.Gateway, jsonrpc.ClientCloser, error) { - addr, headers, err := GetRawAPI(ctx, repo.FullNode) + addr, headers, err := GetRawAPI(ctx, repo.FullNode, "v1") + if err != nil { + return nil, nil, err + } + + return client.NewGatewayRPCV1(ctx.Context, addr, headers) +} + +func GetGatewayAPIV0(ctx *cli.Context) (v0api.Gateway, jsonrpc.ClientCloser, error) { + addr, headers, err := GetRawAPI(ctx, repo.FullNode, "v0") if err != nil { return nil, nil, err } - return client.NewGatewayRPC(ctx.Context, addr, headers) + return client.NewGatewayRPCV0(ctx.Context, addr, headers) } func DaemonContext(cctx *cli.Context) context.Context { diff --git a/cli/util/apiinfo.go b/cli/util/apiinfo.go index 1f9a837697a..41ca18c6104 100644 --- a/cli/util/apiinfo.go +++ b/cli/util/apiinfo.go @@ -36,7 +36,7 @@ func ParseApiInfo(s string) APIInfo { } } -func (a APIInfo) DialArgs() (string, error) { +func (a APIInfo) DialArgs(version string) (string, error) { ma, err := multiaddr.NewMultiaddr(a.Addr) if err == nil { _, addr, err := manet.DialArgs(ma) @@ -44,14 +44,14 @@ func (a APIInfo) DialArgs() (string, error) { return "", err } - return "ws://" + addr + "/rpc/v0", nil + return "ws://" + addr + "/rpc/" + version, nil } _, err = url.Parse(a.Addr) if err != nil { return "", err } - return a.Addr + "/rpc/v0", nil + return a.Addr + "/rpc/" + version, nil } func (a APIInfo) Host() (string, error) { diff --git a/cmd/chain-noise/main.go b/cmd/chain-noise/main.go index 37d623ce2af..8106ce592b2 100644 --- a/cmd/chain-noise/main.go +++ b/cmd/chain-noise/main.go @@ -8,7 +8,7 @@ import ( "time" "github.com/filecoin-project/go-address" - "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" @@ -72,7 +72,7 @@ var runCmd = &cli.Command{ }, } -func sendSmallFundsTxs(ctx context.Context, api api.FullNode, from address.Address, rate, limit int) error { +func sendSmallFundsTxs(ctx context.Context, api v0api.FullNode, from address.Address, rate, limit int) error { var sendSet []address.Address for i := 0; i < 20; i++ { naddr, err := api.WalletNew(ctx, types.KTSecp256k1) diff --git a/cmd/lotus-chainwatch/processor/miner.go b/cmd/lotus-chainwatch/processor/miner.go index 5f2ef55dd19..f3514df88ce 100644 --- a/cmd/lotus-chainwatch/processor/miner.go +++ b/cmd/lotus-chainwatch/processor/miner.go @@ -14,7 +14,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" - "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" "github.com/filecoin-project/lotus/chain/actors/builtin/power" @@ -1026,7 +1026,7 @@ func (p *Processor) storeMinersPower(miners []minerActorInfo) error { } // load the power actor state clam as an adt.Map at the tipset `ts`. -func getPowerActorState(ctx context.Context, api api.FullNode, ts types.TipSetKey) (power.State, error) { +func getPowerActorState(ctx context.Context, api v0api.FullNode, ts types.TipSetKey) (power.State, error) { powerActor, err := api.StateGetActor(ctx, power.Address, ts) if err != nil { return nil, err diff --git a/cmd/lotus-chainwatch/processor/processor.go b/cmd/lotus-chainwatch/processor/processor.go index 8da6b08cc2b..af5935d4795 100644 --- a/cmd/lotus-chainwatch/processor/processor.go +++ b/cmd/lotus-chainwatch/processor/processor.go @@ -17,7 +17,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" - "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/chain/types" cw_util "github.com/filecoin-project/lotus/cmd/lotus-chainwatch/util" "github.com/filecoin-project/lotus/lib/parmap" @@ -28,7 +28,7 @@ var log = logging.Logger("processor") type Processor struct { db *sql.DB - node api.FullNode + node v0api.FullNode ctxStore *cw_util.APIIpldStore genesisTs *types.TipSet @@ -52,7 +52,7 @@ type actorInfo struct { state string } -func NewProcessor(ctx context.Context, db *sql.DB, node api.FullNode, batch int) *Processor { +func NewProcessor(ctx context.Context, db *sql.DB, node v0api.FullNode, batch int) *Processor { ctxStore := cw_util.NewAPIIpldStore(ctx, node) return &Processor{ db: db, diff --git a/cmd/lotus-chainwatch/run.go b/cmd/lotus-chainwatch/run.go index 64f242755ab..6e47a100d79 100644 --- a/cmd/lotus-chainwatch/run.go +++ b/cmd/lotus-chainwatch/run.go @@ -8,6 +8,8 @@ import ( "os" "strings" + "github.com/filecoin-project/lotus/api/v0api" + _ "github.com/lib/pq" "github.com/filecoin-project/go-jsonrpc" @@ -15,7 +17,6 @@ import ( "github.com/urfave/cli/v2" "golang.org/x/xerrors" - "github.com/filecoin-project/lotus/api" lcli "github.com/filecoin-project/lotus/cli" "github.com/filecoin-project/lotus/cmd/lotus-chainwatch/processor" "github.com/filecoin-project/lotus/cmd/lotus-chainwatch/scheduler" @@ -44,7 +45,7 @@ var runCmd = &cli.Command{ return err } - var api api.FullNode + var api v0api.FullNode var closer jsonrpc.ClientCloser var err error if tokenMaddr := cctx.String("api"); tokenMaddr != "" { diff --git a/cmd/lotus-chainwatch/syncer/sync.go b/cmd/lotus-chainwatch/syncer/sync.go index 37af9cce08c..b5e9c73d6f4 100644 --- a/cmd/lotus-chainwatch/syncer/sync.go +++ b/cmd/lotus-chainwatch/syncer/sync.go @@ -13,7 +13,7 @@ import ( "github.com/ipfs/go-cid" logging "github.com/ipfs/go-log/v2" - "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" ) @@ -26,10 +26,10 @@ type Syncer struct { lookbackLimit uint64 headerLk sync.Mutex - node api.FullNode + node v0api.FullNode } -func NewSyncer(db *sql.DB, node api.FullNode, lookbackLimit uint64) *Syncer { +func NewSyncer(db *sql.DB, node v0api.FullNode, lookbackLimit uint64) *Syncer { return &Syncer{ db: db, node: node, diff --git a/cmd/lotus-chainwatch/util/api.go b/cmd/lotus-chainwatch/util/api.go index cfda833e023..f8f22cbbf67 100644 --- a/cmd/lotus-chainwatch/util/api.go +++ b/cmd/lotus-chainwatch/util/api.go @@ -5,13 +5,13 @@ import ( "net/http" "github.com/filecoin-project/go-jsonrpc" - "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/client" + "github.com/filecoin-project/lotus/api/v0api" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" ) -func GetFullNodeAPIUsingCredentials(ctx context.Context, listenAddr, token string) (api.FullNode, jsonrpc.ClientCloser, error) { +func GetFullNodeAPIUsingCredentials(ctx context.Context, listenAddr, token string) (v0api.FullNode, jsonrpc.ClientCloser, error) { parsedAddr, err := ma.NewMultiaddr(listenAddr) if err != nil { return nil, nil, err @@ -22,7 +22,7 @@ func GetFullNodeAPIUsingCredentials(ctx context.Context, listenAddr, token strin return nil, nil, err } - return client.NewFullNodeRPC(ctx, apiURI(addr), apiHeaders(token)) + return client.NewFullNodeRPCV0(ctx, apiURI(addr), apiHeaders(token)) } func apiURI(addr string) string { return "ws://" + addr + "/rpc/v0" diff --git a/cmd/lotus-chainwatch/util/contextStore.go b/cmd/lotus-chainwatch/util/contextStore.go index bd812581b13..c93f87f9b66 100644 --- a/cmd/lotus-chainwatch/util/contextStore.go +++ b/cmd/lotus-chainwatch/util/contextStore.go @@ -8,7 +8,7 @@ import ( "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" - "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" ) // TODO extract this to a common location in lotus and reuse the code @@ -16,10 +16,10 @@ import ( // APIIpldStore is required for AMT and HAMT access. type APIIpldStore struct { ctx context.Context - api api.FullNode + api v0api.FullNode } -func NewAPIIpldStore(ctx context.Context, api api.FullNode) *APIIpldStore { +func NewAPIIpldStore(ctx context.Context, api v0api.FullNode) *APIIpldStore { return &APIIpldStore{ ctx: ctx, api: api, diff --git a/cmd/lotus-fountain/main.go b/cmd/lotus-fountain/main.go index 79f08aa8392..7ac598d8e9a 100644 --- a/cmd/lotus-fountain/main.go +++ b/cmd/lotus-fountain/main.go @@ -15,7 +15,7 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/go-address" - "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" @@ -143,7 +143,7 @@ func prepFundsHtml(box *rice.Box) http.HandlerFunc { type handler struct { ctx context.Context - api api.FullNode + api v0api.FullNode from address.Address sendPerRequest types.FIL diff --git a/cmd/lotus-gateway/api.go b/cmd/lotus-gateway/api.go index 6799ef62727..003625a84bf 100644 --- a/cmd/lotus-gateway/api.go +++ b/cmd/lotus-gateway/api.go @@ -52,14 +52,13 @@ type gatewayDepsAPI interface { 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) (api.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) StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MarketBalance, error) StateMarketStorageDeal(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*api.MarketDeal, error) StateNetworkVersion(context.Context, types.TipSetKey) (network.Version, error) - StateSearchMsgLimited(ctx context.Context, msg cid.Cid, lookbackLimit abi.ChainEpoch) (*api.MsgLookup, error) - StateWaitMsgLimited(ctx context.Context, msg cid.Cid, confidence uint64, h abi.ChainEpoch) (*api.MsgLookup, error) + StateSearchMsg(ctx context.Context, from types.TipSetKey, msg cid.Cid, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) + StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) StateReadState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*api.ActorState, error) StateMinerPower(context.Context, address.Address, types.TipSetKey) (*api.MinerPower, error) StateMinerFaults(context.Context, address.Address, types.TipSetKey) (bitfield.BitField, error) @@ -72,8 +71,11 @@ type gatewayDepsAPI interface { StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error) StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) StateVMCirculatingSupplyInternal(context.Context, types.TipSetKey) (api.CirculatingSupply, error) + WalletBalance(context.Context, address.Address) (types.BigInt, error) //perm:read } +var _ gatewayDepsAPI = *new(api.FullNode) // gateway depends on latest + type GatewayAPI struct { api gatewayDepsAPI lookbackCap time.Duration @@ -261,14 +263,6 @@ func (a *GatewayAPI) StateGetActor(ctx context.Context, actor address.Address, t return a.api.StateGetActor(ctx, actor, tsk) } -func (a *GatewayAPI) StateGetReceipt(ctx context.Context, c cid.Cid, tsk types.TipSetKey) (*types.MessageReceipt, error) { - if err := a.checkTipsetKey(ctx, tsk); err != nil { - return nil, err - } - - return a.api.StateGetReceipt(ctx, c, tsk) -} - func (a *GatewayAPI) StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) { if err := a.checkTipsetKey(ctx, tsk); err != nil { return nil, err @@ -309,12 +303,29 @@ func (a *GatewayAPI) StateNetworkVersion(ctx context.Context, tsk types.TipSetKe return a.api.StateNetworkVersion(ctx, tsk) } -func (a *GatewayAPI) StateSearchMsg(ctx context.Context, msg cid.Cid) (*api.MsgLookup, error) { - return a.api.StateSearchMsgLimited(ctx, msg, a.stateWaitLookbackLimit) +func (a *GatewayAPI) StateSearchMsg(ctx context.Context, from types.TipSetKey, msg cid.Cid, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) { + if limit == api.LookbackNoLimit { + limit = a.stateWaitLookbackLimit + } + if a.stateWaitLookbackLimit != api.LookbackNoLimit && limit > a.stateWaitLookbackLimit { + limit = a.stateWaitLookbackLimit + } + if err := a.checkTipsetKey(ctx, from); err != nil { + return nil, err + } + + return a.api.StateSearchMsg(ctx, from, msg, limit, allowReplaced) } -func (a *GatewayAPI) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error) { - return a.api.StateWaitMsgLimited(ctx, msg, confidence, a.stateWaitLookbackLimit) +func (a *GatewayAPI) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) { + if limit == api.LookbackNoLimit { + limit = a.stateWaitLookbackLimit + } + if a.stateWaitLookbackLimit != api.LookbackNoLimit && limit > a.stateWaitLookbackLimit { + limit = a.stateWaitLookbackLimit + } + + return a.api.StateWaitMsg(ctx, msg, confidence, limit, allowReplaced) } func (a *GatewayAPI) StateReadState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*api.ActorState, error) { @@ -404,6 +415,10 @@ func (a *GatewayAPI) WalletVerify(ctx context.Context, k address.Address, msg [] return sigs.Verify(sig, k, msg) == nil, nil } +func (a *GatewayAPI) WalletBalance(ctx context.Context, k address.Address) (types.BigInt, error) { + return a.api.WalletBalance(ctx, k) +} + var _ api.Gateway = (*GatewayAPI)(nil) var _ full.ChainModuleAPI = (*GatewayAPI)(nil) var _ full.GasModuleAPI = (*GatewayAPI)(nil) diff --git a/cmd/lotus-gateway/endtoend_test.go b/cmd/lotus-gateway/endtoend_test.go index 8c1901d65b5..3fae221c337 100644 --- a/cmd/lotus-gateway/endtoend_test.go +++ b/cmd/lotus-gateway/endtoend_test.go @@ -18,12 +18,16 @@ import ( "github.com/stretchr/testify/require" "golang.org/x/xerrors" + "github.com/ipfs/go-cid" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-jsonrpc" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/client" "github.com/filecoin-project/lotus/api/test" + "github.com/filecoin-project/lotus/api/v0api" + "github.com/filecoin-project/lotus/api/v1api" "github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/types" @@ -100,10 +104,31 @@ func TestWalletMsig(t *testing.T) { // Create an msig with three of the addresses and threshold of two sigs msigAddrs := walletAddrs[:3] amt := types.NewInt(1000) - addProposal, err := lite.MsigCreate(ctx, 2, msigAddrs, abi.ChainEpoch(50), amt, liteWalletAddr, types.NewInt(0)) + proto, err := lite.MsigCreate(ctx, 2, msigAddrs, abi.ChainEpoch(50), amt, liteWalletAddr, types.NewInt(0)) + require.NoError(t, err) + + doSend := func(proto *api.MessagePrototype) (cid.Cid, error) { + if proto.ValidNonce { + sm, err := lite.WalletSignMessage(ctx, proto.Message.From, &proto.Message) + if err != nil { + return cid.Undef, err + } + + return lite.MpoolPush(ctx, sm) + } + + sm, err := lite.MpoolPushMessage(ctx, &proto.Message, nil) + if err != nil { + return cid.Undef, err + } + + return sm.Cid(), nil + } + + addProposal, err := doSend(proto) require.NoError(t, err) - res, err := lite.StateWaitMsg(ctx, addProposal, 1) + res, err := lite.StateWaitMsg(ctx, addProposal, 1, api.LookbackNoLimit, true) require.NoError(t, err) require.EqualValues(t, 0, res.Receipt.ExitCode) @@ -120,10 +145,13 @@ func TestWalletMsig(t *testing.T) { require.Less(t, msigBalance.Int64(), amt.Int64()) // Propose to add a new address to the msig - addProposal, err = lite.MsigAddPropose(ctx, msig, walletAddrs[0], walletAddrs[3], false) + proto, err = lite.MsigAddPropose(ctx, msig, walletAddrs[0], walletAddrs[3], false) + require.NoError(t, err) + + addProposal, err = doSend(proto) require.NoError(t, err) - res, err = lite.StateWaitMsg(ctx, addProposal, 1) + res, err = lite.StateWaitMsg(ctx, addProposal, 1, api.LookbackNoLimit, true) require.NoError(t, err) require.EqualValues(t, 0, res.Receipt.ExitCode) @@ -134,10 +162,13 @@ func TestWalletMsig(t *testing.T) { // Approve proposal (proposer is first (implicit) signer, approver is // second signer txnID := uint64(proposeReturn.TxnID) - approval1, err := lite.MsigAddApprove(ctx, msig, walletAddrs[1], txnID, walletAddrs[0], walletAddrs[3], false) + proto, err = lite.MsigAddApprove(ctx, msig, walletAddrs[1], txnID, walletAddrs[0], walletAddrs[3], false) + require.NoError(t, err) + + approval1, err := doSend(proto) require.NoError(t, err) - res, err = lite.StateWaitMsg(ctx, approval1, 1) + res, err = lite.StateWaitMsg(ctx, approval1, 1, api.LookbackNoLimit, true) require.NoError(t, err) require.EqualValues(t, 0, res.Receipt.ExitCode) @@ -245,12 +276,15 @@ func startNodes( // Create a gateway server in front of the full node gapiImpl := newGatewayAPI(fullNode, lookbackCap, stateWaitLookbackLimit) - _, addr, err := builder.CreateRPCServer(t, gapiImpl) + _, addr, err := builder.CreateRPCServer(t, map[string]interface{}{ + "/rpc/v1": gapiImpl, + "/rpc/v0": api.Wrap(new(v1api.FullNodeStruct), new(v0api.WrapperV1Full), gapiImpl), + }) require.NoError(t, err) // Create a gateway client API that connects to the gateway server var gapi api.Gateway - gapi, closer, err = client.NewGatewayRPC(ctx, addr, nil) + gapi, closer, err = client.NewGatewayRPCV1(ctx, addr+"/rpc/v1", nil) require.NoError(t, err) // Provide the gateway API to dependency injection @@ -299,7 +333,7 @@ func sendFunds(ctx context.Context, fromNode test.TestNode, fromAddr address.Add return err } - res, err := fromNode.StateWaitMsg(ctx, sm.Cid(), 1) + res, err := fromNode.StateWaitMsg(ctx, sm.Cid(), 3, api.LookbackNoLimit, true) if err != nil { return err } diff --git a/cmd/lotus-gateway/main.go b/cmd/lotus-gateway/main.go index 23b743d7392..e2ef27dd9e2 100644 --- a/cmd/lotus-gateway/main.go +++ b/cmd/lotus-gateway/main.go @@ -11,12 +11,15 @@ import ( promclient "github.com/prometheus/client_golang/prometheus" "go.opencensus.io/tag" + lapi "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" + "github.com/filecoin-project/lotus/api/v1api" "github.com/filecoin-project/lotus/build" lcli "github.com/filecoin-project/lotus/cli" "github.com/filecoin-project/lotus/lib/lotuslog" "github.com/filecoin-project/lotus/metrics" - logging "github.com/ipfs/go-log" + logging "github.com/ipfs/go-log/v2" "go.opencensus.io/stats/view" "github.com/gorilla/mux" @@ -82,7 +85,7 @@ var runCmd = &cli.Command{ log.Fatalf("Cannot register the view: %v", err) } - api, closer, err := lcli.GetFullNodeAPI(cctx) + api, closer, err := lcli.GetFullNodeAPIV1(cctx) if err != nil { return err } @@ -93,14 +96,21 @@ var runCmd = &cli.Command{ log.Info("Setting up API endpoint at " + address) - serverOptions := make([]jsonrpc.ServerOption, 0) - if maxRequestSize := cctx.Int("api-max-req-size"); maxRequestSize != 0 { - serverOptions = append(serverOptions, jsonrpc.WithMaxRequestSize(int64(maxRequestSize))) + serveRpc := func(path string, hnd interface{}) { + serverOptions := make([]jsonrpc.ServerOption, 0) + if maxRequestSize := cctx.Int("api-max-req-size"); maxRequestSize != 0 { + serverOptions = append(serverOptions, jsonrpc.WithMaxRequestSize(int64(maxRequestSize))) + } + rpcServer := jsonrpc.NewServer(serverOptions...) + rpcServer.Register("Filecoin", hnd) + + mux.Handle(path, rpcServer) } - rpcServer := jsonrpc.NewServer(serverOptions...) - rpcServer.Register("Filecoin", metrics.MetricedGatewayAPI(NewGatewayAPI(api))) - mux.Handle("/rpc/v0", rpcServer) + ma := metrics.MetricedGatewayAPI(NewGatewayAPI(api)) + + serveRpc("/rpc/v1", ma) + serveRpc("/rpc/v0", lapi.Wrap(new(v1api.FullNodeStruct), new(v0api.WrapperV1Full), ma)) registry := promclient.DefaultRegisterer.(*promclient.Registry) exporter, err := prometheus.NewExporter(prometheus.Options{ diff --git a/cmd/lotus-health/main.go b/cmd/lotus-health/main.go index e8a32a71946..da90242c888 100644 --- a/cmd/lotus-health/main.go +++ b/cmd/lotus-health/main.go @@ -8,13 +8,14 @@ import ( "syscall" "time" + "github.com/filecoin-project/lotus/api/v0api" + cid "github.com/ipfs/go-cid" - logging "github.com/ipfs/go-log" + logging "github.com/ipfs/go-log/v2" "github.com/urfave/cli/v2" "github.com/filecoin-project/go-jsonrpc" - "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" @@ -180,7 +181,7 @@ func checkWindow(window CidWindow, t int) bool { * returns a slice of slices of Cids * len of slice <= `t` - threshold */ -func updateWindow(ctx context.Context, a api.FullNode, w CidWindow, t int, r int, to time.Duration) (CidWindow, error) { +func updateWindow(ctx context.Context, a v0api.FullNode, w CidWindow, t int, r int, to time.Duration) (CidWindow, error) { head, err := getHead(ctx, a, r, to) if err != nil { return nil, err @@ -194,7 +195,7 @@ func updateWindow(ctx context.Context, a api.FullNode, w CidWindow, t int, r int * retries if API no available * returns tipset */ -func getHead(ctx context.Context, a api.FullNode, r int, t time.Duration) (*types.TipSet, error) { +func getHead(ctx context.Context, a v0api.FullNode, r int, t time.Duration) (*types.TipSet, error) { for i := 0; i < r; i++ { head, err := a.ChainHead(ctx) if err != nil && i == (r-1) { @@ -226,7 +227,7 @@ func appendCIDsToWindow(w CidWindow, c []cid.Cid, t int) CidWindow { /* * wait for node to sync */ -func waitForSyncComplete(ctx context.Context, a api.FullNode, r int, t time.Duration) error { +func waitForSyncComplete(ctx context.Context, a v0api.FullNode, r int, t time.Duration) error { for { select { case <-ctx.Done(): @@ -248,7 +249,7 @@ func waitForSyncComplete(ctx context.Context, a api.FullNode, r int, t time.Dura * A thin wrapper around lotus cli GetFullNodeAPI * Adds retry logic */ -func getFullNodeAPI(ctx *cli.Context, r int, t time.Duration) (api.FullNode, jsonrpc.ClientCloser, error) { +func getFullNodeAPI(ctx *cli.Context, r int, t time.Duration) (v0api.FullNode, jsonrpc.ClientCloser, error) { for i := 0; i < r; i++ { api, closer, err := lcli.GetFullNodeAPI(ctx) if err != nil && i == (r-1) { diff --git a/cmd/lotus-seal-worker/main.go b/cmd/lotus-seal-worker/main.go index 24918e52a39..693b833a539 100644 --- a/cmd/lotus-seal-worker/main.go +++ b/cmd/lotus-seal-worker/main.go @@ -28,7 +28,6 @@ import ( "github.com/filecoin-project/go-statestore" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/api/apistruct" "github.com/filecoin-project/lotus/build" lcli "github.com/filecoin-project/lotus/cli" cliutil "github.com/filecoin-project/lotus/cli/util" @@ -211,8 +210,8 @@ var runCmd = &cli.Command{ if err != nil { return err } - if v.APIVersion != api.MinerAPIVersion { - return xerrors.Errorf("lotus-miner API version doesn't match: expected: %s", api.APIVersion{APIVersion: api.MinerAPIVersion}) + if v.APIVersion != api.MinerAPIVersion0 { + return xerrors.Errorf("lotus-miner API version doesn't match: expected: %s", api.APIVersion{APIVersion: api.MinerAPIVersion0}) } log.Infof("Remote version %s", v) @@ -366,7 +365,7 @@ var runCmd = &cli.Command{ fh := &stores.FetchHandler{Local: localStore} remoteHandler := func(w http.ResponseWriter, r *http.Request) { - if !auth.HasPerm(r.Context(), nil, apistruct.PermAdmin) { + if !auth.HasPerm(r.Context(), nil, api.PermAdmin) { w.WriteHeader(401) _ = json.NewEncoder(w).Encode(struct{ Error string }{"unauthorized: missing admin permission"}) return @@ -394,7 +393,7 @@ var runCmd = &cli.Command{ readerHandler, readerServerOpt := rpcenc.ReaderParamDecoder() rpcServer := jsonrpc.NewServer(readerServerOpt) - rpcServer.Register("Filecoin", apistruct.PermissionedWorkerAPI(metrics.MetricedWorkerAPI(workerApi))) + rpcServer.Register("Filecoin", api.PermissionedWorkerAPI(metrics.MetricedWorkerAPI(workerApi))) mux.Handle("/rpc/v0", rpcServer) mux.Handle("/rpc/streams/v0/push/{uuid}", readerHandler) diff --git a/cmd/lotus-seal-worker/rpc.go b/cmd/lotus-seal-worker/rpc.go index 3649d6c8f9e..6a6263671bd 100644 --- a/cmd/lotus-seal-worker/rpc.go +++ b/cmd/lotus-seal-worker/rpc.go @@ -26,7 +26,7 @@ type worker struct { } func (w *worker) Version(context.Context) (api.Version, error) { - return api.WorkerAPIVersion, nil + return api.WorkerAPIVersion0, nil } func (w *worker) StorageAddLocal(ctx context.Context, path string) error { diff --git a/cmd/lotus-shed/balances.go b/cmd/lotus-shed/balances.go index 8c5bfefb8d6..87530c666ee 100644 --- a/cmd/lotus-shed/balances.go +++ b/cmd/lotus-shed/balances.go @@ -3,13 +3,18 @@ package main import ( "context" "encoding/csv" + "encoding/json" "fmt" "io" "os" + "runtime" "strconv" "strings" + "sync" "time" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/gen/genesis" _init "github.com/filecoin-project/lotus/chain/actors/builtin/init" @@ -64,9 +69,321 @@ var auditsCmd = &cli.Command{ Description: "a collection of utilities for auditing the filecoin chain", Subcommands: []*cli.Command{ chainBalanceCmd, + chainBalanceSanityCheckCmd, chainBalanceStateCmd, chainPledgeCmd, fillBalancesCmd, + duplicatedMessagesCmd, + }, +} + +var duplicatedMessagesCmd = &cli.Command{ + Name: "duplicate-messages", + Usage: "Check for duplicate messages included in a tipset.", + UsageText: `Check for duplicate messages included in a tipset. + +Due to Filecoin's expected consensus, a tipset may include the same message multiple times in +different blocks. The message will only be executed once. + +This command will find such duplicate messages and print them to standard out as newline-delimited +JSON. Status messages in the form of "H: $HEIGHT ($PROGRESS%)" will be printed to standard error for +every day of chain processed. +`, + Flags: []cli.Flag{ + &cli.IntFlag{ + Name: "parallel", + Usage: "the number of parallel threads for block processing", + DefaultText: "half the number of cores", + }, + &cli.IntFlag{ + Name: "start", + Usage: "the first epoch to check", + DefaultText: "genesis", + }, + &cli.IntFlag{ + Name: "end", + Usage: "the last epoch to check", + DefaultText: "the current head", + }, + &cli.IntSliceFlag{ + Name: "method", + Usage: "filter results by method number", + DefaultText: "all methods", + }, + &cli.StringSliceFlag{ + Name: "include-to", + Usage: "include only messages to the given address (does not perform address resolution)", + DefaultText: "all recipients", + }, + &cli.StringSliceFlag{ + Name: "include-from", + Usage: "include only messages from the given address (does not perform address resolution)", + DefaultText: "all senders", + }, + &cli.StringSliceFlag{ + Name: "exclude-to", + Usage: "exclude messages to the given address (does not perform address resolution)", + }, + &cli.StringSliceFlag{ + Name: "exclude-from", + Usage: "exclude messages from the given address (does not perform address resolution)", + }, + }, + Action: func(cctx *cli.Context) error { + api, closer, err := lcli.GetFullNodeAPI(cctx) + if err != nil { + return err + } + + defer closer() + ctx := lcli.ReqContext(cctx) + + var head *types.TipSet + if cctx.IsSet("end") { + epoch := abi.ChainEpoch(cctx.Int("end")) + head, err = api.ChainGetTipSetByHeight(ctx, epoch, types.EmptyTSK) + } else { + head, err = api.ChainHead(ctx) + } + if err != nil { + return err + } + + var printLk sync.Mutex + + threads := runtime.NumCPU() / 2 + if cctx.IsSet("parallel") { + threads = cctx.Int("int") + if threads <= 0 { + return fmt.Errorf("parallelism needs to be at least 1") + } + } else if threads == 0 { + threads = 1 // if we have one core, but who are we kidding... + } + + throttle := make(chan struct{}, threads) + + methods := map[abi.MethodNum]bool{} + for _, m := range cctx.IntSlice("method") { + if m < 0 { + return fmt.Errorf("expected method numbers to be non-negative") + } + methods[abi.MethodNum(m)] = true + } + + addressSet := func(flag string) (map[address.Address]bool, error) { + if !cctx.IsSet(flag) { + return nil, nil + } + addrs := cctx.StringSlice(flag) + set := make(map[address.Address]bool, len(addrs)) + for _, addrStr := range addrs { + addr, err := address.NewFromString(addrStr) + if err != nil { + return nil, fmt.Errorf("failed to parse address %s: %w", addrStr, err) + } + set[addr] = true + } + return set, nil + } + + onlyFrom, err := addressSet("include-from") + if err != nil { + return err + } + onlyTo, err := addressSet("include-to") + if err != nil { + return err + } + excludeFrom, err := addressSet("exclude-from") + if err != nil { + return err + } + excludeTo, err := addressSet("exclude-to") + if err != nil { + return err + } + + target := abi.ChainEpoch(cctx.Int("start")) + if target < 0 || target > head.Height() { + return fmt.Errorf("start height must be greater than 0 and less than the end height") + } + totalEpochs := head.Height() - target + + for target <= head.Height() { + select { + case throttle <- struct{}{}: + case <-ctx.Done(): + return ctx.Err() + } + + go func(ts *types.TipSet) { + defer func() { + <-throttle + }() + + type addrNonce struct { + s address.Address + n uint64 + } + anonce := func(m *types.Message) addrNonce { + return addrNonce{ + s: m.From, + n: m.Nonce, + } + } + + msgs := map[addrNonce]map[cid.Cid]*types.Message{} + + processMessage := func(c cid.Cid, m *types.Message) { + // Filter + if len(methods) > 0 && !methods[m.Method] { + return + } + if len(onlyFrom) > 0 && !onlyFrom[m.From] { + return + } + if len(onlyTo) > 0 && !onlyTo[m.To] { + return + } + if excludeFrom[m.From] || excludeTo[m.To] { + return + } + + // Record + msgSet, ok := msgs[anonce(m)] + if !ok { + msgSet = make(map[cid.Cid]*types.Message, 1) + msgs[anonce(m)] = msgSet + } + msgSet[c] = m + } + + encoder := json.NewEncoder(os.Stdout) + + for _, bh := range ts.Blocks() { + bms, err := api.ChainGetBlockMessages(ctx, bh.Cid()) + if err != nil { + fmt.Fprintln(os.Stderr, "ERROR: ", err) + return + } + + for i, m := range bms.BlsMessages { + processMessage(bms.Cids[i], m) + } + + for i, m := range bms.SecpkMessages { + processMessage(bms.Cids[len(bms.BlsMessages)+i], &m.Message) + } + } + for _, ms := range msgs { + if len(ms) == 1 { + continue + } + type Msg struct { + Cid string + Value string + Method uint64 + } + grouped := map[string][]Msg{} + for c, m := range ms { + addr := m.To.String() + grouped[addr] = append(grouped[addr], Msg{ + Cid: c.String(), + Value: types.FIL(m.Value).String(), + Method: uint64(m.Method), + }) + } + printLk.Lock() + err := encoder.Encode(grouped) + if err != nil { + fmt.Fprintln(os.Stderr, "ERROR: ", err) + } + printLk.Unlock() + } + }(head) + + if head.Parents().IsEmpty() { + break + } + + head, err = api.ChainGetTipSet(ctx, head.Parents()) + if err != nil { + return err + } + + if head.Height()%2880 == 0 { + printLk.Lock() + fmt.Fprintf(os.Stderr, "H: %s (%d%%)\n", head.Height(), (100*(head.Height()-target))/totalEpochs) + printLk.Unlock() + } + } + + for i := 0; i < threads; i++ { + select { + case throttle <- struct{}{}: + case <-ctx.Done(): + return ctx.Err() + } + + } + + printLk.Lock() + fmt.Fprintf(os.Stderr, "H: %s (100%%)\n", head.Height()) + printLk.Unlock() + + return nil + }, +} + +var chainBalanceSanityCheckCmd = &cli.Command{ + Name: "chain-balance-sanity", + Description: "Confirms that the total balance of every actor in state is still 2 billion", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "tipset", + Usage: "specify tipset to start from", + }, + }, + Action: func(cctx *cli.Context) error { + api, closer, err := lcli.GetFullNodeAPI(cctx) + if err != nil { + return err + } + + defer closer() + ctx := lcli.ReqContext(cctx) + + ts, err := lcli.LoadTipSet(ctx, cctx, api) + if err != nil { + return err + } + + tsk := ts.Key() + actors, err := api.StateListActors(ctx, tsk) + if err != nil { + return err + } + + bal := big.Zero() + for _, addr := range actors { + act, err := api.StateGetActor(ctx, addr, tsk) + if err != nil { + return err + } + + bal = big.Add(bal, act.Balance) + } + + attoBase := big.Mul(big.NewInt(int64(build.FilBase)), big.NewInt(int64(build.FilecoinPrecision))) + + if big.Cmp(attoBase, bal) != 0 { + return xerrors.Errorf("sanity check failed (expected %s, actual %s)", attoBase, bal) + } + + fmt.Println("sanity check successful") + + return nil }, } diff --git a/cmd/lotus-shed/consensus.go b/cmd/lotus-shed/consensus.go index c78c9c00f03..2c5df4ea59f 100644 --- a/cmd/lotus-shed/consensus.go +++ b/cmd/lotus-shed/consensus.go @@ -113,12 +113,12 @@ var consensusCheckCmd = &cli.Command{ return err } ainfo := cliutil.APIInfo{Addr: apima.String()} - addr, err := ainfo.DialArgs() + addr, err := ainfo.DialArgs("v1") if err != nil { return err } - api, closer, err := client.NewFullNodeRPC(cctx.Context, addr, nil) + api, closer, err := client.NewFullNodeRPCV1(cctx.Context, addr, nil) if err != nil { return err } diff --git a/cmd/lotus-shed/cron-count.go b/cmd/lotus-shed/cron-count.go new file mode 100644 index 00000000000..79fd6ec42cc --- /dev/null +++ b/cmd/lotus-shed/cron-count.go @@ -0,0 +1,99 @@ +package main + +import ( + "fmt" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/lotus/build" + lcli "github.com/filecoin-project/lotus/cli" + "github.com/urfave/cli/v2" + "golang.org/x/xerrors" +) + +var cronWcCmd = &cli.Command{ + Name: "cron-wc", + Description: "cron stats", + Subcommands: []*cli.Command{ + minerDeadlineCronCountCmd, + }, +} + +var minerDeadlineCronCountCmd = &cli.Command{ + Name: "deadline", + Description: "list all addresses of miners with active deadline crons", + Action: func(c *cli.Context) error { + return countDeadlineCrons(c) + }, + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "tipset", + Usage: "specify tipset state to search on (pass comma separated array of cids)", + }, + }, +} + +func findDeadlineCrons(c *cli.Context) (map[address.Address]struct{}, error) { + api, acloser, err := lcli.GetFullNodeAPI(c) + if err != nil { + return nil, err + } + defer acloser() + ctx := lcli.ReqContext(c) + + ts, err := lcli.LoadTipSet(ctx, c, api) + if err != nil { + return nil, err + } + if ts == nil { + ts, err = api.ChainHead(ctx) + if err != nil { + return nil, err + } + } + + mAddrs, err := api.StateListMiners(ctx, ts.Key()) + if err != nil { + return nil, err + } + activeMiners := make(map[address.Address]struct{}) + for _, mAddr := range mAddrs { + // All miners have active cron before v4. + // v4 upgrade epoch is last epoch running v3 epoch and api.StateReadState reads + // parent state, so v4 state isn't read until upgrade epoch + 2 + if ts.Height() <= build.UpgradeActorsV4Height+1 { + activeMiners[mAddr] = struct{}{} + continue + } + st, err := api.StateReadState(ctx, mAddr, ts.Key()) + if err != nil { + return nil, err + } + minerState, ok := st.State.(map[string]interface{}) + if !ok { + return nil, xerrors.Errorf("internal error: failed to cast miner state to expected map type") + } + + activeDlineIface, ok := minerState["DeadlineCronActive"] + if !ok { + return nil, xerrors.Errorf("miner %s had no deadline state, is this a v3 state root?", mAddr) + } + active := activeDlineIface.(bool) + if active { + activeMiners[mAddr] = struct{}{} + } + } + + return activeMiners, nil +} + +func countDeadlineCrons(c *cli.Context) error { + activeMiners, err := findDeadlineCrons(c) + if err != nil { + return err + } + for addr := range activeMiners { + fmt.Printf("%s\n", addr) + } + + return nil +} diff --git a/cmd/lotus-shed/datastore.go b/cmd/lotus-shed/datastore.go index e77b9a33ac8..c3a9e572ce4 100644 --- a/cmd/lotus-shed/datastore.go +++ b/cmd/lotus-shed/datastore.go @@ -13,7 +13,7 @@ import ( "github.com/docker/go-units" "github.com/ipfs/go-datastore" dsq "github.com/ipfs/go-datastore/query" - logging "github.com/ipfs/go-log" + logging "github.com/ipfs/go-log/v2" "github.com/mitchellh/go-homedir" "github.com/polydawn/refmt/cbor" "github.com/urfave/cli/v2" @@ -181,7 +181,7 @@ var datastoreBackupStatCmd = &cli.Command{ defer f.Close() // nolint:errcheck var keys, logs, kbytes, vbytes uint64 - err = backupds.ReadBackup(f, func(key datastore.Key, value []byte, log bool) error { + clean, err := backupds.ReadBackup(f, func(key datastore.Key, value []byte, log bool) error { if log { logs++ } @@ -194,6 +194,7 @@ var datastoreBackupStatCmd = &cli.Command{ return err } + fmt.Println("Truncated: ", !clean) fmt.Println("Keys: ", keys) fmt.Println("Log values: ", log) fmt.Println("Key bytes: ", units.BytesSize(float64(kbytes))) @@ -229,7 +230,7 @@ var datastoreBackupListCmd = &cli.Command{ defer f.Close() // nolint:errcheck printKv := kvPrinter(cctx.Bool("top-level"), cctx.String("get-enc")) - err = backupds.ReadBackup(f, func(key datastore.Key, value []byte, _ bool) error { + _, err = backupds.ReadBackup(f, func(key datastore.Key, value []byte, _ bool) error { return printKv(key.String(), value) }) if err != nil { diff --git a/cmd/lotus-shed/election.go b/cmd/lotus-shed/election.go index ffe30d16367..c844203d6c9 100644 --- a/cmd/lotus-shed/election.go +++ b/cmd/lotus-shed/election.go @@ -7,30 +7,35 @@ import ( "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" "github.com/urfave/cli/v2" "golang.org/x/xerrors" ) var electionCmd = &cli.Command{ Name: "election", - Usage: "commands related to leader election", + Usage: "Commands related to leader election", Subcommands: []*cli.Command{ electionRunDummy, + electionEstimate, }, } var electionRunDummy = &cli.Command{ Name: "run-dummy", - Usage: "runs dummy elections with given power", + Usage: "Runs dummy elections with given power", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "network-power", + Name: "network-power", + Usage: "network storage power", }, &cli.StringFlag{ - Name: "miner-power", + Name: "miner-power", + Usage: "miner storage power", }, &cli.Uint64Flag{ Name: "seed", + Usage: "rand number", Value: 0, }, }, @@ -42,7 +47,7 @@ var electionRunDummy = &cli.Command{ } networkPow, err := types.BigFromString(cctx.String("network-power")) if err != nil { - return xerrors.Errorf("decoding miner-power: %w", err) + return xerrors.Errorf("decoding network-power: %w", err) } ep := &types.ElectionProof{} @@ -68,3 +73,54 @@ var electionRunDummy = &cli.Command{ } }, } + +var electionEstimate = &cli.Command{ + Name: "estimate", + Usage: "Estimate elections with given power", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "network-power", + Usage: "network storage power", + }, + &cli.StringFlag{ + Name: "miner-power", + Usage: "miner storage power", + }, + &cli.Uint64Flag{ + Name: "seed", + Usage: "rand number", + Value: 0, + }, + }, + Action: func(cctx *cli.Context) error { + minerPow, err := types.BigFromString(cctx.String("miner-power")) + if err != nil { + return xerrors.Errorf("decoding miner-power: %w", err) + } + networkPow, err := types.BigFromString(cctx.String("network-power")) + if err != nil { + return xerrors.Errorf("decoding network-power: %w", err) + } + + ep := &types.ElectionProof{} + ep.VRFProof = make([]byte, 32) + seed := cctx.Uint64("seed") + if seed == 0 { + seed = rand.Uint64() + } + binary.BigEndian.PutUint64(ep.VRFProof, seed) + + winYear := int64(0) + for i := 0; i < builtin2.EpochsInYear; i++ { + binary.BigEndian.PutUint64(ep.VRFProof[8:], uint64(i)) + j := ep.ComputeWinCount(minerPow, networkPow) + winYear += j + } + winHour := winYear * builtin2.EpochsInHour / builtin2.EpochsInYear + winDay := winYear * builtin2.EpochsInDay / builtin2.EpochsInYear + winMonth := winYear * builtin2.EpochsInDay * 30 / builtin2.EpochsInYear + fmt.Println("winInHour, winInDay, winInMonth, winInYear") + fmt.Printf("%d, %d, %d, %d\n", winHour, winDay, winMonth, winYear) + return nil + }, +} diff --git a/cmd/lotus-shed/frozen-miners.go b/cmd/lotus-shed/frozen-miners.go index 6b843f0d6ba..ed09c00c5a9 100644 --- a/cmd/lotus-shed/frozen-miners.go +++ b/cmd/lotus-shed/frozen-miners.go @@ -35,12 +35,6 @@ var frozenMinersCmd = &cli.Command{ if err != nil { return err } - if ts == nil { - ts, err = api.ChainHead(ctx) - if err != nil { - return err - } - } queryEpoch := ts.Height() diff --git a/cmd/lotus-shed/jwt.go b/cmd/lotus-shed/jwt.go index 78abcec76ee..e8853b419b6 100644 --- a/cmd/lotus-shed/jwt.go +++ b/cmd/lotus-shed/jwt.go @@ -15,7 +15,8 @@ import ( "github.com/urfave/cli/v2" "github.com/filecoin-project/go-jsonrpc/auth" - "github.com/filecoin-project/lotus/api/apistruct" + + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/node/modules" ) @@ -98,19 +99,19 @@ var jwtTokenCmd = &cli.Command{ perms := []auth.Permission{} if cctx.Bool("read") { - perms = append(perms, apistruct.PermRead) + perms = append(perms, api.PermRead) } if cctx.Bool("write") { - perms = append(perms, apistruct.PermWrite) + perms = append(perms, api.PermWrite) } if cctx.Bool("sign") { - perms = append(perms, apistruct.PermSign) + perms = append(perms, api.PermSign) } if cctx.Bool("admin") { - perms = append(perms, apistruct.PermAdmin) + perms = append(perms, api.PermAdmin) } p := modules.JwtPayload{ @@ -152,7 +153,7 @@ var jwtNewCmd = &cli.Command{ } p := modules.JwtPayload{ - Allow: apistruct.AllPermissions, + Allow: api.AllPermissions, } token, err := jwt.Sign(&p, jwt.NewHS256(keyInfo.PrivateKey)) diff --git a/cmd/lotus-shed/ledger.go b/cmd/lotus-shed/ledger.go index 8d42b0e55c8..0e9c11742cc 100644 --- a/cmd/lotus-shed/ledger.go +++ b/cmd/lotus-shed/ledger.go @@ -6,13 +6,14 @@ import ( "strconv" "strings" + "github.com/filecoin-project/lotus/api/v0api" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/crypto" "github.com/urfave/cli/v2" ledgerfil "github.com/whyrusleeping/ledger-filecoin-go" - "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/types" ledgerwallet "github.com/filecoin-project/lotus/chain/wallet/ledger" lcli "github.com/filecoin-project/lotus/cli" @@ -42,7 +43,7 @@ var ledgerListAddressesCmd = &cli.Command{ }, }, Action: func(cctx *cli.Context) error { - var api api.FullNode + var api v0api.FullNode if cctx.Bool("print-balances") { a, closer, err := lcli.GetFullNodeAPI(cctx) if err != nil { diff --git a/cmd/lotus-shed/main.go b/cmd/lotus-shed/main.go index da1fcbd9249..da896b4cb40 100644 --- a/cmd/lotus-shed/main.go +++ b/cmd/lotus-shed/main.go @@ -20,6 +20,7 @@ func main() { base32Cmd, base16Cmd, bitFieldCmd, + cronWcCmd, frozenMinersCmd, keyinfoCmd, jwtCmd, @@ -34,6 +35,7 @@ func main() { postFindCmd, proofsCmd, verifRegCmd, + marketCmd, miscCmd, mpoolCmd, genesisVerifyCmd, @@ -55,6 +57,7 @@ func main() { blockmsgidCmd, signaturesCmd, actorCmd, + minerTypesCmd, } app := &cli.App{ diff --git a/cmd/lotus-shed/market.go b/cmd/lotus-shed/market.go new file mode 100644 index 00000000000..e2e322784cb --- /dev/null +++ b/cmd/lotus-shed/market.go @@ -0,0 +1,102 @@ +package main + +import ( + "fmt" + + lcli "github.com/filecoin-project/lotus/cli" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/big" + "github.com/urfave/cli/v2" + "golang.org/x/xerrors" +) + +var marketCmd = &cli.Command{ + Name: "market", + Usage: "Interact with the market actor", + Flags: []cli.Flag{}, + Subcommands: []*cli.Command{ + marketDealFeesCmd, + }, +} + +var marketDealFeesCmd = &cli.Command{ + Name: "get-deal-fees", + Usage: "View the storage fees associated with a particular deal or storage provider", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "provider", + Usage: "provider whose outstanding fees you'd like to calculate", + }, + &cli.IntFlag{ + Name: "dealId", + Usage: "deal whose outstanding fees you'd like to calculate", + }, + }, + Action: func(cctx *cli.Context) error { + api, closer, err := lcli.GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer closer() + + ctx := lcli.ReqContext(cctx) + + ts, err := lcli.LoadTipSet(ctx, cctx, api) + if err != nil { + return err + } + + ht := ts.Height() + + if cctx.IsSet("provider") { + p, err := address.NewFromString(cctx.String("provider")) + if err != nil { + return fmt.Errorf("failed to parse provider: %w", err) + } + + deals, err := api.StateMarketDeals(ctx, ts.Key()) + if err != nil { + return err + } + + ef := big.Zero() + pf := big.Zero() + count := 0 + + for _, deal := range deals { + if deal.Proposal.Provider == p { + e, p := deal.Proposal.GetDealFees(ht) + ef = big.Add(ef, e) + pf = big.Add(pf, p) + count++ + } + } + + fmt.Println("Total deals: ", count) + fmt.Println("Total earned fees: ", ef) + fmt.Println("Total pending fees: ", pf) + fmt.Println("Total fees: ", big.Add(ef, pf)) + + return nil + } + + if dealid := cctx.Int("dealId"); dealid != 0 { + deal, err := api.StateMarketStorageDeal(ctx, abi.DealID(dealid), ts.Key()) + if err != nil { + return err + } + + ef, pf := deal.Proposal.GetDealFees(ht) + + fmt.Println("Earned fees: ", ef) + fmt.Println("Pending fees: ", pf) + fmt.Println("Total fees: ", big.Add(ef, pf)) + + return nil + } + + return xerrors.New("must provide either --provider or --dealId flag") + }, +} diff --git a/cmd/lotus-shed/mempool-stats.go b/cmd/lotus-shed/mempool-stats.go index bc4a801f0eb..597ba03936a 100644 --- a/cmd/lotus-shed/mempool-stats.go +++ b/cmd/lotus-shed/mempool-stats.go @@ -8,7 +8,7 @@ import ( "contrib.go.opencensus.io/exporter/prometheus" "github.com/ipfs/go-cid" - logging "github.com/ipfs/go-log" + logging "github.com/ipfs/go-log/v2" "github.com/urfave/cli/v2" "go.opencensus.io/stats" "go.opencensus.io/stats/view" diff --git a/cmd/lotus-shed/miner-types.go b/cmd/lotus-shed/miner-types.go new file mode 100644 index 00000000000..bee47819501 --- /dev/null +++ b/cmd/lotus-shed/miner-types.go @@ -0,0 +1,123 @@ +package main + +import ( + "context" + "fmt" + "io" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + "github.com/filecoin-project/lotus/chain/state" + "github.com/filecoin-project/lotus/chain/store" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/chain/vm" + "github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper" + "github.com/filecoin-project/lotus/node/repo" + builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" + "github.com/filecoin-project/specs-actors/v4/actors/util/adt" + "github.com/ipfs/go-cid" + cbor "github.com/ipfs/go-ipld-cbor" + "github.com/urfave/cli/v2" + "golang.org/x/xerrors" +) + +var minerTypesCmd = &cli.Command{ + Name: "miner-types", + Usage: "Scrape state to report on how many miners of each WindowPoStProofType exist", Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "repo", + Value: "~/.lotus", + }, + }, + Action: func(cctx *cli.Context) error { + ctx := context.TODO() + + if !cctx.Args().Present() { + return fmt.Errorf("must pass state root") + } + + sroot, err := cid.Decode(cctx.Args().First()) + if err != nil { + return fmt.Errorf("failed to parse input: %w", err) + } + + fsrepo, err := repo.NewFS(cctx.String("repo")) + if err != nil { + return err + } + + lkrepo, err := fsrepo.Lock(repo.FullNode) + if err != nil { + return err + } + + defer lkrepo.Close() //nolint:errcheck + + bs, err := lkrepo.Blockstore(ctx, repo.UniversalBlockstore) + if err != nil { + return fmt.Errorf("failed to open blockstore: %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) + } + } + }() + + mds, err := lkrepo.Datastore(context.Background(), "/metadata") + if err != nil { + return err + } + + cs := store.NewChainStore(bs, bs, mds, vm.Syscalls(ffiwrapper.ProofVerifier), nil) + defer cs.Close() //nolint:errcheck + + cst := cbor.NewCborStore(bs) + store := adt.WrapStore(ctx, cst) + + tree, err := state.LoadStateTree(cst, sroot) + if err != nil { + return err + } + + typeMap := make(map[abi.RegisteredPoStProof]int64) + + err = tree.ForEach(func(addr address.Address, act *types.Actor) error { + if act.Code == builtin4.StorageMinerActorCodeID { + ms, err := miner.Load(store, act) + if err != nil { + return err + } + + mi, err := ms.Info() + if err != nil { + return err + } + + if mi.WindowPoStProofType < abi.RegisteredPoStProof_StackedDrgWindow32GiBV1 { + fmt.Println(addr) + } + + c, f := typeMap[mi.WindowPoStProofType] + if !f { + typeMap[mi.WindowPoStProofType] = 1 + } else { + typeMap[mi.WindowPoStProofType] = c + 1 + } + } + return nil + }) + if err != nil { + return xerrors.Errorf("failed to loop over actors: %w", err) + } + + for k, v := range typeMap { + fmt.Println("Type:", k, " Count: ", v) + } + + return nil + }, +} diff --git a/cmd/lotus-shed/mpool.go b/cmd/lotus-shed/mpool.go index d3660db6958..004bd99a6bd 100644 --- a/cmd/lotus-shed/mpool.go +++ b/cmd/lotus-shed/mpool.go @@ -15,6 +15,7 @@ var mpoolCmd = &cli.Command{ Flags: []cli.Flag{}, Subcommands: []*cli.Command{ minerSelectMsgsCmd, + mpoolClear, }, } @@ -66,3 +67,36 @@ var minerSelectMsgsCmd = &cli.Command{ return nil }, } + +var mpoolClear = &cli.Command{ + Name: "clear", + Usage: "Clear all pending messages from the mpool (USE WITH CARE)", + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "local", + Usage: "also clear local messages", + }, + &cli.BoolFlag{ + Name: "really-do-it", + Usage: "must be specified for the action to take effect", + }, + }, + Action: func(cctx *cli.Context) error { + api, closer, err := lcli.GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer closer() + + really := cctx.Bool("really-do-it") + if !really { + //nolint:golint + return fmt.Errorf("--really-do-it must be specified for this action to have an effect; you have been warned") + } + + local := cctx.Bool("local") + + ctx := lcli.ReqContext(cctx) + return api.MpoolClear(ctx, local) + }, +} diff --git a/cmd/lotus-shed/postfind.go b/cmd/lotus-shed/postfind.go index 83006fd09fb..c8a4c990769 100644 --- a/cmd/lotus-shed/postfind.go +++ b/cmd/lotus-shed/postfind.go @@ -49,12 +49,6 @@ var postFindCmd = &cli.Command{ if err != nil { return err } - if startTs == nil { - startTs, err = api.ChainHead(ctx) - if err != nil { - return err - } - } stopEpoch := startTs.Height() - abi.ChainEpoch(c.Int("lookback")) if verbose { fmt.Printf("Collecting messages between %d and %d\n", startTs.Height(), stopEpoch) diff --git a/cmd/lotus-shed/rpc.go b/cmd/lotus-shed/rpc.go index fe81e5a62b2..81171916e14 100644 --- a/cmd/lotus-shed/rpc.go +++ b/cmd/lotus-shed/rpc.go @@ -28,6 +28,10 @@ var rpcCmd = &cli.Command{ &cli.BoolFlag{ Name: "miner", }, + &cli.StringFlag{ + Name: "version", + Value: "v0", + }, }, Action: func(cctx *cli.Context) error { rt := repo.FullNode @@ -35,7 +39,7 @@ var rpcCmd = &cli.Command{ rt = repo.StorageMiner } - addr, headers, err := lcli.GetRawAPI(cctx, rt) + addr, headers, err := lcli.GetRawAPI(cctx, rt, cctx.String("version")) if err != nil { return err } diff --git a/cmd/lotus-shed/sectors.go b/cmd/lotus-shed/sectors.go index 6cf6ee86ea2..cf40e1152d0 100644 --- a/cmd/lotus-shed/sectors.go +++ b/cmd/lotus-shed/sectors.go @@ -254,7 +254,7 @@ var terminateSectorPenaltyEstimationCmd = &cli.Command{ //TODO: 4667 add an option to give a more precise estimation with pending termination penalty excluded - invocResult, err := nodeApi.StateCall(ctx, msg, types.TipSetKey{}) + invocResult, err := nodeApi.StateCall(ctx, msg, types.EmptyTSK) if err != nil { return xerrors.Errorf("fail to state call: %w", err) } diff --git a/cmd/lotus-shed/signatures.go b/cmd/lotus-shed/signatures.go index 76a4b3bdfe3..d287e0c3f18 100644 --- a/cmd/lotus-shed/signatures.go +++ b/cmd/lotus-shed/signatures.go @@ -5,6 +5,10 @@ import ( "fmt" "strconv" + ffi "github.com/filecoin-project/filecoin-ffi" + lcli "github.com/filecoin-project/lotus/cli" + "github.com/ipfs/go-cid" + "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/lotus/lib/sigs" @@ -18,6 +22,76 @@ var signaturesCmd = &cli.Command{ Usage: "tools involving signatures", Subcommands: []*cli.Command{ sigsVerifyVoteCmd, + sigsVerifyBlsMsgsCmd, + }, +} + +var sigsVerifyBlsMsgsCmd = &cli.Command{ + Name: "verify-bls", + Description: "given a block, verifies the bls signature of the messages in the block", + Usage: "", + Action: func(cctx *cli.Context) error { + if cctx.Args().Len() != 1 { + return xerrors.Errorf("usage: ") + } + + api, closer, err := lcli.GetFullNodeAPI(cctx) + if err != nil { + return err + } + + defer closer() + ctx := lcli.ReqContext(cctx) + + bc, err := cid.Decode(cctx.Args().First()) + if err != nil { + return err + } + + b, err := api.ChainGetBlock(ctx, bc) + if err != nil { + return err + } + + ms, err := api.ChainGetBlockMessages(ctx, bc) + if err != nil { + return err + } + + var sigCids []cid.Cid // this is what we get for people not wanting the marshalcbor method on the cid type + var pubks [][]byte + + for _, m := range ms.BlsMessages { + sigCids = append(sigCids, m.Cid()) + + if m.From.Protocol() != address.BLS { + return xerrors.Errorf("address must be BLS address") + } + + pubks = append(pubks, m.From.Payload()) + } + + msgsS := make([]ffi.Message, len(sigCids)) + pubksS := make([]ffi.PublicKey, len(sigCids)) + for i := 0; i < len(sigCids); i++ { + msgsS[i] = sigCids[i].Bytes() + copy(pubksS[i][:], pubks[i][:ffi.PublicKeyBytes]) + } + + sigS := new(ffi.Signature) + copy(sigS[:], b.BLSAggregate.Data[:ffi.SignatureBytes]) + + if len(sigCids) == 0 { + return nil + } + + valid := ffi.HashVerify(sigS, msgsS, pubksS) + if !valid { + return xerrors.New("bls aggregate signature failed to verify") + } + + fmt.Println("BLS siggys valid!") + return nil }, } diff --git a/cmd/lotus-shed/stateroot-stats.go b/cmd/lotus-shed/stateroot-stats.go index 023f782bdd1..6d5d577089f 100644 --- a/cmd/lotus-shed/stateroot-stats.go +++ b/cmd/lotus-shed/stateroot-stats.go @@ -56,13 +56,6 @@ var staterootDiffsCmd = &cli.Command{ return err } - if ts == nil { - ts, err = api.ChainHead(ctx) - if err != nil { - return err - } - } - fn := func(ts *types.TipSet) (cid.Cid, []cid.Cid) { blk := ts.Blocks()[0] strt := blk.ParentStateRoot @@ -134,13 +127,6 @@ var staterootStatCmd = &cli.Command{ return err } - if ts == nil { - ts, err = api.ChainHead(ctx) - if err != nil { - return err - } - } - var addrs []address.Address for _, inp := range cctx.Args().Slice() { diff --git a/cmd/lotus-shed/verifreg.go b/cmd/lotus-shed/verifreg.go index 426827ad265..52e1aa1d627 100644 --- a/cmd/lotus-shed/verifreg.go +++ b/cmd/lotus-shed/verifreg.go @@ -67,11 +67,13 @@ var verifRegAddVerifierCmd = &cli.Command{ return err } - api, closer, err := lcli.GetFullNodeAPI(cctx) + srv, err := lcli.GetFullNodeServices(cctx) if err != nil { return err } - defer closer() + defer srv.Close() //nolint:errcheck + + api := srv.FullNodeAPI() ctx := lcli.ReqContext(cctx) vrk, err := api.StateVerifiedRegistryRootKey(ctx, types.EmptyTSK) @@ -79,14 +81,21 @@ var verifRegAddVerifierCmd = &cli.Command{ return err } - smsg, err := api.MsigPropose(ctx, vrk, verifreg.Address, big.Zero(), sender, uint64(verifreg.Methods.AddVerifier), params) + proto, err := api.MsigPropose(ctx, vrk, verifreg.Address, big.Zero(), sender, uint64(verifreg.Methods.AddVerifier), params) + if err != nil { + return err + } + + sm, _, err := srv.PublishMessage(ctx, proto, false) if err != nil { return err } - fmt.Printf("message sent, now waiting on cid: %s\n", smsg) + msgCid := sm.Cid() + + fmt.Printf("message sent, now waiting on cid: %s\n", msgCid) - mwait, err := api.StateWaitMsg(ctx, smsg, build.MessageConfidence) + mwait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")), build.Finality, true) if err != nil { return err } diff --git a/cmd/lotus-storage-miner/actor.go b/cmd/lotus-storage-miner/actor.go index 8c2ab95bd71..7e428d0e4af 100644 --- a/cmd/lotus-storage-miner/actor.go +++ b/cmd/lotus-storage-miner/actor.go @@ -53,8 +53,22 @@ var actorSetAddrsCmd = &cli.Command{ Usage: "set gas limit", Value: 0, }, + &cli.BoolFlag{ + Name: "unset", + Usage: "unset address", + Value: false, + }, }, Action: func(cctx *cli.Context) error { + args := cctx.Args().Slice() + unset := cctx.Bool("unset") + if len(args) == 0 && !unset { + return cli.ShowSubcommandHelp(cctx) + } + if len(args) > 0 && unset { + return fmt.Errorf("unset can only be used with no arguments") + } + nodeAPI, closer, err := lcli.GetStorageMinerAPI(cctx) if err != nil { return err @@ -70,7 +84,7 @@ var actorSetAddrsCmd = &cli.Command{ ctx := lcli.ReqContext(cctx) var addrs []abi.Multiaddrs - for _, a := range cctx.Args().Slice() { + for _, a := range args { maddr, err := ma.NewMultiaddr(a) if err != nil { return fmt.Errorf("failed to parse %q as a multiaddr: %w", a, err) diff --git a/cmd/lotus-storage-miner/actor_test.go b/cmd/lotus-storage-miner/actor_test.go index 02b41202cb1..5bc82d842c2 100644 --- a/cmd/lotus-storage-miner/actor_test.go +++ b/cmd/lotus-storage-miner/actor_test.go @@ -51,7 +51,7 @@ func TestWorkerKeyChange(t *testing.T) { blocktime := 1 * time.Millisecond - n, sn := builder.MockSbBuilder(t, []test.FullNodeOpts{test.FullNodeWithActorsV3At(2), test.FullNodeWithActorsV3At(2)}, test.OneMiner) + n, sn := builder.MockSbBuilder(t, []test.FullNodeOpts{test.FullNodeWithLatestActorsAt(-1), test.FullNodeWithLatestActorsAt(-1)}, test.OneMiner) client1 := n[0] client2 := n[1] diff --git a/cmd/lotus-storage-miner/info.go b/cmd/lotus-storage-miner/info.go index cf39e5516da..7650de03582 100644 --- a/cmd/lotus-storage-miner/info.go +++ b/cmd/lotus-storage-miner/info.go @@ -90,7 +90,7 @@ func infoCmdAct(cctx *cli.Context) error { fmt.Println() - maddr, err := getActorAddress(ctx, nodeApi, cctx.String("actor")) + maddr, err := getActorAddress(ctx, cctx) if err != nil { return err } diff --git a/cmd/lotus-storage-miner/init.go b/cmd/lotus-storage-miner/init.go index 2e38dcc06ca..a02520116ce 100644 --- a/cmd/lotus-storage-miner/init.go +++ b/cmd/lotus-storage-miner/init.go @@ -37,6 +37,8 @@ import ( power2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/power" lapi "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" + "github.com/filecoin-project/lotus/api/v1api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" @@ -149,7 +151,11 @@ var initCmd = &cli.Command{ log.Info("Trying to connect to full node RPC") - api, closer, err := lcli.GetFullNodeAPI(cctx) // TODO: consider storing full node address in config + if err := checkV1ApiSupport(ctx, cctx); err != nil { + return err + } + + api, closer, err := lcli.GetFullNodeAPIV1(cctx) // TODO: consider storing full node address in config if err != nil { return err } @@ -158,7 +164,7 @@ var initCmd = &cli.Command{ log.Info("Checking full node sync status") if !cctx.Bool("genesis-miner") && !cctx.Bool("nosync") { - if err := lcli.SyncWait(ctx, api, false); err != nil { + if err := lcli.SyncWait(ctx, &v0api.WrapperV1Full{FullNode: api}, false); err != nil { return xerrors.Errorf("sync wait: %w", err) } } @@ -186,8 +192,8 @@ var initCmd = &cli.Command{ return err } - if !v.APIVersion.EqMajorMinor(lapi.FullAPIVersion) { - return xerrors.Errorf("Remote API version didn't match (expected %s, remote %s)", lapi.FullAPIVersion, v.APIVersion) + if !v.APIVersion.EqMajorMinor(lapi.FullAPIVersion1) { + return xerrors.Errorf("Remote API version didn't match (expected %s, remote %s)", lapi.FullAPIVersion1, v.APIVersion) } log.Info("Initializing repo") @@ -269,7 +275,7 @@ var initCmd = &cli.Command{ }, } -func migratePreSealMeta(ctx context.Context, api lapi.FullNode, metadata string, maddr address.Address, mds dtypes.MetadataDS) error { +func migratePreSealMeta(ctx context.Context, api v1api.FullNode, metadata string, maddr address.Address, mds dtypes.MetadataDS) error { metadata, err := homedir.Expand(metadata) if err != nil { return xerrors.Errorf("expanding preseal dir: %w", err) @@ -379,7 +385,7 @@ func migratePreSealMeta(ctx context.Context, api lapi.FullNode, metadata string, return mds.Put(datastore.NewKey(modules.StorageCounterDSPrefix), buf[:size]) } -func findMarketDealID(ctx context.Context, api lapi.FullNode, deal market2.DealProposal) (abi.DealID, error) { +func findMarketDealID(ctx context.Context, api v1api.FullNode, deal market2.DealProposal) (abi.DealID, error) { // TODO: find a better way // (this is only used by genesis miners) @@ -398,7 +404,7 @@ func findMarketDealID(ctx context.Context, api lapi.FullNode, deal market2.DealP return 0, xerrors.New("deal not found") } -func storageMinerInit(ctx context.Context, cctx *cli.Context, api lapi.FullNode, r repo.Repo, ssize abi.SectorSize, gasPrice types.BigInt) error { +func storageMinerInit(ctx context.Context, cctx *cli.Context, api v1api.FullNode, r repo.Repo, ssize abi.SectorSize, gasPrice types.BigInt) error { lr, err := r.Lock(repo.StorageMiner) if err != nil { return err @@ -562,7 +568,7 @@ func makeHostKey(lr repo.LockedRepo) (crypto.PrivKey, error) { return pk, nil } -func configureStorageMiner(ctx context.Context, api lapi.FullNode, addr address.Address, peerid peer.ID, gasPrice types.BigInt) error { +func configureStorageMiner(ctx context.Context, api v1api.FullNode, addr address.Address, peerid peer.ID, gasPrice types.BigInt) error { mi, err := api.StateMinerInfo(ctx, addr, types.EmptyTSK) if err != nil { return xerrors.Errorf("getWorkerAddr returned bad address: %w", err) @@ -588,7 +594,7 @@ func configureStorageMiner(ctx context.Context, api lapi.FullNode, addr address. } log.Info("Waiting for message: ", smsg.Cid()) - ret, err := api.StateWaitMsg(ctx, smsg.Cid(), build.MessageConfidence) + ret, err := api.StateWaitMsg(ctx, smsg.Cid(), build.MessageConfidence, lapi.LookbackNoLimit, true) if err != nil { return err } @@ -600,7 +606,7 @@ func configureStorageMiner(ctx context.Context, api lapi.FullNode, addr address. return nil } -func createStorageMiner(ctx context.Context, api lapi.FullNode, peerid peer.ID, gasPrice types.BigInt, cctx *cli.Context) (address.Address, error) { +func createStorageMiner(ctx context.Context, api v1api.FullNode, peerid peer.ID, gasPrice types.BigInt, cctx *cli.Context) (address.Address, error) { var err error var owner address.Address if cctx.String("owner") != "" { @@ -642,7 +648,7 @@ func createStorageMiner(ctx context.Context, api lapi.FullNode, peerid peer.ID, log.Infof("Initializing worker account %s, message: %s", worker, signed.Cid()) log.Infof("Waiting for confirmation") - mw, err := api.StateWaitMsg(ctx, signed.Cid(), build.MessageConfidence) + mw, err := api.StateWaitMsg(ctx, signed.Cid(), build.MessageConfidence, lapi.LookbackNoLimit, true) if err != nil { return address.Undef, xerrors.Errorf("waiting for worker init: %w", err) } @@ -700,7 +706,7 @@ func createStorageMiner(ctx context.Context, api lapi.FullNode, peerid peer.ID, log.Infof("Pushed CreateMiner message: %s", signed.Cid()) log.Infof("Waiting for confirmation") - mw, err := api.StateWaitMsg(ctx, signed.Cid(), build.MessageConfidence) + mw, err := api.StateWaitMsg(ctx, signed.Cid(), build.MessageConfidence, lapi.LookbackNoLimit, true) if err != nil { return address.Undef, xerrors.Errorf("waiting for createMiner message: %w", err) } @@ -717,3 +723,24 @@ func createStorageMiner(ctx context.Context, api lapi.FullNode, peerid peer.ID, log.Infof("New miners address is: %s (%s)", retval.IDAddress, retval.RobustAddress) return retval.IDAddress, nil } + +func checkV1ApiSupport(ctx context.Context, cctx *cli.Context) error { + // check v0 api version to make sure it supports v1 api + api0, closer, err := lcli.GetFullNodeAPI(cctx) + if err != nil { + return err + } + + v, err := api0.Version(ctx) + closer() + + if err != nil { + return err + } + + if !v.APIVersion.EqMajorMinor(lapi.FullAPIVersion0) { + return xerrors.Errorf("Remote API version didn't match (expected %s, remote %s)", lapi.FullAPIVersion0, v.APIVersion) + } + + return nil +} diff --git a/cmd/lotus-storage-miner/init_restore.go b/cmd/lotus-storage-miner/init_restore.go index 12358e63a75..eec7b841389 100644 --- a/cmd/lotus-storage-miner/init_restore.go +++ b/cmd/lotus-storage-miner/init_restore.go @@ -6,6 +6,8 @@ import ( "io/ioutil" "os" + "github.com/filecoin-project/lotus/api/v0api" + "github.com/docker/go-units" "github.com/ipfs/go-datastore" "github.com/libp2p/go-libp2p-core/peer" @@ -52,9 +54,15 @@ var initRestoreCmd = &cli.Command{ return xerrors.Errorf("expected 1 argument") } + ctx := lcli.ReqContext(cctx) + log.Info("Trying to connect to full node RPC") - api, closer, err := lcli.GetFullNodeAPI(cctx) // TODO: consider storing full node address in config + if err := checkV1ApiSupport(ctx, cctx); err != nil { + return err + } + + api, closer, err := lcli.GetFullNodeAPIV1(cctx) // TODO: consider storing full node address in config if err != nil { return err } @@ -62,19 +70,17 @@ var initRestoreCmd = &cli.Command{ log.Info("Checking full node version") - ctx := lcli.ReqContext(cctx) - v, err := api.Version(ctx) if err != nil { return err } - if !v.APIVersion.EqMajorMinor(lapi.FullAPIVersion) { - return xerrors.Errorf("Remote API version didn't match (expected %s, remote %s)", lapi.FullAPIVersion, v.APIVersion) + if !v.APIVersion.EqMajorMinor(lapi.FullAPIVersion1) { + return xerrors.Errorf("Remote API version didn't match (expected %s, remote %s)", lapi.FullAPIVersion1, v.APIVersion) } if !cctx.Bool("nosync") { - if err := lcli.SyncWait(ctx, api, false); err != nil { + if err := lcli.SyncWait(ctx, &v0api.WrapperV1Full{FullNode: api}, false); err != nil { return xerrors.Errorf("sync wait: %w", err) } } diff --git a/cmd/lotus-storage-miner/main.go b/cmd/lotus-storage-miner/main.go index 84654d7899b..f5ff2517772 100644 --- a/cmd/lotus-storage-miner/main.go +++ b/cmd/lotus-storage-miner/main.go @@ -106,15 +106,21 @@ func main() { lcli.RunApp(app) } -func getActorAddress(ctx context.Context, nodeAPI api.StorageMiner, overrideMaddr string) (maddr address.Address, err error) { - if overrideMaddr != "" { - maddr, err = address.NewFromString(overrideMaddr) +func getActorAddress(ctx context.Context, cctx *cli.Context) (maddr address.Address, err error) { + if cctx.IsSet("actor") { + maddr, err = address.NewFromString(cctx.String("actor")) if err != nil { return maddr, err } return } + nodeAPI, closer, err := lcli.GetStorageMinerAPI(cctx) + if err != nil { + return address.Undef, err + } + defer closer() + maddr, err = nodeAPI.ActorAddress(ctx) if err != nil { return maddr, xerrors.Errorf("getting actor address: %w", err) diff --git a/cmd/lotus-storage-miner/proving.go b/cmd/lotus-storage-miner/proving.go index f6bc74318e8..66007b63dc1 100644 --- a/cmd/lotus-storage-miner/proving.go +++ b/cmd/lotus-storage-miner/proving.go @@ -38,12 +38,6 @@ var provingFaultsCmd = &cli.Command{ Action: func(cctx *cli.Context) error { color.NoColor = !cctx.Bool("color") - nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx) - if err != nil { - return err - } - defer closer() - api, acloser, err := lcli.GetFullNodeAPI(cctx) if err != nil { return err @@ -54,7 +48,7 @@ var provingFaultsCmd = &cli.Command{ stor := store.ActorStore(ctx, blockstore.NewAPIBlockstore(api)) - maddr, err := getActorAddress(ctx, nodeApi, cctx.String("actor")) + maddr, err := getActorAddress(ctx, cctx) if err != nil { return err } @@ -98,12 +92,6 @@ var provingInfoCmd = &cli.Command{ Action: func(cctx *cli.Context) error { color.NoColor = !cctx.Bool("color") - nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx) - if err != nil { - return err - } - defer closer() - api, acloser, err := lcli.GetFullNodeAPI(cctx) if err != nil { return err @@ -112,7 +100,7 @@ var provingInfoCmd = &cli.Command{ ctx := lcli.ReqContext(cctx) - maddr, err := getActorAddress(ctx, nodeApi, cctx.String("actor")) + maddr, err := getActorAddress(ctx, cctx) if err != nil { return err } @@ -211,12 +199,6 @@ var provingDeadlinesCmd = &cli.Command{ Action: func(cctx *cli.Context) error { color.NoColor = !cctx.Bool("color") - nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx) - if err != nil { - return err - } - defer closer() - api, acloser, err := lcli.GetFullNodeAPI(cctx) if err != nil { return err @@ -225,7 +207,7 @@ var provingDeadlinesCmd = &cli.Command{ ctx := lcli.ReqContext(cctx) - maddr, err := getActorAddress(ctx, nodeApi, cctx.String("actor")) + maddr, err := getActorAddress(ctx, cctx) if err != nil { return err } @@ -301,12 +283,6 @@ var provingDeadlineInfoCmd = &cli.Command{ return xerrors.Errorf("could not parse deadline index: %w", err) } - nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx) - if err != nil { - return err - } - defer closer() - api, acloser, err := lcli.GetFullNodeAPI(cctx) if err != nil { return err @@ -315,7 +291,7 @@ var provingDeadlineInfoCmd = &cli.Command{ ctx := lcli.ReqContext(cctx) - maddr, err := getActorAddress(ctx, nodeApi, cctx.String("actor")) + maddr, err := getActorAddress(ctx, cctx) if err != nil { return err } diff --git a/cmd/lotus-storage-miner/run.go b/cmd/lotus-storage-miner/run.go index cdcc4d88f59..5d67cf33dfd 100644 --- a/cmd/lotus-storage-miner/run.go +++ b/cmd/lotus-storage-miner/run.go @@ -9,6 +9,10 @@ import ( "os/signal" "syscall" + "github.com/filecoin-project/lotus/api/v1api" + + "github.com/filecoin-project/lotus/api/v0api" + mux "github.com/gorilla/mux" "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" @@ -22,7 +26,6 @@ import ( "github.com/filecoin-project/go-jsonrpc/auth" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/api/apistruct" "github.com/filecoin-project/lotus/build" lcli "github.com/filecoin-project/lotus/cli" "github.com/filecoin-project/lotus/lib/ulimit" @@ -64,19 +67,13 @@ var runCmd = &cli.Command{ } } - nodeApi, ncloser, err := lcli.GetFullNodeAPI(cctx) - if err != nil { - return xerrors.Errorf("getting full node api: %w", err) - } - defer ncloser() - ctx, _ := tag.New(lcli.DaemonContext(cctx), tag.Insert(metrics.Version, build.BuildVersion), tag.Insert(metrics.Commit, build.CurrentCommit), tag.Insert(metrics.NodeType, "miner"), ) // Register all metric views - if err = view.Register( + if err := view.Register( metrics.MinerNodeViews..., ); err != nil { log.Fatalf("Cannot register the view: %v", err) @@ -84,6 +81,16 @@ var runCmd = &cli.Command{ // Set the metric to one so it is published to the exporter stats.Record(ctx, metrics.LotusInfo.M(1)) + if err := checkV1ApiSupport(ctx, cctx); err != nil { + return err + } + + nodeApi, ncloser, err := lcli.GetFullNodeAPIV1(cctx) + if err != nil { + return xerrors.Errorf("getting full node api: %w", err) + } + defer ncloser() + v, err := nodeApi.Version(ctx) if err != nil { return err @@ -95,14 +102,14 @@ var runCmd = &cli.Command{ } } - if v.APIVersion != api.FullAPIVersion { - return xerrors.Errorf("lotus-daemon API version doesn't match: expected: %s", api.APIVersion{APIVersion: api.FullAPIVersion}) + if v.APIVersion != api.FullAPIVersion1 { + return xerrors.Errorf("lotus-daemon API version doesn't match: expected: %s", api.APIVersion{APIVersion: api.FullAPIVersion1}) } log.Info("Checking full node sync status") if !cctx.Bool("nosync") { - if err := lcli.SyncWait(ctx, nodeApi, false); err != nil { + if err := lcli.SyncWait(ctx, &v0api.WrapperV1Full{FullNode: nodeApi}, false); err != nil { return xerrors.Errorf("sync wait: %w", err) } } @@ -134,7 +141,7 @@ var runCmd = &cli.Command{ node.Override(new(dtypes.APIEndpoint), func() (dtypes.APIEndpoint, error) { return multiaddr.NewMultiaddr("/ip4/127.0.0.1/tcp/" + cctx.String("miner-api")) })), - node.Override(new(api.FullNode), nodeApi), + node.Override(new(v1api.FullNode), nodeApi), ) if err != nil { return xerrors.Errorf("creating node: %w", err) @@ -165,7 +172,7 @@ var runCmd = &cli.Command{ mux := mux.NewRouter() rpcServer := jsonrpc.NewServer() - rpcServer.Register("Filecoin", apistruct.PermissionedStorMinerAPI(metrics.MetricedStorMinerAPI(minerapi))) + rpcServer.Register("Filecoin", api.PermissionedStorMinerAPI(metrics.MetricedStorMinerAPI(minerapi))) mux.Handle("/rpc/v0", rpcServer) mux.PathPrefix("/remote").HandlerFunc(minerapi.(*impl.StorageMinerAPI).ServeRemote) diff --git a/cmd/lotus-storage-miner/sectors.go b/cmd/lotus-storage-miner/sectors.go index 8f6fd374f42..3791dbf0741 100644 --- a/cmd/lotus-storage-miner/sectors.go +++ b/cmd/lotus-storage-miner/sectors.go @@ -16,7 +16,7 @@ import ( "github.com/filecoin-project/go-bitfield" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" - miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" + miner3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/miner" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors" @@ -422,16 +422,27 @@ var sectorsExtendCmd = &cli.Command{ &cli.Int64Flag{ Name: "new-expiration", Usage: "new expiration epoch", - Required: true, + Required: false, + }, + &cli.BoolFlag{ + Name: "v1-sectors", + Usage: "renews all v1 sectors up to the maximum possible lifetime", + Required: false, + }, + &cli.Int64Flag{ + Name: "tolerance", + Value: 20160, + Usage: "when extending v1 sectors, don't try to extend sectors by fewer than this number of epochs", + Required: false, + }, + &cli.Int64Flag{ + Name: "expiration-cutoff", + Usage: "when extending v1 sectors, skip sectors whose current expiration is more than epochs from now (infinity if unspecified)", + Required: false, }, &cli.StringFlag{}, }, Action: func(cctx *cli.Context) error { - nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx) - if err != nil { - return err - } - defer closer() api, nCloser, err := lcli.GetFullNodeAPI(cctx) if err != nil { @@ -440,49 +451,160 @@ var sectorsExtendCmd = &cli.Command{ defer nCloser() ctx := lcli.ReqContext(cctx) - if !cctx.Args().Present() { - return xerrors.Errorf("must pass at least one sector number") - } - maddr, err := nodeApi.ActorAddress(ctx) + maddr, err := getActorAddress(ctx, cctx) if err != nil { - return xerrors.Errorf("getting miner actor address: %w", err) + return err } - sectors := map[miner.SectorLocation][]uint64{} + var params []miner3.ExtendSectorExpirationParams - for i, s := range cctx.Args().Slice() { - id, err := strconv.ParseUint(s, 10, 64) + if cctx.Bool("v1-sectors") { + + head, err := api.ChainHead(ctx) if err != nil { - return xerrors.Errorf("could not parse sector %d: %w", i, err) + return err } - p, err := api.StateSectorPartition(ctx, maddr, abi.SectorNumber(id), types.EmptyTSK) + nv, err := api.StateNetworkVersion(ctx, types.EmptyTSK) if err != nil { - return xerrors.Errorf("getting sector location for sector %d: %w", id, err) + return err + } + + extensions := map[miner.SectorLocation]map[abi.ChainEpoch][]uint64{} + + // are given durations within tolerance epochs + withinTolerance := func(a, b abi.ChainEpoch) bool { + diff := a - b + if diff < 0 { + diff = b - a + } + + return diff <= abi.ChainEpoch(cctx.Int64("tolerance")) } - if p == nil { - return xerrors.Errorf("sector %d not found in any partition", id) + sis, err := api.StateMinerActiveSectors(ctx, maddr, types.EmptyTSK) + if err != nil { + return xerrors.Errorf("getting miner sector infos: %w", err) } - sectors[*p] = append(sectors[*p], id) - } + for _, si := range sis { + if si.SealProof >= abi.RegisteredSealProof_StackedDrg2KiBV1_1 { + continue + } + + if cctx.IsSet("expiration-cutoff") { + if si.Expiration > (head.Height() + abi.ChainEpoch(cctx.Int64("expiration-cutoff"))) { + continue + } + } + + ml := policy.GetSectorMaxLifetime(si.SealProof, nv) + // if the sector's missing less than "tolerance" of its maximum possible lifetime, don't bother extending it + if withinTolerance(si.Expiration-si.Activation, ml) { + continue + } + + // Set the new expiration to 48 hours less than the theoretical maximum lifetime + newExp := ml - (miner3.WPoStProvingPeriod * 2) + si.Activation + p, err := api.StateSectorPartition(ctx, maddr, si.SectorNumber, types.EmptyTSK) + if err != nil { + return xerrors.Errorf("getting sector location for sector %d: %w", si.SectorNumber, err) + } + + if p == nil { + return xerrors.Errorf("sector %d not found in any partition", si.SectorNumber) + } - params := &miner0.ExtendSectorExpirationParams{} - for l, numbers := range sectors { + es, found := extensions[*p] + if !found { + ne := make(map[abi.ChainEpoch][]uint64) + ne[newExp] = []uint64{uint64(si.SectorNumber)} + extensions[*p] = ne + } else { + added := false + for exp := range es { + if withinTolerance(exp, newExp) { + es[exp] = append(es[exp], uint64(si.SectorNumber)) + added = true + break + } + } - params.Extensions = append(params.Extensions, miner0.ExpirationExtension{ - Deadline: l.Deadline, - Partition: l.Partition, - Sectors: bitfield.NewFromSet(numbers), - NewExpiration: abi.ChainEpoch(cctx.Int64("new-expiration")), - }) + if !added { + es[newExp] = []uint64{uint64(si.SectorNumber)} + } + } + } + + p := miner3.ExtendSectorExpirationParams{} + scount := 0 + + for l, exts := range extensions { + for newExp, numbers := range exts { + scount += len(numbers) + if scount > policy.GetAddressedSectorsMax(nv) || len(p.Extensions) == policy.GetDeclarationsMax(nv) { + params = append(params, p) + p = miner3.ExtendSectorExpirationParams{} + scount = len(numbers) + } + + p.Extensions = append(p.Extensions, miner3.ExpirationExtension{ + Deadline: l.Deadline, + Partition: l.Partition, + Sectors: bitfield.NewFromSet(numbers), + NewExpiration: newExp, + }) + } + } + + // if we have any sectors, then one last append is needed here + if scount != 0 { + params = append(params, p) + } + + } else { + if !cctx.Args().Present() || !cctx.IsSet("new-expiration") { + return xerrors.Errorf("must pass at least one sector number and new expiration") + } + sectors := map[miner.SectorLocation][]uint64{} + + for i, s := range cctx.Args().Slice() { + id, err := strconv.ParseUint(s, 10, 64) + if err != nil { + return xerrors.Errorf("could not parse sector %d: %w", i, err) + } + + p, err := api.StateSectorPartition(ctx, maddr, abi.SectorNumber(id), types.EmptyTSK) + if err != nil { + return xerrors.Errorf("getting sector location for sector %d: %w", id, err) + } + + if p == nil { + return xerrors.Errorf("sector %d not found in any partition", id) + } + + sectors[*p] = append(sectors[*p], id) + } + + p := miner3.ExtendSectorExpirationParams{} + for l, numbers := range sectors { + + // TODO: Dedup with above loop + p.Extensions = append(p.Extensions, miner3.ExpirationExtension{ + Deadline: l.Deadline, + Partition: l.Partition, + Sectors: bitfield.NewFromSet(numbers), + NewExpiration: abi.ChainEpoch(cctx.Int64("new-expiration")), + }) + } + + params = append(params, p) } - sp, err := actors.SerializeParams(params) - if err != nil { - return xerrors.Errorf("serializing params: %w", err) + if len(params) == 0 { + fmt.Println("nothing to extend") + return nil } mi, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK) @@ -490,19 +612,26 @@ var sectorsExtendCmd = &cli.Command{ return xerrors.Errorf("getting miner info: %w", err) } - smsg, err := api.MpoolPushMessage(ctx, &types.Message{ - From: mi.Worker, - To: maddr, - Method: miner.Methods.ExtendSectorExpiration, + for i := range params { + sp, aerr := actors.SerializeParams(¶ms[i]) + if aerr != nil { + return xerrors.Errorf("serializing params: %w", err) + } - Value: big.Zero(), - Params: sp, - }, nil) - if err != nil { - return xerrors.Errorf("mpool push message: %w", err) - } + smsg, err := api.MpoolPushMessage(ctx, &types.Message{ + From: mi.Worker, + To: maddr, + Method: miner.Methods.ExtendSectorExpiration, - fmt.Println(smsg.Cid()) + Value: big.Zero(), + Params: sp, + }, nil) + if err != nil { + return xerrors.Errorf("mpool push message: %w", err) + } + + fmt.Println(smsg.Cid()) + } return nil }, @@ -741,12 +870,6 @@ var sectorsCapacityCollateralCmd = &cli.Command{ }, Action: func(cctx *cli.Context) error { - mApi, mCloser, err := lcli.GetStorageMinerAPI(cctx) - if err != nil { - return err - } - defer mCloser() - nApi, nCloser, err := lcli.GetFullNodeAPI(cctx) if err != nil { return err @@ -755,7 +878,7 @@ var sectorsCapacityCollateralCmd = &cli.Command{ ctx := lcli.ReqContext(cctx) - maddr, err := mApi.ActorAddress(ctx) + maddr, err := getActorAddress(ctx, cctx) if err != nil { return err } diff --git a/cmd/lotus-storage-miner/storage.go b/cmd/lotus-storage-miner/storage.go index 2f42fd530e4..b4ab26ad3e2 100644 --- a/cmd/lotus-storage-miner/storage.go +++ b/cmd/lotus-storage-miner/storage.go @@ -12,6 +12,8 @@ import ( "strings" "time" + "github.com/filecoin-project/lotus/api/v0api" + "github.com/docker/go-units" "github.com/fatih/color" "github.com/google/uuid" @@ -668,7 +670,7 @@ var storageCleanupCmd = &cli.Command{ }, } -func cleanupRemovedSectorData(ctx context.Context, api api.StorageMiner, napi api.FullNode) error { +func cleanupRemovedSectorData(ctx context.Context, api api.StorageMiner, napi v0api.FullNode) error { sectors, err := api.SectorsList(ctx) if err != nil { return err diff --git a/cmd/lotus-wallet/interactive.go b/cmd/lotus-wallet/interactive.go index 91c181e6530..e1ad2cbb292 100644 --- a/cmd/lotus-wallet/interactive.go +++ b/cmd/lotus-wallet/interactive.go @@ -20,6 +20,7 @@ import ( "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/builtin/multisig" "github.com/filecoin-project/lotus/chain/stmgr" @@ -30,8 +31,8 @@ import ( type InteractiveWallet struct { lk sync.Mutex - apiGetter func() (api.FullNode, jsonrpc.ClientCloser, error) - under api.Wallet + apiGetter func() (v0api.FullNode, jsonrpc.ClientCloser, error) + under v0api.Wallet } func (c *InteractiveWallet) WalletNew(ctx context.Context, typ types.KeyType) (address.Address, error) { diff --git a/cmd/lotus-wallet/main.go b/cmd/lotus-wallet/main.go index 271ed198ec3..2c86c6180fa 100644 --- a/cmd/lotus-wallet/main.go +++ b/cmd/lotus-wallet/main.go @@ -6,6 +6,8 @@ import ( "net/http" "os" + "github.com/filecoin-project/lotus/api/v0api" + "github.com/gorilla/mux" logging "github.com/ipfs/go-log/v2" "github.com/urfave/cli/v2" @@ -149,10 +151,10 @@ var runCmd = &cli.Command{ log.Info("Setting up API endpoint at " + address) if cctx.Bool("interactive") { - var ag func() (api.FullNode, jsonrpc.ClientCloser, error) + var ag func() (v0api.FullNode, jsonrpc.ClientCloser, error) if !cctx.Bool("offline") { - ag = func() (api.FullNode, jsonrpc.ClientCloser, error) { + ag = func() (v0api.FullNode, jsonrpc.ClientCloser, error) { return lcli.GetFullNodeAPI(cctx) } } diff --git a/cmd/lotus/main.go b/cmd/lotus/main.go index af9c567357e..c1dab8e940e 100644 --- a/cmd/lotus/main.go +++ b/cmd/lotus/main.go @@ -2,7 +2,9 @@ package main import ( "context" + "os" + "github.com/mattn/go-isatty" "github.com/urfave/cli/v2" "go.opencensus.io/trace" @@ -52,6 +54,8 @@ func main() { ctx, span := trace.StartSpan(context.Background(), "/cli") defer span.End() + interactiveDef := isatty.IsTerminal(os.Stdout.Fd()) || isatty.IsCygwinTerminal(os.Stdout.Fd()) + app := &cli.App{ Name: "lotus", Usage: "Filecoin decentralized storage network client", @@ -64,10 +68,20 @@ func main() { Hidden: true, Value: "~/.lotus", // TODO: Consider XDG_DATA_HOME }, + &cli.BoolFlag{ + Name: "interactive", + Usage: "setting to false will disable interactive functionality of commands", + Value: interactiveDef, + }, + &cli.BoolFlag{ + Name: "force-send", + Usage: "if true, will ignore pre-send checks", + }, }, Commands: append(local, lcli.Commands...), } + app.Setup() app.Metadata["traceContext"] = ctx app.Metadata["repoType"] = repo.FullNode diff --git a/cmd/lotus/rpc.go b/cmd/lotus/rpc.go index abadfd20c8f..95050d63936 100644 --- a/cmd/lotus/rpc.go +++ b/cmd/lotus/rpc.go @@ -22,7 +22,8 @@ import ( "github.com/filecoin-project/go-jsonrpc/auth" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/api/apistruct" + "github.com/filecoin-project/lotus/api/v0api" + "github.com/filecoin-project/lotus/api/v1api" "github.com/filecoin-project/lotus/metrics" "github.com/filecoin-project/lotus/node" "github.com/filecoin-project/lotus/node/impl" @@ -30,21 +31,27 @@ import ( var log = logging.Logger("main") -func serveRPC(a api.FullNode, stop node.StopFunc, addr multiaddr.Multiaddr, shutdownCh <-chan struct{}, maxRequestSize int64) error { +func serveRPC(a v1api.FullNode, stop node.StopFunc, addr multiaddr.Multiaddr, shutdownCh <-chan struct{}, maxRequestSize int64) error { serverOptions := make([]jsonrpc.ServerOption, 0) if maxRequestSize != 0 { // config set serverOptions = append(serverOptions, jsonrpc.WithMaxRequestSize(maxRequestSize)) } - rpcServer := jsonrpc.NewServer(serverOptions...) - rpcServer.Register("Filecoin", apistruct.PermissionedFullAPI(metrics.MetricedFullAPI(a))) - rpcServer.AliasMethod("rpc.discover", "Filecoin.Discover") + serveRpc := func(path string, hnd interface{}) { + rpcServer := jsonrpc.NewServer(serverOptions...) + rpcServer.Register("Filecoin", hnd) - ah := &auth.Handler{ - Verify: a.AuthVerify, - Next: rpcServer.ServeHTTP, + ah := &auth.Handler{ + Verify: a.AuthVerify, + Next: rpcServer.ServeHTTP, + } + + http.Handle(path, ah) } - http.Handle("/rpc/v0", ah) + pma := api.PermissionedFullAPI(metrics.MetricedFullAPI(a)) + + serveRpc("/rpc/v1", pma) + serveRpc("/rpc/v0", &v0api.WrapperV1Full{FullNode: pma}) importAH := &auth.Handler{ Verify: a.AuthVerify, @@ -109,7 +116,7 @@ func handleImport(a *impl.FullNodeAPI) func(w http.ResponseWriter, r *http.Reque w.WriteHeader(404) return } - if !auth.HasPerm(r.Context(), nil, apistruct.PermWrite) { + if !auth.HasPerm(r.Context(), nil, api.PermWrite) { w.WriteHeader(401) _ = json.NewEncoder(w).Encode(struct{ Error string }{"unauthorized: missing write permission"}) return diff --git a/cmd/tvx/extract_message.go b/cmd/tvx/extract_message.go index 0c2fcff4a88..8e993cbd369 100644 --- a/cmd/tvx/extract_message.go +++ b/cmd/tvx/extract_message.go @@ -8,6 +8,8 @@ import ( "io" "log" + "github.com/filecoin-project/lotus/api/v0api" + "github.com/fatih/color" "github.com/filecoin-project/go-address" @@ -318,7 +320,7 @@ func doExtractMessage(opts extractOpts) error { // resolveFromChain queries the chain for the provided message, using the block CID to // speed up the query, if provided -func resolveFromChain(ctx context.Context, api api.FullNode, mcid cid.Cid, block string) (msg *types.Message, execTs *types.TipSet, incTs *types.TipSet, err error) { +func resolveFromChain(ctx context.Context, api v0api.FullNode, mcid cid.Cid, block string) (msg *types.Message, execTs *types.TipSet, incTs *types.TipSet, err error) { // Extract the full message. msg, err = api.ChainGetMessage(ctx, mcid) if err != nil { @@ -373,7 +375,7 @@ func resolveFromChain(ctx context.Context, api api.FullNode, mcid cid.Cid, block // as the previous tipset. In the context of vector generation, the target // tipset is the one where a message was executed, and the previous tipset is // the one where the message was included. -func fetchThisAndPrevTipset(ctx context.Context, api api.FullNode, target types.TipSetKey) (targetTs *types.TipSet, prevTs *types.TipSet, err error) { +func fetchThisAndPrevTipset(ctx context.Context, api v0api.FullNode, target types.TipSetKey) (targetTs *types.TipSet, prevTs *types.TipSet, err error) { // get the tipset on which this message was "executed" on. // https://github.com/filecoin-project/lotus/issues/2847 targetTs, err = api.ChainGetTipSet(ctx, target) diff --git a/cmd/tvx/main.go b/cmd/tvx/main.go index 94a656c3e87..0fed8fad4b1 100644 --- a/cmd/tvx/main.go +++ b/cmd/tvx/main.go @@ -9,13 +9,13 @@ import ( "github.com/filecoin-project/go-jsonrpc" "github.com/urfave/cli/v2" - "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" lcli "github.com/filecoin-project/lotus/cli" ) // FullAPI is a JSON-RPC client targeting a full node. It's initialized in a // cli.BeforeFunc. -var FullAPI api.FullNode +var FullAPI v0api.FullNode // Closer is the closer for the JSON-RPC client, which must be called on // cli.AfterFunc. diff --git a/cmd/tvx/state.go b/cmd/tvx/state.go index bff5cbd6ecb..f2d25300adb 100644 --- a/cmd/tvx/state.go +++ b/cmd/tvx/state.go @@ -6,6 +6,8 @@ import ( "io" "log" + "github.com/filecoin-project/lotus/api/v0api" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/ipfs/go-cid" @@ -13,7 +15,6 @@ import ( "github.com/ipld/go-car" cbg "github.com/whyrusleeping/cbor-gen" - "github.com/filecoin-project/lotus/api" init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" "github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/types" @@ -23,13 +24,13 @@ import ( // StateSurgeon is an object used to fetch and manipulate state. type StateSurgeon struct { ctx context.Context - api api.FullNode + api v0api.FullNode stores *Stores } // NewSurgeon returns a state surgeon, an object used to fetch and manipulate // state. -func NewSurgeon(ctx context.Context, api api.FullNode, stores *Stores) *StateSurgeon { +func NewSurgeon(ctx context.Context, api v0api.FullNode, stores *Stores) *StateSurgeon { return &StateSurgeon{ ctx: ctx, api: api, @@ -85,7 +86,7 @@ func (sg *StateSurgeon) GetMaskedStateTree(previousRoot cid.Cid, retain []addres // GetAccessedActors identifies the actors that were accessed during the // execution of a message. -func (sg *StateSurgeon) GetAccessedActors(ctx context.Context, a api.FullNode, mid cid.Cid) ([]address.Address, error) { +func (sg *StateSurgeon) GetAccessedActors(ctx context.Context, a v0api.FullNode, mid cid.Cid) ([]address.Address, error) { log.Printf("calculating accessed actors during execution of message: %s", mid) msgInfo, err := a.StateSearchMsg(ctx, mid) if err != nil { diff --git a/cmd/tvx/stores.go b/cmd/tvx/stores.go index 66445be70b2..04000564178 100644 --- a/cmd/tvx/stores.go +++ b/cmd/tvx/stores.go @@ -5,10 +5,11 @@ import ( "log" "sync" + "github.com/filecoin-project/lotus/api/v0api" + "github.com/fatih/color" dssync "github.com/ipfs/go-datastore/sync" - "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/chain/actors/adt" @@ -40,7 +41,7 @@ type Stores struct { // NewProxyingStores is a set of Stores backed by a proxying Blockstore that // proxies Get requests for unknown CIDs to a Filecoin node, via the // ChainReadObj RPC. -func NewProxyingStores(ctx context.Context, api api.FullNode) *Stores { +func NewProxyingStores(ctx context.Context, api v0api.FullNode) *Stores { ds := dssync.MutexWrap(ds.NewMapDatastore()) bs := &proxyingBlockstore{ ctx: ctx, @@ -85,7 +86,7 @@ type TracingBlockstore interface { // a Filecoin node via JSON-RPC. type proxyingBlockstore struct { ctx context.Context - api api.FullNode + api v0api.FullNode lk sync.Mutex tracing bool diff --git a/conformance/rand_record.go b/conformance/rand_record.go index 6f6d064dc74..165e86e850e 100644 --- a/conformance/rand_record.go +++ b/conformance/rand_record.go @@ -10,14 +10,14 @@ import ( "github.com/filecoin-project/test-vectors/schema" - "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/vm" ) type RecordingRand struct { reporter Reporter - api api.FullNode + api v0api.FullNode // once guards the loading of the head tipset. // can be removed when https://github.com/filecoin-project/lotus/issues/4223 @@ -33,7 +33,7 @@ var _ vm.Rand = (*RecordingRand)(nil) // NewRecordingRand returns a vm.Rand implementation that proxies calls to a // full Lotus node via JSON-RPC, and records matching rules and responses so // they can later be embedded in test vectors. -func NewRecordingRand(reporter Reporter, api api.FullNode) *RecordingRand { +func NewRecordingRand(reporter Reporter, api v0api.FullNode) *RecordingRand { return &RecordingRand{reporter: reporter, api: api} } diff --git a/documentation/en/api-methods-miner.md b/documentation/en/api-v0-methods-miner.md similarity index 99% rename from documentation/en/api-methods-miner.md rename to documentation/en/api-v0-methods-miner.md index 7a1fed274f6..ea5ca75f851 100644 --- a/documentation/en/api-methods-miner.md +++ b/documentation/en/api-v0-methods-miner.md @@ -14,6 +14,8 @@ * [AuthVerify](#AuthVerify) * [Check](#Check) * [CheckProvable](#CheckProvable) +* [Compute](#Compute) + * [ComputeProof](#ComputeProof) * [Create](#Create) * [CreateBackup](#CreateBackup) * [Deals](#Deals) @@ -191,7 +193,7 @@ Response: ```json { "Version": "string value", - "APIVersion": 65792, + "APIVersion": 131328, "BlockDelay": 42 } ``` @@ -295,6 +297,24 @@ Response: } ``` +## Compute + + +### ComputeProof + + +Perms: read + +Inputs: +```json +[ + null, + null +] +``` + +Response: `null` + ## Create @@ -585,7 +605,10 @@ Response: "Voucher": "string value", "Message": "string value", "OtherPeer": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", - "Transferred": 42 + "Transferred": 42, + "Stages": { + "Stages": null + } } ``` diff --git a/documentation/en/api-methods-worker.md b/documentation/en/api-v0-methods-worker.md similarity index 99% rename from documentation/en/api-methods-worker.md rename to documentation/en/api-v0-methods-worker.md index 40300866edf..b0130a2a06e 100644 --- a/documentation/en/api-methods-worker.md +++ b/documentation/en/api-v0-methods-worker.md @@ -145,7 +145,7 @@ Perms: admin Inputs: `null` -Response: `65792` +Response: `131328` ## Add diff --git a/documentation/en/api-methods.md b/documentation/en/api-v0-methods.md similarity index 99% rename from documentation/en/api-methods.md rename to documentation/en/api-v0-methods.md index b8764d5b1fb..3c5356a5659 100644 --- a/documentation/en/api-methods.md +++ b/documentation/en/api-v0-methods.md @@ -35,6 +35,7 @@ * [Client](#Client) * [ClientCalcCommP](#ClientCalcCommP) * [ClientCancelDataTransfer](#ClientCancelDataTransfer) + * [ClientCancelRetrievalDeal](#ClientCancelRetrievalDeal) * [ClientDataTransferUpdates](#ClientDataTransferUpdates) * [ClientDealPieceCID](#ClientDealPieceCID) * [ClientDealSize](#ClientDealSize) @@ -275,7 +276,7 @@ Response: ```json { "Version": "string value", - "APIVersion": 65792, + "APIVersion": 131328, "BlockDelay": 42 } ``` @@ -921,6 +922,21 @@ Inputs: Response: `{}` +### ClientCancelRetrievalDeal +ClientCancelRetrievalDeal cancels an ongoing retrieval deal based on DealID + + +Perms: write + +Inputs: +```json +[ + 5 +] +``` + +Response: `{}` + ### ClientDataTransferUpdates @@ -941,7 +957,10 @@ Response: "Voucher": "string value", "Message": "string value", "OtherPeer": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", - "Transferred": 42 + "Transferred": 42, + "Stages": { + "Stages": null + } } ``` @@ -1054,6 +1073,9 @@ Response: }, "State": 42, "Message": "string value", + "DealStages": { + "Stages": null + }, "Provider": "f01234", "DataRef": { "TransferType": "string value", @@ -1089,7 +1111,10 @@ Response: "Voucher": "string value", "Message": "string value", "OtherPeer": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", - "Transferred": 42 + "Transferred": 42, + "Stages": { + "Stages": null + } } } ``` @@ -1125,6 +1150,9 @@ Response: }, "State": 42, "Message": "string value", + "DealStages": { + "Stages": null + }, "Provider": "f01234", "DataRef": { "TransferType": "string value", @@ -1160,7 +1188,10 @@ Response: "Voucher": "string value", "Message": "string value", "OtherPeer": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", - "Transferred": 42 + "Transferred": 42, + "Stages": { + "Stages": null + } } } ``` @@ -1352,6 +1383,7 @@ Inputs: }, "Piece": null, "Size": 42, + "LocalStore": 12, "Total": "0", "UnsealPrice": "0", "PaymentInterval": 42, @@ -1405,6 +1437,7 @@ Inputs: }, "Piece": null, "Size": 42, + "LocalStore": 12, "Total": "0", "UnsealPrice": "0", "PaymentInterval": 42, @@ -4484,7 +4517,7 @@ Inputs: ] ``` -Response: `9` +Response: `11` ### StateReadState StateReadState returns the indicated actor's state. @@ -4910,7 +4943,8 @@ Response: "FilMined": "0", "FilBurnt": "0", "FilLocked": "0", - "FilCirculating": "0" + "FilCirculating": "0", + "FilReserveDisbursed": "0" } ``` diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md new file mode 100644 index 00000000000..83c2d6d41be --- /dev/null +++ b/documentation/en/api-v1-unstable-methods.md @@ -0,0 +1,5742 @@ +# Groups +* [](#) + * [Closing](#Closing) + * [Discover](#Discover) + * [Session](#Session) + * [Shutdown](#Shutdown) + * [Version](#Version) +* [Auth](#Auth) + * [AuthNew](#AuthNew) + * [AuthVerify](#AuthVerify) +* [Beacon](#Beacon) + * [BeaconGetEntry](#BeaconGetEntry) +* [Chain](#Chain) + * [ChainDeleteObj](#ChainDeleteObj) + * [ChainExport](#ChainExport) + * [ChainGetBlock](#ChainGetBlock) + * [ChainGetBlockMessages](#ChainGetBlockMessages) + * [ChainGetGenesis](#ChainGetGenesis) + * [ChainGetMessage](#ChainGetMessage) + * [ChainGetNode](#ChainGetNode) + * [ChainGetParentMessages](#ChainGetParentMessages) + * [ChainGetParentReceipts](#ChainGetParentReceipts) + * [ChainGetPath](#ChainGetPath) + * [ChainGetRandomnessFromBeacon](#ChainGetRandomnessFromBeacon) + * [ChainGetRandomnessFromTickets](#ChainGetRandomnessFromTickets) + * [ChainGetTipSet](#ChainGetTipSet) + * [ChainGetTipSetByHeight](#ChainGetTipSetByHeight) + * [ChainHasObj](#ChainHasObj) + * [ChainHead](#ChainHead) + * [ChainNotify](#ChainNotify) + * [ChainReadObj](#ChainReadObj) + * [ChainSetHead](#ChainSetHead) + * [ChainStatObj](#ChainStatObj) + * [ChainTipSetWeight](#ChainTipSetWeight) +* [Client](#Client) + * [ClientCalcCommP](#ClientCalcCommP) + * [ClientCancelDataTransfer](#ClientCancelDataTransfer) + * [ClientCancelRetrievalDeal](#ClientCancelRetrievalDeal) + * [ClientDataTransferUpdates](#ClientDataTransferUpdates) + * [ClientDealPieceCID](#ClientDealPieceCID) + * [ClientDealSize](#ClientDealSize) + * [ClientFindData](#ClientFindData) + * [ClientGenCar](#ClientGenCar) + * [ClientGetDealInfo](#ClientGetDealInfo) + * [ClientGetDealStatus](#ClientGetDealStatus) + * [ClientGetDealUpdates](#ClientGetDealUpdates) + * [ClientHasLocal](#ClientHasLocal) + * [ClientImport](#ClientImport) + * [ClientListDataTransfers](#ClientListDataTransfers) + * [ClientListDeals](#ClientListDeals) + * [ClientListImports](#ClientListImports) + * [ClientMinerQueryOffer](#ClientMinerQueryOffer) + * [ClientQueryAsk](#ClientQueryAsk) + * [ClientRemoveImport](#ClientRemoveImport) + * [ClientRestartDataTransfer](#ClientRestartDataTransfer) + * [ClientRetrieve](#ClientRetrieve) + * [ClientRetrieveTryRestartInsufficientFunds](#ClientRetrieveTryRestartInsufficientFunds) + * [ClientRetrieveWithEvents](#ClientRetrieveWithEvents) + * [ClientStartDeal](#ClientStartDeal) +* [Create](#Create) + * [CreateBackup](#CreateBackup) +* [Gas](#Gas) + * [GasEstimateFeeCap](#GasEstimateFeeCap) + * [GasEstimateGasLimit](#GasEstimateGasLimit) + * [GasEstimateGasPremium](#GasEstimateGasPremium) + * [GasEstimateMessageGas](#GasEstimateMessageGas) +* [I](#I) + * [ID](#ID) +* [Log](#Log) + * [LogList](#LogList) + * [LogSetLevel](#LogSetLevel) +* [Market](#Market) + * [MarketAddBalance](#MarketAddBalance) + * [MarketGetReserved](#MarketGetReserved) + * [MarketReleaseFunds](#MarketReleaseFunds) + * [MarketReserveFunds](#MarketReserveFunds) + * [MarketWithdraw](#MarketWithdraw) +* [Miner](#Miner) + * [MinerCreateBlock](#MinerCreateBlock) + * [MinerGetBaseInfo](#MinerGetBaseInfo) +* [Mpool](#Mpool) + * [MpoolBatchPush](#MpoolBatchPush) + * [MpoolBatchPushMessage](#MpoolBatchPushMessage) + * [MpoolBatchPushUntrusted](#MpoolBatchPushUntrusted) + * [MpoolCheckMessages](#MpoolCheckMessages) + * [MpoolCheckPendingMessages](#MpoolCheckPendingMessages) + * [MpoolCheckReplaceMessages](#MpoolCheckReplaceMessages) + * [MpoolClear](#MpoolClear) + * [MpoolGetConfig](#MpoolGetConfig) + * [MpoolGetNonce](#MpoolGetNonce) + * [MpoolPending](#MpoolPending) + * [MpoolPush](#MpoolPush) + * [MpoolPushMessage](#MpoolPushMessage) + * [MpoolPushUntrusted](#MpoolPushUntrusted) + * [MpoolSelect](#MpoolSelect) + * [MpoolSetConfig](#MpoolSetConfig) + * [MpoolSub](#MpoolSub) +* [Msig](#Msig) + * [MsigAddApprove](#MsigAddApprove) + * [MsigAddCancel](#MsigAddCancel) + * [MsigAddPropose](#MsigAddPropose) + * [MsigApprove](#MsigApprove) + * [MsigApproveTxnHash](#MsigApproveTxnHash) + * [MsigCancel](#MsigCancel) + * [MsigCreate](#MsigCreate) + * [MsigGetAvailableBalance](#MsigGetAvailableBalance) + * [MsigGetPending](#MsigGetPending) + * [MsigGetVested](#MsigGetVested) + * [MsigGetVestingSchedule](#MsigGetVestingSchedule) + * [MsigPropose](#MsigPropose) + * [MsigRemoveSigner](#MsigRemoveSigner) + * [MsigSwapApprove](#MsigSwapApprove) + * [MsigSwapCancel](#MsigSwapCancel) + * [MsigSwapPropose](#MsigSwapPropose) +* [Net](#Net) + * [NetAddrsListen](#NetAddrsListen) + * [NetAgentVersion](#NetAgentVersion) + * [NetAutoNatStatus](#NetAutoNatStatus) + * [NetBandwidthStats](#NetBandwidthStats) + * [NetBandwidthStatsByPeer](#NetBandwidthStatsByPeer) + * [NetBandwidthStatsByProtocol](#NetBandwidthStatsByProtocol) + * [NetBlockAdd](#NetBlockAdd) + * [NetBlockList](#NetBlockList) + * [NetBlockRemove](#NetBlockRemove) + * [NetConnect](#NetConnect) + * [NetConnectedness](#NetConnectedness) + * [NetDisconnect](#NetDisconnect) + * [NetFindPeer](#NetFindPeer) + * [NetPeerInfo](#NetPeerInfo) + * [NetPeers](#NetPeers) + * [NetPubsubScores](#NetPubsubScores) +* [Node](#Node) + * [NodeStatus](#NodeStatus) +* [Paych](#Paych) + * [PaychAllocateLane](#PaychAllocateLane) + * [PaychAvailableFunds](#PaychAvailableFunds) + * [PaychAvailableFundsByFromTo](#PaychAvailableFundsByFromTo) + * [PaychCollect](#PaychCollect) + * [PaychGet](#PaychGet) + * [PaychGetWaitReady](#PaychGetWaitReady) + * [PaychList](#PaychList) + * [PaychNewPayment](#PaychNewPayment) + * [PaychSettle](#PaychSettle) + * [PaychStatus](#PaychStatus) + * [PaychVoucherAdd](#PaychVoucherAdd) + * [PaychVoucherCheckSpendable](#PaychVoucherCheckSpendable) + * [PaychVoucherCheckValid](#PaychVoucherCheckValid) + * [PaychVoucherCreate](#PaychVoucherCreate) + * [PaychVoucherList](#PaychVoucherList) + * [PaychVoucherSubmit](#PaychVoucherSubmit) +* [State](#State) + * [StateAccountKey](#StateAccountKey) + * [StateAllMinerFaults](#StateAllMinerFaults) + * [StateCall](#StateCall) + * [StateChangedActors](#StateChangedActors) + * [StateCirculatingSupply](#StateCirculatingSupply) + * [StateCompute](#StateCompute) + * [StateDealProviderCollateralBounds](#StateDealProviderCollateralBounds) + * [StateDecodeParams](#StateDecodeParams) + * [StateGetActor](#StateGetActor) + * [StateListActors](#StateListActors) + * [StateListMessages](#StateListMessages) + * [StateListMiners](#StateListMiners) + * [StateLookupID](#StateLookupID) + * [StateMarketBalance](#StateMarketBalance) + * [StateMarketDeals](#StateMarketDeals) + * [StateMarketParticipants](#StateMarketParticipants) + * [StateMarketStorageDeal](#StateMarketStorageDeal) + * [StateMinerActiveSectors](#StateMinerActiveSectors) + * [StateMinerAvailableBalance](#StateMinerAvailableBalance) + * [StateMinerDeadlines](#StateMinerDeadlines) + * [StateMinerFaults](#StateMinerFaults) + * [StateMinerInfo](#StateMinerInfo) + * [StateMinerInitialPledgeCollateral](#StateMinerInitialPledgeCollateral) + * [StateMinerPartitions](#StateMinerPartitions) + * [StateMinerPower](#StateMinerPower) + * [StateMinerPreCommitDepositForPower](#StateMinerPreCommitDepositForPower) + * [StateMinerProvingDeadline](#StateMinerProvingDeadline) + * [StateMinerRecoveries](#StateMinerRecoveries) + * [StateMinerSectorAllocated](#StateMinerSectorAllocated) + * [StateMinerSectorCount](#StateMinerSectorCount) + * [StateMinerSectors](#StateMinerSectors) + * [StateNetworkName](#StateNetworkName) + * [StateNetworkVersion](#StateNetworkVersion) + * [StateReadState](#StateReadState) + * [StateReplay](#StateReplay) + * [StateSearchMsg](#StateSearchMsg) + * [StateSectorExpiration](#StateSectorExpiration) + * [StateSectorGetInfo](#StateSectorGetInfo) + * [StateSectorPartition](#StateSectorPartition) + * [StateSectorPreCommitInfo](#StateSectorPreCommitInfo) + * [StateVMCirculatingSupplyInternal](#StateVMCirculatingSupplyInternal) + * [StateVerifiedClientStatus](#StateVerifiedClientStatus) + * [StateVerifiedRegistryRootKey](#StateVerifiedRegistryRootKey) + * [StateVerifierStatus](#StateVerifierStatus) + * [StateWaitMsg](#StateWaitMsg) +* [Sync](#Sync) + * [SyncCheckBad](#SyncCheckBad) + * [SyncCheckpoint](#SyncCheckpoint) + * [SyncIncomingBlocks](#SyncIncomingBlocks) + * [SyncMarkBad](#SyncMarkBad) + * [SyncState](#SyncState) + * [SyncSubmitBlock](#SyncSubmitBlock) + * [SyncUnmarkAllBad](#SyncUnmarkAllBad) + * [SyncUnmarkBad](#SyncUnmarkBad) + * [SyncValidateTipset](#SyncValidateTipset) +* [Wallet](#Wallet) + * [WalletBalance](#WalletBalance) + * [WalletDefaultAddress](#WalletDefaultAddress) + * [WalletDelete](#WalletDelete) + * [WalletExport](#WalletExport) + * [WalletHas](#WalletHas) + * [WalletImport](#WalletImport) + * [WalletList](#WalletList) + * [WalletNew](#WalletNew) + * [WalletSetDefault](#WalletSetDefault) + * [WalletSign](#WalletSign) + * [WalletSignMessage](#WalletSignMessage) + * [WalletValidateAddress](#WalletValidateAddress) + * [WalletVerify](#WalletVerify) +## + + +### Closing + + +Perms: read + +Inputs: `null` + +Response: `{}` + +### Discover + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "info": { + "title": "Lotus RPC API", + "version": "1.2.1/generated=2020-11-22T08:22:42-06:00" + }, + "methods": [], + "openrpc": "1.2.6" +} +``` + +### Session + + +Perms: read + +Inputs: `null` + +Response: `"07070707-0707-0707-0707-070707070707"` + +### Shutdown + + +Perms: admin + +Inputs: `null` + +Response: `{}` + +### Version + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "Version": "string value", + "APIVersion": 131328, + "BlockDelay": 42 +} +``` + +## Auth + + +### AuthNew + + +Perms: admin + +Inputs: +```json +[ + null +] +``` + +Response: `"Ynl0ZSBhcnJheQ=="` + +### AuthVerify + + +Perms: read + +Inputs: +```json +[ + "string value" +] +``` + +Response: `null` + +## Beacon +The Beacon method group contains methods for interacting with the random beacon (DRAND) + + +### BeaconGetEntry +BeaconGetEntry returns the beacon entry for the given filecoin epoch. If +the entry has not yet been produced, the call will block until the entry +becomes available + + +Perms: read + +Inputs: +```json +[ + 10101 +] +``` + +Response: +```json +{ + "Round": 42, + "Data": "Ynl0ZSBhcnJheQ==" +} +``` + +## Chain +The Chain method group contains methods for interacting with the +blockchain, but that do not require any form of state computation. + + +### ChainDeleteObj +ChainDeleteObj deletes node referenced by the given CID + + +Perms: admin + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: `{}` + +### ChainExport +ChainExport returns a stream of bytes with CAR dump of chain data. +The exported chain data includes the header chain from the given tipset +back to genesis, the entire genesis state, and the most recent 'nroots' +state trees. +If oldmsgskip is set, messages from before the requested roots are also not included. + + +Perms: read + +Inputs: +```json +[ + 10101, + true, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `"Ynl0ZSBhcnJheQ=="` + +### ChainGetBlock +ChainGetBlock returns the block specified by the given CID. + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: +```json +{ + "Miner": "f01234", + "Ticket": { + "VRFProof": "Ynl0ZSBhcnJheQ==" + }, + "ElectionProof": { + "WinCount": 9, + "VRFProof": "Ynl0ZSBhcnJheQ==" + }, + "BeaconEntries": null, + "WinPoStProof": null, + "Parents": null, + "ParentWeight": "0", + "Height": 10101, + "ParentStateRoot": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "ParentMessageReceipts": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Messages": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "BLSAggregate": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "Timestamp": 42, + "BlockSig": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "ForkSignaling": 42, + "ParentBaseFee": "0" +} +``` + +### ChainGetBlockMessages +ChainGetBlockMessages returns messages stored in the specified block. + +Note: If there are multiple blocks in a tipset, it's likely that some +messages will be duplicated. It's also possible for blocks in a tipset to have +different messages from the same sender at the same nonce. When that happens, +only the first message (in a block with lowest ticket) will be considered +for execution + +NOTE: THIS METHOD SHOULD ONLY BE USED FOR GETTING MESSAGES IN A SPECIFIC BLOCK + +DO NOT USE THIS METHOD TO GET MESSAGES INCLUDED IN A TIPSET +Use ChainGetParentMessages, which will perform correct message deduplication + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: +```json +{ + "BlsMessages": null, + "SecpkMessages": null, + "Cids": null +} +``` + +### ChainGetGenesis +ChainGetGenesis returns the genesis tipset. + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "Cids": null, + "Blocks": null, + "Height": 0 +} +``` + +### ChainGetMessage +ChainGetMessage reads a message referenced by the specified CID from the +chain blockstore. + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: +```json +{ + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } +} +``` + +### ChainGetNode + + +Perms: read + +Inputs: +```json +[ + "string value" +] +``` + +Response: +```json +{ + "Cid": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Obj": {} +} +``` + +### ChainGetParentMessages +ChainGetParentMessages returns messages stored in parent tipset of the +specified block. + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: `null` + +### ChainGetParentReceipts +ChainGetParentReceipts returns receipts for messages in parent tipset of +the specified block. The receipts in the list returned is one-to-one with the +messages returned by a call to ChainGetParentMessages with the same blockCid. + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: `null` + +### ChainGetPath +ChainGetPath returns a set of revert/apply operations needed to get from +one tipset to another, for example: +``` + to + ^ +from tAA + ^ ^ +tBA tAB + ^---*--^ + ^ + tRR +``` +Would return `[revert(tBA), apply(tAB), apply(tAA)]` + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ], + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `null` + +### ChainGetRandomnessFromBeacon +ChainGetRandomnessFromBeacon is used to sample the beacon for randomness. + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ], + 2, + 10101, + "Ynl0ZSBhcnJheQ==" +] +``` + +Response: `null` + +### ChainGetRandomnessFromTickets +ChainGetRandomnessFromTickets is used to sample the chain for randomness. + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ], + 2, + 10101, + "Ynl0ZSBhcnJheQ==" +] +``` + +Response: `null` + +### ChainGetTipSet +ChainGetTipSet returns the tipset specified by the given TipSetKey. + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "Cids": null, + "Blocks": null, + "Height": 0 +} +``` + +### ChainGetTipSetByHeight +ChainGetTipSetByHeight looks back for a tipset at the specified epoch. +If there are no blocks at the specified epoch, a tipset at an earlier epoch +will be returned. + + +Perms: read + +Inputs: +```json +[ + 10101, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "Cids": null, + "Blocks": null, + "Height": 0 +} +``` + +### ChainHasObj +ChainHasObj checks if a given CID exists in the chain blockstore. + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: `true` + +### ChainHead +ChainHead returns the current head of the chain. + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "Cids": null, + "Blocks": null, + "Height": 0 +} +``` + +### ChainNotify +ChainNotify returns channel with chain head updates. +First message is guaranteed to be of len == 1, and type == 'current'. + + +Perms: read + +Inputs: `null` + +Response: `null` + +### ChainReadObj +ChainReadObj reads ipld nodes referenced by the specified CID from chain +blockstore and returns raw bytes. + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: `"Ynl0ZSBhcnJheQ=="` + +### ChainSetHead +ChainSetHead forcefully sets current chain head. Use with caution. + + +Perms: admin + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `{}` + +### ChainStatObj +ChainStatObj returns statistics about the graph referenced by 'obj'. +If 'base' is also specified, then the returned stat will be a diff +between the two objects. + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: +```json +{ + "Size": 42, + "Links": 42 +} +``` + +### ChainTipSetWeight +ChainTipSetWeight computes weight for the specified tipset. + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `"0"` + +## Client +The Client methods all have to do with interacting with the storage and +retrieval markets as a client + + +### ClientCalcCommP +ClientCalcCommP calculates the CommP for a specified file + + +Perms: write + +Inputs: +```json +[ + "string value" +] +``` + +Response: +```json +{ + "Root": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Size": 1024 +} +``` + +### ClientCancelDataTransfer +ClientCancelDataTransfer cancels a data transfer with the given transfer ID and other peer + + +Perms: write + +Inputs: +```json +[ + 3, + "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + true +] +``` + +Response: `{}` + +### ClientCancelRetrievalDeal +ClientCancelRetrievalDeal cancels an ongoing retrieval deal based on DealID + + +Perms: write + +Inputs: +```json +[ + 5 +] +``` + +Response: `{}` + +### ClientDataTransferUpdates + + +Perms: write + +Inputs: `null` + +Response: +```json +{ + "TransferID": 3, + "Status": 1, + "BaseCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "IsInitiator": true, + "IsSender": true, + "Voucher": "string value", + "Message": "string value", + "OtherPeer": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Transferred": 42, + "Stages": { + "Stages": null + } +} +``` + +### ClientDealPieceCID +ClientCalcCommP calculates the CommP and data size of the specified CID + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: +```json +{ + "PayloadSize": 9, + "PieceSize": 1032, + "PieceCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +} +``` + +### ClientDealSize +ClientDealSize calculates real deal data size + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: +```json +{ + "PayloadSize": 9, + "PieceSize": 1032 +} +``` + +### ClientFindData +ClientFindData identifies peers that have a certain file, and returns QueryOffers (one per peer). + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + null +] +``` + +Response: `null` + +### ClientGenCar +ClientGenCar generates a CAR file for the specified file. + + +Perms: write + +Inputs: +```json +[ + { + "Path": "string value", + "IsCAR": true + }, + "string value" +] +``` + +Response: `{}` + +### ClientGetDealInfo +ClientGetDealInfo returns the latest information about a given deal. + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: +```json +{ + "ProposalCid": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "State": 42, + "Message": "string value", + "DealStages": { + "Stages": null + }, + "Provider": "f01234", + "DataRef": { + "TransferType": "string value", + "Root": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "PieceCid": null, + "PieceSize": 1024, + "RawBlockSize": 42 + }, + "PieceCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Size": 42, + "PricePerEpoch": "0", + "Duration": 42, + "DealID": 5432, + "CreationTime": "0001-01-01T00:00:00Z", + "Verified": true, + "TransferChannelID": { + "Initiator": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Responder": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "ID": 3 + }, + "DataTransfer": { + "TransferID": 3, + "Status": 1, + "BaseCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "IsInitiator": true, + "IsSender": true, + "Voucher": "string value", + "Message": "string value", + "OtherPeer": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Transferred": 42, + "Stages": { + "Stages": null + } + } +} +``` + +### ClientGetDealStatus +ClientGetDealStatus returns status given a code + + +Perms: read + +Inputs: +```json +[ + 42 +] +``` + +Response: `"string value"` + +### ClientGetDealUpdates +ClientGetDealUpdates returns the status of updated deals + + +Perms: write + +Inputs: `null` + +Response: +```json +{ + "ProposalCid": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "State": 42, + "Message": "string value", + "DealStages": { + "Stages": null + }, + "Provider": "f01234", + "DataRef": { + "TransferType": "string value", + "Root": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "PieceCid": null, + "PieceSize": 1024, + "RawBlockSize": 42 + }, + "PieceCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Size": 42, + "PricePerEpoch": "0", + "Duration": 42, + "DealID": 5432, + "CreationTime": "0001-01-01T00:00:00Z", + "Verified": true, + "TransferChannelID": { + "Initiator": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Responder": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "ID": 3 + }, + "DataTransfer": { + "TransferID": 3, + "Status": 1, + "BaseCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "IsInitiator": true, + "IsSender": true, + "Voucher": "string value", + "Message": "string value", + "OtherPeer": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Transferred": 42, + "Stages": { + "Stages": null + } + } +} +``` + +### ClientHasLocal +ClientHasLocal indicates whether a certain CID is locally stored. + + +Perms: write + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: `true` + +### ClientImport +ClientImport imports file under the specified path into filestore. + + +Perms: admin + +Inputs: +```json +[ + { + "Path": "string value", + "IsCAR": true + } +] +``` + +Response: +```json +{ + "Root": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "ImportID": 50 +} +``` + +### ClientListDataTransfers +ClientListTransfers returns the status of all ongoing transfers of data + + +Perms: write + +Inputs: `null` + +Response: `null` + +### ClientListDeals +ClientListDeals returns information about the deals made by the local client. + + +Perms: write + +Inputs: `null` + +Response: `null` + +### ClientListImports +ClientListImports lists imported files and their root CIDs + + +Perms: write + +Inputs: `null` + +Response: `null` + +### ClientMinerQueryOffer +ClientMinerQueryOffer returns a QueryOffer for the specific miner and file. + + +Perms: read + +Inputs: +```json +[ + "f01234", + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + null +] +``` + +Response: +```json +{ + "Err": "string value", + "Root": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Piece": null, + "Size": 42, + "MinPrice": "0", + "UnsealPrice": "0", + "PaymentInterval": 42, + "PaymentIntervalIncrease": 42, + "Miner": "f01234", + "MinerPeer": { + "Address": "f01234", + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "PieceCID": null + } +} +``` + +### ClientQueryAsk +ClientQueryAsk returns a signed StorageAsk from the specified miner. + + +Perms: read + +Inputs: +```json +[ + "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "f01234" +] +``` + +Response: +```json +{ + "Price": "0", + "VerifiedPrice": "0", + "MinPieceSize": 1032, + "MaxPieceSize": 1032, + "Miner": "f01234", + "Timestamp": 10101, + "Expiry": 10101, + "SeqNo": 42 +} +``` + +### ClientRemoveImport +ClientRemoveImport removes file import + + +Perms: admin + +Inputs: +```json +[ + 50 +] +``` + +Response: `{}` + +### ClientRestartDataTransfer +ClientRestartDataTransfer attempts to restart a data transfer with the given transfer ID and other peer + + +Perms: write + +Inputs: +```json +[ + 3, + "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + true +] +``` + +Response: `{}` + +### ClientRetrieve +ClientRetrieve initiates the retrieval of a file, as specified in the order. + + +Perms: admin + +Inputs: +```json +[ + { + "Root": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Piece": null, + "Size": 42, + "LocalStore": 12, + "Total": "0", + "UnsealPrice": "0", + "PaymentInterval": 42, + "PaymentIntervalIncrease": 42, + "Client": "f01234", + "Miner": "f01234", + "MinerPeer": { + "Address": "f01234", + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "PieceCID": null + } + }, + { + "Path": "string value", + "IsCAR": true + } +] +``` + +Response: `{}` + +### ClientRetrieveTryRestartInsufficientFunds +ClientRetrieveTryRestartInsufficientFunds attempts to restart stalled retrievals on a given payment channel +which are stuck due to insufficient funds + + +Perms: write + +Inputs: +```json +[ + "f01234" +] +``` + +Response: `{}` + +### ClientRetrieveWithEvents +ClientRetrieveWithEvents initiates the retrieval of a file, as specified in the order, and provides a channel +of status updates. + + +Perms: admin + +Inputs: +```json +[ + { + "Root": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Piece": null, + "Size": 42, + "LocalStore": 12, + "Total": "0", + "UnsealPrice": "0", + "PaymentInterval": 42, + "PaymentIntervalIncrease": 42, + "Client": "f01234", + "Miner": "f01234", + "MinerPeer": { + "Address": "f01234", + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "PieceCID": null + } + }, + { + "Path": "string value", + "IsCAR": true + } +] +``` + +Response: +```json +{ + "Event": 5, + "Status": 0, + "BytesReceived": 42, + "FundsSpent": "0", + "Err": "string value" +} +``` + +### ClientStartDeal +ClientStartDeal proposes a deal with a miner. + + +Perms: admin + +Inputs: +```json +[ + { + "Data": { + "TransferType": "string value", + "Root": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "PieceCid": null, + "PieceSize": 1024, + "RawBlockSize": 42 + }, + "Wallet": "f01234", + "Miner": "f01234", + "EpochPrice": "0", + "MinBlocksDuration": 42, + "ProviderCollateral": "0", + "DealStartEpoch": 10101, + "FastRetrieval": true, + "VerifiedDeal": true + } +] +``` + +Response: `null` + +## Create + + +### CreateBackup +CreateBackup creates node backup onder the specified file name. The +method requires that the lotus daemon is running with the +LOTUS_BACKUP_BASE_PATH environment variable set to some path, and that +the path specified when calling CreateBackup is within the base path + + +Perms: admin + +Inputs: +```json +[ + "string value" +] +``` + +Response: `{}` + +## Gas + + +### GasEstimateFeeCap +GasEstimateFeeCap estimates gas fee cap + + +Perms: read + +Inputs: +```json +[ + { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + 9, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `"0"` + +### GasEstimateGasLimit +GasEstimateGasLimit estimates gas used by the message and returns it. +It fails if message fails to execute. + + +Perms: read + +Inputs: +```json +[ + { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `9` + +### GasEstimateGasPremium +GasEstimateGasPremium estimates what gas price should be used for a +message to have high likelihood of inclusion in `nblocksincl` epochs. + + +Perms: read + +Inputs: +```json +[ + 42, + "f01234", + 9, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `"0"` + +### GasEstimateMessageGas +GasEstimateMessageGas estimates gas values for unset message gas fields + + +Perms: read + +Inputs: +```json +[ + { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + { + "MaxFee": "0" + }, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } +} +``` + +## I + + +### ID + + +Perms: read + +Inputs: `null` + +Response: `"12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf"` + +## Log + + +### LogList + + +Perms: write + +Inputs: `null` + +Response: `null` + +### LogSetLevel + + +Perms: write + +Inputs: +```json +[ + "string value", + "string value" +] +``` + +Response: `{}` + +## Market + + +### MarketAddBalance +MarketAddBalance adds funds to the market actor + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "f01234", + "0" +] +``` + +Response: +```json +{ + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" +} +``` + +### MarketGetReserved +MarketGetReserved gets the amount of funds that are currently reserved for the address + + +Perms: sign + +Inputs: +```json +[ + "f01234" +] +``` + +Response: `"0"` + +### MarketReleaseFunds +MarketReleaseFunds releases funds reserved by MarketReserveFunds + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "0" +] +``` + +Response: `{}` + +### MarketReserveFunds +MarketReserveFunds reserves funds for a deal + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "f01234", + "0" +] +``` + +Response: +```json +{ + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" +} +``` + +### MarketWithdraw +MarketWithdraw withdraws unlocked funds from the market actor + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "f01234", + "0" +] +``` + +Response: +```json +{ + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" +} +``` + +## Miner + + +### MinerCreateBlock + + +Perms: write + +Inputs: +```json +[ + { + "Miner": "f01234", + "Parents": [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ], + "Ticket": { + "VRFProof": "Ynl0ZSBhcnJheQ==" + }, + "Eproof": { + "WinCount": 9, + "VRFProof": "Ynl0ZSBhcnJheQ==" + }, + "BeaconValues": null, + "Messages": null, + "Epoch": 10101, + "Timestamp": 42, + "WinningPoStProof": null + } +] +``` + +Response: +```json +{ + "Header": { + "Miner": "f01234", + "Ticket": { + "VRFProof": "Ynl0ZSBhcnJheQ==" + }, + "ElectionProof": { + "WinCount": 9, + "VRFProof": "Ynl0ZSBhcnJheQ==" + }, + "BeaconEntries": null, + "WinPoStProof": null, + "Parents": null, + "ParentWeight": "0", + "Height": 10101, + "ParentStateRoot": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "ParentMessageReceipts": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Messages": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "BLSAggregate": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "Timestamp": 42, + "BlockSig": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "ForkSignaling": 42, + "ParentBaseFee": "0" + }, + "BlsMessages": null, + "SecpkMessages": null +} +``` + +### MinerGetBaseInfo +There are not yet any comments for this method. + +Perms: read + +Inputs: +```json +[ + "f01234", + 10101, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "MinerPower": "0", + "NetworkPower": "0", + "Sectors": null, + "WorkerKey": "f01234", + "SectorSize": 34359738368, + "PrevBeaconEntry": { + "Round": 42, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "BeaconEntries": null, + "EligibleForMining": true +} +``` + +## Mpool +The Mpool methods are for interacting with the message pool. The message pool +manages all incoming and outgoing 'messages' going over the network. + + +### MpoolBatchPush +MpoolBatchPush batch pushes a signed message to mempool. + + +Perms: write + +Inputs: +```json +[ + null +] +``` + +Response: `null` + +### MpoolBatchPushMessage +MpoolBatchPushMessage batch pushes a unsigned message to mempool. + + +Perms: sign + +Inputs: +```json +[ + null, + { + "MaxFee": "0" + } +] +``` + +Response: `null` + +### MpoolBatchPushUntrusted +MpoolBatchPushUntrusted batch pushes a signed message to mempool from untrusted sources. + + +Perms: write + +Inputs: +```json +[ + null +] +``` + +Response: `null` + +### MpoolCheckMessages +MpoolCheckMessages performs logical checks on a batch of messages + + +Perms: read + +Inputs: +```json +[ + null +] +``` + +Response: `null` + +### MpoolCheckPendingMessages +MpoolCheckPendingMessages performs logical checks for all pending messages from a given address + + +Perms: read + +Inputs: +```json +[ + "f01234" +] +``` + +Response: `null` + +### MpoolCheckReplaceMessages +MpoolCheckReplaceMessages performs logical checks on pending messages with replacement + + +Perms: read + +Inputs: +```json +[ + null +] +``` + +Response: `null` + +### MpoolClear +MpoolClear clears pending messages from the mpool + + +Perms: write + +Inputs: +```json +[ + true +] +``` + +Response: `{}` + +### MpoolGetConfig +MpoolGetConfig returns (a copy of) the current mpool config + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "PriorityAddrs": null, + "SizeLimitHigh": 123, + "SizeLimitLow": 123, + "ReplaceByFeeRatio": 12.3, + "PruneCooldown": 60000000000, + "GasLimitOverestimation": 12.3 +} +``` + +### MpoolGetNonce +MpoolGetNonce gets next nonce for the specified sender. +Note that this method may not be atomic. Use MpoolPushMessage instead. + + +Perms: read + +Inputs: +```json +[ + "f01234" +] +``` + +Response: `42` + +### MpoolPending +MpoolPending returns pending mempool messages. + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `null` + +### MpoolPush +MpoolPush pushes a signed message to mempool. + + +Perms: write + +Inputs: +```json +[ + { + "Message": { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + "Signature": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + } +] +``` + +Response: +```json +{ + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" +} +``` + +### MpoolPushMessage +MpoolPushMessage atomically assigns a nonce, signs, and pushes a message +to mempool. +maxFee is only used when GasFeeCap/GasPremium fields aren't specified + +When maxFee is set to 0, MpoolPushMessage will guess appropriate fee +based on current chain conditions + + +Perms: sign + +Inputs: +```json +[ + { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + { + "MaxFee": "0" + } +] +``` + +Response: +```json +{ + "Message": { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + "Signature": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } +} +``` + +### MpoolPushUntrusted +MpoolPushUntrusted pushes a signed message to mempool from untrusted sources. + + +Perms: write + +Inputs: +```json +[ + { + "Message": { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + "Signature": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + } +] +``` + +Response: +```json +{ + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" +} +``` + +### MpoolSelect +MpoolSelect returns a list of pending messages for inclusion in the next block + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ], + 12.3 +] +``` + +Response: `null` + +### MpoolSetConfig +MpoolSetConfig sets the mpool config to (a copy of) the supplied config + + +Perms: admin + +Inputs: +```json +[ + { + "PriorityAddrs": null, + "SizeLimitHigh": 123, + "SizeLimitLow": 123, + "ReplaceByFeeRatio": 12.3, + "PruneCooldown": 60000000000, + "GasLimitOverestimation": 12.3 + } +] +``` + +Response: `{}` + +### MpoolSub + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "Type": 0, + "Message": { + "Message": { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + "Signature": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + } +} +``` + +## Msig +The Msig methods are used to interact with multisig wallets on the +filecoin network + + +### MsigAddApprove +MsigAddApprove approves a previously proposed AddSigner message +It takes the following params: , , , +, , + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "f01234", + 42, + "f01234", + "f01234", + true +] +``` + +Response: +```json +{ + "Message": { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + "ValidNonce": true +} +``` + +### MsigAddCancel +MsigAddCancel cancels a previously proposed AddSigner message +It takes the following params: , , , +, + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "f01234", + 42, + "f01234", + true +] +``` + +Response: +```json +{ + "Message": { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + "ValidNonce": true +} +``` + +### MsigAddPropose +MsigAddPropose proposes adding a signer in the multisig +It takes the following params: , , +, + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "f01234", + "f01234", + true +] +``` + +Response: +```json +{ + "Message": { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + "ValidNonce": true +} +``` + +### MsigApprove +MsigApprove approves a previously-proposed multisig message by transaction ID +It takes the following params: , + + +Perms: sign + +Inputs: +```json +[ + "f01234", + 42, + "f01234" +] +``` + +Response: +```json +{ + "Message": { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + "ValidNonce": true +} +``` + +### MsigApproveTxnHash +MsigApproveTxnHash approves a previously-proposed multisig message, specified +using both transaction ID and a hash of the parameters used in the +proposal. This method of approval can be used to ensure you only approve +exactly the transaction you think you are. +It takes the following params: , , , , , +, , + + +Perms: sign + +Inputs: +```json +[ + "f01234", + 42, + "f01234", + "f01234", + "0", + "f01234", + 42, + "Ynl0ZSBhcnJheQ==" +] +``` + +Response: +```json +{ + "Message": { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + "ValidNonce": true +} +``` + +### MsigCancel +MsigCancel cancels a previously-proposed multisig message +It takes the following params: , , , , +, , + + +Perms: sign + +Inputs: +```json +[ + "f01234", + 42, + "f01234", + "0", + "f01234", + 42, + "Ynl0ZSBhcnJheQ==" +] +``` + +Response: +```json +{ + "Message": { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + "ValidNonce": true +} +``` + +### MsigCreate +MsigCreate creates a multisig wallet +It takes the following params: , , +, , + + +Perms: sign + +Inputs: +```json +[ + 42, + null, + 10101, + "0", + "f01234", + "0" +] +``` + +Response: +```json +{ + "Message": { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + "ValidNonce": true +} +``` + +### MsigGetAvailableBalance +MsigGetAvailableBalance returns the portion of a multisig's balance that can be withdrawn or spent + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `"0"` + +### MsigGetPending +MsigGetPending returns pending transactions for the given multisig +wallet. Once pending transactions are fully approved, they will no longer +appear here. + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `null` + +### MsigGetVested +MsigGetVested returns the amount of FIL that vested in a multisig in a certain period. +It takes the following params: , , + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ], + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `"0"` + +### MsigGetVestingSchedule +MsigGetVestingSchedule returns the vesting details of a given multisig. + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "InitialBalance": "0", + "StartEpoch": 10101, + "UnlockDuration": 10101 +} +``` + +### MsigPropose +MsigPropose proposes a multisig message +It takes the following params: , , , +, , + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "f01234", + "0", + "f01234", + 42, + "Ynl0ZSBhcnJheQ==" +] +``` + +Response: +```json +{ + "Message": { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + "ValidNonce": true +} +``` + +### MsigRemoveSigner +MsigRemoveSigner proposes the removal of a signer from the multisig. +It accepts the multisig to make the change on, the proposer address to +send the message from, the address to be removed, and a boolean +indicating whether or not the signing threshold should be lowered by one +along with the address removal. + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "f01234", + "f01234", + true +] +``` + +Response: +```json +{ + "Message": { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + "ValidNonce": true +} +``` + +### MsigSwapApprove +MsigSwapApprove approves a previously proposed SwapSigner +It takes the following params: , , , +, , + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "f01234", + 42, + "f01234", + "f01234", + "f01234" +] +``` + +Response: +```json +{ + "Message": { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + "ValidNonce": true +} +``` + +### MsigSwapCancel +MsigSwapCancel cancels a previously proposed SwapSigner message +It takes the following params: , , , +, + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "f01234", + 42, + "f01234", + "f01234" +] +``` + +Response: +```json +{ + "Message": { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + "ValidNonce": true +} +``` + +### MsigSwapPropose +MsigSwapPropose proposes swapping 2 signers in the multisig +It takes the following params: , , +, + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "f01234", + "f01234", + "f01234" +] +``` + +Response: +```json +{ + "Message": { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + "ValidNonce": true +} +``` + +## Net + + +### NetAddrsListen + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "Addrs": null, + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" +} +``` + +### NetAgentVersion + + +Perms: read + +Inputs: +```json +[ + "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" +] +``` + +Response: `"string value"` + +### NetAutoNatStatus + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "Reachability": 1, + "PublicAddr": "string value" +} +``` + +### NetBandwidthStats + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "TotalIn": 9, + "TotalOut": 9, + "RateIn": 12.3, + "RateOut": 12.3 +} +``` + +### NetBandwidthStatsByPeer + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "12D3KooWSXmXLJmBR1M7i9RW9GQPNUhZSzXKzxDHWtAgNuJAbyEJ": { + "TotalIn": 174000, + "TotalOut": 12500, + "RateIn": 100, + "RateOut": 50 + } +} +``` + +### NetBandwidthStatsByProtocol + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "/fil/hello/1.0.0": { + "TotalIn": 174000, + "TotalOut": 12500, + "RateIn": 100, + "RateOut": 50 + } +} +``` + +### NetBlockAdd + + +Perms: admin + +Inputs: +```json +[ + { + "Peers": null, + "IPAddrs": null, + "IPSubnets": null + } +] +``` + +Response: `{}` + +### NetBlockList + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "Peers": null, + "IPAddrs": null, + "IPSubnets": null +} +``` + +### NetBlockRemove + + +Perms: admin + +Inputs: +```json +[ + { + "Peers": null, + "IPAddrs": null, + "IPSubnets": null + } +] +``` + +Response: `{}` + +### NetConnect + + +Perms: write + +Inputs: +```json +[ + { + "Addrs": null, + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" + } +] +``` + +Response: `{}` + +### NetConnectedness + + +Perms: read + +Inputs: +```json +[ + "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" +] +``` + +Response: `1` + +### NetDisconnect + + +Perms: write + +Inputs: +```json +[ + "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" +] +``` + +Response: `{}` + +### NetFindPeer + + +Perms: read + +Inputs: +```json +[ + "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" +] +``` + +Response: +```json +{ + "Addrs": null, + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" +} +``` + +### NetPeerInfo + + +Perms: read + +Inputs: +```json +[ + "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf" +] +``` + +Response: +```json +{ + "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Agent": "string value", + "Addrs": null, + "Protocols": null, + "ConnMgrMeta": { + "FirstSeen": "0001-01-01T00:00:00Z", + "Value": 123, + "Tags": { + "name": 42 + }, + "Conns": { + "name": "2021-03-08T22:52:18Z" + } + } +} +``` + +### NetPeers + + +Perms: read + +Inputs: `null` + +Response: `null` + +### NetPubsubScores + + +Perms: read + +Inputs: `null` + +Response: `null` + +## Node +These methods are general node management and status commands + + +### NodeStatus +There are not yet any comments for this method. + +Perms: read + +Inputs: +```json +[ + true +] +``` + +Response: +```json +{ + "SyncStatus": { + "Epoch": 42, + "Behind": 42 + }, + "PeerStatus": { + "PeersToPublishMsgs": 123, + "PeersToPublishBlocks": 123 + }, + "ChainStatus": { + "BlocksPerTipsetLast100": 12.3, + "BlocksPerTipsetLastFinality": 12.3 + } +} +``` + +## Paych +The Paych methods are for interacting with and managing payment channels + + +### PaychAllocateLane + + +Perms: sign + +Inputs: +```json +[ + "f01234" +] +``` + +Response: `42` + +### PaychAvailableFunds + + +Perms: sign + +Inputs: +```json +[ + "f01234" +] +``` + +Response: +```json +{ + "Channel": "\u003cempty\u003e", + "From": "f01234", + "To": "f01234", + "ConfirmedAmt": "0", + "PendingAmt": "0", + "PendingWaitSentinel": null, + "QueuedAmt": "0", + "VoucherReedeemedAmt": "0" +} +``` + +### PaychAvailableFundsByFromTo + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "f01234" +] +``` + +Response: +```json +{ + "Channel": "\u003cempty\u003e", + "From": "f01234", + "To": "f01234", + "ConfirmedAmt": "0", + "PendingAmt": "0", + "PendingWaitSentinel": null, + "QueuedAmt": "0", + "VoucherReedeemedAmt": "0" +} +``` + +### PaychCollect + + +Perms: sign + +Inputs: +```json +[ + "f01234" +] +``` + +Response: +```json +{ + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" +} +``` + +### PaychGet +There are not yet any comments for this method. + +Perms: sign + +Inputs: +```json +[ + "f01234", + "f01234", + "0" +] +``` + +Response: +```json +{ + "Channel": "f01234", + "WaitSentinel": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +} +``` + +### PaychGetWaitReady + + +Perms: sign + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: `"f01234"` + +### PaychList + + +Perms: read + +Inputs: `null` + +Response: `null` + +### PaychNewPayment + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "f01234", + null +] +``` + +Response: +```json +{ + "Channel": "f01234", + "WaitSentinel": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Vouchers": null +} +``` + +### PaychSettle + + +Perms: sign + +Inputs: +```json +[ + "f01234" +] +``` + +Response: +```json +{ + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" +} +``` + +### PaychStatus + + +Perms: read + +Inputs: +```json +[ + "f01234" +] +``` + +Response: +```json +{ + "ControlAddr": "f01234", + "Direction": 1 +} +``` + +### PaychVoucherAdd + + +Perms: write + +Inputs: +```json +[ + "f01234", + { + "ChannelAddr": "f01234", + "TimeLockMin": 10101, + "TimeLockMax": 10101, + "SecretPreimage": "Ynl0ZSBhcnJheQ==", + "Extra": { + "Actor": "f01234", + "Method": 1, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "Lane": 42, + "Nonce": 42, + "Amount": "0", + "MinSettleHeight": 10101, + "Merges": null, + "Signature": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + } + }, + "Ynl0ZSBhcnJheQ==", + "0" +] +``` + +Response: `"0"` + +### PaychVoucherCheckSpendable + + +Perms: read + +Inputs: +```json +[ + "f01234", + { + "ChannelAddr": "f01234", + "TimeLockMin": 10101, + "TimeLockMax": 10101, + "SecretPreimage": "Ynl0ZSBhcnJheQ==", + "Extra": { + "Actor": "f01234", + "Method": 1, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "Lane": 42, + "Nonce": 42, + "Amount": "0", + "MinSettleHeight": 10101, + "Merges": null, + "Signature": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + } + }, + "Ynl0ZSBhcnJheQ==", + "Ynl0ZSBhcnJheQ==" +] +``` + +Response: `true` + +### PaychVoucherCheckValid + + +Perms: read + +Inputs: +```json +[ + "f01234", + { + "ChannelAddr": "f01234", + "TimeLockMin": 10101, + "TimeLockMax": 10101, + "SecretPreimage": "Ynl0ZSBhcnJheQ==", + "Extra": { + "Actor": "f01234", + "Method": 1, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "Lane": 42, + "Nonce": 42, + "Amount": "0", + "MinSettleHeight": 10101, + "Merges": null, + "Signature": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + } + } +] +``` + +Response: `{}` + +### PaychVoucherCreate + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "0", + 42 +] +``` + +Response: +```json +{ + "Voucher": { + "ChannelAddr": "f01234", + "TimeLockMin": 10101, + "TimeLockMax": 10101, + "SecretPreimage": "Ynl0ZSBhcnJheQ==", + "Extra": { + "Actor": "f01234", + "Method": 1, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "Lane": 42, + "Nonce": 42, + "Amount": "0", + "MinSettleHeight": 10101, + "Merges": null, + "Signature": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + } + }, + "Shortfall": "0" +} +``` + +### PaychVoucherList + + +Perms: write + +Inputs: +```json +[ + "f01234" +] +``` + +Response: `null` + +### PaychVoucherSubmit + + +Perms: sign + +Inputs: +```json +[ + "f01234", + { + "ChannelAddr": "f01234", + "TimeLockMin": 10101, + "TimeLockMax": 10101, + "SecretPreimage": "Ynl0ZSBhcnJheQ==", + "Extra": { + "Actor": "f01234", + "Method": 1, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "Lane": 42, + "Nonce": 42, + "Amount": "0", + "MinSettleHeight": 10101, + "Merges": null, + "Signature": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + } + }, + "Ynl0ZSBhcnJheQ==", + "Ynl0ZSBhcnJheQ==" +] +``` + +Response: +```json +{ + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" +} +``` + +## 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 parent state of the tipset. +A nil TipSetKey can be provided as a param, this will cause the heaviest tipset in the chain to be used. + + +### StateAccountKey +StateAccountKey returns the public key address of the given ID address + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `"f01234"` + +### StateAllMinerFaults +StateAllMinerFaults returns all non-expired Faults that occur within lookback epochs of the given tipset + + +Perms: read + +Inputs: +```json +[ + 10101, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `null` + +### StateCall +StateCall runs the given message and returns its result without any persisted changes. + +StateCall applies the message to the tipset's parent state. The +message is not applied on-top-of the messages in the passed-in +tipset. + + +Perms: read + +Inputs: +```json +[ + { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "MsgCid": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Msg": { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + "MsgRct": { + "ExitCode": 0, + "Return": "Ynl0ZSBhcnJheQ==", + "GasUsed": 9 + }, + "GasCost": { + "Message": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "GasUsed": "0", + "BaseFeeBurn": "0", + "OverEstimationBurn": "0", + "MinerPenalty": "0", + "MinerTip": "0", + "Refund": "0", + "TotalCost": "0" + }, + "ExecutionTrace": { + "Msg": { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + "MsgRct": { + "ExitCode": 0, + "Return": "Ynl0ZSBhcnJheQ==", + "GasUsed": 9 + }, + "Error": "string value", + "Duration": 60000000000, + "GasCharges": null, + "Subcalls": null + }, + "Error": "string value", + "Duration": 60000000000 +} +``` + +### StateChangedActors +StateChangedActors returns all the actors whose states change between the two given state CIDs +TODO: Should this take tipset keys instead? + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: +```json +{ + "t01236": { + "Code": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Head": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Nonce": 42, + "Balance": "0" + } +} +``` + +### StateCirculatingSupply +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. + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `"0"` + +### StateCompute +StateCompute is a flexible command that applies the given messages on the given tipset. +The messages are run as though the VM were at the provided height. + +When called, StateCompute will: +- Load the provided tipset, or use the current chain head if not provided +- Compute the tipset state of the provided tipset on top of the parent state + - (note that this step runs before vmheight is applied to the execution) + - Execute state upgrade if any were scheduled at the epoch, or in null + blocks preceding the tipset + - Call the cron actor on null blocks preceding the tipset + - For each block in the tipset + - Apply messages in blocks in the specified + - Award block reward by calling the reward actor + - Call the cron actor for the current epoch +- If the specified vmheight is higher than the current epoch, apply any + needed state upgrades to the state +- Apply the specified messages to the state + +The vmheight parameter sets VM execution epoch, and can be used to simulate +message execution in different network versions. If the specified vmheight +epoch is higher than the epoch of the specified tipset, any state upgrades +until the vmheight will be executed on the state before applying messages +specified by the user. + +Note that the initial tipset state computation is not affected by the +vmheight parameter - only the messages in the `apply` set are + +If the caller wants to simply compute the state, vmheight should be set to +the epoch of the specified tipset. + +Messages in the `apply` parameter must have the correct nonces, and gas +values set. + + +Perms: read + +Inputs: +```json +[ + 10101, + null, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "Root": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Trace": null +} +``` + +### StateDealProviderCollateralBounds +StateDealProviderCollateralBounds returns the min and max collateral a storage provider +can issue. It takes the deal size and verified status as parameters. + + +Perms: read + +Inputs: +```json +[ + 1032, + true, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "Min": "0", + "Max": "0" +} +``` + +### StateDecodeParams +StateDecodeParams attempts to decode the provided params, based on the recipient actor address and method number. + + +Perms: read + +Inputs: +```json +[ + "f01234", + 1, + "Ynl0ZSBhcnJheQ==", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `{}` + +### StateGetActor +StateGetActor returns the indicated actor's nonce and balance. + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "Code": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Head": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Nonce": 42, + "Balance": "0" +} +``` + +### StateListActors +StateListActors returns the addresses of every actor in the state + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `null` + +### StateListMessages +StateListMessages looks back and returns all messages with a matching to or from address, stopping at the given height. + + +Perms: read + +Inputs: +```json +[ + { + "To": "f01234", + "From": "f01234" + }, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ], + 10101 +] +``` + +Response: `null` + +### StateListMiners +StateListMiners returns the addresses of every miner that has claimed power in the Power Actor + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `null` + +### StateLookupID +StateLookupID retrieves the ID address of the given address + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `"f01234"` + +### StateMarketBalance +StateMarketBalance looks up the Escrow and Locked balances of the given address in the Storage Market + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "Escrow": "0", + "Locked": "0" +} +``` + +### StateMarketDeals +StateMarketDeals returns information about every deal in the Storage Market + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "t026363": { + "Proposal": { + "PieceCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "PieceSize": 1032, + "VerifiedDeal": true, + "Client": "f01234", + "Provider": "f01234", + "Label": "string value", + "StartEpoch": 10101, + "EndEpoch": 10101, + "StoragePricePerEpoch": "0", + "ProviderCollateral": "0", + "ClientCollateral": "0" + }, + "State": { + "SectorStartEpoch": 10101, + "LastUpdatedEpoch": 10101, + "SlashEpoch": 10101 + } + } +} +``` + +### StateMarketParticipants +StateMarketParticipants returns the Escrow and Locked balances of every participant in the Storage Market + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "t026363": { + "Escrow": "0", + "Locked": "0" + } +} +``` + +### StateMarketStorageDeal +StateMarketStorageDeal returns information about the indicated deal + + +Perms: read + +Inputs: +```json +[ + 5432, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "Proposal": { + "PieceCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "PieceSize": 1032, + "VerifiedDeal": true, + "Client": "f01234", + "Provider": "f01234", + "Label": "string value", + "StartEpoch": 10101, + "EndEpoch": 10101, + "StoragePricePerEpoch": "0", + "ProviderCollateral": "0", + "ClientCollateral": "0" + }, + "State": { + "SectorStartEpoch": 10101, + "LastUpdatedEpoch": 10101, + "SlashEpoch": 10101 + } +} +``` + +### StateMinerActiveSectors +StateMinerActiveSectors returns info about sectors that a given miner is actively proving. + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `null` + +### StateMinerAvailableBalance +StateMinerAvailableBalance returns the portion of a miner's balance that can be withdrawn or spent + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `"0"` + +### StateMinerDeadlines +StateMinerDeadlines returns all the proving deadlines for the given miner + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `null` + +### StateMinerFaults +StateMinerFaults returns a bitfield indicating the faulty sectors of the given miner + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +[ + 5, + 1 +] +``` + +### StateMinerInfo +StateMinerInfo returns info about the indicated miner + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "Owner": "f01234", + "Worker": "f01234", + "NewWorker": "f01234", + "ControlAddresses": null, + "WorkerChangeEpoch": 10101, + "PeerId": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "Multiaddrs": null, + "WindowPoStProofType": 8, + "SectorSize": 34359738368, + "WindowPoStPartitionSectors": 42, + "ConsensusFaultElapsed": 10101 +} +``` + +### StateMinerInitialPledgeCollateral +StateMinerInitialPledgeCollateral returns the initial pledge collateral for the specified miner's sector + + +Perms: read + +Inputs: +```json +[ + "f01234", + { + "SealProof": 8, + "SectorNumber": 9, + "SealedCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "SealRandEpoch": 10101, + "DealIDs": null, + "Expiration": 10101, + "ReplaceCapacity": true, + "ReplaceSectorDeadline": 42, + "ReplaceSectorPartition": 42, + "ReplaceSectorNumber": 9 + }, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `"0"` + +### StateMinerPartitions +StateMinerPartitions returns all partitions in the specified deadline + + +Perms: read + +Inputs: +```json +[ + "f01234", + 42, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `null` + +### StateMinerPower +StateMinerPower returns the power of the indicated miner + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "MinerPower": { + "RawBytePower": "0", + "QualityAdjPower": "0" + }, + "TotalPower": { + "RawBytePower": "0", + "QualityAdjPower": "0" + }, + "HasMinPower": true +} +``` + +### StateMinerPreCommitDepositForPower +StateMinerInitialPledgeCollateral returns the precommit deposit for the specified miner's sector + + +Perms: read + +Inputs: +```json +[ + "f01234", + { + "SealProof": 8, + "SectorNumber": 9, + "SealedCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "SealRandEpoch": 10101, + "DealIDs": null, + "Expiration": 10101, + "ReplaceCapacity": true, + "ReplaceSectorDeadline": 42, + "ReplaceSectorPartition": 42, + "ReplaceSectorNumber": 9 + }, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `"0"` + +### StateMinerProvingDeadline +StateMinerProvingDeadline calculates the deadline at some epoch for a proving period +and returns the deadline-related calculations. + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "CurrentEpoch": 10101, + "PeriodStart": 10101, + "Index": 42, + "Open": 10101, + "Close": 10101, + "Challenge": 10101, + "FaultCutoff": 10101, + "WPoStPeriodDeadlines": 42, + "WPoStProvingPeriod": 10101, + "WPoStChallengeWindow": 10101, + "WPoStChallengeLookback": 10101, + "FaultDeclarationCutoff": 10101 +} +``` + +### StateMinerRecoveries +StateMinerRecoveries returns a bitfield indicating the recovering sectors of the given miner + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +[ + 5, + 1 +] +``` + +### StateMinerSectorAllocated +StateMinerSectorAllocated checks if a sector is allocated + + +Perms: read + +Inputs: +```json +[ + "f01234", + 9, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `true` + +### StateMinerSectorCount +StateMinerSectorCount returns the number of sectors in a miner's sector set and proving set + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "Live": 42, + "Active": 42, + "Faulty": 42 +} +``` + +### StateMinerSectors +StateMinerSectors returns info about the given miner's sectors. If the filter bitfield is nil, all sectors are included. + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + 0 + ], + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `null` + +### StateNetworkName +StateNetworkName returns the name of the network the node is synced to + + +Perms: read + +Inputs: `null` + +Response: `"lotus"` + +### StateNetworkVersion +StateNetworkVersion returns the network version at the given tipset + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `11` + +### StateReadState +StateReadState returns the indicated actor's state. + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "Balance": "0", + "Code": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "State": {} +} +``` + +### StateReplay +StateReplay replays a given message, assuming it was included in a block in the specified tipset. + +If a tipset key is provided, and a replacing message is found on chain, +the method will return an error saying that the message wasn't found + +If no tipset key is provided, the appropriate tipset is looked up, and if +the message was gas-repriced, the on-chain message will be replayed - in +that case the returned InvocResult.MsgCid will not match the Cid param + +If the caller wants to ensure that exactly the requested message was executed, +they MUST check that InvocResult.MsgCid is equal to the provided Cid. +Without this check both the requested and original message may appear as +successfully executed on-chain, which may look like a double-spend. + +A replacing message is a message with a different CID, any of Gas values, and +different signature, but with all other parameters matching (source/destination, +nonce, params, etc.) + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ], + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: +```json +{ + "MsgCid": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Msg": { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + "MsgRct": { + "ExitCode": 0, + "Return": "Ynl0ZSBhcnJheQ==", + "GasUsed": 9 + }, + "GasCost": { + "Message": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "GasUsed": "0", + "BaseFeeBurn": "0", + "OverEstimationBurn": "0", + "MinerPenalty": "0", + "MinerTip": "0", + "Refund": "0", + "TotalCost": "0" + }, + "ExecutionTrace": { + "Msg": { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + "MsgRct": { + "ExitCode": 0, + "Return": "Ynl0ZSBhcnJheQ==", + "GasUsed": 9 + }, + "Error": "string value", + "Duration": 60000000000, + "GasCharges": null, + "Subcalls": null + }, + "Error": "string value", + "Duration": 60000000000 +} +``` + +### StateSearchMsg +StateSearchMsg looks back up to limit epochs in the chain for a message, and returns its receipt and the tipset where it was executed + +NOTE: If a replacing message is found on chain, this method will return +a MsgLookup for the replacing message - the MsgLookup.Message will be a different +CID than the one provided in the 'cid' param, MsgLookup.Receipt will contain the +result of the execution of the replacing message. + +If the caller wants to ensure that exactly the requested message was executed, +they must check that MsgLookup.Message is equal to the provided 'cid', or set the +`allowReplaced` parameter to false. Without this check, and with `allowReplaced` +set to true, both the requested and original message may appear as +successfully executed on-chain, which may look like a double-spend. + +A replacing message is a message with a different CID, any of Gas values, and +different signature, but with all other parameters matching (source/destination, +nonce, params, etc.) + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ], + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + 10101, + true +] +``` + +Response: +```json +{ + "Message": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Receipt": { + "ExitCode": 0, + "Return": "Ynl0ZSBhcnJheQ==", + "GasUsed": 9 + }, + "ReturnDec": {}, + "TipSet": [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ], + "Height": 10101 +} +``` + +### StateSectorExpiration +StateSectorExpiration returns epoch at which given sector will expire + + +Perms: read + +Inputs: +```json +[ + "f01234", + 9, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "OnTime": 10101, + "Early": 10101 +} +``` + +### StateSectorGetInfo +StateSectorGetInfo returns the on-chain info for the specified miner's sector. Returns null in case the sector info isn't found +NOTE: returned info.Expiration may not be accurate in some cases, use StateSectorExpiration to get accurate +expiration epoch + + +Perms: read + +Inputs: +```json +[ + "f01234", + 9, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "SectorNumber": 9, + "SealProof": 8, + "SealedCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "DealIDs": null, + "Activation": 10101, + "Expiration": 10101, + "DealWeight": "0", + "VerifiedDealWeight": "0", + "InitialPledge": "0", + "ExpectedDayReward": "0", + "ExpectedStoragePledge": "0" +} +``` + +### StateSectorPartition +StateSectorPartition finds deadline/partition with the specified sector + + +Perms: read + +Inputs: +```json +[ + "f01234", + 9, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "Deadline": 42, + "Partition": 42 +} +``` + +### StateSectorPreCommitInfo +StateSectorPreCommitInfo returns the PreCommit info for the specified miner's sector + + +Perms: read + +Inputs: +```json +[ + "f01234", + 9, + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "Info": { + "SealProof": 8, + "SectorNumber": 9, + "SealedCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "SealRandEpoch": 10101, + "DealIDs": null, + "Expiration": 10101, + "ReplaceCapacity": true, + "ReplaceSectorDeadline": 42, + "ReplaceSectorPartition": 42, + "ReplaceSectorNumber": 9 + }, + "PreCommitDeposit": "0", + "PreCommitEpoch": 10101, + "DealWeight": "0", + "VerifiedDealWeight": "0" +} +``` + +### StateVMCirculatingSupplyInternal +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. + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: +```json +{ + "FilVested": "0", + "FilMined": "0", + "FilBurnt": "0", + "FilLocked": "0", + "FilCirculating": "0", + "FilReserveDisbursed": "0" +} +``` + +### StateVerifiedClientStatus +StateVerifiedClientStatus returns the data cap for the given address. +Returns nil if there is no entry in the data cap table for the +address. + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `"0"` + +### StateVerifiedRegistryRootKey +StateVerifiedClientStatus returns the address of the Verified Registry's root key + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `"f01234"` + +### StateVerifierStatus +StateVerifierStatus returns the data cap for the given address. +Returns nil if there is no entry in the data cap table for the +address. + + +Perms: read + +Inputs: +```json +[ + "f01234", + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `"0"` + +### StateWaitMsg +StateWaitMsg looks back up to limit epochs in the chain for a message. +If not found, it blocks until the message arrives on chain, and gets to the +indicated confidence depth. + +NOTE: If a replacing message is found on chain, this method will return +a MsgLookup for the replacing message - the MsgLookup.Message will be a different +CID than the one provided in the 'cid' param, MsgLookup.Receipt will contain the +result of the execution of the replacing message. + +If the caller wants to ensure that exactly the requested message was executed, +they must check that MsgLookup.Message is equal to the provided 'cid', or set the +`allowReplaced` parameter to false. Without this check, and with `allowReplaced` +set to true, both the requested and original message may appear as +successfully executed on-chain, which may look like a double-spend. + +A replacing message is a message with a different CID, any of Gas values, and +different signature, but with all other parameters matching (source/destination, +nonce, params, etc.) + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + 42, + 10101, + true +] +``` + +Response: +```json +{ + "Message": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Receipt": { + "ExitCode": 0, + "Return": "Ynl0ZSBhcnJheQ==", + "GasUsed": 9 + }, + "ReturnDec": {}, + "TipSet": [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ], + "Height": 10101 +} +``` + +## Sync +The Sync method group contains methods for interacting with and +observing the lotus sync service. + + +### SyncCheckBad +SyncCheckBad checks if a block was marked as bad, and if it was, returns +the reason. + + +Perms: read + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: `"string value"` + +### SyncCheckpoint +SyncCheckpoint marks a blocks as checkpointed, meaning that it won't ever fork away from it. + + +Perms: admin + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `{}` + +### SyncIncomingBlocks +SyncIncomingBlocks returns a channel streaming incoming, potentially not +yet synced block headers. + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "Miner": "f01234", + "Ticket": { + "VRFProof": "Ynl0ZSBhcnJheQ==" + }, + "ElectionProof": { + "WinCount": 9, + "VRFProof": "Ynl0ZSBhcnJheQ==" + }, + "BeaconEntries": null, + "WinPoStProof": null, + "Parents": null, + "ParentWeight": "0", + "Height": 10101, + "ParentStateRoot": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "ParentMessageReceipts": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Messages": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "BLSAggregate": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "Timestamp": 42, + "BlockSig": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "ForkSignaling": 42, + "ParentBaseFee": "0" +} +``` + +### SyncMarkBad +SyncMarkBad marks a blocks as bad, meaning that it won't ever by synced. +Use with extreme caution. + + +Perms: admin + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: `{}` + +### SyncState +SyncState returns the current status of the lotus sync system. + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "ActiveSyncs": null, + "VMApplied": 42 +} +``` + +### SyncSubmitBlock +SyncSubmitBlock can be used to submit a newly created block to the. +network through this node + + +Perms: write + +Inputs: +```json +[ + { + "Header": { + "Miner": "f01234", + "Ticket": { + "VRFProof": "Ynl0ZSBhcnJheQ==" + }, + "ElectionProof": { + "WinCount": 9, + "VRFProof": "Ynl0ZSBhcnJheQ==" + }, + "BeaconEntries": null, + "WinPoStProof": null, + "Parents": null, + "ParentWeight": "0", + "Height": 10101, + "ParentStateRoot": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "ParentMessageReceipts": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "Messages": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "BLSAggregate": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "Timestamp": 42, + "BlockSig": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "ForkSignaling": 42, + "ParentBaseFee": "0" + }, + "BlsMessages": null, + "SecpkMessages": null + } +] +``` + +Response: `{}` + +### SyncUnmarkAllBad +SyncUnmarkAllBad purges bad block cache, making it possible to sync to chains previously marked as bad + + +Perms: admin + +Inputs: `null` + +Response: `{}` + +### SyncUnmarkBad +SyncUnmarkBad unmarks a blocks as bad, making it possible to be validated and synced again. + + +Perms: admin + +Inputs: +```json +[ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + } +] +``` + +Response: `{}` + +### SyncValidateTipset +SyncValidateTipset indicates whether the provided tipset is valid or not + + +Perms: read + +Inputs: +```json +[ + [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ] +] +``` + +Response: `true` + +## Wallet + + +### WalletBalance +WalletBalance returns the balance of the given address at the current head of the chain. + + +Perms: read + +Inputs: +```json +[ + "f01234" +] +``` + +Response: `"0"` + +### WalletDefaultAddress +WalletDefaultAddress returns the address marked as default in the wallet. + + +Perms: write + +Inputs: `null` + +Response: `"f01234"` + +### WalletDelete +WalletDelete deletes an address from the wallet. + + +Perms: admin + +Inputs: +```json +[ + "f01234" +] +``` + +Response: `{}` + +### WalletExport +WalletExport returns the private key of an address in the wallet. + + +Perms: admin + +Inputs: +```json +[ + "f01234" +] +``` + +Response: +```json +{ + "Type": "bls", + "PrivateKey": "Ynl0ZSBhcnJheQ==" +} +``` + +### WalletHas +WalletHas indicates whether the given address is in the wallet. + + +Perms: write + +Inputs: +```json +[ + "f01234" +] +``` + +Response: `true` + +### WalletImport +WalletImport receives a KeyInfo, which includes a private key, and imports it into the wallet. + + +Perms: admin + +Inputs: +```json +[ + { + "Type": "bls", + "PrivateKey": "Ynl0ZSBhcnJheQ==" + } +] +``` + +Response: `"f01234"` + +### WalletList +WalletList lists all the addresses in the wallet. + + +Perms: write + +Inputs: `null` + +Response: `null` + +### WalletNew +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 + + +Perms: write + +Inputs: +```json +[ + "bls" +] +``` + +Response: `"f01234"` + +### WalletSetDefault +WalletSetDefault marks the given address as as the default one. + + +Perms: write + +Inputs: +```json +[ + "f01234" +] +``` + +Response: `{}` + +### WalletSign +WalletSign signs the given bytes using the given address. + + +Perms: sign + +Inputs: +```json +[ + "f01234", + "Ynl0ZSBhcnJheQ==" +] +``` + +Response: +```json +{ + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" +} +``` + +### WalletSignMessage +WalletSignMessage signs the given message using the given address. + + +Perms: sign + +Inputs: +```json +[ + "f01234", + { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + } +] +``` + +Response: +```json +{ + "Message": { + "Version": 42, + "To": "f01234", + "From": "f01234", + "Nonce": 42, + "Value": "0", + "GasLimit": 9, + "GasFeeCap": "0", + "GasPremium": "0", + "Method": 1, + "Params": "Ynl0ZSBhcnJheQ==", + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } + }, + "Signature": { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + }, + "CID": { + "/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s" + } +} +``` + +### WalletValidateAddress +WalletValidateAddress validates whether a given string can be decoded as a well-formed address + + +Perms: read + +Inputs: +```json +[ + "string value" +] +``` + +Response: `"f01234"` + +### WalletVerify +WalletVerify takes an address, a signature, and some bytes, and indicates whether the signature is valid. +The address does not have to be in the wallet. + + +Perms: read + +Inputs: +```json +[ + "f01234", + "Ynl0ZSBhcnJheQ==", + { + "Type": 2, + "Data": "Ynl0ZSBhcnJheQ==" + } +] +``` + +Response: `true` + diff --git a/documentation/en/cli-lotus-miner.md b/documentation/en/cli-lotus-miner.md new file mode 100644 index 00000000000..1b9b80ee94a --- /dev/null +++ b/documentation/en/cli-lotus-miner.md @@ -0,0 +1,1816 @@ +# lotus-miner +``` +NAME: + lotus-miner - Filecoin decentralized storage network miner + +USAGE: + lotus-miner [global options] command [command options] [arguments...] + +VERSION: + 1.11.0-dev + +COMMANDS: + init Initialize a lotus miner repo + run Start a lotus miner process + stop Stop a running lotus miner + config Output default configuration + backup Create node metadata backup + version Print version + help, h Shows a list of commands or help for one command + CHAIN: + actor manipulate the miner actor + info Print miner info + DEVELOPER: + auth Manage RPC permissions + log Manage logging + wait-api Wait for lotus api to come online + fetch-params Fetch proving parameters + MARKET: + storage-deals Manage storage deals and related configuration + retrieval-deals Manage retrieval deals and related configuration + data-transfers Manage data transfers + NETWORK: + net Manage P2P Network + RETRIEVAL: + pieces interact with the piecestore + STORAGE: + sectors interact with sector store + proving View proving information + storage manage sector storage + sealing interact with sealing pipeline + +GLOBAL OPTIONS: + --actor value, -a value specify other actor to check state for (read only) + --color (default: false) + --miner-repo value, --storagerepo value Specify miner repo path. flag(storagerepo) and env(LOTUS_STORAGE_PATH) are DEPRECATION, will REMOVE SOON (default: "~/.lotusminer") [$LOTUS_MINER_PATH, $LOTUS_STORAGE_PATH] + --help, -h show help (default: false) + --version, -v print the version (default: false) +``` + +## lotus-miner init +``` +NAME: + lotus-miner init - Initialize a lotus miner repo + +USAGE: + lotus-miner init command [command options] [arguments...] + +COMMANDS: + restore Initialize a lotus miner repo from a backup + help, h Shows a list of commands or help for one command + +OPTIONS: + --actor value specify the address of an already created miner actor + --create-worker-key create separate worker key (default: false) + --worker value, -w value worker key to use (overrides --create-worker-key) + --owner value, -o value owner key to use + --sector-size value specify sector size to use (default: "32GiB") + --pre-sealed-sectors value specify set of presealed sectors for starting as a genesis miner + --pre-sealed-metadata value specify the metadata file for the presealed sectors + --nosync don't check full-node sync status (default: false) + --symlink-imported-sectors attempt to symlink to presealed sectors instead of copying them into place (default: false) + --no-local-storage don't use storageminer repo for sector storage (default: false) + --gas-premium value set gas premium for initialization messages in AttoFIL (default: "0") + --from value select which address to send actor creation message from + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +### lotus-miner init restore +``` +NAME: + lotus-miner init restore - Initialize a lotus miner repo from a backup + +USAGE: + lotus-miner init restore [command options] [backupFile] + +OPTIONS: + --nosync don't check full-node sync status (default: false) + --config value config file (config.toml) + --storage-config value storage paths config (storage.json) + --help, -h show help (default: false) + +``` + +## lotus-miner run +``` +NAME: + lotus-miner run - Start a lotus miner process + +USAGE: + lotus-miner run [command options] [arguments...] + +OPTIONS: + --miner-api value 2345 + --enable-gpu-proving enable use of GPU for mining operations (default: true) + --nosync don't check full-node sync status (default: false) + --manage-fdlimit manage open file limit (default: true) + --help, -h show help (default: false) + +``` + +## lotus-miner stop +``` +NAME: + lotus-miner stop - Stop a running lotus miner + +USAGE: + lotus-miner stop [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +## lotus-miner config +``` +NAME: + lotus-miner config - Output default configuration + +USAGE: + lotus-miner config [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +## lotus-miner backup +``` +NAME: + lotus-miner backup - Create node metadata backup + +USAGE: + lotus-miner backup [command options] [backup file path] + +DESCRIPTION: + The backup command writes a copy of node metadata under the specified path + +Online backups: +For security reasons, the daemon must be have LOTUS_BACKUP_BASE_PATH env var set +to a path where backup files are supposed to be saved, and the path specified in +this command must be within this base path + +OPTIONS: + --offline create backup without the node running (default: false) + --help, -h show help (default: false) + +``` + +## lotus-miner version +``` +NAME: + lotus-miner version - Print version + +USAGE: + lotus-miner version [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +## lotus-miner actor +``` +NAME: + lotus-miner actor - manipulate the miner actor + +USAGE: + lotus-miner actor command [command options] [arguments...] + +COMMANDS: + set-addrs set addresses that your miner can be publicly dialed on + withdraw withdraw available balance + repay-debt pay down a miner's debt + set-peer-id set the peer id of your miner + set-owner Set owner address (this command should be invoked twice, first with the old owner as the senderAddress, and then with the new owner) + control Manage control addresses + propose-change-worker Propose a worker address change + confirm-change-worker Confirm a worker address change + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +### lotus-miner actor set-addrs +``` +NAME: + lotus-miner actor set-addrs - set addresses that your miner can be publicly dialed on + +USAGE: + lotus-miner actor set-addrs [command options] [arguments...] + +OPTIONS: + --gas-limit value set gas limit (default: 0) + --unset unset address (default: false) + --help, -h show help (default: false) + +``` + +### lotus-miner actor withdraw +``` +NAME: + lotus-miner actor withdraw - withdraw available balance + +USAGE: + lotus-miner actor withdraw [command options] [amount (FIL)] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus-miner actor repay-debt +``` +NAME: + lotus-miner actor repay-debt - pay down a miner's debt + +USAGE: + lotus-miner actor repay-debt [command options] [amount (FIL)] + +OPTIONS: + --from value optionally specify the account to send funds from + --help, -h show help (default: false) + +``` + +### lotus-miner actor set-peer-id +``` +NAME: + lotus-miner actor set-peer-id - set the peer id of your miner + +USAGE: + lotus-miner actor set-peer-id [command options] [arguments...] + +OPTIONS: + --gas-limit value set gas limit (default: 0) + --help, -h show help (default: false) + +``` + +### lotus-miner actor set-owner +``` +NAME: + lotus-miner actor set-owner - Set owner address (this command should be invoked twice, first with the old owner as the senderAddress, and then with the new owner) + +USAGE: + lotus-miner actor set-owner [command options] [newOwnerAddress senderAddress] + +OPTIONS: + --really-do-it Actually send transaction performing the action (default: false) + --help, -h show help (default: false) + +``` + +### lotus-miner actor control +``` +NAME: + lotus-miner actor control - Manage control addresses + +USAGE: + lotus-miner actor control command [command options] [arguments...] + +COMMANDS: + list Get currently set control addresses + set Set control address(-es) + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +#### lotus-miner actor control list +``` +NAME: + lotus-miner actor control list - Get currently set control addresses + +USAGE: + lotus-miner actor control list [command options] [arguments...] + +OPTIONS: + --verbose (default: false) + --color (default: true) + --help, -h show help (default: false) + +``` + +#### lotus-miner actor control set +``` +NAME: + lotus-miner actor control set - Set control address(-es) + +USAGE: + lotus-miner actor control set [command options] [...address] + +OPTIONS: + --really-do-it Actually send transaction performing the action (default: false) + --help, -h show help (default: false) + +``` + +### lotus-miner actor propose-change-worker +``` +NAME: + lotus-miner actor propose-change-worker - Propose a worker address change + +USAGE: + lotus-miner actor propose-change-worker [command options] [address] + +OPTIONS: + --really-do-it Actually send transaction performing the action (default: false) + --help, -h show help (default: false) + +``` + +### lotus-miner actor confirm-change-worker +``` +NAME: + lotus-miner actor confirm-change-worker - Confirm a worker address change + +USAGE: + lotus-miner actor confirm-change-worker [command options] [address] + +OPTIONS: + --really-do-it Actually send transaction performing the action (default: false) + --help, -h show help (default: false) + +``` + +## lotus-miner info +``` +NAME: + lotus-miner info - Print miner info + +USAGE: + lotus-miner info command [command options] [arguments...] + +COMMANDS: + all dump all related miner info + help, h Shows a list of commands or help for one command + +OPTIONS: + --hide-sectors-info hide sectors info (default: false) + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +### lotus-miner info all +``` +NAME: + lotus-miner info all - dump all related miner info + +USAGE: + lotus-miner info all [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +## lotus-miner auth +``` +NAME: + lotus-miner auth - Manage RPC permissions + +USAGE: + lotus-miner auth command [command options] [arguments...] + +COMMANDS: + create-token Create token + api-info Get token with API info required to connect to this node + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +### lotus-miner auth create-token +``` +NAME: + lotus-miner auth create-token - Create token + +USAGE: + lotus-miner auth create-token [command options] [arguments...] + +OPTIONS: + --perm value permission to assign to the token, one of: read, write, sign, admin + --help, -h show help (default: false) + +``` + +### lotus-miner auth api-info +``` +NAME: + lotus-miner auth api-info - Get token with API info required to connect to this node + +USAGE: + lotus-miner auth api-info [command options] [arguments...] + +OPTIONS: + --perm value permission to assign to the token, one of: read, write, sign, admin + --help, -h show help (default: false) + +``` + +## lotus-miner log +``` +NAME: + lotus-miner log - Manage logging + +USAGE: + lotus-miner log command [command options] [arguments...] + +COMMANDS: + list List log systems + set-level Set log level + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +### lotus-miner log list +``` +NAME: + lotus-miner log list - List log systems + +USAGE: + lotus-miner log list [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus-miner log set-level +``` +NAME: + lotus-miner log set-level - Set log level + +USAGE: + lotus-miner log set-level [command options] [level] + +DESCRIPTION: + Set the log level for logging systems: + + The system flag can be specified multiple times. + + eg) log set-level --system chain --system chainxchg debug + + Available Levels: + debug + info + warn + error + + Environment Variables: + GOLOG_LOG_LEVEL - Default log level for all log systems + GOLOG_LOG_FMT - Change output log format (json, nocolor) + GOLOG_FILE - Write logs to file + GOLOG_OUTPUT - Specify whether to output to file, stderr, stdout or a combination, i.e. file+stderr + + +OPTIONS: + --system value limit to log system + --help, -h show help (default: false) + +``` + +## lotus-miner wait-api +``` +NAME: + lotus-miner wait-api - Wait for lotus api to come online + +USAGE: + lotus-miner wait-api [command options] [arguments...] + +CATEGORY: + DEVELOPER + +OPTIONS: + --help, -h show help (default: false) + +``` + +## lotus-miner fetch-params +``` +NAME: + lotus-miner fetch-params - Fetch proving parameters + +USAGE: + lotus-miner fetch-params [command options] [sectorSize] + +CATEGORY: + DEVELOPER + +OPTIONS: + --help, -h show help (default: false) + +``` + +## lotus-miner storage-deals +``` +NAME: + lotus-miner storage-deals - Manage storage deals and related configuration + +USAGE: + lotus-miner storage-deals command [command options] [arguments...] + +COMMANDS: + import-data Manually import data for a deal + list List all deals for this miner + selection Configure acceptance criteria for storage deal proposals + set-ask Configure the miner's ask + get-ask Print the miner's ask + set-blocklist Set the miner's list of blocklisted piece CIDs + get-blocklist List the contents of the miner's piece CID blocklist + reset-blocklist Remove all entries from the miner's piece CID blocklist + set-seal-duration Set the expected time, in minutes, that you expect sealing sectors to take. Deals that start before this duration will be rejected. + pending-publish list deals waiting in publish queue + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +### lotus-miner storage-deals import-data +``` +NAME: + lotus-miner storage-deals import-data - Manually import data for a deal + +USAGE: + lotus-miner storage-deals import-data [command options] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus-miner storage-deals list +``` +NAME: + lotus-miner storage-deals list - List all deals for this miner + +USAGE: + lotus-miner storage-deals list [command options] [arguments...] + +OPTIONS: + --verbose, -v (default: false) + --watch watch deal updates in real-time, rather than a one time list (default: false) + --help, -h show help (default: false) + +``` + +### lotus-miner storage-deals selection +``` +NAME: + lotus-miner storage-deals selection - Configure acceptance criteria for storage deal proposals + +USAGE: + lotus-miner storage-deals selection command [command options] [arguments...] + +COMMANDS: + list List storage deal proposal selection criteria + reset Reset storage deal proposal selection criteria to default values + reject Configure criteria which necessitate automatic rejection + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +#### lotus-miner storage-deals selection list +``` +NAME: + lotus-miner storage-deals selection list - List storage deal proposal selection criteria + +USAGE: + lotus-miner storage-deals selection list [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +#### lotus-miner storage-deals selection reset +``` +NAME: + lotus-miner storage-deals selection reset - Reset storage deal proposal selection criteria to default values + +USAGE: + lotus-miner storage-deals selection reset [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +#### lotus-miner storage-deals selection reject +``` +NAME: + lotus-miner storage-deals selection reject - Configure criteria which necessitate automatic rejection + +USAGE: + lotus-miner storage-deals selection reject [command options] [arguments...] + +OPTIONS: + --online (default: false) + --offline (default: false) + --verified (default: false) + --unverified (default: false) + --help, -h show help (default: false) + +``` + +### lotus-miner storage-deals set-ask +``` +NAME: + lotus-miner storage-deals set-ask - Configure the miner's ask + +USAGE: + lotus-miner storage-deals set-ask [command options] [arguments...] + +OPTIONS: + --price PRICE Set the price of the ask for unverified deals (specified as FIL / GiB / Epoch) to PRICE. + --verified-price PRICE Set the price of the ask for verified deals (specified as FIL / GiB / Epoch) to PRICE + --min-piece-size SIZE Set minimum piece size (w/bit-padding, in bytes) in ask to SIZE (default: 256B) + --max-piece-size SIZE Set maximum piece size (w/bit-padding, in bytes) in ask to SIZE (default: miner sector size) + --help, -h show help (default: false) + +``` + +### lotus-miner storage-deals get-ask +``` +NAME: + lotus-miner storage-deals get-ask - Print the miner's ask + +USAGE: + lotus-miner storage-deals get-ask [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus-miner storage-deals set-blocklist +``` +NAME: + lotus-miner storage-deals set-blocklist - Set the miner's list of blocklisted piece CIDs + +USAGE: + lotus-miner storage-deals set-blocklist [command options] [ (optional, will read from stdin if omitted)] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus-miner storage-deals get-blocklist +``` +NAME: + lotus-miner storage-deals get-blocklist - List the contents of the miner's piece CID blocklist + +USAGE: + lotus-miner storage-deals get-blocklist [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus-miner storage-deals reset-blocklist +``` +NAME: + lotus-miner storage-deals reset-blocklist - Remove all entries from the miner's piece CID blocklist + +USAGE: + lotus-miner storage-deals reset-blocklist [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus-miner storage-deals set-seal-duration +``` +NAME: + lotus-miner storage-deals set-seal-duration - Set the expected time, in minutes, that you expect sealing sectors to take. Deals that start before this duration will be rejected. + +USAGE: + lotus-miner storage-deals set-seal-duration [command options] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus-miner storage-deals pending-publish +``` +NAME: + lotus-miner storage-deals pending-publish - list deals waiting in publish queue + +USAGE: + lotus-miner storage-deals pending-publish [command options] [arguments...] + +OPTIONS: + --publish-now send a publish message now (default: false) + --help, -h show help (default: false) + +``` + +## lotus-miner retrieval-deals +``` +NAME: + lotus-miner retrieval-deals - Manage retrieval deals and related configuration + +USAGE: + lotus-miner retrieval-deals command [command options] [arguments...] + +COMMANDS: + selection Configure acceptance criteria for retrieval deal proposals + list List all active retrieval deals for this miner + set-ask Configure the provider's retrieval ask + get-ask Get the provider's current retrieval ask + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +### lotus-miner retrieval-deals selection +``` +NAME: + lotus-miner retrieval-deals selection - Configure acceptance criteria for retrieval deal proposals + +USAGE: + lotus-miner retrieval-deals selection command [command options] [arguments...] + +COMMANDS: + list List retrieval deal proposal selection criteria + reset Reset retrieval deal proposal selection criteria to default values + reject Configure criteria which necessitate automatic rejection + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +#### lotus-miner retrieval-deals selection list +``` +NAME: + lotus-miner retrieval-deals selection list - List retrieval deal proposal selection criteria + +USAGE: + lotus-miner retrieval-deals selection list [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +#### lotus-miner retrieval-deals selection reset +``` +NAME: + lotus-miner retrieval-deals selection reset - Reset retrieval deal proposal selection criteria to default values + +USAGE: + lotus-miner retrieval-deals selection reset [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +#### lotus-miner retrieval-deals selection reject +``` +NAME: + lotus-miner retrieval-deals selection reject - Configure criteria which necessitate automatic rejection + +USAGE: + lotus-miner retrieval-deals selection reject [command options] [arguments...] + +OPTIONS: + --online (default: false) + --offline (default: false) + --help, -h show help (default: false) + +``` + +### lotus-miner retrieval-deals list +``` +NAME: + lotus-miner retrieval-deals list - List all active retrieval deals for this miner + +USAGE: + lotus-miner retrieval-deals list [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus-miner retrieval-deals set-ask +``` +NAME: + lotus-miner retrieval-deals set-ask - Configure the provider's retrieval ask + +USAGE: + lotus-miner retrieval-deals set-ask [command options] [arguments...] + +OPTIONS: + --price value Set the price of the ask for retrievals (FIL/GiB) + --unseal-price value Set the price to unseal + --payment-interval value Set the payment interval (in bytes) for retrieval (default: 1MiB) + --payment-interval-increase value Set the payment interval increase (in bytes) for retrieval (default: 1MiB) + --help, -h show help (default: false) + +``` + +### lotus-miner retrieval-deals get-ask +``` +NAME: + lotus-miner retrieval-deals get-ask - Get the provider's current retrieval ask + +USAGE: + lotus-miner retrieval-deals get-ask [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +## lotus-miner data-transfers +``` +NAME: + lotus-miner data-transfers - Manage data transfers + +USAGE: + lotus-miner data-transfers command [command options] [arguments...] + +COMMANDS: + list List ongoing data transfers for this miner + restart Force restart a stalled data transfer + cancel Force cancel a data transfer + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +### lotus-miner data-transfers list +``` +NAME: + lotus-miner data-transfers list - List ongoing data transfers for this miner + +USAGE: + lotus-miner data-transfers list [command options] [arguments...] + +OPTIONS: + --verbose, -v print verbose transfer details (default: false) + --color use color in display output (default: true) + --completed show completed data transfers (default: false) + --watch watch deal updates in real-time, rather than a one time list (default: false) + --show-failed show failed/cancelled transfers (default: false) + --help, -h show help (default: false) + +``` + +### lotus-miner data-transfers restart +``` +NAME: + lotus-miner data-transfers restart - Force restart a stalled data transfer + +USAGE: + lotus-miner data-transfers restart [command options] [arguments...] + +OPTIONS: + --peerid value narrow to transfer with specific peer + --initiator specify only transfers where peer is/is not initiator (default: false) + --help, -h show help (default: false) + +``` + +### lotus-miner data-transfers cancel +``` +NAME: + lotus-miner data-transfers cancel - Force cancel a data transfer + +USAGE: + lotus-miner data-transfers cancel [command options] [arguments...] + +OPTIONS: + --peerid value narrow to transfer with specific peer + --initiator specify only transfers where peer is/is not initiator (default: false) + --cancel-timeout value time to wait for cancel to be sent to client (default: 5s) + --help, -h show help (default: false) + +``` + +## lotus-miner net +``` +NAME: + lotus-miner net - Manage P2P Network + +USAGE: + lotus-miner net command [command options] [arguments...] + +COMMANDS: + peers Print peers + connect Connect to a peer + listen List listen addresses + id Get node identity + findpeer Find the addresses of a given peerID + scores Print peers' pubsub scores + reachability Print information about reachability from the internet + bandwidth Print bandwidth usage information + block Manage network connection gating rules + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +### lotus-miner net peers +``` +NAME: + lotus-miner net peers - Print peers + +USAGE: + lotus-miner net peers [command options] [arguments...] + +OPTIONS: + --agent, -a Print agent name (default: false) + --extended, -x Print extended peer information in json (default: false) + --help, -h show help (default: false) + +``` + +### lotus-miner net connect +``` +NAME: + lotus-miner net connect - Connect to a peer + +USAGE: + lotus-miner net connect [command options] [peerMultiaddr|minerActorAddress] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus-miner net listen +``` +NAME: + lotus-miner net listen - List listen addresses + +USAGE: + lotus-miner net listen [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus-miner net id +``` +NAME: + lotus-miner net id - Get node identity + +USAGE: + lotus-miner net id [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus-miner net findpeer +``` +NAME: + lotus-miner net findpeer - Find the addresses of a given peerID + +USAGE: + lotus-miner net findpeer [command options] [peerId] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus-miner net scores +``` +NAME: + lotus-miner net scores - Print peers' pubsub scores + +USAGE: + lotus-miner net scores [command options] [arguments...] + +OPTIONS: + --extended, -x print extended peer scores in json (default: false) + --help, -h show help (default: false) + +``` + +### lotus-miner net reachability +``` +NAME: + lotus-miner net reachability - Print information about reachability from the internet + +USAGE: + lotus-miner net reachability [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus-miner net bandwidth +``` +NAME: + lotus-miner net bandwidth - Print bandwidth usage information + +USAGE: + lotus-miner net bandwidth [command options] [arguments...] + +OPTIONS: + --by-peer list bandwidth usage by peer (default: false) + --by-protocol list bandwidth usage by protocol (default: false) + --help, -h show help (default: false) + +``` + +### lotus-miner net block +``` +NAME: + lotus-miner net block - Manage network connection gating rules + +USAGE: + lotus-miner net block command [command options] [arguments...] + +COMMANDS: + add Add connection gating rules + remove Remove connection gating rules + list list connection gating rules + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +#### lotus-miner net block add +``` +NAME: + lotus-miner net block add - Add connection gating rules + +USAGE: + lotus-miner net block add command [command options] [arguments...] + +COMMANDS: + peer Block a peer + ip Block an IP address + subnet Block an IP subnet + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +##### lotus-miner net block add peer +``` +NAME: + lotus-miner net block add peer - Block a peer + +USAGE: + lotus-miner net block add peer [command options] ... + +OPTIONS: + --help, -h show help (default: false) + +``` + +##### lotus-miner net block add ip +``` +NAME: + lotus-miner net block add ip - Block an IP address + +USAGE: + lotus-miner net block add ip [command options] ... + +OPTIONS: + --help, -h show help (default: false) + +``` + +##### lotus-miner net block add subnet +``` +NAME: + lotus-miner net block add subnet - Block an IP subnet + +USAGE: + lotus-miner net block add subnet [command options] ... + +OPTIONS: + --help, -h show help (default: false) + +``` + +#### lotus-miner net block remove +``` +NAME: + lotus-miner net block remove - Remove connection gating rules + +USAGE: + lotus-miner net block remove command [command options] [arguments...] + +COMMANDS: + peer Unblock a peer + ip Unblock an IP address + subnet Unblock an IP subnet + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +##### lotus-miner net block remove peer +``` +NAME: + lotus-miner net block remove peer - Unblock a peer + +USAGE: + lotus-miner net block remove peer [command options] ... + +OPTIONS: + --help, -h show help (default: false) + +``` + +##### lotus-miner net block remove ip +``` +NAME: + lotus-miner net block remove ip - Unblock an IP address + +USAGE: + lotus-miner net block remove ip [command options] ... + +OPTIONS: + --help, -h show help (default: false) + +``` + +##### lotus-miner net block remove subnet +``` +NAME: + lotus-miner net block remove subnet - Unblock an IP subnet + +USAGE: + lotus-miner net block remove subnet [command options] ... + +OPTIONS: + --help, -h show help (default: false) + +``` + +#### lotus-miner net block list +``` +NAME: + lotus-miner net block list - list connection gating rules + +USAGE: + lotus-miner net block list [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +## lotus-miner pieces +``` +NAME: + lotus-miner pieces - interact with the piecestore + +USAGE: + lotus-miner pieces command [command options] [arguments...] + +DESCRIPTION: + The piecestore is a database that tracks and manages data that is made available to the retrieval market + +COMMANDS: + list-pieces list registered pieces + list-cids list registered payload CIDs + piece-info get registered information for a given piece CID + cid-info get registered information for a given payload CID + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +### lotus-miner pieces list-pieces +``` +NAME: + lotus-miner pieces list-pieces - list registered pieces + +USAGE: + lotus-miner pieces list-pieces [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus-miner pieces list-cids +``` +NAME: + lotus-miner pieces list-cids - list registered payload CIDs + +USAGE: + lotus-miner pieces list-cids [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus-miner pieces piece-info +``` +NAME: + lotus-miner pieces piece-info - get registered information for a given piece CID + +USAGE: + lotus-miner pieces piece-info [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus-miner pieces cid-info +``` +NAME: + lotus-miner pieces cid-info - get registered information for a given payload CID + +USAGE: + lotus-miner pieces cid-info [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +## lotus-miner sectors +``` +NAME: + lotus-miner sectors - interact with sector store + +USAGE: + lotus-miner sectors command [command options] [arguments...] + +COMMANDS: + status Get the seal status of a sector by its number + list List sectors + refs List References to sectors + update-state ADVANCED: manually update the state of a sector, this may aid in error recovery + pledge store random data in a sector + extend Extend sector expiration + terminate Terminate sector on-chain then remove (WARNING: This means losing power and collateral for the removed sector) + remove Forcefully remove a sector (WARNING: This means losing power and collateral for the removed sector (use 'terminate' for lower penalty)) + mark-for-upgrade Mark a committed capacity sector for replacement by a sector with deals + seal Manually start sealing a sector (filling any unused space with junk) + set-seal-delay Set the time, in minutes, that a new sector waits for deals before sealing starts + get-cc-collateral Get the collateral required to pledge a committed capacity sector + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +### lotus-miner sectors status +``` +NAME: + lotus-miner sectors status - Get the seal status of a sector by its number + +USAGE: + lotus-miner sectors status [command options] + +OPTIONS: + --log display event log (default: false) + --on-chain-info show sector on chain info (default: false) + --help, -h show help (default: false) + +``` + +### lotus-miner sectors list +``` +NAME: + lotus-miner sectors list - List sectors + +USAGE: + lotus-miner sectors list [command options] [arguments...] + +OPTIONS: + --show-removed show removed sectors (default: false) + --color, -c (default: true) + --fast don't show on-chain info for better performance (default: false) + --events display number of events the sector has received (default: false) + --seal-time display how long it took for the sector to be sealed (default: false) + --states value filter sectors by a comma-separated list of states + --help, -h show help (default: false) + +``` + +### lotus-miner sectors refs +``` +NAME: + lotus-miner sectors refs - List References to sectors + +USAGE: + lotus-miner sectors refs [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus-miner sectors update-state +``` +NAME: + lotus-miner sectors update-state - ADVANCED: manually update the state of a sector, this may aid in error recovery + +USAGE: + lotus-miner sectors update-state [command options] + +OPTIONS: + --really-do-it pass this flag if you know what you are doing (default: false) + --help, -h show help (default: false) + +``` + +### lotus-miner sectors pledge +``` +NAME: + lotus-miner sectors pledge - store random data in a sector + +USAGE: + lotus-miner sectors pledge [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus-miner sectors extend +``` +NAME: + lotus-miner sectors extend - Extend sector expiration + +USAGE: + lotus-miner sectors extend [command options] + +OPTIONS: + --new-expiration value new expiration epoch (default: 0) + --v1-sectors renews all v1 sectors up to the maximum possible lifetime (default: false) + --tolerance value when extending v1 sectors, don't try to extend sectors by fewer than this number of epochs (default: 20160) + --expiration-cutoff value when extending v1 sectors, skip sectors whose current expiration is more than epochs from now (infinity if unspecified) (default: 0) + + --help, -h show help (default: false) + +``` + +### lotus-miner sectors terminate +``` +NAME: + lotus-miner sectors terminate - Terminate sector on-chain then remove (WARNING: This means losing power and collateral for the removed sector) + +USAGE: + lotus-miner sectors terminate command [command options] + +COMMANDS: + flush Send a terminate message if there are sectors queued for termination + pending List sector numbers of sectors pending termination + help, h Shows a list of commands or help for one command + +OPTIONS: + --really-do-it pass this flag if you know what you are doing (default: false) + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +#### lotus-miner sectors terminate flush +``` +NAME: + lotus-miner sectors terminate flush - Send a terminate message if there are sectors queued for termination + +USAGE: + lotus-miner sectors terminate flush [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +#### lotus-miner sectors terminate pending +``` +NAME: + lotus-miner sectors terminate pending - List sector numbers of sectors pending termination + +USAGE: + lotus-miner sectors terminate pending [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus-miner sectors remove +``` +NAME: + lotus-miner sectors remove - Forcefully remove a sector (WARNING: This means losing power and collateral for the removed sector (use 'terminate' for lower penalty)) + +USAGE: + lotus-miner sectors remove [command options] + +OPTIONS: + --really-do-it pass this flag if you know what you are doing (default: false) + --help, -h show help (default: false) + +``` + +### lotus-miner sectors mark-for-upgrade +``` +NAME: + lotus-miner sectors mark-for-upgrade - Mark a committed capacity sector for replacement by a sector with deals + +USAGE: + lotus-miner sectors mark-for-upgrade [command options] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus-miner sectors seal +``` +NAME: + lotus-miner sectors seal - Manually start sealing a sector (filling any unused space with junk) + +USAGE: + lotus-miner sectors seal [command options] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus-miner sectors set-seal-delay +``` +NAME: + lotus-miner sectors set-seal-delay - Set the time, in minutes, that a new sector waits for deals before sealing starts + +USAGE: + lotus-miner sectors set-seal-delay [command options] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus-miner sectors get-cc-collateral +``` +NAME: + lotus-miner sectors get-cc-collateral - Get the collateral required to pledge a committed capacity sector + +USAGE: + lotus-miner sectors get-cc-collateral [command options] [arguments...] + +OPTIONS: + --expiration value the epoch when the sector will expire (default: 0) + --help, -h show help (default: false) + +``` + +## lotus-miner proving +``` +NAME: + lotus-miner proving - View proving information + +USAGE: + lotus-miner proving command [command options] [arguments...] + +COMMANDS: + info View current state information + deadlines View the current proving period deadlines information + deadline View the current proving period deadline information by its index + faults View the currently known proving faulty sectors information + check Check sectors provable + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +### lotus-miner proving info +``` +NAME: + lotus-miner proving info - View current state information + +USAGE: + lotus-miner proving info [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus-miner proving deadlines +``` +NAME: + lotus-miner proving deadlines - View the current proving period deadlines information + +USAGE: + lotus-miner proving deadlines [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus-miner proving deadline +``` +NAME: + lotus-miner proving deadline - View the current proving period deadline information by its index + +USAGE: + lotus-miner proving deadline [command options] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus-miner proving faults +``` +NAME: + lotus-miner proving faults - View the currently known proving faulty sectors information + +USAGE: + lotus-miner proving faults [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus-miner proving check +``` +NAME: + lotus-miner proving check - Check sectors provable + +USAGE: + lotus-miner proving check [command options] + +OPTIONS: + --only-bad print only bad sectors (default: false) + --slow run slower checks (default: false) + --help, -h show help (default: false) + +``` + +## lotus-miner storage +``` +NAME: + lotus-miner storage - manage sector storage + +USAGE: + lotus-miner storage command [command options] [arguments...] + +DESCRIPTION: + Sectors can be stored across many filesystem paths. These +commands provide ways to manage the storage the miner will used to store sectors +long term for proving (references as 'store') as well as how sectors will be +stored while moving through the sealing pipeline (references as 'seal'). + +COMMANDS: + attach attach local storage path + list list local storage paths + find find sector in the storage system + cleanup trigger cleanup actions + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +### lotus-miner storage attach +``` +NAME: + lotus-miner storage attach - attach local storage path + +USAGE: + lotus-miner storage attach [command options] [arguments...] + +DESCRIPTION: + Storage can be attached to the miner using this command. The storage volume +list is stored local to the miner in $LOTUS_MINER_PATH/storage.json. We do not +recommend manually modifying this value without further understanding of the +storage system. + +Each storage volume contains a configuration file which describes the +capabilities of the volume. When the '--init' flag is provided, this file will +be created using the additional flags. + +Weight +A high weight value means data will be more likely to be stored in this path + +Seal +Data for the sealing process will be stored here + +Store +Finalized sectors that will be moved here for long term storage and be proven +over time + + +OPTIONS: + --init initialize the path first (default: false) + --weight value (for init) path weight (default: 10) + --seal (for init) use path for sealing (default: false) + --store (for init) use path for long-term storage (default: false) + --max-storage value (for init) limit storage space for sectors (expensive for very large paths!) + --help, -h show help (default: false) + +``` + +### lotus-miner storage list +``` +NAME: + lotus-miner storage list - list local storage paths + +USAGE: + lotus-miner storage list command [command options] [arguments...] + +COMMANDS: + sectors get list of all sector files + help, h Shows a list of commands or help for one command + +OPTIONS: + --color (default: false) + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +#### lotus-miner storage list sectors +``` +NAME: + lotus-miner storage list sectors - get list of all sector files + +USAGE: + lotus-miner storage list sectors [command options] [arguments...] + +OPTIONS: + --color (default: true) + --help, -h show help (default: false) + +``` + +### lotus-miner storage find +``` +NAME: + lotus-miner storage find - find sector in the storage system + +USAGE: + lotus-miner storage find [command options] [sector number] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus-miner storage cleanup +``` +NAME: + lotus-miner storage cleanup - trigger cleanup actions + +USAGE: + lotus-miner storage cleanup [command options] [arguments...] + +OPTIONS: + --removed cleanup remaining files from removed sectors (default: true) + --help, -h show help (default: false) + +``` + +## lotus-miner sealing +``` +NAME: + lotus-miner sealing - interact with sealing pipeline + +USAGE: + lotus-miner sealing command [command options] [arguments...] + +COMMANDS: + jobs list running jobs + workers list workers + sched-diag Dump internal scheduler state + abort Abort a running job + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +### lotus-miner sealing jobs +``` +NAME: + lotus-miner sealing jobs - list running jobs + +USAGE: + lotus-miner sealing jobs [command options] [arguments...] + +OPTIONS: + --color (default: false) + --show-ret-done show returned but not consumed calls (default: false) + --help, -h show help (default: false) + +``` + +### lotus-miner sealing workers +``` +NAME: + lotus-miner sealing workers - list workers + +USAGE: + lotus-miner sealing workers [command options] [arguments...] + +OPTIONS: + --color (default: false) + --help, -h show help (default: false) + +``` + +### lotus-miner sealing sched-diag +``` +NAME: + lotus-miner sealing sched-diag - Dump internal scheduler state + +USAGE: + lotus-miner sealing sched-diag [command options] [arguments...] + +OPTIONS: + --force-sched (default: false) + --help, -h show help (default: false) + +``` + +### lotus-miner sealing abort +``` +NAME: + lotus-miner sealing abort - Abort a running job + +USAGE: + lotus-miner sealing abort [command options] [callid] + +OPTIONS: + --help, -h show help (default: false) + +``` diff --git a/documentation/en/cli-lotus-worker.md b/documentation/en/cli-lotus-worker.md new file mode 100644 index 00000000000..0b29da503ce --- /dev/null +++ b/documentation/en/cli-lotus-worker.md @@ -0,0 +1,171 @@ +# lotus-worker +``` +NAME: + lotus-worker - Remote miner worker + +USAGE: + lotus-worker [global options] command [command options] [arguments...] + +VERSION: + 1.11.0-dev + +COMMANDS: + run Start lotus worker + info Print worker info + storage manage sector storage + set Manage worker settings + wait-quiet Block until all running tasks exit + tasks Manage task processing + help, h Shows a list of commands or help for one command + +GLOBAL OPTIONS: + --worker-repo value, --workerrepo value Specify worker repo path. flag workerrepo and env WORKER_PATH are DEPRECATION, will REMOVE SOON (default: "~/.lotusworker") [$LOTUS_WORKER_PATH, $WORKER_PATH] + --miner-repo value, --storagerepo value Specify miner repo path. flag storagerepo and env LOTUS_STORAGE_PATH are DEPRECATION, will REMOVE SOON (default: "~/.lotusminer") [$LOTUS_MINER_PATH, $LOTUS_STORAGE_PATH] + --enable-gpu-proving enable use of GPU for mining operations (default: true) + --help, -h show help (default: false) + --version, -v print the version (default: false) +``` + +## lotus-worker run +``` +NAME: + lotus-worker run - Start lotus worker + +USAGE: + lotus-worker run [command options] [arguments...] + +OPTIONS: + --listen value host address and port the worker api will listen on (default: "0.0.0.0:3456") + --no-local-storage don't use storageminer repo for sector storage (default: false) + --no-swap don't use swap (default: false) + --addpiece enable addpiece (default: true) + --precommit1 enable precommit1 (32G sectors: 1 core, 128GiB Memory) (default: true) + --unseal enable unsealing (32G sectors: 1 core, 128GiB Memory) (default: true) + --precommit2 enable precommit2 (32G sectors: all cores, 96GiB Memory) (default: true) + --commit enable commit (32G sectors: all cores or GPUs, 128GiB Memory + 64GiB swap) (default: true) + --parallel-fetch-limit value maximum fetch operations to run in parallel (default: 5) + --timeout value used when 'listen' is unspecified. must be a valid duration recognized by golang's time.ParseDuration function (default: "30m") + --help, -h show help (default: false) + +``` + +## lotus-worker info +``` +NAME: + lotus-worker info - Print worker info + +USAGE: + lotus-worker info [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +## lotus-worker storage +``` +NAME: + lotus-worker storage - manage sector storage + +USAGE: + lotus-worker storage command [command options] [arguments...] + +COMMANDS: + attach attach local storage path + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +### lotus-worker storage attach +``` +NAME: + lotus-worker storage attach - attach local storage path + +USAGE: + lotus-worker storage attach [command options] [arguments...] + +OPTIONS: + --init initialize the path first (default: false) + --weight value (for init) path weight (default: 10) + --seal (for init) use path for sealing (default: false) + --store (for init) use path for long-term storage (default: false) + --max-storage value (for init) limit storage space for sectors (expensive for very large paths!) + --help, -h show help (default: false) + +``` + +## lotus-worker set +``` +NAME: + lotus-worker set - Manage worker settings + +USAGE: + lotus-worker set [command options] [arguments...] + +OPTIONS: + --enabled enable/disable new task processing (default: true) + --help, -h show help (default: false) + +``` + +## lotus-worker wait-quiet +``` +NAME: + lotus-worker wait-quiet - Block until all running tasks exit + +USAGE: + lotus-worker wait-quiet [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +## lotus-worker tasks +``` +NAME: + lotus-worker tasks - Manage task processing + +USAGE: + lotus-worker tasks command [command options] [arguments...] + +COMMANDS: + enable Enable a task type + disable Disable a task type + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +### lotus-worker tasks enable +``` +NAME: + lotus-worker tasks enable - Enable a task type + +USAGE: + lotus-worker tasks enable [command options] [UNS|C2|PC2|PC1|AP] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus-worker tasks disable +``` +NAME: + lotus-worker tasks disable - Disable a task type + +USAGE: + lotus-worker tasks disable [command options] [UNS|C2|PC2|PC1|AP] + +OPTIONS: + --help, -h show help (default: false) + +``` diff --git a/documentation/en/cli-lotus.md b/documentation/en/cli-lotus.md new file mode 100644 index 00000000000..1b32ffe50c0 --- /dev/null +++ b/documentation/en/cli-lotus.md @@ -0,0 +1,2698 @@ +# lotus +``` +NAME: + lotus - Filecoin decentralized storage network client + +USAGE: + lotus [global options] command [command options] [arguments...] + +VERSION: + 1.11.0-dev + +COMMANDS: + daemon Start a lotus daemon process + backup Create node metadata backup + version Print version + help, h Shows a list of commands or help for one command + BASIC: + send Send funds between accounts + wallet Manage wallet + client Make deals, store data, retrieve data + msig Interact with a multisig wallet + paych Manage payment channels + DEVELOPER: + auth Manage RPC permissions + mpool Manage message pool + state Interact with and query filecoin chain state + chain Interact with filecoin blockchain + log Manage logging + wait-api Wait for lotus api to come online + fetch-params Fetch proving parameters + NETWORK: + net Manage P2P Network + sync Inspect or interact with the chain syncer + STATUS: + status Check node status + +GLOBAL OPTIONS: + --interactive setting to false will disable interactive functionality of commands (default: false) + --force-send if true, will ignore pre-send checks (default: false) + --help, -h show help (default: false) + --version, -v print the version (default: false) +``` + +## lotus daemon +``` +NAME: + lotus daemon - Start a lotus daemon process + +USAGE: + lotus daemon command [command options] [arguments...] + +COMMANDS: + stop Stop a running lotus daemon + help, h Shows a list of commands or help for one command + +OPTIONS: + --api value (default: "1234") + --genesis value genesis file to use for first node run + --bootstrap (default: true) + --import-chain value on first run, load chain from given file or url and validate + --import-snapshot value import chain state from a given chain export file or url + --halt-after-import halt the process after importing chain from file (default: false) + --pprof value specify name of file for writing cpu profile to + --profile value specify type of node + --manage-fdlimit manage open file limit (default: true) + --config value specify path of config file to use + --api-max-req-size value maximum API request size accepted by the JSON RPC server (default: 0) + --restore value restore from backup file + --restore-config value config file to use when restoring from backup + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +### lotus daemon stop +``` +NAME: + lotus daemon stop - Stop a running lotus daemon + +USAGE: + lotus daemon stop [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +## lotus backup +``` +NAME: + lotus backup - Create node metadata backup + +USAGE: + lotus backup [command options] [backup file path] + +DESCRIPTION: + The backup command writes a copy of node metadata under the specified path + +Online backups: +For security reasons, the daemon must be have LOTUS_BACKUP_BASE_PATH env var set +to a path where backup files are supposed to be saved, and the path specified in +this command must be within this base path + +OPTIONS: + --offline create backup without the node running (default: false) + --help, -h show help (default: false) + +``` + +## lotus version +``` +NAME: + lotus version - Print version + +USAGE: + lotus version [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +## lotus send +``` +NAME: + lotus send - Send funds between accounts + +USAGE: + lotus send [command options] [targetAddress] [amount] + +CATEGORY: + BASIC + +OPTIONS: + --from value optionally specify the account to send funds from + --gas-premium value specify gas price to use in AttoFIL (default: "0") + --gas-feecap value specify gas fee cap to use in AttoFIL (default: "0") + --gas-limit value specify gas limit (default: 0) + --nonce value specify the nonce to use (default: 0) + --method value specify method to invoke (default: 0) + --params-json value specify invocation parameters in json + --params-hex value specify invocation parameters in hex + --force Deprecated: use global 'force-send' (default: false) + --help, -h show help (default: false) + +``` + +## lotus wallet +``` +NAME: + lotus wallet - Manage wallet + +USAGE: + lotus wallet command [command options] [arguments...] + +COMMANDS: + new Generate a new key of the given type + list List wallet address + balance Get account balance + export export keys + import import keys + default Get default wallet address + set-default Set default wallet address + sign sign a message + verify verify the signature of a message + delete Delete an account from the wallet + market Interact with market balances + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +### lotus wallet new +``` +NAME: + lotus wallet new - Generate a new key of the given type + +USAGE: + lotus wallet new [command options] [bls|secp256k1 (default secp256k1)] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus wallet list +``` +NAME: + lotus wallet list - List wallet address + +USAGE: + lotus wallet list [command options] [arguments...] + +OPTIONS: + --addr-only, -a Only print addresses (default: false) + --id, -i Output ID addresses (default: false) + --market, -m Output market balances (default: false) + --help, -h show help (default: false) + +``` + +### lotus wallet balance +``` +NAME: + lotus wallet balance - Get account balance + +USAGE: + lotus wallet balance [command options] [address] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus wallet export +``` +NAME: + lotus wallet export - export keys + +USAGE: + lotus wallet export [command options] [address] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus wallet import +``` +NAME: + lotus wallet import - import keys + +USAGE: + lotus wallet import [command options] [ (optional, will read from stdin if omitted)] + +OPTIONS: + --format value specify input format for key (default: "hex-lotus") + --as-default import the given key as your new default key (default: false) + --help, -h show help (default: false) + +``` + +### lotus wallet default +``` +NAME: + lotus wallet default - Get default wallet address + +USAGE: + lotus wallet default [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus wallet set-default +``` +NAME: + lotus wallet set-default - Set default wallet address + +USAGE: + lotus wallet set-default [command options] [address] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus wallet sign +``` +NAME: + lotus wallet sign - sign a message + +USAGE: + lotus wallet sign [command options] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus wallet verify +``` +NAME: + lotus wallet verify - verify the signature of a message + +USAGE: + lotus wallet verify [command options] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus wallet delete +``` +NAME: + lotus wallet delete - Delete an account from the wallet + +USAGE: + lotus wallet delete [command options]
+ +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus wallet market +``` +NAME: + lotus wallet market - Interact with market balances + +USAGE: + lotus wallet market command [command options] [arguments...] + +COMMANDS: + withdraw Withdraw funds from the Storage Market Actor + add Add funds to the Storage Market Actor + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +#### lotus wallet market withdraw +``` +NAME: + lotus wallet market withdraw - Withdraw funds from the Storage Market Actor + +USAGE: + lotus wallet market withdraw [command options] [amount (FIL) optional, otherwise will withdraw max available] + +OPTIONS: + --wallet value, -w value Specify address to withdraw funds to, otherwise it will use the default wallet address + --address value, -a value Market address to withdraw from (account or miner actor address, defaults to --wallet address) + --help, -h show help (default: false) + +``` + +#### lotus wallet market add +``` +NAME: + lotus wallet market add - Add funds to the Storage Market Actor + +USAGE: + lotus wallet market add [command options] + +OPTIONS: + --from value, -f value Specify address to move funds from, otherwise it will use the default wallet address + --address value, -a value Market address to move funds to (account or miner actor address, defaults to --from address) + --help, -h show help (default: false) + +``` + +## lotus client +``` +NAME: + lotus client - Make deals, store data, retrieve data + +USAGE: + lotus client command [command options] [arguments...] + +COMMANDS: + help, h Shows a list of commands or help for one command + DATA: + import Import data + drop Remove import + local List locally imported data + stat Print information about a locally stored file (piece size, etc) + RETRIEVAL: + find Find data in the network + retrieve Retrieve data from network + cancel-retrieval Cancel a retrieval deal by deal ID; this also cancels the associated transfer + STORAGE: + deal Initialize storage deal with a miner + query-ask Find a miners ask + list-deals List storage market deals + get-deal Print detailed deal information + list-asks List asks for top miners + deal-stats Print statistics about local storage deals + inspect-deal Inspect detailed information about deal's lifecycle and the various stages it goes through + UTIL: + commP Calculate the piece-cid (commP) of a CAR file + generate-car Generate a car file from input + balances Print storage market client balances + list-transfers List ongoing data transfers for deals + restart-transfer Force restart a stalled data transfer + cancel-transfer Force cancel a data transfer + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +### lotus client import +``` +NAME: + lotus client import - Import data + +USAGE: + lotus client import [command options] [inputPath] + +CATEGORY: + DATA + +OPTIONS: + --car import from a car file instead of a regular file (default: false) + --quiet, -q Output root CID only (default: false) + --help, -h show help (default: false) + +``` + +### lotus client drop +``` +NAME: + lotus client drop - Remove import + +USAGE: + lotus client drop [command options] [import ID...] + +CATEGORY: + DATA + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus client local +``` +NAME: + lotus client local - List locally imported data + +USAGE: + lotus client local [command options] [arguments...] + +CATEGORY: + DATA + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus client stat +``` +NAME: + lotus client stat - Print information about a locally stored file (piece size, etc) + +USAGE: + lotus client stat [command options] + +CATEGORY: + DATA + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus client find +``` +NAME: + lotus client find - Find data in the network + +USAGE: + lotus client find [command options] [dataCid] + +CATEGORY: + RETRIEVAL + +OPTIONS: + --pieceCid value require data to be retrieved from a specific Piece CID + --help, -h show help (default: false) + +``` + +### lotus client retrieve +``` +NAME: + lotus client retrieve - Retrieve data from network + +USAGE: + lotus client retrieve [command options] [dataCid outputPath] + +CATEGORY: + RETRIEVAL + +OPTIONS: + --from value address to send transactions from + --car export to a car file instead of a regular file (default: false) + --miner value miner address for retrieval, if not present it'll use local discovery + --maxPrice value maximum price the client is willing to consider (default: 0.01 FIL) + --pieceCid value require data to be retrieved from a specific Piece CID + --allow-local (default: false) + --help, -h show help (default: false) + +``` + +### lotus client cancel-retrieval +``` +NAME: + lotus client cancel-retrieval - Cancel a retrieval deal by deal ID; this also cancels the associated transfer + +USAGE: + lotus client cancel-retrieval [command options] [arguments...] + +CATEGORY: + RETRIEVAL + +OPTIONS: + --deal-id value specify retrieval deal by deal ID (default: 0) + --help, -h show help (default: false) + +``` + +### lotus client deal +``` +NAME: + lotus client deal - Initialize storage deal with a miner + +USAGE: + lotus client deal [command options] [dataCid miner price duration] + +CATEGORY: + STORAGE + +DESCRIPTION: + Make a deal with a miner. +dataCid comes from running 'lotus client import'. +miner is the address of the miner you wish to make a deal with. +price is measured in FIL/GB/Epoch. Miners usually don't accept a bid +lower than their advertised ask. You can check a miners listed price +with 'lotus client query-ask '. +duration is how long the miner should store the data for, in blocks. +The minimum value is 518400 (6 months). + +OPTIONS: + --manual-piece-cid value manually specify piece commitment for data (dataCid must be to a car file) + --manual-piece-size value if manually specifying piece cid, used to specify size (dataCid must be to a car file) (default: 0) + --from value specify address to fund the deal with + --start-epoch value specify the epoch that the deal should start at (default: -1) + --fast-retrieval indicates that data should be available for fast retrieval (default: true) + --verified-deal indicate that the deal counts towards verified client total (default: true if client is verified, false otherwise) + --provider-collateral value specify the requested provider collateral the miner should put up + --help, -h show help (default: false) + +``` + +### lotus client query-ask +``` +NAME: + lotus client query-ask - Find a miners ask + +USAGE: + lotus client query-ask [command options] [minerAddress] + +CATEGORY: + STORAGE + +OPTIONS: + --peerid value specify peer ID of node to make query against + --size value data size in bytes (default: 0) + --duration value deal duration (default: 0) + --help, -h show help (default: false) + +``` + +### lotus client list-deals +``` +NAME: + lotus client list-deals - List storage market deals + +USAGE: + lotus client list-deals [command options] [arguments...] + +CATEGORY: + STORAGE + +OPTIONS: + --verbose, -v print verbose deal details (default: false) + --color use color in display output (default: true) + --show-failed show failed/failing deals (default: false) + --watch watch deal updates in real-time, rather than a one time list (default: false) + --help, -h show help (default: false) + +``` + +### lotus client get-deal +``` +NAME: + lotus client get-deal - Print detailed deal information + +USAGE: + lotus client get-deal [command options] [arguments...] + +CATEGORY: + STORAGE + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus client list-asks +``` +NAME: + lotus client list-asks - List asks for top miners + +USAGE: + lotus client list-asks [command options] [arguments...] + +CATEGORY: + STORAGE + +OPTIONS: + --by-ping sort by ping (default: false) + --output-format value Either 'text' or 'csv' (default: "text") + --help, -h show help (default: false) + +``` + +### lotus client deal-stats +``` +NAME: + lotus client deal-stats - Print statistics about local storage deals + +USAGE: + lotus client deal-stats [command options] [arguments...] + +CATEGORY: + STORAGE + +OPTIONS: + --newer-than value (default: 0s) + --help, -h show help (default: false) + +``` + +### lotus client inspect-deal +``` +NAME: + lotus client inspect-deal - Inspect detailed information about deal's lifecycle and the various stages it goes through + +USAGE: + lotus client inspect-deal [command options] [arguments...] + +CATEGORY: + STORAGE + +OPTIONS: + --deal-id value (default: 0) + --proposal-cid value + --help, -h show help (default: false) + +``` + +### lotus client commP +``` +NAME: + lotus client commP - Calculate the piece-cid (commP) of a CAR file + +USAGE: + lotus client commP [command options] [inputFile] + +CATEGORY: + UTIL + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus client generate-car +``` +NAME: + lotus client generate-car - Generate a car file from input + +USAGE: + lotus client generate-car [command options] [inputPath outputPath] + +CATEGORY: + UTIL + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus client balances +``` +NAME: + lotus client balances - Print storage market client balances + +USAGE: + lotus client balances [command options] [arguments...] + +CATEGORY: + UTIL + +OPTIONS: + --client value specify storage client address + --help, -h show help (default: false) + +``` + +### lotus client list-transfers +``` +NAME: + lotus client list-transfers - List ongoing data transfers for deals + +USAGE: + lotus client list-transfers [command options] [arguments...] + +CATEGORY: + UTIL + +OPTIONS: + --verbose, -v print verbose transfer details (default: false) + --color use color in display output (default: true) + --completed show completed data transfers (default: false) + --watch watch deal updates in real-time, rather than a one time list (default: false) + --show-failed show failed/cancelled transfers (default: false) + --help, -h show help (default: false) + +``` + +### lotus client restart-transfer +``` +NAME: + lotus client restart-transfer - Force restart a stalled data transfer + +USAGE: + lotus client restart-transfer [command options] [arguments...] + +CATEGORY: + UTIL + +OPTIONS: + --peerid value narrow to transfer with specific peer + --initiator specify only transfers where peer is/is not initiator (default: true) + --help, -h show help (default: false) + +``` + +### lotus client cancel-transfer +``` +NAME: + lotus client cancel-transfer - Force cancel a data transfer + +USAGE: + lotus client cancel-transfer [command options] [arguments...] + +CATEGORY: + UTIL + +OPTIONS: + --peerid value narrow to transfer with specific peer + --initiator specify only transfers where peer is/is not initiator (default: true) + --cancel-timeout value time to wait for cancel to be sent to storage provider (default: 5s) + --help, -h show help (default: false) + +``` + +## lotus msig +``` +NAME: + lotus msig - Interact with a multisig wallet + +USAGE: + lotus msig command [command options] [arguments...] + +COMMANDS: + create Create a new multisig wallet + inspect Inspect a multisig wallet + propose Propose a multisig transaction + propose-remove Propose to remove a signer + approve Approve a multisig message + add-propose Propose to add a signer + add-approve Approve a message to add a signer + add-cancel Cancel a message to add a signer + swap-propose Propose to swap signers + swap-approve Approve a message to swap signers + swap-cancel Cancel a message to swap signers + lock-propose Propose to lock up some balance + lock-approve Approve a message to lock up some balance + lock-cancel Cancel a message to lock up some balance + vested Gets the amount vested in an msig between two epochs + propose-threshold Propose setting a different signing threshold on the account + help, h Shows a list of commands or help for one command + +OPTIONS: + --confidence value number of block confirmations to wait for (default: 5) + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +### lotus msig create +``` +NAME: + lotus msig create - Create a new multisig wallet + +USAGE: + lotus msig create [command options] [address1 address2 ...] + +OPTIONS: + --required value number of required approvals (uses number of signers provided if omitted) (default: 0) + --value value initial funds to give to multisig (default: "0") + --duration value length of the period over which funds unlock (default: "0") + --from value account to send the create message from + --help, -h show help (default: false) + +``` + +### lotus msig inspect +``` +NAME: + lotus msig inspect - Inspect a multisig wallet + +USAGE: + lotus msig inspect [command options] [address] + +OPTIONS: + --vesting Include vesting details (default: false) + --decode-params Decode parameters of transaction proposals (default: false) + --help, -h show help (default: false) + +``` + +### lotus msig propose +``` +NAME: + lotus msig propose - Propose a multisig transaction + +USAGE: + lotus msig propose [command options] [multisigAddress destinationAddress value (optional)] + +OPTIONS: + --from value account to send the propose message from + --help, -h show help (default: false) + +``` + +### lotus msig propose-remove +``` +NAME: + lotus msig propose-remove - Propose to remove a signer + +USAGE: + lotus msig propose-remove [command options] [multisigAddress signer] + +OPTIONS: + --decrease-threshold whether the number of required signers should be decreased (default: false) + --from value account to send the propose message from + --help, -h show help (default: false) + +``` + +### lotus msig approve +``` +NAME: + lotus msig approve - Approve a multisig message + +USAGE: + lotus msig approve [command options] [proposerAddress destination value [methodId methodParams]] + +OPTIONS: + --from value account to send the approve message from + --help, -h show help (default: false) + +``` + +### lotus msig add-propose +``` +NAME: + lotus msig add-propose - Propose to add a signer + +USAGE: + lotus msig add-propose [command options] [multisigAddress signer] + +OPTIONS: + --increase-threshold whether the number of required signers should be increased (default: false) + --from value account to send the propose message from + --help, -h show help (default: false) + +``` + +### lotus msig add-approve +``` +NAME: + lotus msig add-approve - Approve a message to add a signer + +USAGE: + lotus msig add-approve [command options] [multisigAddress proposerAddress txId newAddress increaseThreshold] + +OPTIONS: + --from value account to send the approve message from + --help, -h show help (default: false) + +``` + +### lotus msig add-cancel +``` +NAME: + lotus msig add-cancel - Cancel a message to add a signer + +USAGE: + lotus msig add-cancel [command options] [multisigAddress txId newAddress increaseThreshold] + +OPTIONS: + --from value account to send the approve message from + --help, -h show help (default: false) + +``` + +### lotus msig swap-propose +``` +NAME: + lotus msig swap-propose - Propose to swap signers + +USAGE: + lotus msig swap-propose [command options] [multisigAddress oldAddress newAddress] + +OPTIONS: + --from value account to send the approve message from + --help, -h show help (default: false) + +``` + +### lotus msig swap-approve +``` +NAME: + lotus msig swap-approve - Approve a message to swap signers + +USAGE: + lotus msig swap-approve [command options] [multisigAddress proposerAddress txId oldAddress newAddress] + +OPTIONS: + --from value account to send the approve message from + --help, -h show help (default: false) + +``` + +### lotus msig swap-cancel +``` +NAME: + lotus msig swap-cancel - Cancel a message to swap signers + +USAGE: + lotus msig swap-cancel [command options] [multisigAddress txId oldAddress newAddress] + +OPTIONS: + --from value account to send the approve message from + --help, -h show help (default: false) + +``` + +### lotus msig lock-propose +``` +NAME: + lotus msig lock-propose - Propose to lock up some balance + +USAGE: + lotus msig lock-propose [command options] [multisigAddress startEpoch unlockDuration amount] + +OPTIONS: + --from value account to send the propose message from + --help, -h show help (default: false) + +``` + +### lotus msig lock-approve +``` +NAME: + lotus msig lock-approve - Approve a message to lock up some balance + +USAGE: + lotus msig lock-approve [command options] [multisigAddress proposerAddress txId startEpoch unlockDuration amount] + +OPTIONS: + --from value account to send the approve message from + --help, -h show help (default: false) + +``` + +### lotus msig lock-cancel +``` +NAME: + lotus msig lock-cancel - Cancel a message to lock up some balance + +USAGE: + lotus msig lock-cancel [command options] [multisigAddress txId startEpoch unlockDuration amount] + +OPTIONS: + --from value account to send the cancel message from + --help, -h show help (default: false) + +``` + +### lotus msig vested +``` +NAME: + lotus msig vested - Gets the amount vested in an msig between two epochs + +USAGE: + lotus msig vested [command options] [multisigAddress] + +OPTIONS: + --start-epoch value start epoch to measure vesting from (default: 0) + --end-epoch value end epoch to stop measure vesting at (default: -1) + --help, -h show help (default: false) + +``` + +### lotus msig propose-threshold +``` +NAME: + lotus msig propose-threshold - Propose setting a different signing threshold on the account + +USAGE: + lotus msig propose-threshold [command options] + +OPTIONS: + --from value account to send the proposal from + --help, -h show help (default: false) + +``` + +## lotus paych +``` +NAME: + lotus paych - Manage payment channels + +USAGE: + lotus paych command [command options] [arguments...] + +COMMANDS: + add-funds Add funds to the payment channel between fromAddress and toAddress. Creates the payment channel if it doesn't already exist. + list List all locally registered payment channels + voucher Interact with payment channel vouchers + settle Settle a payment channel + status Show the status of an outbound payment channel + status-by-from-to Show the status of an active outbound payment channel by from/to addresses + collect Collect funds for a payment channel + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +### lotus paych add-funds +``` +NAME: + lotus paych add-funds - Add funds to the payment channel between fromAddress and toAddress. Creates the payment channel if it doesn't already exist. + +USAGE: + lotus paych add-funds [command options] [fromAddress toAddress amount] + +OPTIONS: + --restart-retrievals restart stalled retrieval deals on this payment channel (default: true) + --help, -h show help (default: false) + +``` + +### lotus paych list +``` +NAME: + lotus paych list - List all locally registered payment channels + +USAGE: + lotus paych list [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus paych voucher +``` +NAME: + lotus paych voucher - Interact with payment channel vouchers + +USAGE: + lotus paych voucher command [command options] [arguments...] + +COMMANDS: + create Create a signed payment channel voucher + check Check validity of payment channel voucher + add Add payment channel voucher to local datastore + list List stored vouchers for a given payment channel + best-spendable Print vouchers with highest value that is currently spendable for each lane + submit Submit voucher to chain to update payment channel state + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +#### lotus paych voucher create +``` +NAME: + lotus paych voucher create - Create a signed payment channel voucher + +USAGE: + lotus paych voucher create [command options] [channelAddress amount] + +OPTIONS: + --lane value specify payment channel lane to use (default: 0) + --help, -h show help (default: false) + +``` + +#### lotus paych voucher check +``` +NAME: + lotus paych voucher check - Check validity of payment channel voucher + +USAGE: + lotus paych voucher check [command options] [channelAddress voucher] + +OPTIONS: + --help, -h show help (default: false) + +``` + +#### lotus paych voucher add +``` +NAME: + lotus paych voucher add - Add payment channel voucher to local datastore + +USAGE: + lotus paych voucher add [command options] [channelAddress voucher] + +OPTIONS: + --help, -h show help (default: false) + +``` + +#### lotus paych voucher list +``` +NAME: + lotus paych voucher list - List stored vouchers for a given payment channel + +USAGE: + lotus paych voucher list [command options] [channelAddress] + +OPTIONS: + --export Print voucher as serialized string (default: false) + --help, -h show help (default: false) + +``` + +#### lotus paych voucher best-spendable +``` +NAME: + lotus paych voucher best-spendable - Print vouchers with highest value that is currently spendable for each lane + +USAGE: + lotus paych voucher best-spendable [command options] [channelAddress] + +OPTIONS: + --export Print voucher as serialized string (default: false) + --help, -h show help (default: false) + +``` + +#### lotus paych voucher submit +``` +NAME: + lotus paych voucher submit - Submit voucher to chain to update payment channel state + +USAGE: + lotus paych voucher submit [command options] [channelAddress voucher] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus paych settle +``` +NAME: + lotus paych settle - Settle a payment channel + +USAGE: + lotus paych settle [command options] [channelAddress] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus paych status +``` +NAME: + lotus paych status - Show the status of an outbound payment channel + +USAGE: + lotus paych status [command options] [channelAddress] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus paych status-by-from-to +``` +NAME: + lotus paych status-by-from-to - Show the status of an active outbound payment channel by from/to addresses + +USAGE: + lotus paych status-by-from-to [command options] [fromAddress toAddress] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus paych collect +``` +NAME: + lotus paych collect - Collect funds for a payment channel + +USAGE: + lotus paych collect [command options] [channelAddress] + +OPTIONS: + --help, -h show help (default: false) + +``` + +## lotus auth +``` +NAME: + lotus auth - Manage RPC permissions + +USAGE: + lotus auth command [command options] [arguments...] + +COMMANDS: + create-token Create token + api-info Get token with API info required to connect to this node + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +### lotus auth create-token +``` +NAME: + lotus auth create-token - Create token + +USAGE: + lotus auth create-token [command options] [arguments...] + +OPTIONS: + --perm value permission to assign to the token, one of: read, write, sign, admin + --help, -h show help (default: false) + +``` + +### lotus auth api-info +``` +NAME: + lotus auth api-info - Get token with API info required to connect to this node + +USAGE: + lotus auth api-info [command options] [arguments...] + +OPTIONS: + --perm value permission to assign to the token, one of: read, write, sign, admin + --help, -h show help (default: false) + +``` + +## lotus mpool +``` +NAME: + lotus mpool - Manage message pool + +USAGE: + lotus mpool command [command options] [arguments...] + +COMMANDS: + pending Get pending messages + sub Subscribe to mpool changes + stat print mempool stats + replace replace a message in the mempool + find find a message in the mempool + config get or set current mpool configuration + gas-perf Check gas performance of messages in mempool + manage + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +### lotus mpool pending +``` +NAME: + lotus mpool pending - Get pending messages + +USAGE: + lotus mpool pending [command options] [arguments...] + +OPTIONS: + --local print pending messages for addresses in local wallet only (default: false) + --cids only print cids of messages in output (default: false) + --to value return messages to a given address + --from value return messages from a given address + --help, -h show help (default: false) + +``` + +### lotus mpool sub +``` +NAME: + lotus mpool sub - Subscribe to mpool changes + +USAGE: + lotus mpool sub [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus mpool stat +``` +NAME: + lotus mpool stat - print mempool stats + +USAGE: + lotus mpool stat [command options] [arguments...] + +OPTIONS: + --local print stats for addresses in local wallet only (default: false) + --basefee-lookback value number of blocks to look back for minimum basefee (default: 60) + --help, -h show help (default: false) + +``` + +### lotus mpool replace +``` +NAME: + lotus mpool replace - replace a message in the mempool + +USAGE: + lotus mpool replace [command options] | + +OPTIONS: + --gas-feecap value gas feecap for new message (burn and pay to miner, attoFIL/GasUnit) + --gas-premium value gas price for new message (pay to miner, attoFIL/GasUnit) + --gas-limit value gas limit for new message (GasUnit) (default: 0) + --auto automatically reprice the specified message (default: false) + --max-fee value Spend up to X attoFIL for this message (applicable for auto mode) + --help, -h show help (default: false) + +``` + +### lotus mpool find +``` +NAME: + lotus mpool find - find a message in the mempool + +USAGE: + lotus mpool find [command options] [arguments...] + +OPTIONS: + --from value search for messages with given 'from' address + --to value search for messages with given 'to' address + --method value search for messages with given method (default: 0) + --help, -h show help (default: false) + +``` + +### lotus mpool config +``` +NAME: + lotus mpool config - get or set current mpool configuration + +USAGE: + lotus mpool config [command options] [new-config] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus mpool gas-perf +``` +NAME: + lotus mpool gas-perf - Check gas performance of messages in mempool + +USAGE: + lotus mpool gas-perf [command options] [arguments...] + +OPTIONS: + --all print gas performance for all mempool messages (default only prints for local) (default: false) + --help, -h show help (default: false) + +``` +# nage +``` +``` + +## lotus state +``` +NAME: + lotus state - Interact with and query filecoin chain state + +USAGE: + lotus state command [command options] [arguments...] + +COMMANDS: + power Query network or miner power + sectors Query the sector set of a miner + active-sectors Query the active sector set of a miner + list-actors list all actors in the network + list-miners list all miners in the network + circulating-supply Get the exact current circulating supply of Filecoin + sector Get miner sector info + get-actor Print actor information + lookup Find corresponding ID address + replay Replay a particular message + sector-size Look up miners sector size + read-state View a json representation of an actors state + list-messages list messages on chain matching given criteria + compute-state Perform state computations + call Invoke a method on an actor locally + get-deal View on-chain deal info + wait-msg Wait for a message to appear on chain + search-msg Search to see whether a message has appeared on chain + miner-info Retrieve miner information + market Inspect the storage market actor + exec-trace Get the execution trace of a given message + network-version Returns the network version + miner-proving-deadline Retrieve information about a given miner's proving deadline + help, h Shows a list of commands or help for one command + +OPTIONS: + --tipset value specify tipset to call method on (pass comma separated array of cids) + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +### lotus state power +``` +NAME: + lotus state power - Query network or miner power + +USAGE: + lotus state power [command options] [ (optional)] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus state sectors +``` +NAME: + lotus state sectors - Query the sector set of a miner + +USAGE: + lotus state sectors [command options] [minerAddress] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus state active-sectors +``` +NAME: + lotus state active-sectors - Query the active sector set of a miner + +USAGE: + lotus state active-sectors [command options] [minerAddress] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus state list-actors +``` +NAME: + lotus state list-actors - list all actors in the network + +USAGE: + lotus state list-actors [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus state list-miners +``` +NAME: + lotus state list-miners - list all miners in the network + +USAGE: + lotus state list-miners [command options] [arguments...] + +OPTIONS: + --sort-by value criteria to sort miners by (none, num-deals) + --help, -h show help (default: false) + +``` + +### lotus state circulating-supply +``` +NAME: + lotus state circulating-supply - Get the exact current circulating supply of Filecoin + +USAGE: + lotus state circulating-supply [command options] [arguments...] + +OPTIONS: + --vm-supply calculates the approximation of the circulating supply used internally by the VM (instead of the exact amount) (default: false) + --help, -h show help (default: false) + +``` + +### lotus state sector +``` +NAME: + lotus state sector - Get miner sector info + +USAGE: + lotus state sector [command options] [minerAddress] [sectorNumber] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus state get-actor +``` +NAME: + lotus state get-actor - Print actor information + +USAGE: + lotus state get-actor [command options] [actorrAddress] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus state lookup +``` +NAME: + lotus state lookup - Find corresponding ID address + +USAGE: + lotus state lookup [command options] [address] + +OPTIONS: + --reverse, -r Perform reverse lookup (default: false) + --help, -h show help (default: false) + +``` + +### lotus state replay +``` +NAME: + lotus state replay - Replay a particular message + +USAGE: + lotus state replay [command options] + +OPTIONS: + --show-trace print out full execution trace for given message (default: false) + --detailed-gas print out detailed gas costs for given message (default: false) + --help, -h show help (default: false) + +``` + +### lotus state sector-size +``` +NAME: + lotus state sector-size - Look up miners sector size + +USAGE: + lotus state sector-size [command options] [minerAddress] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus state read-state +``` +NAME: + lotus state read-state - View a json representation of an actors state + +USAGE: + lotus state read-state [command options] [actorAddress] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus state list-messages +``` +NAME: + lotus state list-messages - list messages on chain matching given criteria + +USAGE: + lotus state list-messages [command options] [arguments...] + +OPTIONS: + --to value return messages to a given address + --from value return messages from a given address + --toheight value don't look before given block height (default: 0) + --cids print message CIDs instead of messages (default: false) + --help, -h show help (default: false) + +``` + +### lotus state compute-state +``` +NAME: + lotus state compute-state - Perform state computations + +USAGE: + lotus state compute-state [command options] [arguments...] + +OPTIONS: + --vm-height value set the height that the vm will see (default: 0) + --apply-mpool-messages apply messages from the mempool to the computed state (default: false) + --show-trace print out full execution trace for given tipset (default: false) + --html generate html report (default: false) + --json generate json output (default: false) + --compute-state-output value a json file containing pre-existing compute-state output, to generate html reports without rerunning state changes + --no-timing don't show timing information in html traces (default: false) + --help, -h show help (default: false) + +``` + +### lotus state call +``` +NAME: + lotus state call - Invoke a method on an actor locally + +USAGE: + lotus state call [command options] [toAddress methodId (optional)] + +OPTIONS: + --from value (default: "f00") + --value value specify value field for invocation (default: "0") + --ret value specify how to parse output (auto, raw, addr, big) (default: "auto") + --help, -h show help (default: false) + +``` + +### lotus state get-deal +``` +NAME: + lotus state get-deal - View on-chain deal info + +USAGE: + lotus state get-deal [command options] [dealId] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus state wait-msg +``` +NAME: + lotus state wait-msg - Wait for a message to appear on chain + +USAGE: + lotus state wait-msg [command options] [messageCid] + +OPTIONS: + --timeout value (default: "10m") + --help, -h show help (default: false) + +``` + +### lotus state search-msg +``` +NAME: + lotus state search-msg - Search to see whether a message has appeared on chain + +USAGE: + lotus state search-msg [command options] [messageCid] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus state miner-info +``` +NAME: + lotus state miner-info - Retrieve miner information + +USAGE: + lotus state miner-info [command options] [minerAddress] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus state market +``` +NAME: + lotus state market - Inspect the storage market actor + +USAGE: + lotus state market command [command options] [arguments...] + +COMMANDS: + balance Get the market balance (locked and escrowed) for a given account + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +#### lotus state market balance +``` +NAME: + lotus state market balance - Get the market balance (locked and escrowed) for a given account + +USAGE: + lotus state market balance [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus state exec-trace +``` +NAME: + lotus state exec-trace - Get the execution trace of a given message + +USAGE: + lotus state exec-trace [command options] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus state network-version +``` +NAME: + lotus state network-version - Returns the network version + +USAGE: + lotus state network-version [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus state miner-proving-deadline +``` +NAME: + lotus state miner-proving-deadline - Retrieve information about a given miner's proving deadline + +USAGE: + lotus state miner-proving-deadline [command options] [minerAddress] + +OPTIONS: + --help, -h show help (default: false) + +``` + +## lotus chain +``` +NAME: + lotus chain - Interact with filecoin blockchain + +USAGE: + lotus chain command [command options] [arguments...] + +COMMANDS: + head Print chain head + getblock Get a block and print its details + read-obj Read the raw bytes of an object + delete-obj Delete an object from the chain blockstore + stat-obj Collect size and ipld link counts for objs + getmessage Get and print a message by its cid + sethead manually set the local nodes head tipset (Caution: normally only used for recovery) + list, love View a segment of the chain + get Get chain DAG node by path + bisect bisect chain for an event + export export chain to a car file + slash-consensus Report consensus fault + gas-price Estimate gas prices + inspect-usage Inspect block space usage of a given tipset + decode decode various types + encode encode various types + disputer interact with the window post disputer + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +### lotus chain head +``` +NAME: + lotus chain head - Print chain head + +USAGE: + lotus chain head [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus chain getblock +``` +NAME: + lotus chain getblock - Get a block and print its details + +USAGE: + lotus chain getblock [command options] [blockCid] + +OPTIONS: + --raw print just the raw block header (default: false) + --help, -h show help (default: false) + +``` + +### lotus chain read-obj +``` +NAME: + lotus chain read-obj - Read the raw bytes of an object + +USAGE: + lotus chain read-obj [command options] [objectCid] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus chain delete-obj +``` +NAME: + lotus chain delete-obj - Delete an object from the chain blockstore + +USAGE: + lotus chain delete-obj [command options] [objectCid] + +DESCRIPTION: + WARNING: Removing wrong objects from the chain blockstore may lead to sync issues + +OPTIONS: + --really-do-it (default: false) + --help, -h show help (default: false) + +``` + +### lotus chain stat-obj +``` +NAME: + lotus chain stat-obj - Collect size and ipld link counts for objs + +USAGE: + lotus chain stat-obj [command options] [cid] + +DESCRIPTION: + Collect object size and ipld link count for an object. + + When a base is provided it will be walked first, and all links visisted + will be ignored when the passed in object is walked. + + +OPTIONS: + --base value ignore links found in this obj + --help, -h show help (default: false) + +``` + +### lotus chain getmessage +``` +NAME: + lotus chain getmessage - Get and print a message by its cid + +USAGE: + lotus chain getmessage [command options] [messageCid] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus chain sethead +``` +NAME: + lotus chain sethead - manually set the local nodes head tipset (Caution: normally only used for recovery) + +USAGE: + lotus chain sethead [command options] [tipsetkey] + +OPTIONS: + --genesis reset head to genesis (default: false) + --epoch value reset head to given epoch (default: 0) + --help, -h show help (default: false) + +``` + +#### lotus chain list, love +``` +``` + +### lotus chain get +``` +NAME: + lotus chain get - Get chain DAG node by path + +USAGE: + lotus chain get [command options] [path] + +DESCRIPTION: + Get ipld node under a specified path: + + lotus chain get /ipfs/[cid]/some/path + + Path prefixes: + - /ipfs/[cid], /ipld/[cid] - traverse IPLD path + - /pstate - traverse from head.ParentStateRoot + + Note: + You can use special path elements to traverse through some data structures: + - /ipfs/[cid]/@H:elem - get 'elem' from hamt + - /ipfs/[cid]/@Hi:123 - get varint elem 123 from hamt + - /ipfs/[cid]/@Hu:123 - get uvarint elem 123 from hamt + - /ipfs/[cid]/@Ha:t01 - get element under Addr(t01).Bytes + - /ipfs/[cid]/@A:10 - get 10th amt element + - .../@Ha:t01/@state - get pretty map-based actor state + + List of --as-type types: + - raw + - block + - message + - smessage, signedmessage + - actor + - amt + - hamt-epoch + - hamt-address + - cronevent + - account-state + + +OPTIONS: + --as-type value specify type to interpret output as + --verbose (default: false) + --tipset value specify tipset for /pstate (pass comma separated array of cids) + --help, -h show help (default: false) + +``` + +### lotus chain bisect +``` +NAME: + lotus chain bisect - bisect chain for an event + +USAGE: + lotus chain bisect [command options] [minHeight maxHeight path shellCommand ] + +DESCRIPTION: + Bisect the chain state tree: + + lotus chain bisect [min height] [max height] '1/2/3/state/path' 'shell command' 'args' + + Returns the first tipset in which condition is true + v + [start] FFFFFFFTTT [end] + + Example: find height at which deal ID 100 000 appeared + - lotus chain bisect 1 32000 '@Ha:t03/1' jq -e '.[2] > 100000' + + For special path elements see 'chain get' help + + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus chain export +``` +NAME: + lotus chain export - export chain to a car file + +USAGE: + lotus chain export [command options] [outputPath] + +OPTIONS: + --tipset value + --recent-stateroots value specify the number of recent state roots to include in the export (default: 0) + --skip-old-msgs (default: false) + --help, -h show help (default: false) + +``` + +### lotus chain slash-consensus +``` +NAME: + lotus chain slash-consensus - Report consensus fault + +USAGE: + lotus chain slash-consensus [command options] [blockCid1 blockCid2] + +OPTIONS: + --from value optionally specify the account to report consensus from + --extra value Extra block cid + --help, -h show help (default: false) + +``` + +### lotus chain gas-price +``` +NAME: + lotus chain gas-price - Estimate gas prices + +USAGE: + lotus chain gas-price [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus chain inspect-usage +``` +NAME: + lotus chain inspect-usage - Inspect block space usage of a given tipset + +USAGE: + lotus chain inspect-usage [command options] [arguments...] + +OPTIONS: + --tipset value specify tipset to view block space usage of (default: "@head") + --length value length of chain to inspect block space usage for (default: 1) + --num-results value number of results to print per category (default: 10) + --help, -h show help (default: false) + +``` + +### lotus chain decode +``` +NAME: + lotus chain decode - decode various types + +USAGE: + lotus chain decode command [command options] [arguments...] + +COMMANDS: + params Decode message params + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +#### lotus chain decode params +``` +NAME: + lotus chain decode params - Decode message params + +USAGE: + lotus chain decode params [command options] [toAddr method params] + +OPTIONS: + --tipset value + --encoding value specify input encoding to parse (default: "base64") + --help, -h show help (default: false) + +``` + +### lotus chain encode +``` +NAME: + lotus chain encode - encode various types + +USAGE: + lotus chain encode command [command options] [arguments...] + +COMMANDS: + params Encodes the given JSON params + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +#### lotus chain encode params +``` +NAME: + lotus chain encode params - Encodes the given JSON params + +USAGE: + lotus chain encode params [command options] [toAddr method params] + +OPTIONS: + --tipset value + --encoding value specify input encoding to parse (default: "base64") + --help, -h show help (default: false) + +``` + +### lotus chain disputer +``` +NAME: + lotus chain disputer - interact with the window post disputer + +USAGE: + lotus chain disputer command [command options] [arguments...] + +COMMANDS: + start Start the window post disputer + dispute Send a specific DisputeWindowedPoSt message + help, h Shows a list of commands or help for one command + +OPTIONS: + --max-fee value Spend up to X FIL per DisputeWindowedPoSt message + --from value optionally specify the account to send messages from + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +#### lotus chain disputer start +``` +NAME: + lotus chain disputer start - Start the window post disputer + +USAGE: + lotus chain disputer start [command options] [minerAddress] + +OPTIONS: + --start-epoch value only start disputing PoSts after this epoch (default: 0) + --help, -h show help (default: false) + +``` + +#### lotus chain disputer dispute +``` +NAME: + lotus chain disputer dispute - Send a specific DisputeWindowedPoSt message + +USAGE: + lotus chain disputer dispute [command options] [minerAddress index postIndex] + +OPTIONS: + --help, -h show help (default: false) + +``` + +## lotus log +``` +NAME: + lotus log - Manage logging + +USAGE: + lotus log command [command options] [arguments...] + +COMMANDS: + list List log systems + set-level Set log level + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +### lotus log list +``` +NAME: + lotus log list - List log systems + +USAGE: + lotus log list [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus log set-level +``` +NAME: + lotus log set-level - Set log level + +USAGE: + lotus log set-level [command options] [level] + +DESCRIPTION: + Set the log level for logging systems: + + The system flag can be specified multiple times. + + eg) log set-level --system chain --system chainxchg debug + + Available Levels: + debug + info + warn + error + + Environment Variables: + GOLOG_LOG_LEVEL - Default log level for all log systems + GOLOG_LOG_FMT - Change output log format (json, nocolor) + GOLOG_FILE - Write logs to file + GOLOG_OUTPUT - Specify whether to output to file, stderr, stdout or a combination, i.e. file+stderr + + +OPTIONS: + --system value limit to log system + --help, -h show help (default: false) + +``` + +## lotus wait-api +``` +NAME: + lotus wait-api - Wait for lotus api to come online + +USAGE: + lotus wait-api [command options] [arguments...] + +CATEGORY: + DEVELOPER + +OPTIONS: + --help, -h show help (default: false) + +``` + +## lotus fetch-params +``` +NAME: + lotus fetch-params - Fetch proving parameters + +USAGE: + lotus fetch-params [command options] [sectorSize] + +CATEGORY: + DEVELOPER + +OPTIONS: + --help, -h show help (default: false) + +``` + +## lotus net +``` +NAME: + lotus net - Manage P2P Network + +USAGE: + lotus net command [command options] [arguments...] + +COMMANDS: + peers Print peers + connect Connect to a peer + listen List listen addresses + id Get node identity + findpeer Find the addresses of a given peerID + scores Print peers' pubsub scores + reachability Print information about reachability from the internet + bandwidth Print bandwidth usage information + block Manage network connection gating rules + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +### lotus net peers +``` +NAME: + lotus net peers - Print peers + +USAGE: + lotus net peers [command options] [arguments...] + +OPTIONS: + --agent, -a Print agent name (default: false) + --extended, -x Print extended peer information in json (default: false) + --help, -h show help (default: false) + +``` + +### lotus net connect +``` +NAME: + lotus net connect - Connect to a peer + +USAGE: + lotus net connect [command options] [peerMultiaddr|minerActorAddress] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus net listen +``` +NAME: + lotus net listen - List listen addresses + +USAGE: + lotus net listen [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus net id +``` +NAME: + lotus net id - Get node identity + +USAGE: + lotus net id [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus net findpeer +``` +NAME: + lotus net findpeer - Find the addresses of a given peerID + +USAGE: + lotus net findpeer [command options] [peerId] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus net scores +``` +NAME: + lotus net scores - Print peers' pubsub scores + +USAGE: + lotus net scores [command options] [arguments...] + +OPTIONS: + --extended, -x print extended peer scores in json (default: false) + --help, -h show help (default: false) + +``` + +### lotus net reachability +``` +NAME: + lotus net reachability - Print information about reachability from the internet + +USAGE: + lotus net reachability [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus net bandwidth +``` +NAME: + lotus net bandwidth - Print bandwidth usage information + +USAGE: + lotus net bandwidth [command options] [arguments...] + +OPTIONS: + --by-peer list bandwidth usage by peer (default: false) + --by-protocol list bandwidth usage by protocol (default: false) + --help, -h show help (default: false) + +``` + +### lotus net block +``` +NAME: + lotus net block - Manage network connection gating rules + +USAGE: + lotus net block command [command options] [arguments...] + +COMMANDS: + add Add connection gating rules + remove Remove connection gating rules + list list connection gating rules + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +#### lotus net block add +``` +NAME: + lotus net block add - Add connection gating rules + +USAGE: + lotus net block add command [command options] [arguments...] + +COMMANDS: + peer Block a peer + ip Block an IP address + subnet Block an IP subnet + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +##### lotus net block add peer +``` +NAME: + lotus net block add peer - Block a peer + +USAGE: + lotus net block add peer [command options] ... + +OPTIONS: + --help, -h show help (default: false) + +``` + +##### lotus net block add ip +``` +NAME: + lotus net block add ip - Block an IP address + +USAGE: + lotus net block add ip [command options] ... + +OPTIONS: + --help, -h show help (default: false) + +``` + +##### lotus net block add subnet +``` +NAME: + lotus net block add subnet - Block an IP subnet + +USAGE: + lotus net block add subnet [command options] ... + +OPTIONS: + --help, -h show help (default: false) + +``` + +#### lotus net block remove +``` +NAME: + lotus net block remove - Remove connection gating rules + +USAGE: + lotus net block remove command [command options] [arguments...] + +COMMANDS: + peer Unblock a peer + ip Unblock an IP address + subnet Unblock an IP subnet + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +##### lotus net block remove peer +``` +NAME: + lotus net block remove peer - Unblock a peer + +USAGE: + lotus net block remove peer [command options] ... + +OPTIONS: + --help, -h show help (default: false) + +``` + +##### lotus net block remove ip +``` +NAME: + lotus net block remove ip - Unblock an IP address + +USAGE: + lotus net block remove ip [command options] ... + +OPTIONS: + --help, -h show help (default: false) + +``` + +##### lotus net block remove subnet +``` +NAME: + lotus net block remove subnet - Unblock an IP subnet + +USAGE: + lotus net block remove subnet [command options] ... + +OPTIONS: + --help, -h show help (default: false) + +``` + +#### lotus net block list +``` +NAME: + lotus net block list - list connection gating rules + +USAGE: + lotus net block list [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +## lotus sync +``` +NAME: + lotus sync - Inspect or interact with the chain syncer + +USAGE: + lotus sync command [command options] [arguments...] + +COMMANDS: + status check sync status + wait Wait for sync to be complete + mark-bad Mark the given block as bad, will prevent syncing to a chain that contains it + unmark-bad Unmark the given block as bad, makes it possible to sync to a chain containing it + check-bad check if the given block was marked bad, and for what reason + checkpoint mark a certain tipset as checkpointed; the node will never fork away from this tipset + help, h Shows a list of commands or help for one command + +OPTIONS: + --help, -h show help (default: false) + --version, -v print the version (default: false) + +``` + +### lotus sync status +``` +NAME: + lotus sync status - check sync status + +USAGE: + lotus sync status [command options] [arguments...] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus sync wait +``` +NAME: + lotus sync wait - Wait for sync to be complete + +USAGE: + lotus sync wait [command options] [arguments...] + +OPTIONS: + --watch don't exit after node is synced (default: false) + --help, -h show help (default: false) + +``` + +### lotus sync mark-bad +``` +NAME: + lotus sync mark-bad - Mark the given block as bad, will prevent syncing to a chain that contains it + +USAGE: + lotus sync mark-bad [command options] [blockCid] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus sync unmark-bad +``` +NAME: + lotus sync unmark-bad - Unmark the given block as bad, makes it possible to sync to a chain containing it + +USAGE: + lotus sync unmark-bad [command options] [blockCid] + +OPTIONS: + --all drop the entire bad block cache (default: false) + --help, -h show help (default: false) + +``` + +### lotus sync check-bad +``` +NAME: + lotus sync check-bad - check if the given block was marked bad, and for what reason + +USAGE: + lotus sync check-bad [command options] [blockCid] + +OPTIONS: + --help, -h show help (default: false) + +``` + +### lotus sync checkpoint +``` +NAME: + lotus sync checkpoint - mark a certain tipset as checkpointed; the node will never fork away from this tipset + +USAGE: + lotus sync checkpoint [command options] [tipsetKey] + +OPTIONS: + --epoch value checkpoint the tipset at the given epoch (default: 0) + --help, -h show help (default: false) + +``` + +## lotus status +``` +NAME: + lotus status - Check node status + +USAGE: + lotus status [command options] [arguments...] + +CATEGORY: + STATUS + +OPTIONS: + --chain include chain health status (default: false) + --help, -h show help (default: false) + +``` diff --git a/documentation/misc/RELEASE_ISSUE_TEMPLATE.md b/documentation/misc/RELEASE_ISSUE_TEMPLATE.md new file mode 100644 index 00000000000..df5e8d1c52f --- /dev/null +++ b/documentation/misc/RELEASE_ISSUE_TEMPLATE.md @@ -0,0 +1,115 @@ +> Release Issue Template + +# Lotus X.Y.Z Release + +We're happy to announce Lotus X.Y.Z... + +## đŸ—ē Must-dos for the release + +## 🌟 Nice-to-haves for the release + + + +## đŸšĸ Estimated shipping date + + + +## đŸ”Ļ Highlights + +< top highlights for this release notes > + +## ✅ Release Checklist + +First steps: + + - [ ] Fork a new branch (`release/vX.Y.Z`) from `master` and make any further release related changes to this branch. If any "non-trivial" changes get added to the release, uncheck all the checkboxes and return to this stage. + - [ ] Prep the changelog using `scripts/mkreleaselog`, and add it to `CHANGELOG.md` + - [ ] Bump the version in `version.go` in the `master` branch to `vX.(Y+1).0-dev`. + +Prepping an RC: + +- [ ] version string in `build/version.go` has been updated (in the `release/vX.Y.Z` branch). +- [ ] tag commit with `vX.Y.Z-rcN` +- [ ] cut a pre-release [here](https://github.com/filecoin-project/lotus/releases/new?prerelease=true) + +Testing an RC: + +- [ ] **Stage 0 - Automated Testing** + - Automated Testing + - [ ] CI: Ensure that all tests are passing. + - [ ] Testground tests + +- [ ] **Stage 1 - Internal Testing** + - Upgrade our testnet infra + - [ ] 1 bootstrap node + - [ ] 1 miner + - [ ] Scratch nodes + - [ ] Wait 24 hours, confirm nodes stay in sync + - [ ] Remaining testnet infra + - Upgrade our mainnet infra + - [ ] Subset of development full archival nodes + - [ ] Subset of bootstrappers (1 per region) + - [ ] Confirm nodes stay in sync + - Metrics report + - Block validation time + - Memory / CPU usage + - Number of goroutines + - IPLD block read latency + - Bandwidth usage + - [ ] If anything has worsened significantly, investigate + fix + - Confirm the following work (some combination of Testground / Calibnet / Mainnet / beta users) + - [ ] Seal a sector + - [ ] make a deal + - [ ] Submit a PoSt + - [ ] (optional) let a sector go faulty, and see it be recovered + +- [ ] **Stage 2 - Community Testing** + - [ ] Inform beta miners (@lotus-early-testers-miner in Filecoin Slack #fil-lotus) + - [ ] Ask close ecosystem partners to test their projects (@lotus-early-testers-eco-dev in Filecoin slack #fil-lotus) + - [ ] Powergate + - [ ] Glif + - [ ] Zondax + - [ ] Stats dashboard + - [ ] Community dashboards + - [ ] Infura + - [ ] Sentinel + - [ ] Protofire + - [ ] Fleek + +- [ ] **Stage 3 - Community Prod Testing** + - [ ] Documentation + - [ ] Ensure that [CHANGELOG.md](https://github.com/filecoin-project/lotus/blob/master/CHANGELOG.md) is up to date + - [ ] Check if any [config](https://docs.filecoin.io/get-started/lotus/configuration-and-advanced-usage/#configuration) updates are needed + - [ ] Invite the wider community through (link to the release issue): + - [ ] Create a lotus disucssion, example [here](https://github.com/filecoin-project/lotus/discussions/5595) + - [ ] Link the disucssion in #fil-lotus on Filecoin slack + +- [ ] **Stage 4 - Release** + - [ ] Final preparation + - [ ] Verify that version string in [`version.go`](https://github.com/ipfs/go-ipfs/tree/master/version.go) has been updated. + - [ ] Ensure that [CHANGELOG.md](https://github.com/filecoin-project/lotus/blob/master/CHANGELOG.md) is up to date + - [ ] Ensure that [README.md](https://github.com/filecoin-project/lotus/blob/master/README.md) is up to date + - [ ] Merge `release-vX.Y.Z` into the `releases` branch. + - [ ] Tag this merge commit (on the `releases` branch) with `vX.Y.Z`. + - [ ] Cut the release [here](https://github.com/filecoin-project/lotus/releases/new?prerelease=true&target=releases). + - [ ] Final announcements + - [ ] Update network.filecoin.io for mainnet, calib and nerpa. + - [ ] Add a comment when the final release is tagged, example [here](https://github.com/filecoin-project/lotus/discussions/5905#discussioncomment-571752) + - [ ] repost in #fil-lotus in filecoin slack + - [ ] Inform node provides (Protofire, Digital Ocean..) + +- [ ] **Post-Release** + - [ ] Merge the `releases` branch back into `master`, ignoring the changes to `version.go` (keep the `-dev` version from master). + - [ ] Create an issue using this release issue template for the _next_ release. + +## ❤ī¸ Contributors + +< list generated by scripts/mkreleaselog > + +Would you like to contribute to Lotus and don't know how? Well, there are a few places you can get started: + +- TODO + +## ⁉ī¸ Do you have questions? + +Leave a comment [here]() if you have any questions. diff --git a/documentation/misc/actors_version_checklist.md b/documentation/misc/actors_version_checklist.md new file mode 100644 index 00000000000..308358948d6 --- /dev/null +++ b/documentation/misc/actors_version_checklist.md @@ -0,0 +1,19 @@ +### Actor version integration checklist + +- [ ] Import new actors +- [ ] Define upgrade heights in `build/params_` +- [ ] Generate adapters + - [ ] Add the new version in `chain/actors/agen/main.go` + - [ ] Update adapter code in `chain/actors/builtin` if needed +- [ ] Update `chain/actors/policy/policy.go` +- [ ] Update `chain/actors/version.go` +- [ ] Register in `chain/vm/invoker.go` +- [ ] Register in `chain/vm/mkactor.go` +- [ ] Update `chain/types/state.go` +- [ ] Update `chain/state/statetree.go` +- [ ] Update `chain/stmgr/forks.go` + - [ ] Schedule + - [ ] Migration +- [ ] Update upgrade schedule in `api/test/test.go` +- [ ] Update `NewestNetworkVersion` in `build/params_shared_vals.go` +- [ ] Register in init in `chain/stmgr/utils.go` diff --git a/extern/filecoin-ffi b/extern/filecoin-ffi index b6e0b35fb49..3db17a0a0f2 160000 --- a/extern/filecoin-ffi +++ b/extern/filecoin-ffi @@ -1 +1 @@ -Subproject commit b6e0b35fb49ed0fedb6a6a473b222e3b8a7d7f17 +Subproject commit 3db17a0a0f24ce6a04e946f86bf18b0e1d8c0007 diff --git a/extern/sector-storage/ffiwrapper/sealer_cgo.go b/extern/sector-storage/ffiwrapper/sealer_cgo.go index dca8b44b531..36fbacb3055 100644 --- a/extern/sector-storage/ffiwrapper/sealer_cgo.go +++ b/extern/sector-storage/ffiwrapper/sealer_cgo.go @@ -195,12 +195,16 @@ func (sb *Sealer) AddPiece(ctx context.Context, sector storage.SectorRef, existi return piecePromises[0]() } + var payloadRoundedBytes abi.PaddedPieceSize pieceCids := make([]abi.PieceInfo, len(piecePromises)) for i, promise := range piecePromises { - pieceCids[i], err = promise() + pinfo, err := promise() if err != nil { return abi.PieceInfo{}, err } + + pieceCids[i] = pinfo + payloadRoundedBytes += pinfo.Size } pieceCID, err := ffi.GenerateUnsealedCID(sector.ProofType, pieceCids) @@ -213,6 +217,15 @@ func (sb *Sealer) AddPiece(ctx context.Context, sector storage.SectorRef, existi return abi.PieceInfo{}, err } + if payloadRoundedBytes < pieceSize.Padded() { + paddedCid, err := commpffi.ZeroPadPieceCommitment(pieceCID, payloadRoundedBytes.Unpadded(), pieceSize) + if err != nil { + return abi.PieceInfo{}, xerrors.Errorf("failed to pad data: %w", err) + } + + pieceCID = paddedCid + } + return abi.PieceInfo{ Size: pieceSize.Padded(), PieceCID: pieceCID, diff --git a/extern/sector-storage/ffiwrapper/sealer_test.go b/extern/sector-storage/ffiwrapper/sealer_test.go index 3b379af6f60..39e37f0cc0b 100644 --- a/extern/sector-storage/ffiwrapper/sealer_test.go +++ b/extern/sector-storage/ffiwrapper/sealer_test.go @@ -21,7 +21,7 @@ import ( "github.com/ipfs/go-cid" - logging "github.com/ipfs/go-log" + logging "github.com/ipfs/go-log/v2" "github.com/stretchr/testify/require" "golang.org/x/xerrors" @@ -709,3 +709,46 @@ func BenchmarkAddPiece512M(b *testing.B) { fmt.Println(c) } } + +func TestAddPiece512MPadded(t *testing.T) { + sz := abi.PaddedPieceSize(512 << 20).Unpadded() + + cdir, err := ioutil.TempDir("", "sbtest-c-") + if err != nil { + t.Fatal(err) + } + miner := abi.ActorID(123) + + sp := &basicfs.Provider{ + Root: cdir, + } + sb, err := New(sp) + if err != nil { + t.Fatalf("%+v", err) + } + cleanup := func() { + if t.Failed() { + fmt.Printf("not removing %s\n", cdir) + return + } + if err := os.RemoveAll(cdir); err != nil { + t.Error(err) + } + } + t.Cleanup(cleanup) + + r := rand.New(rand.NewSource(0x7e5)) + + c, err := sb.AddPiece(context.TODO(), storage.SectorRef{ + ID: abi.SectorID{ + Miner: miner, + Number: 0, + }, + ProofType: abi.RegisteredSealProof_StackedDrg512MiBV1_1, + }, nil, sz, io.LimitReader(r, int64(sz/4))) + if err != nil { + t.Fatalf("add piece failed: %s", err) + } + + require.Equal(t, "baga6ea4seaqonenxyku4o7hr5xkzbqsceipf6xgli3on54beqbk6k246sbooobq", c.PieceCID.String()) +} diff --git a/extern/sector-storage/manager.go b/extern/sector-storage/manager.go index 3db7ac9ec91..d3fef8533f6 100644 --- a/extern/sector-storage/manager.go +++ b/extern/sector-storage/manager.go @@ -208,6 +208,7 @@ func (m *Manager) schedFetch(sector storage.SectorRef, ft storiface.SectorFileTy func (m *Manager) readPiece(sink io.Writer, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, rok *bool) func(ctx context.Context, w Worker) error { return func(ctx context.Context, w Worker) error { + log.Debugf("read piece data from sector %d, offset %d, size %d", sector.ID, offset, size) r, err := m.waitSimpleCall(ctx)(w.ReadPiece(ctx, sink, sector, offset, size)) if err != nil { return err @@ -215,6 +216,7 @@ func (m *Manager) readPiece(sink io.Writer, sector storage.SectorRef, offset sto if r != nil { *rok = r.(bool) } + log.Debugf("completed read piece data from sector %d, offset %d, size %d: read ok? %t", sector.ID, offset, size, *rok) return nil } } @@ -225,11 +227,13 @@ func (m *Manager) tryReadUnsealedPiece(ctx context.Context, sink io.Writer, sect ctx, cancel := context.WithCancel(ctx) defer cancel() + log.Debugf("acquire read sector lock for sector %d", sector.ID) if err := m.index.StorageLock(ctx, sector.ID, storiface.FTUnsealed, storiface.FTNone); err != nil { returnErr = xerrors.Errorf("acquiring read sector lock: %w", err) return } + log.Debugf("find unsealed sector %d", sector.ID) // passing 0 spt because we only need it when allowFetch is true best, err := m.index.StorageFindSector(ctx, sector.ID, storiface.FTUnsealed, 0, false) if err != nil { @@ -240,41 +244,49 @@ func (m *Manager) tryReadUnsealedPiece(ctx context.Context, sink io.Writer, sect foundUnsealed = len(best) > 0 if foundUnsealed { // append to existing // There is unsealed sector, see if we can read from it + log.Debugf("found unsealed sector %d", sector.ID) selector = newExistingSelector(m.index, sector.ID, storiface.FTUnsealed, false) + log.Debugf("scheduling read of unsealed sector %d", sector.ID) err = m.sched.Schedule(ctx, sector, sealtasks.TTReadUnsealed, selector, m.schedFetch(sector, storiface.FTUnsealed, storiface.PathSealing, storiface.AcquireMove), m.readPiece(sink, sector, offset, size, &readOk)) if err != nil { returnErr = xerrors.Errorf("reading piece from sealed sector: %w", err) } } else { + log.Debugf("did not find unsealed sector %d", sector.ID) selector = newAllocSelector(m.index, storiface.FTUnsealed, storiface.PathSealing) } return } func (m *Manager) ReadPiece(ctx context.Context, sink io.Writer, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, ticket abi.SealRandomness, unsealed cid.Cid) error { + log.Debugf("fetch and read piece in sector %d, offset %d, size %d", sector.ID, offset, size) foundUnsealed, readOk, selector, err := m.tryReadUnsealedPiece(ctx, sink, sector, offset, size) if err != nil { return err } if readOk { + log.Debugf("completed read of unsealed piece in sector %d, offset %d, size %d", sector.ID, offset, size) return nil } ctx, cancel := context.WithCancel(ctx) defer cancel() + log.Debugf("acquire unseal sector lock for sector %d", sector.ID) if err := m.index.StorageLock(ctx, sector.ID, storiface.FTSealed|storiface.FTCache, storiface.FTUnsealed); err != nil { return xerrors.Errorf("acquiring unseal sector lock: %w", err) } unsealFetch := func(ctx context.Context, worker Worker) error { + log.Debugf("copy sealed/cache sector data for sector %d", sector.ID) if _, err := m.waitSimpleCall(ctx)(worker.Fetch(ctx, sector, storiface.FTSealed|storiface.FTCache, storiface.PathSealing, storiface.AcquireCopy)); err != nil { return xerrors.Errorf("copy sealed/cache sector data: %w", err) } if foundUnsealed { + log.Debugf("copy unsealed sector data for sector %d", sector.ID) if _, err := m.waitSimpleCall(ctx)(worker.Fetch(ctx, sector, storiface.FTUnsealed, storiface.PathSealing, storiface.AcquireMove)); err != nil { return xerrors.Errorf("copy unsealed sector data: %w", err) } @@ -291,13 +303,16 @@ func (m *Manager) ReadPiece(ctx context.Context, sink io.Writer, sector storage. return xerrors.Errorf("getting sector size: %w", err) } + log.Debugf("schedule unseal for sector %d", sector.ID) err = m.sched.Schedule(ctx, sector, sealtasks.TTUnseal, selector, unsealFetch, func(ctx context.Context, w Worker) error { // TODO: make restartable // NOTE: we're unsealing the whole sector here as with SDR we can't really // unseal the sector partially. Requesting the whole sector here can // save us some work in case another piece is requested from here + log.Debugf("unseal sector %d", sector.ID) _, err := m.waitSimpleCall(ctx)(w.UnsealPiece(ctx, sector, 0, abi.PaddedPieceSize(ssize).Unpadded(), ticket, unsealed)) + log.Debugf("completed unseal sector %d", sector.ID) return err }) if err != nil { @@ -306,6 +321,7 @@ func (m *Manager) ReadPiece(ctx context.Context, sink io.Writer, sector storage. selector = newExistingSelector(m.index, sector.ID, storiface.FTUnsealed, false) + log.Debugf("schedule read piece for sector %d, offset %d, size %d", sector.ID, offset, size) err = m.sched.Schedule(ctx, sector, sealtasks.TTReadUnsealed, selector, m.schedFetch(sector, storiface.FTUnsealed, storiface.PathSealing, storiface.AcquireMove), m.readPiece(sink, sector, offset, size, &readOk)) if err != nil { @@ -316,6 +332,7 @@ func (m *Manager) ReadPiece(ctx context.Context, sink io.Writer, sector storage. return xerrors.Errorf("failed to read unsealed piece") } + log.Debugf("completed read of piece in sector %d, offset %d, size %d", sector.ID, offset, size) return nil } diff --git a/extern/sector-storage/manager_test.go b/extern/sector-storage/manager_test.go index e768d45161b..1cf9d0aad6c 100644 --- a/extern/sector-storage/manager_test.go +++ b/extern/sector-storage/manager_test.go @@ -16,7 +16,7 @@ import ( "github.com/google/uuid" "github.com/ipfs/go-datastore" - logging "github.com/ipfs/go-log" + logging "github.com/ipfs/go-log/v2" "github.com/stretchr/testify/require" "github.com/filecoin-project/go-state-types/abi" diff --git a/extern/sector-storage/mock/mock.go b/extern/sector-storage/mock/mock.go index 17e96975858..ae7d54985fe 100644 --- a/extern/sector-storage/mock/mock.go +++ b/extern/sector-storage/mock/mock.go @@ -16,7 +16,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/specs-storage/storage" "github.com/ipfs/go-cid" - logging "github.com/ipfs/go-log" + logging "github.com/ipfs/go-log/v2" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper" @@ -27,6 +27,7 @@ var log = logging.Logger("sbmock") type SectorMgr struct { sectors map[abi.SectorID]*sectorState + failPoSt bool pieces map[cid.Cid][]byte nextSectorID abi.SectorNumber @@ -263,6 +264,14 @@ func (mgr *SectorMgr) MarkFailed(sid storage.SectorRef, failed bool) error { return nil } +func (mgr *SectorMgr) Fail() { + mgr.lk.Lock() + defer mgr.lk.Unlock() + mgr.failPoSt = true + + return +} + func (mgr *SectorMgr) MarkCorrupted(sid storage.SectorRef, corrupted bool) error { mgr.lk.Lock() defer mgr.lk.Unlock() @@ -292,10 +301,20 @@ func AddOpFinish(ctx context.Context) (context.Context, func()) { } func (mgr *SectorMgr) GenerateWinningPoSt(ctx context.Context, minerID abi.ActorID, sectorInfo []proof2.SectorInfo, randomness abi.PoStRandomness) ([]proof2.PoStProof, error) { + mgr.lk.Lock() + defer mgr.lk.Unlock() + return generateFakePoSt(sectorInfo, abi.RegisteredSealProof.RegisteredWinningPoStProof, randomness), nil } func (mgr *SectorMgr) GenerateWindowPoSt(ctx context.Context, minerID abi.ActorID, sectorInfo []proof2.SectorInfo, randomness abi.PoStRandomness) ([]proof2.PoStProof, []abi.SectorID, error) { + mgr.lk.Lock() + defer mgr.lk.Unlock() + + if mgr.failPoSt { + return nil, nil, xerrors.Errorf("failed to post (mock)") + } + si := make([]proof2.SectorInfo, 0, len(sectorInfo)) var skipped []abi.SectorID diff --git a/extern/sector-storage/stores/http_handler.go b/extern/sector-storage/stores/http_handler.go index a4c0480d4f5..3e34684709c 100644 --- a/extern/sector-storage/stores/http_handler.go +++ b/extern/sector-storage/stores/http_handler.go @@ -116,9 +116,16 @@ func (handler *FetchHandler) remoteGetSector(w http.ResponseWriter, r *http.Requ w.WriteHeader(500) return } + if !stat.IsDir() { + defer func() { + if err := rd.(*os.File).Close(); err != nil { + log.Errorf("closing source file: %+v", err) + } + }() + } w.WriteHeader(200) - if _, err := io.Copy(w, rd); err != nil { // TODO: default 32k buf may be too small + if _, err := io.CopyBuffer(w, rd, make([]byte, CopyBuf)); err != nil { log.Errorf("%+v", err) return } diff --git a/extern/sector-storage/stores/index.go b/extern/sector-storage/stores/index.go index 7f35418dd8f..4acc2ecdb6c 100644 --- a/extern/sector-storage/stores/index.go +++ b/extern/sector-storage/stores/index.go @@ -184,6 +184,8 @@ func (i *Index) StorageReportHealth(ctx context.Context, id ID, report HealthRep ent.fsi = report.Stat if report.Err != "" { ent.heartbeatErr = errors.New(report.Err) + } else { + ent.heartbeatErr = nil } ent.lastHeartbeat = time.Now() diff --git a/extern/sector-storage/stores/local.go b/extern/sector-storage/stores/local.go index a7df5ae21f4..5a10b21b906 100644 --- a/extern/sector-storage/stores/local.go +++ b/extern/sector-storage/stores/local.go @@ -114,7 +114,7 @@ func (p *path) stat(ls LocalStorage) (fsutil.FsStat, error) { used, err = ls.DiskUsage(p) } if err != nil { - log.Errorf("getting disk usage of '%s': %+v", p.sectorPath(id, fileType), err) + log.Debugf("getting disk usage of '%s': %+v", p.sectorPath(id, fileType), err) continue } @@ -392,8 +392,10 @@ func (st *Local) Reserve(ctx context.Context, sid storage.SectorRef, ft storifac } p.reserved += overhead + p.reservations[sid.ID] |= fileType prevDone := done + saveFileType := fileType done = func() { prevDone() @@ -401,6 +403,10 @@ func (st *Local) Reserve(ctx context.Context, sid storage.SectorRef, ft storifac defer st.localLk.Unlock() p.reserved -= overhead + p.reservations[sid.ID] ^= saveFileType + if p.reservations[sid.ID] == storiface.FTNone { + delete(p.reservations, sid.ID) + } } } diff --git a/extern/storage-sealing/checks.go b/extern/storage-sealing/checks.go index db2e87d0e04..5ee39e58f6c 100644 --- a/extern/storage-sealing/checks.go +++ b/extern/storage-sealing/checks.go @@ -4,7 +4,6 @@ import ( "bytes" "context" - "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/policy" proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof" @@ -94,14 +93,9 @@ func checkPrecommit(ctx context.Context, maddr address.Address, si SectorInfo, t return &ErrBadCommD{xerrors.Errorf("on chain CommD differs from sector: %s != %s", commD, si.CommD)} } - nv, err := api.StateNetworkVersion(ctx, tok) - if err != nil { - return &ErrApi{xerrors.Errorf("calling StateNetworkVersion: %w", err)} - } - - msd := policy.GetMaxProveCommitDuration(actors.VersionForNetwork(nv), si.SectorType) + ticketEarliest := height - policy.MaxPreCommitRandomnessLookback - if height-(si.TicketEpoch+policy.SealRandomnessLookback) > msd { + if si.TicketEpoch < ticketEarliest { return &ErrExpiredTicket{xerrors.Errorf("ticket expired: seal height: %d, head: %d", si.TicketEpoch+policy.SealRandomnessLookback, height)} } diff --git a/extern/storage-sealing/currentdealinfo.go b/extern/storage-sealing/currentdealinfo.go index 105a42d1ef4..44fa68b5468 100644 --- a/extern/storage-sealing/currentdealinfo.go +++ b/extern/storage-sealing/currentdealinfo.go @@ -160,7 +160,7 @@ type CurrentDealInfoTskAPI interface { ChainGetMessage(ctx context.Context, mc cid.Cid) (*types.Message, error) StateLookupID(context.Context, address.Address, types.TipSetKey) (address.Address, error) StateMarketStorageDeal(context.Context, abi.DealID, types.TipSetKey) (*api.MarketDeal, error) - StateSearchMsg(context.Context, cid.Cid) (*api.MsgLookup, error) + StateSearchMsg(ctx context.Context, from types.TipSetKey, msg cid.Cid, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) } type CurrentDealInfoAPIAdapter struct { @@ -186,7 +186,7 @@ func (c *CurrentDealInfoAPIAdapter) StateMarketStorageDeal(ctx context.Context, } func (c *CurrentDealInfoAPIAdapter) StateSearchMsg(ctx context.Context, k cid.Cid) (*MsgLookup, error) { - wmsg, err := c.CurrentDealInfoTskAPI.StateSearchMsg(ctx, k) + wmsg, err := c.CurrentDealInfoTskAPI.StateSearchMsg(ctx, types.EmptyTSK, k, api.LookbackNoLimit, true) if err != nil { return nil, err } diff --git a/extern/storage-sealing/fsm.go b/extern/storage-sealing/fsm.go index 7b60efa68b7..d14d363e519 100644 --- a/extern/storage-sealing/fsm.go +++ b/extern/storage-sealing/fsm.go @@ -242,7 +242,15 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta p := fsmPlanners[state.State] if p == nil { - return nil, 0, xerrors.Errorf("planner for state %s not found", state.State) + if len(events) == 1 { + if _, ok := events[0].User.(globalMutator); ok { + p = planOne() // in case we're in a really weird state, allow restart / update state / remove + } + } + + if p == nil { + return nil, 0, xerrors.Errorf("planner for state %s not found", state.State) + } } processed, err := p(events, state) diff --git a/extern/storage-sealing/fsm_test.go b/extern/storage-sealing/fsm_test.go index ac71588a5b8..b0ffdecf36b 100644 --- a/extern/storage-sealing/fsm_test.go +++ b/extern/storage-sealing/fsm_test.go @@ -175,3 +175,38 @@ func TestPlannerList(t *testing.T) { require.True(t, ok, "state %s", state) } } + +func TestBrokenState(t *testing.T) { + var notif []struct{ before, after SectorInfo } + ma, _ := address.NewIDAddress(55151) + m := test{ + s: &Sealing{ + maddr: ma, + stats: SectorStats{ + bySector: map[abi.SectorID]statSectorState{}, + }, + notifee: func(before, after SectorInfo) { + notif = append(notif, struct{ before, after SectorInfo }{before, after}) + }, + }, + t: t, + state: &SectorInfo{State: "not a state"}, + } + + _, _, err := m.s.plan([]statemachine.Event{{User: SectorPacked{}}}, m.state) + require.Error(t, err) + require.Equal(m.t, m.state.State, SectorState("not a state")) + + m.planSingle(SectorRemove{}) + require.Equal(m.t, m.state.State, Removing) + + expected := []SectorState{"not a state", "not a state", Removing} + for i, n := range notif { + if n.before.State != expected[i] { + t.Fatalf("expected before state: %s, got: %s", expected[i], n.before.State) + } + if n.after.State != expected[i+1] { + t.Fatalf("expected after state: %s, got: %s", expected[i+1], n.after.State) + } + } +} diff --git a/extern/storage-sealing/states_sealing.go b/extern/storage-sealing/states_sealing.go index f5bb4cae6e9..e371ab33fd6 100644 --- a/extern/storage-sealing/states_sealing.go +++ b/extern/storage-sealing/states_sealing.go @@ -12,7 +12,6 @@ import ( "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/go-state-types/exitcode" "github.com/filecoin-project/go-statemachine" - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-storage/storage" "github.com/filecoin-project/lotus/api" @@ -22,7 +21,7 @@ import ( ) var DealSectorPriority = 1024 -var MaxTicketAge = abi.ChainEpoch(builtin0.EpochsInDay * 2) +var MaxTicketAge = policy.MaxPreCommitRandomnessLookback func (m *Sealing) handlePacking(ctx statemachine.Context, sector SectorInfo) error { m.inputLk.Lock() diff --git a/gen/api/proxygen.go b/gen/api/proxygen.go index 42aed096536..71c2f414dd8 100644 --- a/gen/api/proxygen.go +++ b/gen/api/proxygen.go @@ -52,40 +52,47 @@ func (v *Visitor) Visit(node ast.Node) ast.Visitor { return v } + func main() { - if err := runMain(); err != nil { + // latest (v1) + if err := generate("./api", "api", "api", "./api/proxy_gen.go"); err != nil { + fmt.Println("error: ", err) + } + + // v0 + if err := generate("./api/v0api", "v0api", "v0api", "./api/v0api/proxy_gen.go"); err != nil { fmt.Println("error: ", err) } } -func typeName(e ast.Expr) (string, error) { +func typeName(e ast.Expr, pkg string) (string, error) { switch t := e.(type) { case *ast.SelectorExpr: return t.X.(*ast.Ident).Name + "." + t.Sel.Name, nil case *ast.Ident: pstr := t.Name - if !unicode.IsLower(rune(pstr[0])) { + if !unicode.IsLower(rune(pstr[0])) && pkg != "api" { pstr = "api." + pstr // todo src pkg name } return pstr, nil case *ast.ArrayType: - subt, err := typeName(t.Elt) + subt, err := typeName(t.Elt, pkg) if err != nil { return "", err } return "[]" + subt, nil case *ast.StarExpr: - subt, err := typeName(t.X) + subt, err := typeName(t.X, pkg) if err != nil { return "", err } return "*" + subt, nil case *ast.MapType: - k, err := typeName(t.Key) + k, err := typeName(t.Key, pkg) if err != nil { return "", err } - v, err := typeName(t.Value) + v, err := typeName(t.Value, pkg) if err != nil { return "", err } @@ -101,7 +108,7 @@ func typeName(e ast.Expr) (string, error) { } return "interface{}", nil case *ast.ChanType: - subt, err := typeName(t.Value) + subt, err := typeName(t.Value, pkg) if err != nil { return "", err } @@ -116,9 +123,13 @@ func typeName(e ast.Expr) (string, error) { } } -func runMain() error { +func generate(path, pkg, outpkg, outfile string) error { fset := token.NewFileSet() - apiDir, err := filepath.Abs("./api") + apiDir, err := filepath.Abs(path) + if err != nil { + return err + } + outfile, err = filepath.Abs(outfile) if err != nil { return err } @@ -127,16 +138,16 @@ func runMain() error { return err } - ap := pkgs["api"] + ap := pkgs[pkg] v := &Visitor{make(map[string]map[string]*methodMeta), map[string][]string{}} ast.Walk(v, ap) type methodInfo struct { - Name string - node ast.Node - Tags map[string][]string - NamedParams, ParamNames, Results string + Name string + node ast.Node + Tags map[string][]string + NamedParams, ParamNames, Results, DefRes string } type strinfo struct { @@ -148,9 +159,11 @@ func runMain() error { type meta struct { Infos map[string]*strinfo Imports map[string]string + OutPkg string } m := &meta{ + OutPkg: outpkg, Infos: map[string]*strinfo{}, Imports: map[string]string{}, } @@ -165,6 +178,9 @@ func runMain() error { for _, im := range f.Imports { m.Imports[im.Path.Value] = im.Path.Value + if im.Name != nil { + m.Imports[im.Path.Value] = im.Name.Name + " " + m.Imports[im.Path.Value] + } } for ifname, methods := range v.Methods { @@ -182,7 +198,7 @@ func runMain() error { if _, ok := info.Methods[mname]; !ok { var params, pnames []string for _, param := range node.ftype.Params.List { - pstr, err := typeName(param.Type) + pstr, err := typeName(param.Type, outpkg) if err != nil { return err } @@ -199,15 +215,33 @@ func runMain() error { } } - var results []string + results := []string{} for _, result := range node.ftype.Results.List { - rs, err := typeName(result.Type) + rs, err := typeName(result.Type, outpkg) if err != nil { return err } results = append(results, rs) } + defRes := "" + if len(results) > 1 { + defRes = results[0] + switch { + case defRes[0] == '*' || defRes[0] == '<', defRes == "interface{}": + defRes = "nil" + case defRes == "bool": + defRes = "false" + case defRes == "string": + defRes = `""` + case defRes == "int", defRes == "int64", defRes == "uint64", defRes == "uint": + defRes = "0" + default: + defRes = "*new(" + defRes + ")" + } + defRes += ", " + } + info.Methods[mname] = &methodInfo{ Name: mname, node: node.node, @@ -215,6 +249,7 @@ func runMain() error { NamedParams: strings.Join(params, ", "), ParamNames: strings.Join(pnames, ", "), Results: strings.Join(results, ", "), + DefRes: defRes, } } @@ -244,14 +279,17 @@ func runMain() error { } fmt.Println(string(jb))*/ - w := os.Stdout + w, err := os.OpenFile(outfile, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666) + if err != nil { + return err + } err = doTemplate(w, m, `// Code generated by github.com/filecoin-project/lotus/gen/api. DO NOT EDIT. -package apistruct +package {{.OutPkg}} import ( -{{range .Imports}}{{.}} +{{range .Imports}} {{.}} {{end}} ) `) @@ -271,6 +309,12 @@ type {{.Name}}Struct struct { {{end}} } } + +type {{.Name}}Stub struct { +{{range .Include}} + {{.}}Stub +{{end}} +} {{end}} {{range .Infos}} @@ -279,10 +323,14 @@ type {{.Name}}Struct struct { func (s *{{$name}}Struct) {{.Name}}({{.NamedParams}}) ({{.Results}}) { return s.Internal.{{.Name}}({{.ParamNames}}) } + +func (s *{{$name}}Stub) {{.Name}}({{.NamedParams}}) ({{.Results}}) { + return {{.DefRes}}xerrors.New("method not supported") +} {{end}} {{end}} -{{range .Infos}}var _ api.{{.Name}} = new({{.Name}}Struct) +{{range .Infos}}var _ {{.Name}} = new({{.Name}}Struct) {{end}} `) diff --git a/go.mod b/go.mod index 621bea70214..384cac442d5 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/BurntSushi/toml v0.3.1 github.com/GeertJohan/go.rice v1.0.0 github.com/Gurpartap/async v0.0.0-20180927173644-4f7f499dd9ee + github.com/Kubuxu/imtui v0.0.0-20210401140320-41663d68d0fa github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d github.com/alecthomas/jsonschema v0.0.0-20200530073317-71f438968921 @@ -30,25 +31,27 @@ require ( github.com/filecoin-project/go-amt-ipld/v2 v2.1.1-0.20201006184820-924ee87a1349 // indirect github.com/filecoin-project/go-bitfield v0.2.4 github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 - github.com/filecoin-project/go-commp-utils v0.0.0-20201119054358-b88f7a96a434 + github.com/filecoin-project/go-commp-utils v0.1.1-0.20210427191551-70bf140d31c7 github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 - github.com/filecoin-project/go-data-transfer v1.2.7 + github.com/filecoin-project/go-data-transfer v1.4.3 github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a - github.com/filecoin-project/go-fil-markets v1.1.9 + github.com/filecoin-project/go-fil-markets v1.2.5 github.com/filecoin-project/go-jsonrpc v0.1.4-0.20210217175800-45ea43ac2bec github.com/filecoin-project/go-multistore v0.0.3 github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20 github.com/filecoin-project/go-paramfetch v0.0.2-0.20200701152213-3e0f0afdc261 github.com/filecoin-project/go-state-types v0.1.0 github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe - github.com/filecoin-project/go-statestore v0.1.1-0.20210311122610-6c7a5aedbdea + github.com/filecoin-project/go-statestore v0.1.1 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b github.com/filecoin-project/specs-actors v0.9.13 - github.com/filecoin-project/specs-actors/v2 v2.3.4 - github.com/filecoin-project/specs-actors/v3 v3.0.3 + github.com/filecoin-project/specs-actors/v2 v2.3.5-0.20210114162132-5b58b773f4fb + github.com/filecoin-project/specs-actors/v3 v3.1.0 + github.com/filecoin-project/specs-actors/v4 v4.0.0 github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506 github.com/filecoin-project/test-vectors/schema v0.0.5 github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 + github.com/gdamore/tcell/v2 v2.2.0 github.com/go-kit/kit v0.10.0 github.com/go-ole/go-ole v1.2.4 // indirect github.com/golang/mock v1.4.4 @@ -85,8 +88,7 @@ require ( github.com/ipfs/go-ipfs-util v0.0.2 github.com/ipfs/go-ipld-cbor v0.0.5 github.com/ipfs/go-ipld-format v0.2.0 - github.com/ipfs/go-log v1.0.4 - github.com/ipfs/go-log/v2 v2.1.2-0.20200626104915-0016c0b4b3e4 + github.com/ipfs/go-log/v2 v2.1.2 github.com/ipfs/go-merkledag v0.3.2 github.com/ipfs/go-metrics-interface v0.0.1 github.com/ipfs/go-metrics-prometheus v0.0.2 @@ -116,6 +118,7 @@ require ( github.com/libp2p/go-libp2p-yamux v0.4.1 github.com/libp2p/go-maddr-filter v0.1.0 github.com/mattn/go-colorable v0.1.6 // indirect + github.com/mattn/go-isatty v0.0.12 github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 github.com/mitchellh/go-homedir v1.1.0 github.com/multiformats/go-base32 v0.0.3 @@ -150,6 +153,7 @@ require ( golang.org/x/sync v0.0.0-20201207232520-09787c993a3a golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 golang.org/x/time v0.0.0-20191024005414-555d28b269f0 + golang.org/x/tools v0.0.0-20201112185108-eeaa07dd7696 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect gopkg.in/cheggaaa/pb.v1 v1.0.28 diff --git a/go.sum b/go.sum index e4b3d7d0ec3..ef3ac9678ec 100644 --- a/go.sum +++ b/go.sum @@ -42,6 +42,8 @@ github.com/Gurpartap/async v0.0.0-20180927173644-4f7f499dd9ee h1:8doiS7ib3zi6/K1 github.com/Gurpartap/async v0.0.0-20180927173644-4f7f499dd9ee/go.mod h1:W0GbEAA4uFNYOGG2cJpmFJ04E6SD1NLELPYZB57/7AY= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= +github.com/Kubuxu/imtui v0.0.0-20210401140320-41663d68d0fa h1:1PPxEyGdIGVkX/kqMvLJ95a1dGS1Sz7tpNEgehEYYt0= +github.com/Kubuxu/imtui v0.0.0-20210401140320-41663d68d0fa/go.mod h1:WUmMvh9wMtqj1Xhf1hf3kp9RvL+y6odtdYxpyZjb90U= github.com/Masterminds/glide v0.13.2/go.mod h1:STyF5vcenH/rUqTEv+/hBXlSTo7KYwg2oc2f4tzPWic= github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/vcs v1.13.0/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA= @@ -255,26 +257,26 @@ github.com/filecoin-project/go-amt-ipld/v3 v3.0.0 h1:Ou/q82QeHGOhpkedvaxxzpBYuqT github.com/filecoin-project/go-amt-ipld/v3 v3.0.0/go.mod h1:Qa95YNAbtoVCTSVtX38aAC1ptBnJfPma1R/zZsKmx4o= github.com/filecoin-project/go-bitfield v0.2.0/go.mod h1:CNl9WG8hgR5mttCnUErjcQjGvuiZjRqK9rHVBsQF4oM= github.com/filecoin-project/go-bitfield v0.2.3/go.mod h1:CNl9WG8hgR5mttCnUErjcQjGvuiZjRqK9rHVBsQF4oM= -github.com/filecoin-project/go-bitfield v0.2.3/go.mod h1:CNl9WG8hgR5mttCnUErjcQjGvuiZjRqK9rHVBsQF4oM= github.com/filecoin-project/go-bitfield v0.2.4 h1:uZ7MeE+XfM5lqrHJZ93OnhQKc/rveW8p9au0C68JPgk= github.com/filecoin-project/go-bitfield v0.2.4/go.mod h1:CNl9WG8hgR5mttCnUErjcQjGvuiZjRqK9rHVBsQF4oM= github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 h1:av5fw6wmm58FYMgJeoB/lK9XXrgdugYiTqkdxjTy9k8= github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2/go.mod h1:pqTiPHobNkOVM5thSRsHYjyQfq7O5QSCMhvuu9JoDlg= -github.com/filecoin-project/go-commp-utils v0.0.0-20201119054358-b88f7a96a434 h1:0kHszkYP3hgApcjl5x4rpwONhN9+j7XDobf6at5XfHs= github.com/filecoin-project/go-commp-utils v0.0.0-20201119054358-b88f7a96a434/go.mod h1:6s95K91mCyHY51RPWECZieD3SGWTqIFLf1mPOes9l5U= +github.com/filecoin-project/go-commp-utils v0.1.1-0.20210427191551-70bf140d31c7 h1:U9Z+76pHCKBmtdxFV7JFZJj7OVm12I6dEKwtMVbq5p0= +github.com/filecoin-project/go-commp-utils v0.1.1-0.20210427191551-70bf140d31c7/go.mod h1:6s95K91mCyHY51RPWECZieD3SGWTqIFLf1mPOes9l5U= github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 h1:2pMXdBnCiXjfCYx/hLqFxccPoqsSveQFxVLvNxy9bus= github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03/go.mod h1:+viYnvGtUTgJRdy6oaeF4MTFKAfatX071MPDPBL11EQ= github.com/filecoin-project/go-data-transfer v1.0.1/go.mod h1:UxvfUAY9v3ub0a21BSK9u3pB2aq30Y0KMsG+w9/ysyo= -github.com/filecoin-project/go-data-transfer v1.2.7 h1:WE5Cpp9eMt5BDoWOVR64QegSn6bwHQaDzyyjVU377Y0= -github.com/filecoin-project/go-data-transfer v1.2.7/go.mod h1:mvjZ+C3NkBX10JP4JMu27DCjUouHFjHwUGh+Xc4yvDA= +github.com/filecoin-project/go-data-transfer v1.4.3 h1:ECEw69NOfmEZ7XN1NSBvj3KTbbH2mIczQs+Z2w4bD7c= +github.com/filecoin-project/go-data-transfer v1.4.3/go.mod h1:n8kbDQXWrY1c4UgfMa9KERxNCWbOTDwdNhf2MpN9dpo= github.com/filecoin-project/go-ds-versioning v0.1.0 h1:y/X6UksYTsK8TLCI7rttCKEvl8btmWxyFMEeeWGUxIQ= github.com/filecoin-project/go-ds-versioning v0.1.0/go.mod h1:mp16rb4i2QPmxBnmanUx8i/XANp+PFCCJWiAb+VW4/s= github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a h1:hyJ+pUm/4U4RdEZBlg6k8Ma4rDiuvqyGpoICXAxwsTg= github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= github.com/filecoin-project/go-fil-markets v1.0.5-0.20201113164554-c5eba40d5335/go.mod h1:AJySOJC00JRWEZzRG2KsfUnqEf5ITXxeX09BE9N4f9c= -github.com/filecoin-project/go-fil-markets v1.1.9 h1:sA0NIEOpy7brZaeXeNgdXg5pvHaBtD5OTRlraOUbI0w= -github.com/filecoin-project/go-fil-markets v1.1.9/go.mod h1:0yQu5gvrjFoAIyzPSSJ+xUdCG83vjInAFbTswIB5/hk= +github.com/filecoin-project/go-fil-markets v1.2.5 h1:bQgtXbwxKyPxSEQoUI5EaTHJ0qfzyd5NosspuADCm6Y= +github.com/filecoin-project/go-fil-markets v1.2.5/go.mod h1:7JIqNBmFvOyBzk/EiPYnweVdQnWhshixb5B9b1653Ag= github.com/filecoin-project/go-hamt-ipld v0.1.5 h1:uoXrKbCQZ49OHpsTCkrThPNelC4W3LPEk0OrS/ytIBM= github.com/filecoin-project/go-hamt-ipld v0.1.5/go.mod h1:6Is+ONR5Cd5R6XZoCse1CWaXZc0Hdb/JeX+EQCQzX24= github.com/filecoin-project/go-hamt-ipld/v2 v2.0.0 h1:b3UDemBYN2HNfk3KOXNuxgTTxlWi3xVvbQP0IT38fvM= @@ -298,8 +300,8 @@ github.com/filecoin-project/go-state-types v0.1.0/go.mod h1:ezYnPf0bNkTsDibL/psS github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe h1:dF8u+LEWeIcTcfUcCf3WFVlc81Fr2JKg8zPzIbBDKDw= github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZOinUJB4WARkRfNl10O7kTnI= -github.com/filecoin-project/go-statestore v0.1.1-0.20210311122610-6c7a5aedbdea h1:EvmiCrHRrPF2mxVMIRdtsxZGByqwT24aJLw7mdzEFxE= -github.com/filecoin-project/go-statestore v0.1.1-0.20210311122610-6c7a5aedbdea/go.mod h1:LFc9hD+fRxPqiHiaqUEZOinUJB4WARkRfNl10O7kTnI= +github.com/filecoin-project/go-statestore v0.1.1 h1:ufMFq00VqnT2CAuDpcGnwLnCX1I/c3OROw/kXVNSTZk= +github.com/filecoin-project/go-statestore v0.1.1/go.mod h1:LFc9hD+fRxPqiHiaqUEZOinUJB4WARkRfNl10O7kTnI= github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b h1:fkRZSPrYpk42PV3/lIXiL0LHetxde7vyYYvSsttQtfg= github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/go.mod h1:Q0GQOBtKf1oE10eSXSlhN45kDBdGvEcVOqMiffqX+N8= github.com/filecoin-project/specs-actors v0.9.4/go.mod h1:BStZQzx5x7TmCkLv0Bpa07U6cPKol6fd3w9KjMPZ6Z4= @@ -308,10 +310,12 @@ github.com/filecoin-project/specs-actors v0.9.13 h1:rUEOQouefi9fuVY/2HOroROJlZbO github.com/filecoin-project/specs-actors v0.9.13/go.mod h1:TS1AW/7LbG+615j4NsjMK1qlpAwaFsG9w0V2tg2gSao= github.com/filecoin-project/specs-actors/v2 v2.0.1/go.mod h1:v2NZVYinNIKA9acEMBm5wWXxqv5+frFEbekBFemYghY= github.com/filecoin-project/specs-actors/v2 v2.3.2/go.mod h1:UuJQLoTx/HPvvWeqlIFmC/ywlOLHNe8SNQ3OunFbu2Y= -github.com/filecoin-project/specs-actors/v2 v2.3.4 h1:NZK2oMCcA71wNsUzDBmLQyRMzcCnX9tDGvwZ53G67j8= -github.com/filecoin-project/specs-actors/v2 v2.3.4/go.mod h1:UuJQLoTx/HPvvWeqlIFmC/ywlOLHNe8SNQ3OunFbu2Y= -github.com/filecoin-project/specs-actors/v3 v3.0.3 h1:bq9B1Jnq+Z0A+Yj3KnYhN3kcTpUyP6Umo3MZgai0BRE= -github.com/filecoin-project/specs-actors/v3 v3.0.3/go.mod h1:oMcmEed6B7H/wHabM3RQphTIhq0ibAKsbpYs+bQ/uxQ= +github.com/filecoin-project/specs-actors/v2 v2.3.5-0.20210114162132-5b58b773f4fb h1:orr/sMzrDZUPAveRE+paBdu1kScIUO5zm+HYeh+VlhA= +github.com/filecoin-project/specs-actors/v2 v2.3.5-0.20210114162132-5b58b773f4fb/go.mod h1:LljnY2Mn2homxZsmokJZCpRuhOPxfXhvcek5gWkmqAc= +github.com/filecoin-project/specs-actors/v3 v3.1.0 h1:s4qiPw8pgypqBGAy853u/zdZJ7K9cTZdM1rTiSonHrg= +github.com/filecoin-project/specs-actors/v3 v3.1.0/go.mod h1:mpynccOLlIRy0QnR008BwYBwT9fen+sPR13MA1VmMww= +github.com/filecoin-project/specs-actors/v4 v4.0.0 h1:vMALksY5G3J5rj3q9rbcyB+f4Tk1xrLqSgdB3jOok4s= +github.com/filecoin-project/specs-actors/v4 v4.0.0/go.mod h1:TkHXf/l7Wyw4ZejyXIPS2rK8bBO0rdwhTZyQQgaglng= github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506 h1:Ur/l2+6qN+lQiqjozWWc5p9UDaAMDZKTlDS98oRnlIw= github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506/go.mod h1:nJRRM7Aa9XVvygr3W9k6xGF46RWzr2zxF/iGoAIfA/g= github.com/filecoin-project/test-vectors/schema v0.0.5 h1:w3zHQhzM4pYxJDl21avXjOKBLF8egrvwUwjpT8TquDg= @@ -328,6 +332,10 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 h1:EzDjxMg43q1tA2c0MV3tNbaontnHLplHyFF6M5KiVP0= github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1/go.mod h1:0eHX/BVySxPc6SE2mZRoppGq7qcEagxdmQnA3dzork8= +github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko= +github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= +github.com/gdamore/tcell/v2 v2.2.0 h1:vSyEgKwraXPSOkvCk7IwOSyX+Pv3V2cV9CikJMXg4U4= +github.com/gdamore/tcell/v2 v2.2.0/go.mod h1:cTTuF84Dlj/RqmaCIV5p4w8uG1zWdk0SF6oBpwHp4fU= github.com/getsentry/raven-go v0.2.0 h1:no+xWJRb5ZI7eE8TWgIq1jLulQiIoLG0IfYxv5JYMGs= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghemawat/stream v0.0.0-20171120220530-696b145b53b9/go.mod h1:106OIgooyS7OzLDOpUGgm9fA3bQENb/cFSyyBmMoJDs= @@ -595,7 +603,6 @@ github.com/ipfs/go-fs-lock v0.0.6/go.mod h1:OTR+Rj9sHiRubJh3dRhD15Juhd/+w6VPOY28 github.com/ipfs/go-graphsync v0.1.0/go.mod h1:jMXfqIEDFukLPZHqDPp8tJMbHO9Rmeb9CEGevngQbmE= github.com/ipfs/go-graphsync v0.4.2/go.mod h1:/VmbZTUdUMTbNkgzAiCEucIIAU3BkLE2cZrDCVUhyi0= github.com/ipfs/go-graphsync v0.4.3/go.mod h1:mPOwDYv128gf8gxPFgXnz4fNrSYPsWyqisJ7ych+XDY= -github.com/ipfs/go-graphsync v0.5.2/go.mod h1:e2ZxnClqBBYAtd901g9vXMJzS47labjAtOzsWtOzKNk= github.com/ipfs/go-graphsync v0.6.0 h1:x6UvDUGA7wjaKNqx5Vbo7FGT8aJ5ryYA0dMQ5jN3dF0= github.com/ipfs/go-graphsync v0.6.0/go.mod h1:e2ZxnClqBBYAtd901g9vXMJzS47labjAtOzsWtOzKNk= github.com/ipfs/go-hamt-ipld v0.1.1/go.mod h1:1EZCr2v0jlCnhpa+aZ0JZYp8Tt2w16+JJOAVz17YcDk= @@ -671,8 +678,9 @@ github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBW github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= github.com/ipfs/go-log/v2 v2.0.8/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= github.com/ipfs/go-log/v2 v2.1.1/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= -github.com/ipfs/go-log/v2 v2.1.2-0.20200626104915-0016c0b4b3e4 h1:3bijxqzQ1O9yg7gd7Aqk80oaEvsJ+uXw0zSvi2qR3Jw= github.com/ipfs/go-log/v2 v2.1.2-0.20200626104915-0016c0b4b3e4/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= +github.com/ipfs/go-log/v2 v2.1.2 h1:a0dRiL098zY23vay1h3dimx6y94XchEUyt5h0l4VvQU= +github.com/ipfs/go-log/v2 v2.1.2/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= github.com/ipfs/go-merkledag v0.0.3/go.mod h1:Oc5kIXLHokkE1hWGMBHw+oxehkAaTOqtEb7Zbh6BhLA= github.com/ipfs/go-merkledag v0.0.6/go.mod h1:QYPdnlvkOg7GnQRofu9XZimC5ZW5Wi3bKys/4GQQfto= github.com/ipfs/go-merkledag v0.2.3/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB3ClKnBAlk= @@ -1109,6 +1117,8 @@ github.com/lucas-clemente/quic-go v0.11.2/go.mod h1:PpMmPfPKO9nKJ/psF49ESTAGQSdf github.com/lucas-clemente/quic-go v0.16.0/go.mod h1:I0+fcNTdb9eS1ZcjQZbDVPGchJ86chcIxPALn9lEJqE= github.com/lucas-clemente/quic-go v0.18.1 h1:DMR7guC0NtVS8zNZR3IO7NARZvZygkSC56GGtC6cyys= github.com/lucas-clemente/quic-go v0.18.1/go.mod h1:yXttHsSNxQi8AWijC/vLP+OJczXqzHSOcJrM5ITUlCg= +github.com/lucasb-eyer/go-colorful v1.0.3 h1:QIbQXiugsb+q10B+MI+7DI1oQLdmnep86tWFlaaUAac= +github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lufia/iostat v1.1.0/go.mod h1:rEPNA0xXgjHQjuI5Cy05sLlS2oRcSlWHRLrvh/AQ+Pg= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= @@ -1142,8 +1152,9 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54= github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRRpdGg= +github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-xmlrpc v0.0.3/go.mod h1:mqc2dz7tP5x5BKlCahN/n+hs7OSZKJkS9JsHNBRlrxA= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -1368,6 +1379,8 @@ github.com/raulk/go-watchdog v1.0.1/go.mod h1:lzSbAl5sh4rtI8tYHU01BWIDzgzqaQLj6R github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY= +github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -1813,6 +1826,8 @@ golang.org/x/sys v0.0.0-20200926100807-9d91bd62050c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf h1:MZ2shdL+ZM/XzY3ZGOnh4Nlpnxz5GSOhOmtHo3iPU6M= +golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1993,7 +2008,6 @@ modernc.org/cc v1.0.0 h1:nPibNuDEx6tvYrUAtvDTTw98rx5juGsa5zuDnKwEEQQ= modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= modernc.org/fileutil v1.0.0/go.mod h1:JHsWpkrk/CnVV1H/eGlFf85BEpfkrp56ro8nojIq9Q8= modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= -modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= modernc.org/golex v1.0.1 h1:EYKY1a3wStt0RzHaH8mdSRNg78Ub0OHxYfCRWw35YtM= modernc.org/golex v1.0.1/go.mod h1:QCA53QtsT1NdGkaZZkF5ezFwk4IXh4BGNafAARTC254= modernc.org/lex v1.0.0/go.mod h1:G6rxMTy3cH2iA0iXL/HRRv4Znu8MK4higxph/lE7ypk= diff --git a/journal/types.go b/journal/types.go index 5b51ed4c8c3..3e240a9f1de 100644 --- a/journal/types.go +++ b/journal/types.go @@ -5,7 +5,7 @@ import ( "strings" "time" - logging "github.com/ipfs/go-log" + logging "github.com/ipfs/go-log/v2" ) var log = logging.Logger("journal") diff --git a/lib/backupds/log.go b/lib/backupds/log.go index a708254a1da..b76dfbfe653 100644 --- a/lib/backupds/log.go +++ b/lib/backupds/log.go @@ -145,7 +145,7 @@ func (d *Datastore) openLog(p string) (*logfile, string, error) { var lastLogHead string var openCount, vals, logvals int64 // check file integrity - err = ReadBackup(f, func(k datastore.Key, v []byte, log bool) error { + clean, err := ReadBackup(f, func(k datastore.Key, v []byte, log bool) error { if log { logvals++ } else { @@ -160,7 +160,7 @@ func (d *Datastore) openLog(p string) (*logfile, string, error) { if err != nil { return nil, "", xerrors.Errorf("reading backup part of the logfile: %w", err) } - if string(lh) != lastLogHead { + if string(lh) != lastLogHead && clean { // if not clean, user has opted in to ignore truncated logs, this will almost certainly happen return nil, "", xerrors.Errorf("loghead didn't match, expected '%s', last in logfile '%s'", string(lh), lastLogHead) } @@ -178,8 +178,8 @@ func (d *Datastore) openLog(p string) (*logfile, string, error) { } compact := logvals > vals*int64(compactThresh) - if compact { - log.Infow("compacting log", "current", p, "openCount", openCount, "baseValues", vals, "logValues", logvals) + if compact || !clean { + log.Infow("compacting log", "current", p, "openCount", openCount, "baseValues", vals, "logValues", logvals, "truncated", !clean) if err := f.Close(); err != nil { return nil, "", xerrors.Errorf("closing current log: %w", err) } @@ -189,10 +189,14 @@ func (d *Datastore) openLog(p string) (*logfile, string, error) { return nil, "", xerrors.Errorf("creating compacted log: %w", err) } - log.Infow("compacted log created, cleaning up old", "old", p, "new", latest) - if err := os.Remove(p); err != nil { - l.Close() // nolint - return nil, "", xerrors.Errorf("cleaning up old logfile: %w", err) + if clean { + log.Infow("compacted log created, cleaning up old", "old", p, "new", latest) + if err := os.Remove(p); err != nil { + l.Close() // nolint + return nil, "", xerrors.Errorf("cleaning up old logfile: %w", err) + } + } else { + log.Errorw("LOG FILE WAS TRUNCATED, KEEPING THE FILE", "old", p, "new", latest) } return l, latest, nil diff --git a/lib/backupds/read.go b/lib/backupds/read.go index 3d6d24139bd..a44442af167 100644 --- a/lib/backupds/read.go +++ b/lib/backupds/read.go @@ -11,16 +11,16 @@ import ( "golang.org/x/xerrors" ) -func ReadBackup(r io.Reader, cb func(key datastore.Key, value []byte, log bool) error) error { +func ReadBackup(r io.Reader, cb func(key datastore.Key, value []byte, log bool) error) (bool, error) { scratch := make([]byte, 9) // read array[2]( if _, err := r.Read(scratch[:1]); err != nil { - return xerrors.Errorf("reading array header: %w", err) + return false, xerrors.Errorf("reading array header: %w", err) } if scratch[0] != 0x82 { - return xerrors.Errorf("expected array(2) header byte 0x82, got %x", scratch[0]) + return false, xerrors.Errorf("expected array(2) header byte 0x82, got %x", scratch[0]) } hasher := sha256.New() @@ -28,16 +28,16 @@ func ReadBackup(r io.Reader, cb func(key datastore.Key, value []byte, log bool) // read array[*]( if _, err := hr.Read(scratch[:1]); err != nil { - return xerrors.Errorf("reading array header: %w", err) + return false, xerrors.Errorf("reading array header: %w", err) } if scratch[0] != 0x9f { - return xerrors.Errorf("expected indefinite length array header byte 0x9f, got %x", scratch[0]) + return false, xerrors.Errorf("expected indefinite length array header byte 0x9f, got %x", scratch[0]) } for { if _, err := hr.Read(scratch[:1]); err != nil { - return xerrors.Errorf("reading tuple header: %w", err) + return false, xerrors.Errorf("reading tuple header: %w", err) } // close array[*] @@ -47,22 +47,22 @@ func ReadBackup(r io.Reader, cb func(key datastore.Key, value []byte, log bool) // read array[2](key:[]byte, value:[]byte) if scratch[0] != 0x82 { - return xerrors.Errorf("expected array(2) header 0x82, got %x", scratch[0]) + return false, xerrors.Errorf("expected array(2) header 0x82, got %x", scratch[0]) } keyb, err := cbg.ReadByteArray(hr, 1<<40) if err != nil { - return xerrors.Errorf("reading key: %w", err) + return false, xerrors.Errorf("reading key: %w", err) } key := datastore.NewKey(string(keyb)) value, err := cbg.ReadByteArray(hr, 1<<40) if err != nil { - return xerrors.Errorf("reading value: %w", err) + return false, xerrors.Errorf("reading value: %w", err) } if err := cb(key, value, false); err != nil { - return err + return false, err } } @@ -71,11 +71,11 @@ func ReadBackup(r io.Reader, cb func(key datastore.Key, value []byte, log bool) // read the [32]byte checksum expSum, err := cbg.ReadByteArray(r, 32) if err != nil { - return xerrors.Errorf("reading expected checksum: %w", err) + return false, xerrors.Errorf("reading expected checksum: %w", err) } if !bytes.Equal(sum, expSum) { - return xerrors.Errorf("checksum didn't match; expected %x, got %x", expSum, sum) + return false, xerrors.Errorf("checksum didn't match; expected %x, got %x", expSum, sum) } // read the log, set of Entry-ies @@ -86,32 +86,32 @@ func ReadBackup(r io.Reader, cb func(key datastore.Key, value []byte, log bool) _, err := bp.ReadByte() switch err { case io.EOF, io.ErrUnexpectedEOF: - return nil + return true, nil case nil: default: - return xerrors.Errorf("peek log: %w", err) + return false, xerrors.Errorf("peek log: %w", err) } if err := bp.UnreadByte(); err != nil { - return xerrors.Errorf("unread log byte: %w", err) + return false, xerrors.Errorf("unread log byte: %w", err) } if err := ent.UnmarshalCBOR(bp); err != nil { switch err { case io.EOF, io.ErrUnexpectedEOF: if os.Getenv("LOTUS_ALLOW_TRUNCATED_LOG") == "1" { - panic("handleme; just ignore and tell the caller about the corrupted file") // todo - } else { - return xerrors.Errorf("log entry potentially truncated, set LOTUS_ALLOW_TRUNCATED_LOG=1 to proceed: %w", err) + log.Errorw("log entry potentially truncated") + return false, nil } + return false, xerrors.Errorf("log entry potentially truncated, set LOTUS_ALLOW_TRUNCATED_LOG=1 to proceed: %w", err) default: - return xerrors.Errorf("unmarshaling log entry: %w", err) + return false, xerrors.Errorf("unmarshaling log entry: %w", err) } } key := datastore.NewKey(string(ent.Key)) if err := cb(key, ent.Value, true); err != nil { - return err + return false, err } } } @@ -122,7 +122,7 @@ func RestoreInto(r io.Reader, dest datastore.Batching) error { return xerrors.Errorf("creating batch: %w", err) } - err = ReadBackup(r, func(key datastore.Key, value []byte, _ bool) error { + _, err = ReadBackup(r, func(key datastore.Key, value []byte, _ bool) error { if err := batch.Put(key, value); err != nil { return xerrors.Errorf("put key: %w", err) } diff --git a/lib/sigs/bls/bls_test.go b/lib/sigs/bls/bls_test.go new file mode 100644 index 00000000000..4508d0eb9b2 --- /dev/null +++ b/lib/sigs/bls/bls_test.go @@ -0,0 +1,77 @@ +package bls_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/crypto" + + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/chain/wallet" + "github.com/filecoin-project/lotus/lib/sigs" + _ "github.com/filecoin-project/lotus/lib/sigs/bls" +) + +func TestRoundtrip(t *testing.T) { + pk, err := sigs.Generate(crypto.SigTypeBLS) + require.NoError(t, err) + + ki := types.KeyInfo{ + Type: types.KTBLS, + PrivateKey: pk, + } + k, err := wallet.NewKey(ki) + require.NoError(t, err) + + p := []byte("potato") + + si, err := sigs.Sign(crypto.SigTypeBLS, pk, p) + require.NoError(t, err) + + err = sigs.Verify(si, k.Address, p) + require.NoError(t, err) +} + +func TestUncompressedFails(t *testing.T) { + // compressed + err := sigs.Verify(&crypto.Signature{ + Type: crypto.SigTypeBLS, + Data: []byte{0x99, 0x27, 0x44, 0x4b, 0xfc, 0xff, 0xdc, 0xa3, 0x4a, 0xf5, 0x7b, 0x78, 0x75, 0x7b, 0x9b, 0x90, 0xf1, 0xcd, 0x28, 0xd2, 0xa3, 0xae, 0xed, 0x2a, 0xa6, 0xbd, 0xe2, 0x99, 0xf8, 0xbb, 0xb9, 0x18, 0x47, 0x56, 0xf2, 0x28, 0x7b, 0x5, 0x88, 0xe6, 0xd3, 0xf2, 0x86, 0xd, 0x2b, 0xb2, 0x6, 0x6e, 0xc, 0x59, 0x77, 0x8c, 0x1e, 0x64, 0x4f, 0xb2, 0xcf, 0xb3, 0x5f, 0xba, 0x8f, 0x9, 0xfa, 0x82, 0x4a, 0x9e, 0xd8, 0x25, 0x10, 0x8c, 0x82, 0xff, 0x4b, 0xf6, 0x34, 0xc1, 0x3, 0x7e, 0xea, 0xf1, 0x85, 0xf4, 0x56, 0x73, 0xd4, 0xa1, 0xc1, 0xc6, 0xee, 0xb7, 0x12, 0xb7, 0xd7, 0x2a, 0x54, 0x98}, + }, mustAddr("f3tcgq5scpfhdwh4dbalwktzf6mbv3ng2nw7tyzni5cyrsgvineid6jybnweecpa6misa6lk4tvwtxj2gkwpzq"), []byte{0x70, 0x6f, 0x74, 0x61, 0x74, 0x6f}) + require.NoError(t, err) + + // compressed byte changed + err = sigs.Verify(&crypto.Signature{ + Type: crypto.SigTypeBLS, + Data: []byte{0x99, 0x27, 0x44, 0x4b, 0xfc, 0xff, 0xdc, 0xa3, 0x4a, 0xf5, 0x7b, 0x78, 0x75, 0x7b, 0x9b, 0x90, 0xf1, 0xcd, 0x28, 0xd2, 0xa3, 0xae, 0xed, 0x2a, 0xa6, 0xbd, 0xe2, 0x99, 0xf8, 0xbb, 0xb9, 0x18, 0x47, 0x56, 0xf2, 0x28, 0x7b, 0x5, 0x88, 0xf6, 0xd3, 0xf2, 0x86, 0xd, 0x2b, 0xb2, 0x6, 0x6e, 0xc, 0x59, 0x77, 0x8c, 0x1e, 0x64, 0x4f, 0xb2, 0xcf, 0xb3, 0x5f, 0xba, 0x8f, 0x9, 0xfa, 0x82, 0x4a, 0x9e, 0xd8, 0x25, 0x10, 0x8c, 0x82, 0xff, 0x4b, 0xf6, 0x34, 0xc1, 0x3, 0x7e, 0xea, 0xf1, 0x85, 0xf4, 0x56, 0x73, 0xd4, 0xa1, 0xc1, 0xc6, 0xee, 0xb7, 0x12, 0xb7, 0xd7, 0x2a, 0x54, 0x98}, + }, mustAddr("f3tcgq5scpfhdwh4dbalwktzf6mbv3ng2nw7tyzni5cyrsgvineid6jybnweecpa6misa6lk4tvwtxj2gkwpzq"), []byte{0x70, 0x6f, 0x74, 0x61, 0x74, 0x6f}) + require.Error(t, err) + + // compressed prefix + err = sigs.Verify(&crypto.Signature{ + Type: crypto.SigTypeBLS, + Data: []byte{0x99, 0x27, 0x44, 0x4b, 0xfc, 0xff, 0xdc, 0xa3, 0x4a, 0xf5, 0x7b, 0x78, 0x75, 0x7b, 0x9b, 0x90, 0xf1, 0xcd, 0x28, 0xd2, 0xa3, 0xae, 0xed, 0x2a, 0xa6, 0xbd, 0xe2, 0x99, 0xf8, 0xbb, 0xb9, 0x18, 0x47, 0x56, 0xf2, 0x28, 0x7b, 0x5, 0x88, 0xe6, 0xd3, 0xf2, 0x86, 0xd, 0x2b, 0xb2, 0x6, 0x6e, 0xc, 0x59, 0x77, 0x8c, 0x1e, 0x64, 0x4f, 0xb2, 0xcf, 0xb3, 0x5f, 0xba, 0x8f, 0x9, 0xfa, 0x82, 0x4a, 0x9e, 0xd8, 0x25, 0x10, 0x8c, 0x82, 0xff, 0x4b, 0xf6, 0x34, 0xc1, 0x3, 0x7e, 0xea, 0xf1, 0x85, 0xf4, 0x56, 0x73, 0xd4, 0xa1, 0xc1, 0xc6, 0xee, 0xb7, 0x12, 0xb7, 0xd7, 0x2a, 0x54, 0x98, 0x55}, + }, mustAddr("f3tcgq5scpfhdwh4dbalwktzf6mbv3ng2nw7tyzni5cyrsgvineid6jybnweecpa6misa6lk4tvwtxj2gkwpzq"), []byte{0x70, 0x6f, 0x74, 0x61, 0x74, 0x6f}) + require.Error(t, err) + + // uncompressed + err = sigs.Verify(&crypto.Signature{ + Type: crypto.SigTypeBLS, + Data: []byte{0x19, 0x27, 0x44, 0x4b, 0xfc, 0xff, 0xdc, 0xa3, 0x4a, 0xf5, 0x7b, 0x78, 0x75, 0x7b, 0x9b, 0x90, 0xf1, 0xcd, 0x28, 0xd2, 0xa3, 0xae, 0xed, 0x2a, 0xa6, 0xbd, 0xe2, 0x99, 0xf8, 0xbb, 0xb9, 0x18, 0x47, 0x56, 0xf2, 0x28, 0x7b, 0x5, 0x88, 0xe6, 0xd3, 0xf2, 0x86, 0xd, 0x2b, 0xb2, 0x6, 0x6e, 0xc, 0x59, 0x77, 0x8c, 0x1e, 0x64, 0x4f, 0xb2, 0xcf, 0xb3, 0x5f, 0xba, 0x8f, 0x9, 0xfa, 0x82, 0x4a, 0x9e, 0xd8, 0x25, 0x10, 0x8c, 0x82, 0xff, 0x4b, 0xf6, 0x34, 0xc1, 0x3, 0x7e, 0xea, 0xf1, 0x85, 0xf4, 0x56, 0x73, 0xd4, 0xa1, 0xc1, 0xc6, 0xee, 0xb7, 0x12, 0xb7, 0xd7, 0x2a, 0x54, 0x98, 0x8, 0x94, 0x23, 0x78, 0xdb, 0xce, 0x2a, 0xd7, 0x2e, 0x87, 0xdf, 0x8, 0x3b, 0x66, 0xc6, 0x31, 0xc1, 0x8c, 0x58, 0x2f, 0x9f, 0x9e, 0x10, 0x4d, 0x2a, 0x7e, 0x13, 0xe7, 0x9c, 0xbb, 0x22, 0xde, 0xcc, 0xf6, 0x77, 0x77, 0xb0, 0x9c, 0x25, 0x5d, 0x5d, 0xe6, 0x88, 0x9, 0x8c, 0x63, 0x35, 0xd4, 0xa, 0x85, 0x76, 0x8d, 0xb7, 0x66, 0xa6, 0xc6, 0xec, 0xe6, 0xde, 0x2a, 0x9f, 0x34, 0x87, 0x28, 0x1a, 0x48, 0xfe, 0xca, 0xb1, 0x47, 0x2, 0xf6, 0x51, 0x26, 0x52, 0x70, 0x9d, 0x7e, 0xdb, 0x7e, 0x8b, 0xc9, 0xf6, 0x41, 0xaa, 0xa8, 0x3b, 0x7e, 0x8a, 0xfd, 0x7a, 0xe4, 0x79, 0xe6, 0x59, 0xe4}, + }, mustAddr("f3tcgq5scpfhdwh4dbalwktzf6mbv3ng2nw7tyzni5cyrsgvineid6jybnweecpa6misa6lk4tvwtxj2gkwpzq"), []byte{0x70, 0x6f, 0x74, 0x61, 0x74, 0x6f}) + require.Error(t, err) + + // uncompressed one byte change + err = sigs.Verify(&crypto.Signature{ + Type: crypto.SigTypeBLS, + Data: []byte{0x19, 0x27, 0x44, 0x4b, 0xfc, 0xff, 0xdc, 0xa3, 0x4a, 0xf5, 0x7b, 0x78, 0x75, 0x7b, 0x9b, 0x90, 0xf1, 0xcd, 0x28, 0xd2, 0xa3, 0xae, 0xed, 0x2a, 0xa6, 0xbd, 0xe2, 0x99, 0xf8, 0xbb, 0xb9, 0x18, 0x47, 0x56, 0xf2, 0x28, 0x7b, 0x5, 0x88, 0xe6, 0xd3, 0xf2, 0x86, 0xd, 0x2b, 0xb2, 0x6, 0x6e, 0xc, 0x59, 0x77, 0x8c, 0x1e, 0x64, 0x4f, 0xb2, 0xcf, 0xb3, 0x5f, 0xba, 0x8f, 0x9, 0xfa, 0x82, 0x4a, 0x9e, 0xd8, 0x25, 0x10, 0x8c, 0x82, 0xff, 0x4b, 0xf6, 0x34, 0xc1, 0x3, 0x7e, 0xea, 0xf1, 0x85, 0xf4, 0x56, 0x73, 0xd4, 0xa1, 0xc1, 0xc6, 0xee, 0xb7, 0x12, 0xb7, 0xd7, 0x2a, 0x54, 0x98, 0x8, 0x94, 0x23, 0x78, 0xdb, 0xce, 0x2a, 0xd7, 0x2e, 0x87, 0xdf, 0x8, 0x3b, 0x66, 0xc6, 0x31, 0xc1, 0x8c, 0x58, 0x2f, 0x9f, 0x9e, 0x10, 0x4d, 0x2a, 0x7e, 0x13, 0xe7, 0x9c, 0xbb, 0x22, 0xde, 0xcc, 0xf6, 0x77, 0x77, 0xb0, 0x9c, 0x25, 0x5d, 0x5d, 0xe6, 0x88, 0x9, 0x8c, 0x63, 0x35, 0xd4, 0xa, 0x85, 0x66, 0x8d, 0xb7, 0x66, 0xa6, 0xc6, 0xec, 0xe6, 0xde, 0x2a, 0x9f, 0x34, 0x87, 0x28, 0x1a, 0x48, 0xfe, 0xca, 0xb1, 0x47, 0x2, 0xf6, 0x51, 0x26, 0x52, 0x70, 0x9d, 0x7e, 0xdb, 0x7e, 0x8b, 0xc9, 0xf6, 0x41, 0xaa, 0xa8, 0x3b, 0x7e, 0x8a, 0xfd, 0x7a, 0xe4, 0x79, 0xe6, 0x59, 0xe4}, + }, mustAddr("f3tcgq5scpfhdwh4dbalwktzf6mbv3ng2nw7tyzni5cyrsgvineid6jybnweecpa6misa6lk4tvwtxj2gkwpzq"), []byte{0x70, 0x6f, 0x74, 0x61, 0x74, 0x6f}) + require.Error(t, err) +} + +func mustAddr(a string) address.Address { + ad, _ := address.NewFromString(a) + return ad +} diff --git a/lib/ulimit/ulimit.go b/lib/ulimit/ulimit.go index f9999cf6893..16bd4c9c148 100644 --- a/lib/ulimit/ulimit.go +++ b/lib/ulimit/ulimit.go @@ -8,7 +8,7 @@ import ( "strconv" "syscall" - logging "github.com/ipfs/go-log" + logging "github.com/ipfs/go-log/v2" ) var log = logging.Logger("ulimit") diff --git a/lotuspond/front/src/chain/methods.json b/lotuspond/front/src/chain/methods.json index b3bc1aa7c9e..a09d3ec91b4 100644 --- a/lotuspond/front/src/chain/methods.json +++ b/lotuspond/front/src/chain/methods.json @@ -306,5 +306,109 @@ "AddVerifiedClient", "UseBytes", "RestoreBytes" + ], + "fil/4/account": [ + "Send", + "Constructor", + "PubkeyAddress" + ], + "fil/4/cron": [ + "Send", + "Constructor", + "EpochTick" + ], + "fil/4/init": [ + "Send", + "Constructor", + "Exec" + ], + "fil/4/multisig": [ + "Send", + "Constructor", + "Propose", + "Approve", + "Cancel", + "AddSigner", + "RemoveSigner", + "SwapSigner", + "ChangeNumApprovalsThreshold", + "LockBalance" + ], + "fil/4/paymentchannel": [ + "Send", + "Constructor", + "UpdateChannelState", + "Settle", + "Collect" + ], + "fil/4/reward": [ + "Send", + "Constructor", + "AwardBlockReward", + "ThisEpochReward", + "UpdateNetworkKPI" + ], + "fil/4/storagemarket": [ + "Send", + "Constructor", + "AddBalance", + "WithdrawBalance", + "PublishStorageDeals", + "VerifyDealsForActivation", + "ActivateDeals", + "OnMinerSectorsTerminate", + "ComputeDataCommitment", + "CronTick" + ], + "fil/4/storageminer": [ + "Send", + "Constructor", + "ControlAddresses", + "ChangeWorkerAddress", + "ChangePeerID", + "SubmitWindowedPoSt", + "PreCommitSector", + "ProveCommitSector", + "ExtendSectorExpiration", + "TerminateSectors", + "DeclareFaults", + "DeclareFaultsRecovered", + "OnDeferredCronEvent", + "CheckSectorProven", + "ApplyRewards", + "ReportConsensusFault", + "WithdrawBalance", + "ConfirmSectorProofsValid", + "ChangeMultiaddrs", + "CompactPartitions", + "CompactSectorNumbers", + "ConfirmUpdateWorkerKey", + "RepayDebt", + "ChangeOwnerAddress", + "DisputeWindowedPoSt" + ], + "fil/4/storagepower": [ + "Send", + "Constructor", + "CreateMiner", + "UpdateClaimedPower", + "EnrollCronEvent", + "OnEpochTickEnd", + "UpdatePledgeTotal", + "SubmitPoRepForBulkVerify", + "CurrentTotalPower" + ], + "fil/4/system": [ + "Send", + "Constructor" + ], + "fil/4/verifiedregistry": [ + "Send", + "Constructor", + "AddVerifier", + "RemoveVerifier", + "AddVerifiedClient", + "UseBytes", + "RestoreBytes" ] } \ No newline at end of file diff --git a/lotuspond/spawn.go b/lotuspond/spawn.go index ce01b115e50..9085bc24ab7 100644 --- a/lotuspond/spawn.go +++ b/lotuspond/spawn.go @@ -142,11 +142,6 @@ func (api *api) Spawn() (nodeInfo, error) { api.runningLk.Lock() api.running[id].meta.State = NodeStopped api.runningLk.Unlock() - - //logfile.Close() - //errlogfile.Close() - - //close(mux.stop) }, } api.runningLk.Unlock() @@ -221,11 +216,6 @@ func (api *api) SpawnStorage(fullNodeRepo string) (nodeInfo, error) { api.runningLk.Lock() api.running[id].meta.State = NodeStopped api.runningLk.Unlock() - - //logfile.Close() - //errlogfile.Close() - - //close(mux.stop) }, } api.runningLk.Unlock() @@ -272,11 +262,6 @@ func (api *api) RestartNode(id int32) (nodeInfo, error) { api.runningLk.Lock() api.running[id].meta.State = NodeStopped api.runningLk.Unlock() - - //logfile.Close() - //errlogfile.Close() - - //close(mux.stop) } nd.meta.State = NodeRunning diff --git a/markets/retrievaladapter/provider.go b/markets/retrievaladapter/provider.go index 3c8505c51d9..e58257c8abc 100644 --- a/markets/retrievaladapter/provider.go +++ b/markets/retrievaladapter/provider.go @@ -4,10 +4,11 @@ import ( "context" "io" + "github.com/filecoin-project/lotus/api/v1api" + "github.com/ipfs/go-cid" logging "github.com/ipfs/go-log/v2" - "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors/builtin/paych" "github.com/filecoin-project/lotus/chain/types" sectorstorage "github.com/filecoin-project/lotus/extern/sector-storage" @@ -26,12 +27,12 @@ var log = logging.Logger("retrievaladapter") type retrievalProviderNode struct { miner *storage.Miner sealer sectorstorage.SectorManager - full api.FullNode + full v1api.FullNode } // NewRetrievalProviderNode returns a new node adapter for a retrieval provider that talks to the // Lotus Node -func NewRetrievalProviderNode(miner *storage.Miner, sealer sectorstorage.SectorManager, full api.FullNode) retrievalmarket.RetrievalProviderNode { +func NewRetrievalProviderNode(miner *storage.Miner, sealer sectorstorage.SectorManager, full v1api.FullNode) retrievalmarket.RetrievalProviderNode { return &retrievalProviderNode{miner, sealer, full} } @@ -46,6 +47,8 @@ func (rpn *retrievalProviderNode) GetMinerWorkerAddress(ctx context.Context, min } func (rpn *retrievalProviderNode) UnsealSector(ctx context.Context, sectorID abi.SectorNumber, offset abi.UnpaddedPieceSize, length abi.UnpaddedPieceSize) (io.ReadCloser, error) { + log.Debugf("get sector %d, offset %d, length %d", sectorID, offset, length) + si, err := rpn.miner.GetSectorInfo(sectorID) if err != nil { return nil, err @@ -72,7 +75,9 @@ func (rpn *retrievalProviderNode) UnsealSector(ctx context.Context, sectorID abi if si.CommD != nil { commD = *si.CommD } + // Read the piece into the pipe's writer, unsealing the piece if necessary + log.Debugf("read piece in sector %d, offset %d, length %d from miner %d", sectorID, offset, length, mid) err := rpn.sealer.ReadPiece(ctx, w, ref, storiface.UnpaddedByteIndex(offset), length, si.TicketValue, commD) if err != nil { log.Errorf("failed to unseal piece from sector %d: %s", sectorID, err) diff --git a/markets/storageadapter/client.go b/markets/storageadapter/client.go index c0d78a506d6..9357cc271d9 100644 --- a/markets/storageadapter/client.go +++ b/markets/storageadapter/client.go @@ -196,7 +196,7 @@ func (c *ClientNodeAdapter) ValidatePublishedDeal(ctx context.Context, deal stor } // TODO: timeout - ret, err := c.StateWaitMsg(ctx, *deal.PublishMessage, build.MessageConfidence) + ret, err := c.StateWaitMsg(ctx, *deal.PublishMessage, build.MessageConfidence, api.LookbackNoLimit, true) if err != nil { return 0, xerrors.Errorf("waiting for deal publish message: %w", err) } @@ -212,7 +212,13 @@ func (c *ClientNodeAdapter) ValidatePublishedDeal(ctx context.Context, deal stor return res.IDs[dealIdx], nil } -const clientOverestimation = 2 +var clientOverestimation = struct { + numerator int64 + denominator int64 +}{ + numerator: 12, + denominator: 10, +} func (c *ClientNodeAdapter) DealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, isVerified bool) (abi.TokenAmount, abi.TokenAmount, error) { bounds, err := c.StateDealProviderCollateralBounds(ctx, size, isVerified, types.EmptyTSK) @@ -220,7 +226,9 @@ func (c *ClientNodeAdapter) DealProviderCollateralBounds(ctx context.Context, si return abi.TokenAmount{}, abi.TokenAmount{}, err } - return big.Mul(bounds.Min, big.NewInt(clientOverestimation)), bounds.Max, nil + min := big.Mul(bounds.Min, big.NewInt(clientOverestimation.numerator)) + min = big.Div(min, big.NewInt(clientOverestimation.denominator)) + return min, bounds.Max, nil } // TODO: Remove dealID parameter, change publishCid to be cid.Cid (instead of pointer) @@ -363,7 +371,7 @@ func (c *ClientNodeAdapter) GetChainHead(ctx context.Context) (shared.TipSetToke } func (c *ClientNodeAdapter) WaitForMessage(ctx context.Context, mcid cid.Cid, cb func(code exitcode.ExitCode, bytes []byte, finalCid cid.Cid, err error) error) error { - receipt, err := c.StateWaitMsg(ctx, mcid, build.MessageConfidence) + receipt, err := c.StateWaitMsg(ctx, mcid, build.MessageConfidence, api.LookbackNoLimit, true) if err != nil { return cb(0, nil, cid.Undef, err) } diff --git a/markets/storageadapter/provider.go b/markets/storageadapter/provider.go index dcfcdcbcf07..fbeaf3b3dca 100644 --- a/markets/storageadapter/provider.go +++ b/markets/storageadapter/provider.go @@ -21,6 +21,7 @@ import ( market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v1api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors/builtin/market" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" @@ -42,7 +43,7 @@ var defaultMaxProviderCollateralMultiplier = uint64(2) var log = logging.Logger("storageadapter") type ProviderNodeAdapter struct { - api.FullNode + v1api.FullNode // this goes away with the data transfer module dag dtypes.StagingDAG @@ -58,8 +59,8 @@ type ProviderNodeAdapter struct { scMgr *SectorCommittedManager } -func NewProviderNodeAdapter(fc *config.MinerFeeConfig, dc *config.DealmakingConfig) func(mctx helpers.MetricsCtx, lc fx.Lifecycle, dag dtypes.StagingDAG, secb *sectorblocks.SectorBlocks, full api.FullNode, dealPublisher *DealPublisher) storagemarket.StorageProviderNode { - return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, dag dtypes.StagingDAG, secb *sectorblocks.SectorBlocks, full api.FullNode, dealPublisher *DealPublisher) storagemarket.StorageProviderNode { +func NewProviderNodeAdapter(fc *config.MinerFeeConfig, dc *config.DealmakingConfig) func(mctx helpers.MetricsCtx, lc fx.Lifecycle, dag dtypes.StagingDAG, secb *sectorblocks.SectorBlocks, full v1api.FullNode, dealPublisher *DealPublisher) storagemarket.StorageProviderNode { + return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, dag dtypes.StagingDAG, secb *sectorblocks.SectorBlocks, full v1api.FullNode, dealPublisher *DealPublisher) storagemarket.StorageProviderNode { ctx := helpers.LifecycleCtx(mctx, lc) ev := events.NewEvents(ctx, full) @@ -290,7 +291,7 @@ func (n *ProviderNodeAdapter) GetChainHead(ctx context.Context) (shared.TipSetTo } func (n *ProviderNodeAdapter) WaitForMessage(ctx context.Context, mcid cid.Cid, cb func(code exitcode.ExitCode, bytes []byte, finalCid cid.Cid, err error) error) error { - receipt, err := n.StateWaitMsg(ctx, mcid, 2*build.MessageConfidence) + receipt, err := n.StateWaitMsg(ctx, mcid, 2*build.MessageConfidence, api.LookbackNoLimit, true) if err != nil { return cb(0, nil, cid.Undef, err) } @@ -299,7 +300,7 @@ func (n *ProviderNodeAdapter) WaitForMessage(ctx context.Context, mcid cid.Cid, func (n *ProviderNodeAdapter) WaitForPublishDeals(ctx context.Context, publishCid cid.Cid, proposal market2.DealProposal) (*storagemarket.PublishDealsWaitResult, error) { // Wait for deal to be published (plus additional time for confidence) - receipt, err := n.StateWaitMsg(ctx, publishCid, 2*build.MessageConfidence) + receipt, err := n.StateWaitMsg(ctx, publishCid, 2*build.MessageConfidence, api.LookbackNoLimit, true) if err != nil { return nil, xerrors.Errorf("WaitForPublishDeals errored: %w", err) } diff --git a/metrics/metrics.go b/metrics/metrics.go index 5428a81bcc7..9f6eb4b4283 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -76,6 +76,13 @@ var ( PubsubDropRPC = stats.Int64("pubsub/drop_rpc", "Counter for total dropped RPCs", stats.UnitDimensionless) VMFlushCopyDuration = stats.Float64("vm/flush_copy_ms", "Time spent in VM Flush Copy", stats.UnitMilliseconds) VMFlushCopyCount = stats.Int64("vm/flush_copy_count", "Number of copied objects", stats.UnitDimensionless) + VMApplyBlocksTotal = stats.Float64("vm/applyblocks_total_ms", "Time spent applying block state", stats.UnitMilliseconds) + VMApplyMessages = stats.Float64("vm/applyblocks_messages", "Time spent applying block messages", stats.UnitMilliseconds) + VMApplyEarly = stats.Float64("vm/applyblocks_early", "Time spent in early apply-blocks (null cron, upgrades)", stats.UnitMilliseconds) + VMApplyCron = stats.Float64("vm/applyblocks_cron", "Time spent in cron", stats.UnitMilliseconds) + VMApplyFlush = stats.Float64("vm/applyblocks_flush", "Time spent flushing vm state", stats.UnitMilliseconds) + VMSends = stats.Int64("vm/sends", "Counter for sends processed by the VM", stats.UnitDimensionless) + VMApplied = stats.Int64("vm/applied", "Counter for messages (including internal messages) processed by the VM", stats.UnitDimensionless) // miner WorkerCallsStarted = stats.Int64("sealing/worker_calls_started", "Counter of started worker tasks", stats.UnitDimensionless) @@ -208,6 +215,34 @@ var ( Measure: VMFlushCopyCount, Aggregation: view.Sum(), } + VMApplyBlocksTotalView = &view.View{ + Measure: VMApplyBlocksTotal, + Aggregation: defaultMillisecondsDistribution, + } + VMApplyMessagesView = &view.View{ + Measure: VMApplyMessages, + Aggregation: defaultMillisecondsDistribution, + } + VMApplyEarlyView = &view.View{ + Measure: VMApplyEarly, + Aggregation: defaultMillisecondsDistribution, + } + VMApplyCronView = &view.View{ + Measure: VMApplyCron, + Aggregation: defaultMillisecondsDistribution, + } + VMApplyFlushView = &view.View{ + Measure: VMApplyFlush, + Aggregation: defaultMillisecondsDistribution, + } + VMSendsView = &view.View{ + Measure: VMSends, + Aggregation: view.LastValue(), + } + VMAppliedView = &view.View{ + Measure: VMApplied, + Aggregation: view.LastValue(), + } // miner WorkerCallsStartedView = &view.View{ @@ -292,6 +327,13 @@ var ChainNodeViews = append([]*view.View{ SplitstoreCompactionHotView, SplitstoreCompactionColdView, SplitstoreCompactionDeadView, + VMApplyBlocksTotalView, + VMApplyMessagesView, + VMApplyEarlyView, + VMApplyCronView, + VMApplyFlushView, + VMSendsView, + VMAppliedView, }, DefaultViews...) var MinerNodeViews = append([]*view.View{ diff --git a/metrics/proxy.go b/metrics/proxy.go index 309ef80e196..7253a76c2e3 100644 --- a/metrics/proxy.go +++ b/metrics/proxy.go @@ -7,37 +7,36 @@ import ( "go.opencensus.io/tag" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/api/apistruct" ) func MetricedStorMinerAPI(a api.StorageMiner) api.StorageMiner { - var out apistruct.StorageMinerStruct + var out api.StorageMinerStruct proxy(a, &out.Internal) proxy(a, &out.CommonStruct.Internal) return &out } func MetricedFullAPI(a api.FullNode) api.FullNode { - var out apistruct.FullNodeStruct + var out api.FullNodeStruct proxy(a, &out.Internal) proxy(a, &out.CommonStruct.Internal) return &out } func MetricedWorkerAPI(a api.Worker) api.Worker { - var out apistruct.WorkerStruct + var out api.WorkerStruct proxy(a, &out.Internal) return &out } func MetricedWalletAPI(a api.Wallet) api.Wallet { - var out apistruct.WalletStruct + var out api.WalletStruct proxy(a, &out.Internal) return &out } func MetricedGatewayAPI(a api.Gateway) api.Gateway { - var out apistruct.GatewayStruct + var out api.GatewayStruct proxy(a, &out.Internal) return &out } diff --git a/miner/miner.go b/miner/miner.go index eb7dd95f54d..a77e1c18bc5 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -9,8 +9,11 @@ import ( "sync" "time" + "github.com/filecoin-project/lotus/api/v1api" + proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof" + "github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/chain/gen/slashfilter" "github.com/filecoin-project/go-address" @@ -56,7 +59,7 @@ func randTimeOffset(width time.Duration) time.Duration { // NewMiner instantiates a miner with a concrete WinningPoStProver and a miner // address (which can be different from the worker's address). -func NewMiner(api api.FullNode, epp gen.WinningPoStProver, addr address.Address, sf *slashfilter.SlashFilter, j journal.Journal) *Miner { +func NewMiner(api v1api.FullNode, epp gen.WinningPoStProver, addr address.Address, sf *slashfilter.SlashFilter, j journal.Journal) *Miner { arc, err := lru.NewARC(10000) if err != nil { panic(err) @@ -100,7 +103,7 @@ func NewMiner(api api.FullNode, epp gen.WinningPoStProver, addr address.Address, // // Refer to the godocs on mineOne and mine methods for more detail. type Miner struct { - api api.FullNode + api v1api.FullNode epp gen.WinningPoStProver @@ -423,8 +426,25 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg, return nil, xerrors.Errorf("failed to get mining base info: %w", err) } if mbi == nil { + log.Warnf("mineOne: unexpectedly nil MiningBaseInfo for round %d, off tipset %d/%s", round, base.TipSet.Height(), base.TipSet.Key().String()) return nil, nil } + + // always write out a log from this point out + var winner *types.ElectionProof + defer func() { + log.Infow( + "completed mineOne", + "forRound", int64(round), + "baseEpoch", int64(base.TipSet.Height()), + "lookbackEpochs", int64(policy.ChainFinality), // hardcoded as it is unlikely to change again: https://github.com/filecoin-project/lotus/blob/v1.8.0/chain/actors/policy/policy.go#L180-L186 + "networkPowerAtLookback", mbi.NetworkPower.String(), + "minerPowerAtLookback", mbi.MinerPower.String(), + "isEligible", mbi.EligibleForMining, + "isWinner", (winner != nil), + ) + }() + if !mbi.EligibleForMining { // slashed or just have no power yet return nil, nil @@ -451,7 +471,7 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg, return nil, xerrors.Errorf("scratching ticket failed: %w", err) } - winner, err := gen.IsRoundWinner(ctx, base.TipSet, round, m.address, rbase, mbi, m.api) + winner, err = gen.IsRoundWinner(ctx, base.TipSet, round, m.address, rbase, mbi, m.api) if err != nil { return nil, xerrors.Errorf("failed to check if we win next round: %w", err) } @@ -503,7 +523,7 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg, for i, header := range base.TipSet.Blocks() { parentMiners[i] = header.Miner } - log.Infow("mined new block", "cid", b.Cid(), "height", b.Header.Height, "miner", b.Header.Miner, "parents", parentMiners, "took", dur) + log.Infow("mined new block", "cid", b.Cid(), "height", int64(b.Header.Height), "miner", b.Header.Miner, "parents", parentMiners, "parentTipset", base.TipSet.Key().String(), "took", dur) if dur > time.Second*time.Duration(build.BlockDelaySecs) { log.Warnw("CAUTION: block production took longer than the block delay. Your computer may not be fast enough to keep up", "tMinerBaseInfo ", tMBI.Sub(start), diff --git a/miner/testminer.go b/miner/testminer.go index 5f461d88482..7f29a7ae028 100644 --- a/miner/testminer.go +++ b/miner/testminer.go @@ -8,7 +8,8 @@ import ( "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/api/v1api" "github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/gen/slashfilter" "github.com/filecoin-project/lotus/journal" @@ -19,8 +20,8 @@ type MineReq struct { Done func(bool, abi.ChainEpoch, error) } -func NewTestMiner(nextCh <-chan MineReq, addr address.Address) func(api.FullNode, gen.WinningPoStProver) *Miner { - return func(api api.FullNode, epp gen.WinningPoStProver) *Miner { +func NewTestMiner(nextCh <-chan MineReq, addr address.Address) func(v1api.FullNode, gen.WinningPoStProver) *Miner { + return func(api v1api.FullNode, epp gen.WinningPoStProver) *Miner { arc, err := lru.NewARC(10000) if err != nil { panic(err) diff --git a/node/builder.go b/node/builder.go index ad8d43d9ee2..34be610f5bb 100644 --- a/node/builder.go +++ b/node/builder.go @@ -18,7 +18,7 @@ import ( "github.com/filecoin-project/lotus/node/hello" "github.com/filecoin-project/lotus/system" - logging "github.com/ipfs/go-log" + logging "github.com/ipfs/go-log/v2" ci "github.com/libp2p/go-libp2p-core/crypto" "github.com/libp2p/go-libp2p-core/host" "github.com/libp2p/go-libp2p-core/peer" @@ -333,6 +333,7 @@ var ChainNode = Options( // Lite node API ApplyIf(isLiteNode, + Override(new(messagepool.Provider), messagepool.NewProviderLite), Override(new(messagesigner.MpoolNonceAPI), From(new(modules.MpoolNonceAPI))), Override(new(full.ChainModuleAPI), From(new(api.Gateway))), Override(new(full.GasModuleAPI), From(new(api.Gateway))), @@ -343,6 +344,7 @@ var ChainNode = Options( // Full node API / service startup ApplyIf(isFullNode, + Override(new(messagepool.Provider), messagepool.NewProvider), Override(new(messagesigner.MpoolNonceAPI), From(new(*messagepool.MessagePool))), Override(new(full.ChainModuleAPI), From(new(full.ChainModule))), Override(new(full.GasModuleAPI), From(new(full.GasModule))), @@ -612,18 +614,21 @@ func Repo(r repo.Repo) Option { If(cfg.Splitstore.HotStoreType == "badger", Override(new(dtypes.HotBlockstore), modules.BadgerHotBlockstore)), Override(new(dtypes.SplitBlockstore), modules.SplitBlockstore(cfg)), - Override(new(dtypes.ChainBlockstore), modules.ChainSplitBlockstore), - Override(new(dtypes.StateBlockstore), modules.StateSplitBlockstore), + Override(new(dtypes.BasicChainBlockstore), modules.ChainSplitBlockstore), + Override(new(dtypes.BasicStateBlockstore), modules.StateSplitBlockstore), Override(new(dtypes.BaseBlockstore), From(new(dtypes.SplitBlockstore))), Override(new(dtypes.ExposedBlockstore), From(new(dtypes.SplitBlockstore))), ), If(!cfg.EnableSplitstore, - Override(new(dtypes.ChainBlockstore), modules.ChainFlatBlockstore), - Override(new(dtypes.StateBlockstore), modules.StateFlatBlockstore), + Override(new(dtypes.BasicChainBlockstore), modules.ChainFlatBlockstore), + Override(new(dtypes.BasicStateBlockstore), modules.StateFlatBlockstore), Override(new(dtypes.BaseBlockstore), From(new(dtypes.UniversalBlockstore))), Override(new(dtypes.ExposedBlockstore), From(new(dtypes.UniversalBlockstore))), ), + Override(new(dtypes.ChainBlockstore), From(new(dtypes.BasicChainBlockstore))), + Override(new(dtypes.StateBlockstore), From(new(dtypes.BasicStateBlockstore))), + If(os.Getenv("LOTUS_ENABLE_CHAINSTORE_FALLBACK") == "1", Override(new(dtypes.ChainBlockstore), modules.FallbackChainBlockstore), Override(new(dtypes.StateBlockstore), modules.FallbackStateBlockstore), diff --git a/node/config/def.go b/node/config/def.go index 63099516b1e..b4cf5e2fae5 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -205,7 +205,7 @@ func defCommon() Common { } -var DefaultDefaultMaxFee = types.MustParseFIL("0.007") +var DefaultDefaultMaxFee = types.MustParseFIL("0.07") var DefaultSimultaneousTransfers = uint64(20) // DefaultFullNode returns the default config diff --git a/node/impl/client/client.go b/node/impl/client/client.go index ac526ac6030..201afd0a2dd 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -57,6 +57,7 @@ import ( "github.com/filecoin-project/lotus/node/impl/paych" "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/node/repo/importmgr" + "github.com/filecoin-project/lotus/node/repo/retrievalstoremgr" ) var DefaultHashFunction = uint64(mh.BLAKE2B_MIN + 31) @@ -77,6 +78,7 @@ type API struct { Chain *store.ChainStore Imports dtypes.ClientImportMgr + Mds dtypes.ClientMultiDstore CombinedBstore dtypes.ClientBlockstore // TODO: try to remove RetrievalStoreMgr dtypes.ClientRetrievalStoreManager @@ -267,10 +269,14 @@ func (a *API) newDealInfo(ctx context.Context, v storagemarket.ClientDeal) api.D // be not found if it's no longer active if err == nil { ch := api.NewDataTransferChannel(a.Host.ID(), state) + ch.Stages = state.Stages() transferCh = &ch } } - return a.newDealInfoWithTransfer(transferCh, v) + + di := a.newDealInfoWithTransfer(transferCh, v) + di.DealStages = v.DealStages + return di } func (a *API) newDealInfoWithTransfer(transferCh *api.DataTransferChannel, v storagemarket.ClientDeal) api.DealInfo { @@ -475,6 +481,29 @@ func (a *API) ClientListImports(ctx context.Context) ([]api.Import, error) { return out, nil } +func (a *API) ClientCancelRetrievalDeal(ctx context.Context, dealID retrievalmarket.DealID) error { + cerr := make(chan error) + go func() { + err := a.Retrieval.CancelDeal(dealID) + + select { + case cerr <- err: + case <-ctx.Done(): + } + }() + + select { + case err := <-cerr: + if err != nil { + return xerrors.Errorf("failed to cancel retrieval deal: %w", err) + } + + return nil + case <-ctx.Done(): + return xerrors.Errorf("context timeout while canceling retrieval deal: %w", ctx.Err()) + } +} + func (a *API) ClientRetrieve(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) error { events := make(chan marketevents.RetrievalEvent) go a.clientRetrieve(ctx, order, ref, events) @@ -555,86 +584,107 @@ func (a *API) clientRetrieve(ctx context.Context, order api.RetrievalOrder, ref } } - if order.MinerPeer.ID == "" { - mi, err := a.StateMinerInfo(ctx, order.Miner, types.EmptyTSK) - if err != nil { - finish(err) - return + var store retrievalstoremgr.RetrievalStore + + if order.LocalStore == nil { + if order.MinerPeer == nil || order.MinerPeer.ID == "" { + mi, err := a.StateMinerInfo(ctx, order.Miner, types.EmptyTSK) + if err != nil { + finish(err) + return + } + + order.MinerPeer = &retrievalmarket.RetrievalPeer{ + ID: *mi.PeerId, + Address: order.Miner, + } } - order.MinerPeer = retrievalmarket.RetrievalPeer{ - ID: *mi.PeerId, - Address: order.Miner, + if order.Total.Int == nil { + finish(xerrors.Errorf("cannot make retrieval deal for null total")) + return } - } - if order.Size == 0 { - finish(xerrors.Errorf("cannot make retrieval deal for zero bytes")) - return - } + if order.Size == 0 { + finish(xerrors.Errorf("cannot make retrieval deal for zero bytes")) + return + } - /*id, st, err := a.imgr().NewStore() - if err != nil { - return err - } - if err := a.imgr().AddLabel(id, "source", "retrieval"); err != nil { - return err - }*/ + /*id, st, err := a.imgr().NewStore() + if err != nil { + return err + } + if err := a.imgr().AddLabel(id, "source", "retrieval"); err != nil { + return err + }*/ - ppb := types.BigDiv(order.Total, types.NewInt(order.Size)) + ppb := types.BigDiv(order.Total, types.NewInt(order.Size)) - params, err := rm.NewParamsV1(ppb, order.PaymentInterval, order.PaymentIntervalIncrease, shared.AllSelector(), order.Piece, order.UnsealPrice) - if err != nil { - finish(xerrors.Errorf("Error in retrieval params: %s", err)) - return - } - - store, err := a.RetrievalStoreMgr.NewStore() - if err != nil { - finish(xerrors.Errorf("Error setting up new store: %w", err)) - return - } + params, err := rm.NewParamsV1(ppb, order.PaymentInterval, order.PaymentIntervalIncrease, shared.AllSelector(), order.Piece, order.UnsealPrice) + if err != nil { + finish(xerrors.Errorf("Error in retrieval params: %s", err)) + return + } - defer func() { - _ = a.RetrievalStoreMgr.ReleaseStore(store) - }() + store, err = a.RetrievalStoreMgr.NewStore() + if err != nil { + finish(xerrors.Errorf("Error setting up new store: %w", err)) + return + } - // Subscribe to events before retrieving to avoid losing events. - subscribeEvents := make(chan retrievalSubscribeEvent, 1) - subscribeCtx, cancel := context.WithCancel(ctx) - defer cancel() - unsubscribe := a.Retrieval.SubscribeToEvents(func(event rm.ClientEvent, state rm.ClientDealState) { - // We'll check the deal IDs inside readSubscribeEvents. - if state.PayloadCID.Equals(order.Root) { - select { - case <-subscribeCtx.Done(): - case subscribeEvents <- retrievalSubscribeEvent{event, state}: + defer func() { + _ = a.RetrievalStoreMgr.ReleaseStore(store) + }() + + // Subscribe to events before retrieving to avoid losing events. + subscribeEvents := make(chan retrievalSubscribeEvent, 1) + subscribeCtx, cancel := context.WithCancel(ctx) + defer cancel() + unsubscribe := a.Retrieval.SubscribeToEvents(func(event rm.ClientEvent, state rm.ClientDealState) { + // We'll check the deal IDs inside readSubscribeEvents. + if state.PayloadCID.Equals(order.Root) { + select { + case <-subscribeCtx.Done(): + case subscribeEvents <- retrievalSubscribeEvent{event, state}: + } } + }) + + dealID, err := a.Retrieval.Retrieve( + ctx, + order.Root, + params, + order.Total, + *order.MinerPeer, + order.Client, + order.Miner, + store.StoreID()) + + if err != nil { + unsubscribe() + finish(xerrors.Errorf("Retrieve failed: %w", err)) + return } - }) - dealID, err := a.Retrieval.Retrieve( - ctx, - order.Root, - params, - order.Total, - order.MinerPeer, - order.Client, - order.Miner, - store.StoreID()) + err = readSubscribeEvents(ctx, dealID, subscribeEvents, events) - if err != nil { unsubscribe() - finish(xerrors.Errorf("Retrieve failed: %w", err)) - return - } - - err = readSubscribeEvents(ctx, dealID, subscribeEvents, events) + if err != nil { + finish(xerrors.Errorf("Retrieve: %w", err)) + return + } + } else { + // local retrieval + st, err := ((*multistore.MultiStore)(a.Mds)).Get(*order.LocalStore) + if err != nil { + finish(xerrors.Errorf("Retrieve: %w", err)) + return + } - unsubscribe() - if err != nil { - finish(xerrors.Errorf("Retrieve: %w", err)) - return + store = &multiStoreRetrievalStore{ + storeID: *order.LocalStore, + store: st, + } } // If ref is nil, it only fetches the data into the configured blockstore. @@ -674,6 +724,19 @@ func (a *API) clientRetrieve(ctx context.Context, order api.RetrievalOrder, ref return } +type multiStoreRetrievalStore struct { + storeID multistore.StoreID + store *multistore.Store +} + +func (mrs *multiStoreRetrievalStore) StoreID() *multistore.StoreID { + return &mrs.storeID +} + +func (mrs *multiStoreRetrievalStore) DAGService() ipld.DAGService { + return mrs.store.DAG +} + func (a *API) ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.StorageAsk, error) { mi, err := a.StateMinerInfo(ctx, miner, types.EmptyTSK) if err != nil { diff --git a/node/impl/full.go b/node/impl/full.go index add40917c84..50fd09cdf65 100644 --- a/node/impl/full.go +++ b/node/impl/full.go @@ -2,16 +2,21 @@ package impl import ( "context" + "time" + + "github.com/libp2p/go-libp2p-core/peer" logging "github.com/ipfs/go-log/v2" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/node/impl/client" "github.com/filecoin-project/lotus/node/impl/common" "github.com/filecoin-project/lotus/node/impl/full" "github.com/filecoin-project/lotus/node/impl/market" "github.com/filecoin-project/lotus/node/impl/paych" "github.com/filecoin-project/lotus/node/modules/dtypes" + "github.com/filecoin-project/lotus/node/modules/lp2p" ) var log = logging.Logger("node") @@ -30,11 +35,86 @@ type FullNodeAPI struct { full.SyncAPI full.BeaconAPI - DS dtypes.MetadataDS + DS dtypes.MetadataDS + NetworkName dtypes.NetworkName } func (n *FullNodeAPI) CreateBackup(ctx context.Context, fpath string) error { return backup(n.DS, fpath) } +func (n *FullNodeAPI) NodeStatus(ctx context.Context, inclChainStatus bool) (status api.NodeStatus, err error) { + curTs, err := n.ChainHead(ctx) + if err != nil { + return status, err + } + + status.SyncStatus.Epoch = uint64(curTs.Height()) + timestamp := time.Unix(int64(curTs.MinTimestamp()), 0) + delta := time.Since(timestamp).Seconds() + status.SyncStatus.Behind = uint64(delta / 30) + + // get peers in the messages and blocks topics + peersMsgs := make(map[peer.ID]struct{}) + peersBlocks := make(map[peer.ID]struct{}) + + for _, p := range n.PubSub.ListPeers(build.MessagesTopic(n.NetworkName)) { + peersMsgs[p] = struct{}{} + } + + for _, p := range n.PubSub.ListPeers(build.BlocksTopic(n.NetworkName)) { + peersBlocks[p] = struct{}{} + } + + // get scores for all connected and recent peers + scores, err := n.NetPubsubScores(ctx) + if err != nil { + return status, err + } + + for _, score := range scores { + if score.Score.Score > lp2p.PublishScoreThreshold { + _, inMsgs := peersMsgs[score.ID] + if inMsgs { + status.PeerStatus.PeersToPublishMsgs++ + } + + _, inBlocks := peersBlocks[score.ID] + if inBlocks { + status.PeerStatus.PeersToPublishBlocks++ + } + } + } + + if inclChainStatus && status.SyncStatus.Epoch > uint64(build.Finality) { + blockCnt := 0 + ts := curTs + + for i := 0; i < 100; i++ { + blockCnt += len(ts.Blocks()) + tsk := ts.Parents() + ts, err = n.ChainGetTipSet(ctx, tsk) + if err != nil { + return status, err + } + } + + status.ChainStatus.BlocksPerTipsetLast100 = float64(blockCnt) / 100 + + for i := 100; i < int(build.Finality); i++ { + blockCnt += len(ts.Blocks()) + tsk := ts.Parents() + ts, err = n.ChainGetTipSet(ctx, tsk) + if err != nil { + return status, err + } + } + + status.ChainStatus.BlocksPerTipsetLastFinality = float64(blockCnt) / float64(build.Finality) + + } + + return status, nil +} + var _ api.FullNode = &FullNodeAPI{} diff --git a/node/impl/full/chain.go b/node/impl/full/chain.go index 25d366a87b0..f7e28354a12 100644 --- a/node/impl/full/chain.go +++ b/node/impl/full/chain.go @@ -18,7 +18,7 @@ import ( offline "github.com/ipfs/go-ipfs-exchange-offline" cbor "github.com/ipfs/go-ipld-cbor" ipld "github.com/ipfs/go-ipld-format" - logging "github.com/ipfs/go-log" + logging "github.com/ipfs/go-log/v2" "github.com/ipfs/go-merkledag" "github.com/ipfs/go-path" "github.com/ipfs/go-path/resolver" @@ -51,6 +51,8 @@ type ChainModuleAPI interface { ChainReadObj(context.Context, cid.Cid) ([]byte, error) } +var _ ChainModuleAPI = *new(api.FullNode) + // ChainModule provides a default implementation of ChainModuleAPI. // It can be swapped out with another implementation through Dependency // Injection (for example with a thin RPC client). diff --git a/node/impl/full/gas.go b/node/impl/full/gas.go index 3d9889c10e8..7b624d39bfa 100644 --- a/node/impl/full/gas.go +++ b/node/impl/full/gas.go @@ -31,6 +31,8 @@ type GasModuleAPI interface { GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error) } +var _ GasModuleAPI = *new(api.FullNode) + // GasModule provides a default implementation of GasModuleAPI. // It can be swapped out with another implementation through Dependency // Injection (for example with a thin RPC client). @@ -322,7 +324,7 @@ func gasEstimateGasLimit( func (m *GasModule) GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, _ types.TipSetKey) (*types.Message, error) { if msg.GasLimit == 0 { - gasLimit, err := m.GasEstimateGasLimit(ctx, msg, types.TipSetKey{}) + gasLimit, err := m.GasEstimateGasLimit(ctx, msg, types.EmptyTSK) if err != nil { return nil, xerrors.Errorf("estimating gas used: %w", err) } @@ -330,7 +332,7 @@ func (m *GasModule) GasEstimateMessageGas(ctx context.Context, msg *types.Messag } if msg.GasPremium == types.EmptyInt || types.BigCmp(msg.GasPremium, types.NewInt(0)) == 0 { - gasPremium, err := m.GasEstimateGasPremium(ctx, 10, msg.From, msg.GasLimit, types.TipSetKey{}) + gasPremium, err := m.GasEstimateGasPremium(ctx, 10, msg.From, msg.GasLimit, types.EmptyTSK) if err != nil { return nil, xerrors.Errorf("estimating gas price: %w", err) } diff --git a/node/impl/full/mpool.go b/node/impl/full/mpool.go index b1e9f94f994..63d3c7d5868 100644 --- a/node/impl/full/mpool.go +++ b/node/impl/full/mpool.go @@ -20,6 +20,8 @@ type MpoolModuleAPI interface { MpoolPush(ctx context.Context, smsg *types.SignedMessage) (cid.Cid, error) } +var _ MpoolModuleAPI = *new(api.FullNode) + // MpoolModule provides a default implementation of MpoolModuleAPI. // It can be swapped out with another implementation through Dependency // Injection (for example with a thin RPC client). @@ -223,8 +225,20 @@ func (a *MpoolAPI) MpoolBatchPushMessage(ctx context.Context, msgs []*types.Mess return smsgs, nil } +func (a *MpoolAPI) MpoolCheckMessages(ctx context.Context, protos []*api.MessagePrototype) ([][]api.MessageCheckStatus, error) { + return a.Mpool.CheckMessages(protos) +} + +func (a *MpoolAPI) MpoolCheckPendingMessages(ctx context.Context, from address.Address) ([][]api.MessageCheckStatus, error) { + return a.Mpool.CheckPendingMessages(from) +} + +func (a *MpoolAPI) MpoolCheckReplaceMessages(ctx context.Context, msgs []*types.Message) ([][]api.MessageCheckStatus, error) { + return a.Mpool.CheckReplaceMessages(msgs) +} + func (a *MpoolAPI) MpoolGetNonce(ctx context.Context, addr address.Address) (uint64, error) { - return a.Mpool.GetNonce(addr) + return a.Mpool.GetNonce(ctx, addr, types.EmptyTSK) } func (a *MpoolAPI) MpoolSub(ctx context.Context) (<-chan api.MpoolUpdate, error) { diff --git a/node/impl/full/multisig.go b/node/impl/full/multisig.go index 9c5f683c469..e44509d7cbb 100644 --- a/node/impl/full/multisig.go +++ b/node/impl/full/multisig.go @@ -14,7 +14,6 @@ import ( multisig2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig" - "github.com/ipfs/go-cid" "go.uber.org/fx" "golang.org/x/xerrors" ) @@ -37,134 +36,129 @@ func (a *MsigAPI) messageBuilder(ctx context.Context, from address.Address) (mul // TODO: remove gp (gasPrice) from arguments // TODO: Add "vesting start" to arguments. -func (a *MsigAPI) MsigCreate(ctx context.Context, req uint64, addrs []address.Address, duration abi.ChainEpoch, val types.BigInt, src address.Address, gp types.BigInt) (cid.Cid, error) { +func (a *MsigAPI) MsigCreate(ctx context.Context, req uint64, addrs []address.Address, duration abi.ChainEpoch, val types.BigInt, src address.Address, gp types.BigInt) (*api.MessagePrototype, error) { mb, err := a.messageBuilder(ctx, src) if err != nil { - return cid.Undef, err + return nil, err } msg, err := mb.Create(addrs, req, 0, duration, val) if err != nil { - return cid.Undef, err - } - - // send the message out to the network - smsg, err := a.MpoolAPI.MpoolPushMessage(ctx, msg, nil) - if err != nil { - return cid.Undef, err + return nil, err } - return smsg.Cid(), nil + return &api.MessagePrototype{ + Message: *msg, + ValidNonce: false, + }, nil } -func (a *MsigAPI) MsigPropose(ctx context.Context, msig address.Address, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (cid.Cid, error) { +func (a *MsigAPI) MsigPropose(ctx context.Context, msig address.Address, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (*api.MessagePrototype, error) { mb, err := a.messageBuilder(ctx, src) if err != nil { - return cid.Undef, err + return nil, err } msg, err := mb.Propose(msig, to, amt, abi.MethodNum(method), params) if err != nil { - return cid.Undef, xerrors.Errorf("failed to create proposal: %w", err) - } - - smsg, err := a.MpoolAPI.MpoolPushMessage(ctx, msg, nil) - if err != nil { - return cid.Undef, xerrors.Errorf("failed to push message: %w", err) + return nil, xerrors.Errorf("failed to create proposal: %w", err) } - return smsg.Cid(), nil + return &api.MessagePrototype{ + Message: *msg, + ValidNonce: false, + }, nil } -func (a *MsigAPI) MsigAddPropose(ctx context.Context, msig address.Address, src address.Address, newAdd address.Address, inc bool) (cid.Cid, error) { +func (a *MsigAPI) MsigAddPropose(ctx context.Context, msig address.Address, src address.Address, newAdd address.Address, inc bool) (*api.MessagePrototype, error) { enc, actErr := serializeAddParams(newAdd, inc) if actErr != nil { - return cid.Undef, actErr + return nil, actErr } return a.MsigPropose(ctx, msig, msig, big.Zero(), src, uint64(multisig.Methods.AddSigner), enc) } -func (a *MsigAPI) MsigAddApprove(ctx context.Context, msig address.Address, src address.Address, txID uint64, proposer address.Address, newAdd address.Address, inc bool) (cid.Cid, error) { +func (a *MsigAPI) MsigAddApprove(ctx context.Context, msig address.Address, src address.Address, txID uint64, proposer address.Address, newAdd address.Address, inc bool) (*api.MessagePrototype, error) { enc, actErr := serializeAddParams(newAdd, inc) if actErr != nil { - return cid.Undef, actErr + return nil, actErr } return a.MsigApproveTxnHash(ctx, msig, txID, proposer, msig, big.Zero(), src, uint64(multisig.Methods.AddSigner), enc) } -func (a *MsigAPI) MsigAddCancel(ctx context.Context, msig address.Address, src address.Address, txID uint64, newAdd address.Address, inc bool) (cid.Cid, error) { +func (a *MsigAPI) MsigAddCancel(ctx context.Context, msig address.Address, src address.Address, txID uint64, newAdd address.Address, inc bool) (*api.MessagePrototype, error) { enc, actErr := serializeAddParams(newAdd, inc) if actErr != nil { - return cid.Undef, actErr + return nil, actErr } return a.MsigCancel(ctx, msig, txID, msig, big.Zero(), src, uint64(multisig.Methods.AddSigner), enc) } -func (a *MsigAPI) MsigSwapPropose(ctx context.Context, msig address.Address, src address.Address, oldAdd address.Address, newAdd address.Address) (cid.Cid, error) { +func (a *MsigAPI) MsigSwapPropose(ctx context.Context, msig address.Address, src address.Address, oldAdd address.Address, newAdd address.Address) (*api.MessagePrototype, error) { enc, actErr := serializeSwapParams(oldAdd, newAdd) if actErr != nil { - return cid.Undef, actErr + return nil, actErr } return a.MsigPropose(ctx, msig, msig, big.Zero(), src, uint64(multisig.Methods.SwapSigner), enc) } -func (a *MsigAPI) MsigSwapApprove(ctx context.Context, msig address.Address, src address.Address, txID uint64, proposer address.Address, oldAdd address.Address, newAdd address.Address) (cid.Cid, error) { +func (a *MsigAPI) MsigSwapApprove(ctx context.Context, msig address.Address, src address.Address, txID uint64, proposer address.Address, oldAdd address.Address, newAdd address.Address) (*api.MessagePrototype, error) { enc, actErr := serializeSwapParams(oldAdd, newAdd) if actErr != nil { - return cid.Undef, actErr + return nil, actErr } return a.MsigApproveTxnHash(ctx, msig, txID, proposer, msig, big.Zero(), src, uint64(multisig.Methods.SwapSigner), enc) } -func (a *MsigAPI) MsigSwapCancel(ctx context.Context, msig address.Address, src address.Address, txID uint64, oldAdd address.Address, newAdd address.Address) (cid.Cid, error) { +func (a *MsigAPI) MsigSwapCancel(ctx context.Context, msig address.Address, src address.Address, txID uint64, oldAdd address.Address, newAdd address.Address) (*api.MessagePrototype, error) { enc, actErr := serializeSwapParams(oldAdd, newAdd) if actErr != nil { - return cid.Undef, actErr + return nil, actErr } return a.MsigCancel(ctx, msig, txID, msig, big.Zero(), src, uint64(multisig.Methods.SwapSigner), enc) } -func (a *MsigAPI) MsigApprove(ctx context.Context, msig address.Address, txID uint64, src address.Address) (cid.Cid, error) { +func (a *MsigAPI) MsigApprove(ctx context.Context, msig address.Address, txID uint64, src address.Address) (*api.MessagePrototype, error) { return a.msigApproveOrCancelSimple(ctx, api.MsigApprove, msig, txID, src) } -func (a *MsigAPI) MsigApproveTxnHash(ctx context.Context, msig address.Address, txID uint64, proposer address.Address, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (cid.Cid, error) { +func (a *MsigAPI) MsigApproveTxnHash(ctx context.Context, msig address.Address, txID uint64, proposer address.Address, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (*api.MessagePrototype, error) { return a.msigApproveOrCancelTxnHash(ctx, api.MsigApprove, msig, txID, proposer, to, amt, src, method, params) } -func (a *MsigAPI) MsigCancel(ctx context.Context, msig address.Address, txID uint64, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (cid.Cid, error) { +func (a *MsigAPI) MsigCancel(ctx context.Context, msig address.Address, txID uint64, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (*api.MessagePrototype, error) { return a.msigApproveOrCancelTxnHash(ctx, api.MsigCancel, msig, txID, src, to, amt, src, method, params) } -func (a *MsigAPI) MsigRemoveSigner(ctx context.Context, msig address.Address, proposer address.Address, toRemove address.Address, decrease bool) (cid.Cid, error) { +func (a *MsigAPI) MsigRemoveSigner(ctx context.Context, msig address.Address, proposer address.Address, toRemove address.Address, decrease bool) (*api.MessagePrototype, error) { enc, actErr := serializeRemoveParams(toRemove, decrease) if actErr != nil { - return cid.Undef, actErr + return nil, actErr } return a.MsigPropose(ctx, msig, msig, types.NewInt(0), proposer, uint64(multisig.Methods.RemoveSigner), enc) } -func (a *MsigAPI) msigApproveOrCancelSimple(ctx context.Context, operation api.MsigProposeResponse, msig address.Address, txID uint64, src address.Address) (cid.Cid, error) { +func (a *MsigAPI) msigApproveOrCancelSimple(ctx context.Context, operation api.MsigProposeResponse, msig address.Address, txID uint64, src address.Address) (*api.MessagePrototype, error) { if msig == address.Undef { - return cid.Undef, xerrors.Errorf("must provide multisig address") + return nil, xerrors.Errorf("must provide multisig address") } if src == address.Undef { - return cid.Undef, xerrors.Errorf("must provide source address") + return nil, xerrors.Errorf("must provide source address") } mb, err := a.messageBuilder(ctx, src) if err != nil { - return cid.Undef, err + return nil, err } var msg *types.Message @@ -174,34 +168,31 @@ func (a *MsigAPI) msigApproveOrCancelSimple(ctx context.Context, operation api.M case api.MsigCancel: msg, err = mb.Cancel(msig, txID, nil) default: - return cid.Undef, xerrors.Errorf("Invalid operation for msigApproveOrCancel") + return nil, xerrors.Errorf("Invalid operation for msigApproveOrCancel") } if err != nil { - return cid.Undef, err - } - - smsg, err := a.MpoolAPI.MpoolPushMessage(ctx, msg, nil) - if err != nil { - return cid.Undef, err + return nil, err } - return smsg.Cid(), nil - + return &api.MessagePrototype{ + Message: *msg, + ValidNonce: false, + }, nil } -func (a *MsigAPI) msigApproveOrCancelTxnHash(ctx context.Context, operation api.MsigProposeResponse, msig address.Address, txID uint64, proposer address.Address, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (cid.Cid, error) { +func (a *MsigAPI) msigApproveOrCancelTxnHash(ctx context.Context, operation api.MsigProposeResponse, msig address.Address, txID uint64, proposer address.Address, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (*api.MessagePrototype, error) { if msig == address.Undef { - return cid.Undef, xerrors.Errorf("must provide multisig address") + return nil, xerrors.Errorf("must provide multisig address") } if src == address.Undef { - return cid.Undef, xerrors.Errorf("must provide source address") + return nil, xerrors.Errorf("must provide source address") } if proposer.Protocol() != address.ID { proposerID, err := a.StateAPI.StateLookupID(ctx, proposer, types.EmptyTSK) if err != nil { - return cid.Undef, err + return nil, err } proposer = proposerID } @@ -216,7 +207,7 @@ func (a *MsigAPI) msigApproveOrCancelTxnHash(ctx context.Context, operation api. mb, err := a.messageBuilder(ctx, src) if err != nil { - return cid.Undef, err + return nil, err } var msg *types.Message @@ -226,18 +217,16 @@ func (a *MsigAPI) msigApproveOrCancelTxnHash(ctx context.Context, operation api. case api.MsigCancel: msg, err = mb.Cancel(msig, txID, &p) default: - return cid.Undef, xerrors.Errorf("Invalid operation for msigApproveOrCancel") - } - if err != nil { - return cid.Undef, err + return nil, xerrors.Errorf("Invalid operation for msigApproveOrCancel") } - - smsg, err := a.MpoolAPI.MpoolPushMessage(ctx, msg, nil) if err != nil { - return cid.Undef, err + return nil, err } - return smsg.Cid(), nil + return &api.MessagePrototype{ + Message: *msg, + ValidNonce: false, + }, nil } func serializeAddParams(new address.Address, inc bool) ([]byte, error) { diff --git a/node/impl/full/state.go b/node/impl/full/state.go index 7fcd9dc13c1..b3639c5e04c 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -44,7 +44,6 @@ type StateModuleAPI interface { 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) (api.DealCollateralBounds, error) StateGetActor(ctx context.Context, actor address.Address, tsk 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) (api.MarketBalance, error) @@ -53,12 +52,14 @@ type StateModuleAPI interface { StateMinerProvingDeadline(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*dline.Info, error) StateMinerPower(context.Context, address.Address, types.TipSetKey) (*api.MinerPower, error) StateNetworkVersion(ctx context.Context, key types.TipSetKey) (network.Version, error) - StateSearchMsg(ctx context.Context, msg cid.Cid) (*api.MsgLookup, error) StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error) StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) - StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error) + StateSearchMsg(ctx context.Context, from types.TipSetKey, msg cid.Cid, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) + StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) } +var _ StateModuleAPI = *new(api.FullNode) + // StateModule provides a default implementation of StateModuleAPI. // It can be swapped out with another implementation through Dependency // Injection (for example with a thin RPC client). @@ -378,7 +379,7 @@ func (a *StateAPI) StateReplay(ctx context.Context, tsk types.TipSetKey, mc cid. var ts *types.TipSet var err error if tsk == types.EmptyTSK { - mlkp, err := a.StateSearchMsg(ctx, mc) + mlkp, err := a.StateSearchMsg(ctx, types.EmptyTSK, mc, stmgr.LookbackNoLimit, true) if err != nil { return nil, xerrors.Errorf("searching for msg %s: %w", mc, err) } @@ -425,7 +426,7 @@ func (a *StateAPI) StateReplay(ctx context.Context, tsk types.TipSetKey, mc cid. }, nil } -func (m *StateModule) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) { +func (m *StateModule) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (a *types.Actor, err error) { ts, err := m.Chain.GetTipSetFromKey(tsk) if err != nil { return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err) @@ -520,28 +521,22 @@ func (a *StateAPI) MinerCreateBlock(ctx context.Context, bt *api.BlockTemplate) return &out, nil } -func (m *StateModule) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error) { - return stateWaitMsgLimited(ctx, m.StateManager, m.Chain, msg, confidence, stmgr.LookbackNoLimit) -} -func (a *StateAPI) StateWaitMsgLimited(ctx context.Context, msg cid.Cid, confidence uint64, lookbackLimit abi.ChainEpoch) (*api.MsgLookup, error) { - return stateWaitMsgLimited(ctx, a.StateManager, a.Chain, msg, confidence, lookbackLimit) -} -func stateWaitMsgLimited(ctx context.Context, smgr *stmgr.StateManager, cstore *store.ChainStore, msg cid.Cid, confidence uint64, lookbackLimit abi.ChainEpoch) (*api.MsgLookup, error) { - ts, recpt, found, err := smgr.WaitForMessage(ctx, msg, confidence, lookbackLimit) +func (m *StateModule) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64, lookbackLimit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) { + ts, recpt, found, err := m.StateManager.WaitForMessage(ctx, msg, confidence, lookbackLimit, allowReplaced) if err != nil { return nil, err } var returndec interface{} if recpt.ExitCode == 0 && len(recpt.Return) > 0 { - cmsg, err := cstore.GetCMessage(msg) + cmsg, err := m.Chain.GetCMessage(msg) if err != nil { return nil, xerrors.Errorf("failed to load message after successful receipt search: %w", err) } vmsg := cmsg.VMMessage() - t, err := stmgr.GetReturnType(ctx, smgr, vmsg.To, vmsg.Method, ts) + t, err := stmgr.GetReturnType(ctx, m.StateManager, vmsg.To, vmsg.Method, ts) if err != nil { return nil, xerrors.Errorf("failed to get return type: %w", err) } @@ -562,14 +557,13 @@ func stateWaitMsgLimited(ctx context.Context, smgr *stmgr.StateManager, cstore * }, nil } -func (m *StateModule) StateSearchMsg(ctx context.Context, msg cid.Cid) (*api.MsgLookup, error) { - return stateSearchMsgLimited(ctx, m.StateManager, msg, stmgr.LookbackNoLimit) -} -func (a *StateAPI) StateSearchMsgLimited(ctx context.Context, msg cid.Cid, lookbackLimit abi.ChainEpoch) (*api.MsgLookup, error) { - return stateSearchMsgLimited(ctx, a.StateManager, msg, lookbackLimit) -} -func stateSearchMsgLimited(ctx context.Context, smgr *stmgr.StateManager, msg cid.Cid, lookbackLimit abi.ChainEpoch) (*api.MsgLookup, error) { - ts, recpt, found, err := smgr.SearchForMessage(ctx, msg, lookbackLimit) +func (m *StateModule) StateSearchMsg(ctx context.Context, tsk types.TipSetKey, msg cid.Cid, lookbackLimit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) { + fromTs, err := m.Chain.GetTipSetFromKey(tsk) + if err != nil { + return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err) + } + + ts, recpt, found, err := m.StateManager.SearchForMessage(ctx, fromTs, msg, lookbackLimit, allowReplaced) if err != nil { return nil, err } @@ -585,14 +579,6 @@ func stateSearchMsgLimited(ctx context.Context, smgr *stmgr.StateManager, msg ci return nil, nil } -func (m *StateModule) StateGetReceipt(ctx context.Context, msg cid.Cid, tsk types.TipSetKey) (*types.MessageReceipt, error) { - ts, err := m.Chain.GetTipSetFromKey(tsk) - if err != nil { - return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err) - } - return m.StateManager.GetReceipt(ctx, msg, ts) -} - func (m *StateModule) StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) { ts, err := m.Chain.GetTipSetFromKey(tsk) if err != nil { @@ -822,8 +808,31 @@ func (a *StateAPI) StateListMessages(ctx context.Context, match *api.MessageMatc if match.To == address.Undef && match.From == address.Undef { return nil, xerrors.Errorf("must specify at least To or From in message filter") + } else if match.To != address.Undef { + _, err := a.StateLookupID(ctx, match.To, tsk) + + // if the recipient doesn't exist at the start point, we're not gonna find any matches + if xerrors.Is(err, types.ErrActorNotFound) { + return nil, nil + } + + if err != nil { + return nil, xerrors.Errorf("looking up match.To: %w", err) + } + } else if match.From != address.Undef { + _, err := a.StateLookupID(ctx, match.From, tsk) + + // if the sender doesn't exist at the start point, we're not gonna find any matches + if xerrors.Is(err, types.ErrActorNotFound) { + return nil, nil + } + + if err != nil { + return nil, xerrors.Errorf("looking up match.From: %w", err) + } } + // TODO: This should probably match on both ID and robust address, no? matchFunc := func(msg *types.Message) bool { if match.From != address.Undef && match.From != msg.From { return false diff --git a/node/impl/full/sync.go b/node/impl/full/sync.go index 1a088fb7721..2c697483bdd 100644 --- a/node/impl/full/sync.go +++ b/node/impl/full/sync.go @@ -104,7 +104,7 @@ func (a *SyncAPI) SyncIncomingBlocks(ctx context.Context) (<-chan *types.BlockHe func (a *SyncAPI) SyncCheckpoint(ctx context.Context, tsk types.TipSetKey) error { log.Warnf("Marking tipset %s as checkpoint", tsk) - return a.Syncer.SetCheckpoint(tsk) + return a.Syncer.SyncCheckpoint(ctx, tsk) } func (a *SyncAPI) SyncMarkBad(ctx context.Context, bcid cid.Cid) error { diff --git a/node/impl/remoteworker.go b/node/impl/remoteworker.go index 1369dc24873..8dc7510b48e 100644 --- a/node/impl/remoteworker.go +++ b/node/impl/remoteworker.go @@ -33,7 +33,7 @@ func connectRemoteWorker(ctx context.Context, fa api.Common, url string) (*remot headers := http.Header{} headers.Add("Authorization", "Bearer "+string(token)) - wapi, closer, err := client.NewWorkerRPC(context.TODO(), url, headers) + wapi, closer, err := client.NewWorkerRPCV0(context.TODO(), url, headers) if err != nil { return nil, xerrors.Errorf("creating jsonrpc client: %w", err) } diff --git a/node/impl/storminer.go b/node/impl/storminer.go index e81560059c9..27ab1af5f8a 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -8,6 +8,9 @@ import ( "strconv" "time" + "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/chain/gen" + "github.com/filecoin-project/lotus/build" "github.com/google/uuid" "github.com/ipfs/go-cid" @@ -31,7 +34,6 @@ import ( sealing "github.com/filecoin-project/lotus/extern/storage-sealing" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/api/apistruct" apitypes "github.com/filecoin-project/lotus/api/types" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/markets/storageadapter" @@ -63,7 +65,8 @@ type StorageMinerAPI struct { AddrSel *storage.AddressSelector DealPublisher *storageadapter.DealPublisher - DS dtypes.MetadataDS + Epp gen.WinningPoStProver + DS dtypes.MetadataDS ConsiderOnlineStorageDealsConfigFunc dtypes.ConsiderOnlineStorageDealsConfigFunc SetConsiderOnlineStorageDealsConfigFunc dtypes.SetConsiderOnlineStorageDealsConfigFunc @@ -86,7 +89,7 @@ type StorageMinerAPI struct { } func (sm *StorageMinerAPI) ServeRemote(w http.ResponseWriter, r *http.Request) { - if !auth.HasPerm(r.Context(), nil, apistruct.PermAdmin) { + if !auth.HasPerm(r.Context(), nil, api.PermAdmin) { w.WriteHeader(401) _ = json.NewEncoder(w).Encode(struct{ Error string }{"unauthorized: missing write permission"}) return @@ -696,4 +699,8 @@ func (sm *StorageMinerAPI) Discover(ctx context.Context) (apitypes.OpenRPCDocume return build.OpenRPCDiscoverJSON_Miner(), nil } +func (sm *StorageMinerAPI) ComputeProof(ctx context.Context, ssi []builtin.SectorInfo, rand abi.PoStRandomness) ([]builtin.PoStProof, error) { + return sm.Epp.ComputeProof(ctx, ssi, rand) +} + var _ api.StorageMiner = &StorageMinerAPI{} diff --git a/node/modules/blockstore.go b/node/modules/blockstore.go index c1c52fafe75..787d782b7ea 100644 --- a/node/modules/blockstore.go +++ b/node/modules/blockstore.go @@ -94,11 +94,11 @@ func SplitBlockstore(cfg *config.Chainstore) func(lc fx.Lifecycle, r repo.Locked } } -func StateFlatBlockstore(_ fx.Lifecycle, _ helpers.MetricsCtx, bs dtypes.UniversalBlockstore) (dtypes.StateBlockstore, error) { +func StateFlatBlockstore(_ fx.Lifecycle, _ helpers.MetricsCtx, bs dtypes.UniversalBlockstore) (dtypes.BasicStateBlockstore, error) { return bs, nil } -func StateSplitBlockstore(_ fx.Lifecycle, _ helpers.MetricsCtx, bs dtypes.SplitBlockstore) (dtypes.StateBlockstore, error) { +func StateSplitBlockstore(_ fx.Lifecycle, _ helpers.MetricsCtx, bs dtypes.SplitBlockstore) (dtypes.BasicStateBlockstore, error) { return bs, nil } @@ -110,11 +110,11 @@ func ChainSplitBlockstore(_ fx.Lifecycle, _ helpers.MetricsCtx, bs dtypes.SplitB return bs, nil } -func FallbackChainBlockstore(cbs dtypes.ChainBlockstore) dtypes.ChainBlockstore { +func FallbackChainBlockstore(cbs dtypes.BasicChainBlockstore) dtypes.ChainBlockstore { return &blockstore.FallbackStore{Blockstore: cbs} } -func FallbackStateBlockstore(sbs dtypes.StateBlockstore) dtypes.StateBlockstore { +func FallbackStateBlockstore(sbs dtypes.BasicStateBlockstore) dtypes.StateBlockstore { return &blockstore.FallbackStore{Blockstore: sbs} } diff --git a/node/modules/chain.go b/node/modules/chain.go index ffdf3aa3a2d..95432294884 100644 --- a/node/modules/chain.go +++ b/node/modules/chain.go @@ -9,7 +9,6 @@ import ( "github.com/ipfs/go-blockservice" "github.com/libp2p/go-libp2p-core/host" "github.com/libp2p/go-libp2p-core/routing" - pubsub "github.com/libp2p/go-libp2p-pubsub" "go.uber.org/fx" "golang.org/x/xerrors" @@ -59,8 +58,7 @@ func ChainBlockService(bs dtypes.ExposedBlockstore, rem dtypes.ChainBitswap) dty return blockservice.New(bs, rem) } -func MessagePool(lc fx.Lifecycle, sm *stmgr.StateManager, ps *pubsub.PubSub, ds dtypes.MetadataDS, nn dtypes.NetworkName, j journal.Journal) (*messagepool.MessagePool, error) { - mpp := messagepool.NewProvider(sm, ps) +func MessagePool(lc fx.Lifecycle, mpp messagepool.Provider, ds dtypes.MetadataDS, nn dtypes.NetworkName, j journal.Journal) (*messagepool.MessagePool, error) { mp, err := messagepool.New(mpp, ds, nn, j) if err != nil { return nil, xerrors.Errorf("constructing mpool: %w", err) diff --git a/node/modules/client.go b/node/modules/client.go index da6a4cd8315..c5dbff9bd5c 100644 --- a/node/modules/client.go +++ b/node/modules/client.go @@ -7,12 +7,10 @@ import ( "path/filepath" "time" - "github.com/filecoin-project/go-multistore" - "github.com/filecoin-project/go-state-types/abi" - "golang.org/x/xerrors" - "go.uber.org/fx" + "golang.org/x/xerrors" + "github.com/filecoin-project/go-data-transfer/channelmonitor" dtimpl "github.com/filecoin-project/go-data-transfer/impl" dtnet "github.com/filecoin-project/go-data-transfer/network" dtgstransport "github.com/filecoin-project/go-data-transfer/transport/graphsync" @@ -25,7 +23,8 @@ import ( storageimpl "github.com/filecoin-project/go-fil-markets/storagemarket/impl" "github.com/filecoin-project/go-fil-markets/storagemarket/impl/requestvalidation" smnet "github.com/filecoin-project/go-fil-markets/storagemarket/network" - "github.com/filecoin-project/go-storedcounter" + "github.com/filecoin-project/go-multistore" + "github.com/filecoin-project/go-state-types/abi" "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/namespace" "github.com/libp2p/go-libp2p-core/host" @@ -121,8 +120,6 @@ func RegisterClientValidator(crv dtypes.ClientRequestValidator, dtm dtypes.Clien // NewClientGraphsyncDataTransfer returns a data transfer manager that just // uses the clients's Client DAG service for transfers func NewClientGraphsyncDataTransfer(lc fx.Lifecycle, h host.Host, gs dtypes.Graphsync, ds dtypes.MetadataDS, r repo.LockedRepo) (dtypes.ClientDataTransfer, error) { - sc := storedcounter.New(ds, datastore.NewKey("/datatransfer/client/counter")) - // go-data-transfer protocol retries: // 1s, 5s, 25s, 2m5s, 5m x 11 ~= 1 hour dtRetryParams := dtnet.RetryParameters(time.Second, 5*time.Minute, 15, 5) @@ -135,9 +132,30 @@ func NewClientGraphsyncDataTransfer(lc fx.Lifecycle, h host.Host, gs dtypes.Grap return nil, err } - // data-transfer push channel restart configuration - dtRestartConfig := dtimpl.PushChannelRestartConfig(time.Minute, 10, 1024, 10*time.Minute, 3) - dt, err := dtimpl.NewDataTransfer(dtDs, filepath.Join(r.Path(), "data-transfer"), net, transport, sc, dtRestartConfig) + // data-transfer push / pull channel restart configuration: + dtRestartConfig := dtimpl.ChannelRestartConfig(channelmonitor.Config{ + // For now only monitor push channels (for storage deals) + MonitorPushChannels: true, + // TODO: Enable pull channel monitoring (for retrievals) when the + // following issue has been fixed: + // https://github.com/filecoin-project/go-data-transfer/issues/172 + MonitorPullChannels: false, + // Wait up to 30s for the other side to respond to an Open channel message + AcceptTimeout: 30 * time.Second, + // Send a restart message if the data rate falls below 1024 bytes / minute + Interval: time.Minute, + MinBytesTransferred: 1024, + // Perform check 10 times / minute + ChecksPerInterval: 10, + // After sending a restart, wait for at least 1 minute before sending another + RestartBackoff: time.Minute, + // After trying to restart 3 times, give up and fail the transfer + MaxConsecutiveRestarts: 3, + // Wait up to 30s for the other side to send a Complete message once all + // data has been sent / received + CompleteTimeout: 30 * time.Second, + }) + dt, err := dtimpl.NewDataTransfer(dtDs, filepath.Join(r.Path(), "data-transfer"), net, transport, dtRestartConfig) if err != nil { return nil, err } @@ -191,8 +209,7 @@ func StorageClient(lc fx.Lifecycle, h host.Host, ibs dtypes.ClientBlockstore, md func RetrievalClient(lc fx.Lifecycle, h host.Host, mds dtypes.ClientMultiDstore, dt dtypes.ClientDataTransfer, payAPI payapi.PaychAPI, resolver discovery.PeerResolver, ds dtypes.MetadataDS, chainAPI full.ChainAPI, stateAPI full.StateAPI, j journal.Journal) (retrievalmarket.RetrievalClient, error) { adapter := retrievaladapter.NewRetrievalClientNode(payAPI, chainAPI, stateAPI) network := rmnet.NewFromLibp2pHost(h) - sc := storedcounter.New(ds, datastore.NewKey("/retr")) - client, err := retrievalimpl.NewClient(network, mds, dt, adapter, resolver, namespace.Wrap(ds, datastore.NewKey("/retrievals/client")), sc) + client, err := retrievalimpl.NewClient(network, mds, dt, adapter, resolver, namespace.Wrap(ds, datastore.NewKey("/retrievals/client"))) if err != nil { return nil, err } diff --git a/node/modules/core.go b/node/modules/core.go index 83a7e8d4297..e089333e71c 100644 --- a/node/modules/core.go +++ b/node/modules/core.go @@ -22,7 +22,7 @@ import ( "github.com/filecoin-project/go-jsonrpc/auth" "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/lotus/api/apistruct" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/lib/addrutil" @@ -163,7 +163,7 @@ func APISecret(keystore types.KeyStore, lr repo.LockedRepo) (*dtypes.APIAlg, err // TODO: make this configurable p := JwtPayload{ - Allow: apistruct.AllPermissions, + Allow: api.AllPermissions, } cliToken, err := jwt.Sign(&p, jwt.NewHS256(key.PrivateKey)) diff --git a/node/modules/dtypes/storage.go b/node/modules/dtypes/storage.go index 216ccc1b186..e35d02811a7 100644 --- a/node/modules/dtypes/storage.go +++ b/node/modules/dtypes/storage.go @@ -36,12 +36,20 @@ type ( // BaseBlockstore is something, coz DI BaseBlockstore blockstore.Blockstore + // BasicChainBlockstore is like ChainBlockstore, but without the optional + // network fallback support + BasicChainBlockstore blockstore.Blockstore + // ChainBlockstore is a blockstore to store chain data (tipsets, blocks, // messages). It is physically backed by the BareMonolithBlockstore, but it // has a cache on top that is specially tuned for chain data access // patterns. ChainBlockstore blockstore.Blockstore + // BasicStateBlockstore is like StateBlockstore, but without the optional + // network fallback support + BasicStateBlockstore blockstore.Blockstore + // StateBlockstore is a blockstore to store state data (state tree). It is // physically backed by the BareMonolithBlockstore, but it has a cache on // top that is specially tuned for state data access patterns. diff --git a/node/modules/lp2p/pubsub.go b/node/modules/lp2p/pubsub.go index 748167d95f3..32b85daf347 100644 --- a/node/modules/lp2p/pubsub.go +++ b/node/modules/lp2p/pubsub.go @@ -36,6 +36,15 @@ func init() { pubsub.GossipSubHistoryLength = 10 pubsub.GossipSubGossipFactor = 0.1 } + +const ( + GossipScoreThreshold = -500 + PublishScoreThreshold = -1000 + GraylistScoreThreshold = -2500 + AcceptPXScoreThreshold = 1000 + OpportunisticGraftScoreThreshold = 3.5 +) + func ScoreKeeper() *dtypes.ScoreKeeper { return new(dtypes.ScoreKeeper) } @@ -256,11 +265,11 @@ func GossipSub(in GossipIn) (service *pubsub.PubSub, err error) { Topics: topicParams, }, &pubsub.PeerScoreThresholds{ - GossipThreshold: -500, - PublishThreshold: -1000, - GraylistThreshold: -2500, - AcceptPXThreshold: 1000, - OpportunisticGraftThreshold: 3.5, + GossipThreshold: GossipScoreThreshold, + PublishThreshold: PublishScoreThreshold, + GraylistThreshold: GraylistScoreThreshold, + AcceptPXThreshold: AcceptPXScoreThreshold, + OpportunisticGraftThreshold: OpportunisticGraftScoreThreshold, }, ), pubsub.WithPeerScoreInspect(in.Sk.Update, 10*time.Second), diff --git a/node/modules/mpoolnonceapi.go b/node/modules/mpoolnonceapi.go index efcb14037db..67f512960ec 100644 --- a/node/modules/mpoolnonceapi.go +++ b/node/modules/mpoolnonceapi.go @@ -2,6 +2,7 @@ package modules import ( "context" + "strings" "go.uber.org/fx" "golang.org/x/xerrors" @@ -19,44 +20,89 @@ import ( type MpoolNonceAPI struct { fx.In - StateAPI full.StateAPI + ChainModule full.ChainModuleAPI + StateModule full.StateModuleAPI } // GetNonce gets the nonce from current chain head. -func (a *MpoolNonceAPI) GetNonce(addr address.Address) (uint64, error) { - ts := a.StateAPI.Chain.GetHeaviestTipSet() +func (a *MpoolNonceAPI) GetNonce(ctx context.Context, addr address.Address, tsk types.TipSetKey) (uint64, error) { + var err error + var ts *types.TipSet + if tsk == types.EmptyTSK { + // we need consistent tsk + ts, err = a.ChainModule.ChainHead(ctx) + if err != nil { + return 0, xerrors.Errorf("getting head: %w", err) + } + tsk = ts.Key() + } else { + ts, err = a.ChainModule.ChainGetTipSet(ctx, tsk) + if err != nil { + return 0, xerrors.Errorf("getting tipset: %w", err) + } + } - // make sure we have a key address so we can compare with messages - keyAddr, err := a.StateAPI.StateManager.ResolveToKeyAddress(context.TODO(), addr, ts) - if err != nil { - return 0, err + keyAddr := addr + + if addr.Protocol() == address.ID { + // make sure we have a key address so we can compare with messages + keyAddr, err = a.StateModule.StateAccountKey(ctx, addr, tsk) + if err != nil { + return 0, xerrors.Errorf("getting account key: %w", err) + } + } else { + addr, err = a.StateModule.StateLookupID(ctx, addr, types.EmptyTSK) + if err != nil { + log.Infof("failed to look up id addr for %s: %w", addr, err) + addr = address.Undef + } } // Load the last nonce from the state, if it exists. highestNonce := uint64(0) - if baseActor, err := a.StateAPI.StateManager.LoadActorRaw(context.TODO(), addr, ts.ParentState()); err != nil { - if !xerrors.Is(err, types.ErrActorNotFound) { - return 0, err + act, err := a.StateModule.StateGetActor(ctx, keyAddr, ts.Key()) + if err != nil { + if strings.Contains(err.Error(), types.ErrActorNotFound.Error()) { + return 0, xerrors.Errorf("getting actor converted: %w", types.ErrActorNotFound) } - } else { - highestNonce = baseActor.Nonce + return 0, xerrors.Errorf("getting actor: %w", err) } + highestNonce = act.Nonce - // Otherwise, find the highest nonce in the tipset. - msgs, err := a.StateAPI.Chain.MessagesForTipset(ts) - if err != nil { - return 0, err + apply := func(msg *types.Message) { + if msg.From != addr && msg.From != keyAddr { + return + } + if msg.Nonce == highestNonce { + highestNonce = msg.Nonce + 1 + } } - for _, msg := range msgs { - vmmsg := msg.VMMessage() - if vmmsg.From != keyAddr { - continue + + for _, b := range ts.Blocks() { + msgs, err := a.ChainModule.ChainGetBlockMessages(ctx, b.Cid()) + if err != nil { + return 0, xerrors.Errorf("getting block messages: %w", err) } - if vmmsg.Nonce >= highestNonce { - highestNonce = vmmsg.Nonce + 1 + if keyAddr.Protocol() == address.BLS { + for _, m := range msgs.BlsMessages { + apply(m) + } + } else { + for _, sm := range msgs.SecpkMessages { + apply(&sm.Message) + } } } return highestNonce, nil } +func (a *MpoolNonceAPI) GetActor(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*types.Actor, error) { + act, err := a.StateModule.StateGetActor(ctx, addr, tsk) + if err != nil { + return nil, xerrors.Errorf("calling StateGetActor: %w", err) + } + + return act, nil +} + var _ messagesigner.MpoolNonceAPI = (*MpoolNonceAPI)(nil) diff --git a/node/modules/paych.go b/node/modules/paych.go index a9fd25a3ec9..905590057f9 100644 --- a/node/modules/paych.go +++ b/node/modules/paych.go @@ -32,6 +32,8 @@ type PaychAPI struct { full.StateAPI } +var _ paychmgr.PaychAPI = &PaychAPI{} + // HandlePaychManager is called by dependency injection to set up hooks func HandlePaychManager(lc fx.Lifecycle, pm *paychmgr.Manager) { lc.Append(fx.Hook{ diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index d89474eeeba..be949255f7e 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -55,7 +55,8 @@ import ( sealing "github.com/filecoin-project/lotus/extern/storage-sealing" "github.com/filecoin-project/lotus/extern/storage-sealing/sealiface" - lapi "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" + "github.com/filecoin-project/lotus/api/v1api" "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors/builtin" @@ -116,14 +117,14 @@ func MinerID(ma dtypes.MinerAddress) (dtypes.MinerID, error) { return dtypes.MinerID(id), err } -func StorageNetworkName(ctx helpers.MetricsCtx, a lapi.FullNode) (dtypes.NetworkName, error) { +func StorageNetworkName(ctx helpers.MetricsCtx, a v1api.FullNode) (dtypes.NetworkName, error) { if !build.Devnet { return "testnetnet", nil } return a.StateNetworkName(ctx) } -func SealProofType(maddr dtypes.MinerAddress, fnapi lapi.FullNode) (abi.RegisteredSealProof, error) { +func SealProofType(maddr dtypes.MinerAddress, fnapi v1api.FullNode) (abi.RegisteredSealProof, error) { mi, err := fnapi.StateMinerInfo(context.TODO(), address.Address(maddr), types.EmptyTSK) if err != nil { return 0, err @@ -196,7 +197,7 @@ type StorageMinerParams struct { Lifecycle fx.Lifecycle MetricsCtx helpers.MetricsCtx - API lapi.FullNode + API v1api.FullNode Host host.Host MetadataDS dtypes.MetadataDS Sealer sectorstorage.SectorManager @@ -330,7 +331,6 @@ func HandleMigrateProviderFunds(lc fx.Lifecycle, ds dtypes.MetadataDS, node api. // NewProviderDAGServiceDataTransfer returns a data transfer manager that just // uses the provider's Staging DAG service for transfers func NewProviderDAGServiceDataTransfer(lc fx.Lifecycle, h host.Host, gs dtypes.StagingGraphsync, ds dtypes.MetadataDS, r repo.LockedRepo) (dtypes.ProviderDataTransfer, error) { - sc := storedcounter.New(ds, datastore.NewKey("/datatransfer/provider/counter")) net := dtnet.NewFromLibp2pHost(h) dtDs := namespace.Wrap(ds, datastore.NewKey("/datatransfer/provider/transfers")) @@ -340,7 +340,7 @@ func NewProviderDAGServiceDataTransfer(lc fx.Lifecycle, h host.Host, gs dtypes.S return nil, err } - dt, err := dtimpl.NewDataTransfer(dtDs, filepath.Join(r.Path(), "data-transfer"), net, transport, sc) + dt, err := dtimpl.NewDataTransfer(dtDs, filepath.Join(r.Path(), "data-transfer"), net, transport) if err != nil { return nil, err } @@ -438,7 +438,7 @@ func StagingGraphsync(mctx helpers.MetricsCtx, lc fx.Lifecycle, ibs dtypes.Stagi return gs } -func SetupBlockProducer(lc fx.Lifecycle, ds dtypes.MetadataDS, api lapi.FullNode, epp gen.WinningPoStProver, sf *slashfilter.SlashFilter, j journal.Journal) (*lotusminer.Miner, error) { +func SetupBlockProducer(lc fx.Lifecycle, ds dtypes.MetadataDS, api v1api.FullNode, epp gen.WinningPoStProver, sf *slashfilter.SlashFilter, j journal.Journal) (*lotusminer.Miner, error) { minerAddr, err := minerAddrFromDS(ds) if err != nil { return nil, err @@ -461,7 +461,7 @@ func SetupBlockProducer(lc fx.Lifecycle, ds dtypes.MetadataDS, api lapi.FullNode return m, nil } -func NewStorageAsk(ctx helpers.MetricsCtx, fapi lapi.FullNode, ds dtypes.MetadataDS, minerAddress dtypes.MinerAddress, spn storagemarket.StorageProviderNode) (*storedask.StoredAsk, error) { +func NewStorageAsk(ctx helpers.MetricsCtx, fapi v1api.FullNode, ds dtypes.MetadataDS, minerAddress dtypes.MinerAddress, spn storagemarket.StorageProviderNode) (*storedask.StoredAsk, error) { mi, err := fapi.StateMinerInfo(ctx, address.Address(minerAddress), types.EmptyTSK) if err != nil { @@ -636,7 +636,7 @@ func RetrievalDealFilter(userFilter dtypes.RetrievalDealFilter) func(onlineOk dt func RetrievalProvider(h host.Host, miner *storage.Miner, sealer sectorstorage.SectorManager, - full lapi.FullNode, + full v1api.FullNode, ds dtypes.MetadataDS, pieceStore dtypes.ProviderPieceStore, mds dtypes.StagingMultiDstore, @@ -679,7 +679,7 @@ func SectorStorage(mctx helpers.MetricsCtx, lc fx.Lifecycle, ls stores.LocalStor return sst, nil } -func StorageAuth(ctx helpers.MetricsCtx, ca lapi.Common) (sectorstorage.StorageAuth, error) { +func StorageAuth(ctx helpers.MetricsCtx, ca v0api.Common) (sectorstorage.StorageAuth, error) { token, err := ca.AuthNew(ctx, []auth.Permission{"admin"}) if err != nil { return nil, xerrors.Errorf("creating storage auth header: %w", err) diff --git a/node/node_test.go b/node/node_test.go index a246ff65bbc..45a5b7f57ca 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -58,9 +58,23 @@ func TestAPIDealFlow(t *testing.T) { t.Run("TestPublishDealsBatching", func(t *testing.T) { test.TestPublishDealsBatching(t, builder.MockSbBuilder, blockTime, dealStartEpoch) }) - t.Run("TestBatchDealInput", func(t *testing.T) { - test.TestBatchDealInput(t, builder.MockSbBuilder, blockTime, dealStartEpoch) - }) +} + +func TestBatchDealInput(t *testing.T) { + logging.SetLogLevel("miner", "ERROR") + logging.SetLogLevel("chainstore", "ERROR") + logging.SetLogLevel("chain", "ERROR") + logging.SetLogLevel("sub", "ERROR") + logging.SetLogLevel("storageminer", "ERROR") + + blockTime := 10 * time.Millisecond + + // For these tests where the block time is artificially short, just use + // a deal start epoch that is guaranteed to be far enough in the future + // so that the deal starts sealing in time + dealStartEpoch := abi.ChainEpoch(2 << 12) + + test.TestBatchDealInput(t, builder.MockSbBuilder, blockTime, dealStartEpoch) } func TestAPIDealFlowReal(t *testing.T) { @@ -232,3 +246,16 @@ func TestWindowPostDisputeFails(t *testing.T) { test.TestWindowPostDisputeFails(t, builder.MockSbBuilder, 2*time.Millisecond) } + +func TestDeadlineToggling(t *testing.T) { + if os.Getenv("LOTUS_TEST_DEADLINE_TOGGLING") != "1" { + t.Skip("this takes a few minutes, set LOTUS_TEST_DEADLINE_TOGGLING=1 to run") + } + logging.SetLogLevel("miner", "ERROR") + logging.SetLogLevel("chainstore", "ERROR") + logging.SetLogLevel("chain", "ERROR") + logging.SetLogLevel("sub", "ERROR") + logging.SetLogLevel("storageminer", "FATAL") + + test.TestDeadlineToggling(t, builder.MockSbBuilder, 2*time.Millisecond) +} diff --git a/node/test/builder.go b/node/test/builder.go index 72a55ab499a..7e26966a807 100644 --- a/node/test/builder.go +++ b/node/test/builder.go @@ -12,20 +12,25 @@ import ( "testing" "time" + "github.com/gorilla/mux" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-jsonrpc" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/go-state-types/exitcode" "github.com/filecoin-project/go-storedcounter" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/client" "github.com/filecoin-project/lotus/api/test" + "github.com/filecoin-project/lotus/api/v0api" + "github.com/filecoin-project/lotus/api/v1api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + "github.com/filecoin-project/lotus/chain/actors/builtin/power" "github.com/filecoin-project/lotus/chain/gen" genesis2 "github.com/filecoin-project/lotus/chain/gen/genesis" "github.com/filecoin-project/lotus/chain/messagepool" @@ -44,6 +49,7 @@ import ( "github.com/filecoin-project/lotus/node/repo" "github.com/filecoin-project/lotus/storage/mockstorage" miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" + power2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/power" "github.com/ipfs/go-datastore" "github.com/libp2p/go-libp2p-core/crypto" "github.com/libp2p/go-libp2p-core/peer" @@ -122,7 +128,7 @@ func CreateTestStorageNode(ctx context.Context, t *testing.T, waddr address.Addr node.MockHost(mn), - node.Override(new(api.FullNode), tnd), + node.Override(new(v1api.FullNode), tnd), node.Override(new(*lotusminer.Miner), lotusminer.NewTestMiner(mineBlock, act)), opts, @@ -151,6 +157,49 @@ func CreateTestStorageNode(ctx context.Context, t *testing.T, waddr address.Addr return test.TestStorageNode{StorageMiner: minerapi, MineOne: mineOne, Stop: stop} } +func storageBuilder(parentNode test.TestNode, mn mocknet.Mocknet, opts node.Option) test.StorageBuilder { + return func(ctx context.Context, t *testing.T, spt abi.RegisteredSealProof, owner address.Address) test.TestStorageNode { + pk, _, err := crypto.GenerateEd25519Key(rand.Reader) + require.NoError(t, err) + + minerPid, err := peer.IDFromPrivateKey(pk) + require.NoError(t, err) + + params, serr := actors.SerializeParams(&power2.CreateMinerParams{ + Owner: owner, + Worker: owner, + SealProofType: spt, + Peer: abi.PeerID(minerPid), + }) + require.NoError(t, serr) + + createStorageMinerMsg := &types.Message{ + To: power.Address, + From: owner, + Value: big.Zero(), + + Method: power.Methods.CreateMiner, + Params: params, + + GasLimit: 0, + GasPremium: big.NewInt(5252), + } + + signed, err := parentNode.MpoolPushMessage(ctx, createStorageMinerMsg, nil) + require.NoError(t, err) + + mw, err := parentNode.StateWaitMsg(ctx, signed.Cid(), build.MessageConfidence, api.LookbackNoLimit, true) + require.NoError(t, err) + require.Equal(t, exitcode.Ok, mw.Receipt.ExitCode) + + var retval power2.CreateMinerReturn + err = retval.UnmarshalCBOR(bytes.NewReader(mw.Receipt.Return)) + require.NoError(t, err) + + return CreateTestStorageNode(ctx, t, owner, retval.IDAddress, pk, parentNode, mn, opts) + } +} + func Builder(t *testing.T, fullOpts []test.FullNodeOpts, storage []test.StorageMiner) ([]test.TestNode, []test.TestStorageNode) { return mockBuilderOpts(t, fullOpts, storage, false) } @@ -266,6 +315,8 @@ func mockBuilderOpts(t *testing.T, fullOpts []test.FullNodeOpts, storage []test. if rpc { fulls[i] = fullRpc(t, fulls[i]) } + + fulls[i].Stb = storageBuilder(fulls[i], mn, node.Options()) } for i, def := range storage { @@ -432,6 +483,14 @@ func mockSbBuilderOpts(t *testing.T, fullOpts []test.FullNodeOpts, storage []tes if rpc { fulls[i] = fullRpc(t, fulls[i]) } + + fulls[i].Stb = storageBuilder(fulls[i], mn, node.Options( + node.Override(new(sectorstorage.SectorManager), func() (sectorstorage.SectorManager, error) { + return mock.NewMockSectorMgr(nil), nil + }), + node.Override(new(ffiwrapper.Verifier), mock.MockVerifier), + node.Unset(new(*sectorstorage.Manager)), + )) } for i, def := range storage { @@ -500,12 +559,15 @@ func mockSbBuilderOpts(t *testing.T, fullOpts []test.FullNodeOpts, storage []tes } func fullRpc(t *testing.T, nd test.TestNode) test.TestNode { - ma, listenAddr, err := CreateRPCServer(t, nd) + ma, listenAddr, err := CreateRPCServer(t, map[string]interface{}{ + "/rpc/v1": nd, + "/rpc/v0": &v0api.WrapperV1Full{FullNode: nd}, + }) require.NoError(t, err) var stop func() var full test.TestNode - full.FullNode, stop, err = client.NewFullNodeRPC(context.Background(), listenAddr, nil) + full.FullNode, stop, err = client.NewFullNodeRPCV1(context.Background(), listenAddr+"/rpc/v1", nil) require.NoError(t, err) t.Cleanup(stop) @@ -514,12 +576,14 @@ func fullRpc(t *testing.T, nd test.TestNode) test.TestNode { } func storerRpc(t *testing.T, nd test.TestStorageNode) test.TestStorageNode { - ma, listenAddr, err := CreateRPCServer(t, nd) + ma, listenAddr, err := CreateRPCServer(t, map[string]interface{}{ + "/rpc/v0": nd, + }) require.NoError(t, err) var stop func() var storer test.TestStorageNode - storer.StorageMiner, stop, err = client.NewStorageMinerRPC(context.Background(), listenAddr, nil) + storer.StorageMiner, stop, err = client.NewStorageMinerRPCV0(context.Background(), listenAddr+"/rpc/v0", nil) require.NoError(t, err) t.Cleanup(stop) @@ -528,10 +592,14 @@ func storerRpc(t *testing.T, nd test.TestStorageNode) test.TestStorageNode { return storer } -func CreateRPCServer(t *testing.T, handler interface{}) (multiaddr.Multiaddr, string, error) { - rpcServer := jsonrpc.NewServer() - rpcServer.Register("Filecoin", handler) - testServ := httptest.NewServer(rpcServer) // todo: close +func CreateRPCServer(t *testing.T, handlers map[string]interface{}) (multiaddr.Multiaddr, string, error) { + m := mux.NewRouter() + for path, handler := range handlers { + rpcServer := jsonrpc.NewServer() + rpcServer.Register("Filecoin", handler) + m.Handle(path, rpcServer) + } + testServ := httptest.NewServer(m) // todo: close t.Cleanup(testServ.Close) t.Cleanup(testServ.CloseClientConnections) diff --git a/paychmgr/manager.go b/paychmgr/manager.go index e9700bc9d14..6f6efa7ea91 100644 --- a/paychmgr/manager.go +++ b/paychmgr/manager.go @@ -11,6 +11,7 @@ import ( xerrors "golang.org/x/xerrors" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/go-state-types/network" @@ -34,7 +35,7 @@ type stateManagerAPI interface { // paychAPI defines the API methods needed by the payment channel manager type PaychAPI interface { StateAccountKey(context.Context, address.Address, types.TipSetKey) (address.Address, error) - StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error) + StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) MpoolPushMessage(ctx context.Context, msg *types.Message, maxFee *api.MessageSendSpec) (*types.SignedMessage, error) WalletHas(ctx context.Context, addr address.Address) (bool, error) WalletSign(ctx context.Context, k address.Address, msg []byte) (*crypto.Signature, error) diff --git a/paychmgr/mock_test.go b/paychmgr/mock_test.go index 3393a3072e8..2c891803bcd 100644 --- a/paychmgr/mock_test.go +++ b/paychmgr/mock_test.go @@ -8,6 +8,7 @@ import ( "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/crypto" "github.com/filecoin-project/go-state-types/network" @@ -132,7 +133,7 @@ func newMockPaychAPI() *mockPaychAPI { } } -func (pchapi *mockPaychAPI) StateWaitMsg(ctx context.Context, mcid cid.Cid, confidence uint64) (*api.MsgLookup, error) { +func (pchapi *mockPaychAPI) StateWaitMsg(ctx context.Context, mcid cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) { pchapi.lk.Lock() response := make(chan types.MessageReceipt) diff --git a/paychmgr/paych_test.go b/paychmgr/paych_test.go index 8557dfb63f8..04ed5ce5c08 100644 --- a/paychmgr/paych_test.go +++ b/paychmgr/paych_test.go @@ -23,6 +23,7 @@ import ( paychmock "github.com/filecoin-project/lotus/chain/actors/builtin/paych/mock" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/lib/sigs" + _ "github.com/filecoin-project/lotus/lib/sigs/secp" ) func TestCheckVoucherValid(t *testing.T) { diff --git a/paychmgr/settler/settler.go b/paychmgr/settler/settler.go index 3abd136fc6a..676b15c271f 100644 --- a/paychmgr/settler/settler.go +++ b/paychmgr/settler/settler.go @@ -41,7 +41,7 @@ type settlerAPI interface { PaychVoucherCheckSpendable(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (bool, error) PaychVoucherList(context.Context, address.Address) ([]*paych.SignedVoucher, error) PaychVoucherSubmit(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (cid.Cid, error) - StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64) (*api.MsgLookup, error) + StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error) } type paymentChannelSettler struct { @@ -51,12 +51,12 @@ type paymentChannelSettler struct { // SettlePaymentChannels checks the chain for events related to payment channels settling and // submits any vouchers for inbound channels tracked for this node -func SettlePaymentChannels(mctx helpers.MetricsCtx, lc fx.Lifecycle, api API) error { +func SettlePaymentChannels(mctx helpers.MetricsCtx, lc fx.Lifecycle, papi API) error { ctx := helpers.LifecycleCtx(mctx, lc) lc.Append(fx.Hook{ OnStart: func(context.Context) error { - pcs := newPaymentChannelSettler(ctx, &api) - ev := events.NewEvents(ctx, &api) + pcs := newPaymentChannelSettler(ctx, &papi) + ev := events.NewEvents(ctx, papi) return ev.Called(pcs.check, pcs.messageHandler, pcs.revertHandler, int(build.MessageConfidence+1), events.NoTimeout, pcs.matcher) }, }) @@ -93,7 +93,7 @@ func (pcs *paymentChannelSettler) messageHandler(msg *types.Message, rec *types. } go func(voucher *paych.SignedVoucher, submitMessageCID cid.Cid) { defer wg.Done() - msgLookup, err := pcs.api.StateWaitMsg(pcs.ctx, submitMessageCID, build.MessageConfidence) + msgLookup, err := pcs.api.StateWaitMsg(pcs.ctx, submitMessageCID, build.MessageConfidence, api.LookbackNoLimit, true) if err != nil { log.Errorf("submitting voucher: %s", err.Error()) } diff --git a/paychmgr/simple.go b/paychmgr/simple.go index 939a5a5be25..f93c6d5bd20 100644 --- a/paychmgr/simple.go +++ b/paychmgr/simple.go @@ -413,7 +413,7 @@ func (ca *channelAccessor) waitForPaychCreateMsg(channelID string, mcid cid.Cid) } func (ca *channelAccessor) waitPaychCreateMsg(channelID string, mcid cid.Cid) error { - mwait, err := ca.api.StateWaitMsg(ca.chctx, mcid, build.MessageConfidence) + mwait, err := ca.api.StateWaitMsg(ca.chctx, mcid, build.MessageConfidence, api.LookbackNoLimit, true) if err != nil { log.Errorf("wait msg: %v", err) return err @@ -499,7 +499,7 @@ func (ca *channelAccessor) waitForAddFundsMsg(channelID string, mcid cid.Cid) { } func (ca *channelAccessor) waitAddFundsMsg(channelID string, mcid cid.Cid) error { - mwait, err := ca.api.StateWaitMsg(ca.chctx, mcid, build.MessageConfidence) + mwait, err := ca.api.StateWaitMsg(ca.chctx, mcid, build.MessageConfidence, api.LookbackNoLimit, true) if err != nil { log.Error(err) return err diff --git a/scripts/generate-lotus-cli.py b/scripts/generate-lotus-cli.py new file mode 100644 index 00000000000..8018962e9b7 --- /dev/null +++ b/scripts/generate-lotus-cli.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python +# Generate lotus command lines documents as text and markdown in folder "lotus/documentation/en". +# Python 2.7 + +import os + + +def generate_lotus_cli(prog): + output_folder = 'documentation/en' + md_file = open('%s/cli-%s.md' % (output_folder, prog), 'w') # set the name of md output + + def get_cmd_recursively(cur_cmd): + depth = cur_cmd.count(' ') + md_file.writelines(('\n' * min(depth, 1)) + ('#' * depth) + '# ' + cur_cmd[2:] + '\n') + + cmd_flag = False + + print('> ' + cur_cmd) + cmd_help_output = os.popen(cur_cmd + ' -h') + cmd_help_output_lines = cmd_help_output.readlines() + + md_file.writelines('```\n') + md_file.writelines(cmd_help_output_lines) + md_file.writelines('```\n') + + for line in cmd_help_output_lines: + try: + line = line.strip() + if line == 'COMMANDS:': + cmd_flag = True + if cmd_flag is True and line == '': + cmd_flag = False + if cmd_flag is True and line[-1] != ':' and 'help, h' not in line: + gap_pos = 0 + sub_cmd = line + if ' ' in line: + gap_pos = sub_cmd.index(' ') + if gap_pos: + sub_cmd = cur_cmd + ' ' + sub_cmd[:gap_pos] + get_cmd_recursively(sub_cmd) + except Exception as e: + print('Fail to deal with "%s" with error:\n%s' % (line, e)) + + get_cmd_recursively('./' + prog) + md_file.close() + + +if __name__ == "__main__": + os.putenv("LOTUS_VERSION_IGNORE_COMMIT", "1") + generate_lotus_cli('lotus') + generate_lotus_cli('lotus-miner') + generate_lotus_cli('lotus-worker') diff --git a/scripts/mkreleaselog b/scripts/mkreleaselog new file mode 100755 index 00000000000..ffc3d935eb3 --- /dev/null +++ b/scripts/mkreleaselog @@ -0,0 +1,248 @@ +#!/bin/zsh +set -x +set -euo pipefail +export GO111MODULE=on +export GOPATH="$(go env GOPATH)" + +alias jq="jq --unbuffered" + +AUTHORS=( + # orgs + ipfs + ipld + libp2p + multiformats + filecoin-project + ipfs-shipyard + + # Authors of personal repos used by go-ipfs that should be mentioned in the + # release notes. + whyrusleeping + Kubuxu + jbenet + Stebalien + marten-seemann + hsanjuan + lucas-clemente + warpfork +) + +[[ -n "${REPO_FILTER+x}" ]] || REPO_FILTER="github.com/(${$(printf "|%s" "${AUTHORS[@]}"):1})" + +[[ -n "${IGNORED_FILES+x}" ]] || IGNORED_FILES='^\(\.gx\|package\.json\|\.travis\.yml\|go.mod\|go\.sum|\.github|\.circleci\)$' + +NL=$'\n' + +ROOT_DIR="$(git rev-parse --show-toplevel)" + +msg() { + echo "$*" >&2 +} + +statlog() { + local module="$1" + local rpath="$GOPATH/src/$(strip_version "$module")" + local start="${2:-}" + local end="${3:-HEAD}" + local mailmap_file="$rpath/.mailmap" + if ! [[ -e "$mailmap_file" ]]; then + mailmap_file="$ROOT_DIR/.mailmap" + fi + + git -C "$rpath" -c mailmap.file="$mailmap_file" log --use-mailmap --shortstat --no-merges --pretty="tformat:%H%n%aN%n%aE" "$start..$end" | while + read hash + read name + read email + read _ # empty line + read changes + do + changed=0 + insertions=0 + deletions=0 + while read count event; do + if [[ "$event" =~ ^file ]]; then + changed=$count + elif [[ "$event" =~ ^insertion ]]; then + insertions=$count + elif [[ "$event" =~ ^deletion ]]; then + deletions=$count + else + echo "unknown event $event" >&2 + exit 1 + fi + done<<<"${changes//,/$NL}" + + jq -n \ + --arg "hash" "$hash" \ + --arg "name" "$name" \ + --arg "email" "$email" \ + --argjson "changed" "$changed" \ + --argjson "insertions" "$insertions" \ + --argjson "deletions" "$deletions" \ + '{Commit: $hash, Author: $name, Email: $email, Files: $changed, Insertions: $insertions, Deletions: $deletions}' + done +} + +# Returns a stream of deps changed between $1 and $2. +dep_changes() { + { + <"$1" + <"$2" + } | jq -s 'JOIN(INDEX(.[0][]; .Path); .[1][]; .Path; {Path: .[0].Path, Old: (.[1] | del(.Path)), New: (.[0] | del(.Path))}) | select(.New.Version != .Old.Version)' +} + +# resolve_commits resolves a git ref for each version. +resolve_commits() { + jq '. + {Ref: (.Version|capture("^((?.*)\\+incompatible|v.*-(0\\.)?[0-9]{14}-(?[a-f0-9]{12})|(?v.*))$") | .ref1 // .ref2 // .ref3)}' +} + +pr_link() { + local repo="$1" + local prnum="$2" + local ghname="${repo##github.com/}" + printf -- "[%s#%s](https://%s/pull/%s)" "$ghname" "$prnum" "$repo" "$prnum" +} + +# Generate a release log for a range of commits in a single repo. +release_log() { + setopt local_options BASH_REMATCH + + local module="$1" + local start="$2" + local end="${3:-HEAD}" + local repo="$(strip_version "$1")" + local dir="$GOPATH/src/$repo" + + local commit pr + git -C "$dir" log \ + --format='tformat:%H %s' \ + --first-parent \ + "$start..$end" | + while read commit subject; do + # Skip gx-only PRs. + git -C "$dir" diff-tree --no-commit-id --name-only "$commit^" "$commit" | + grep -v "${IGNORED_FILES}" >/dev/null || continue + + if [[ "$subject" =~ '^Merge pull request #([0-9]+) from' ]]; then + local prnum="${BASH_REMATCH[2]}" + local desc="$(git -C "$dir" show --summary --format='tformat:%b' "$commit" | head -1)" + printf -- "- %s (%s)\n" "$desc" "$(pr_link "$repo" "$prnum")" + elif [[ "$subject" =~ '\(#([0-9]+)\)$' ]]; then + local prnum="${BASH_REMATCH[2]}" + printf -- "- %s (%s)\n" "$subject" "$(pr_link "$repo" "$prnum")" + else + printf -- "- %s\n" "$subject" + fi + done +} + +indent() { + sed -e 's/^/ /' +} + +mod_deps() { + go list -mod=mod -json -m all | jq 'select(.Version != null)' +} + +ensure() { + local repo="$(strip_version "$1")" + local commit="$2" + local rpath="$GOPATH/src/$repo" + if [[ ! -d "$rpath" ]]; then + msg "Cloning $repo..." + git clone "http://$repo" "$rpath" >&2 + fi + + if ! git -C "$rpath" rev-parse --verify "$commit" >/dev/null; then + msg "Fetching $repo..." + git -C "$rpath" fetch --all >&2 + fi + + git -C "$rpath" rev-parse --verify "$commit" >/dev/null || return 1 +} + +statsummary() { + jq -s 'group_by(.Author)[] | {Author: .[0].Author, Commits: (. | length), Insertions: (map(.Insertions) | add), Deletions: (map(.Deletions) | add), Files: (map(.Files) | add)}' | + jq '. + {Lines: (.Deletions + .Insertions)}' +} + +strip_version() { + local repo="$1" + if [[ "$repo" =~ '.*/v[0-9]+$' ]]; then + repo="$(dirname "$repo")" + fi + echo "$repo" +} + +recursive_release_log() { + local start="${1:-$(git tag -l | sort -V | grep -v -- '-rc' | grep 'v'| tail -n1)}" + local end="${2:-$(git rev-parse HEAD)}" + local repo_root="$(git rev-parse --show-toplevel)" + local module="$(go list -m)" + local dir="$(go list -m -f '{{.Dir}}')" + + if [[ "${GOPATH}/${module}" -ef "${dir}" ]]; then + echo "This script requires the target module and all dependencies to live in a GOPATH." + return 1 + fi + + ( + local result=0 + local workspace="$(mktemp -d)" + trap "$(printf 'rm -rf "%q"' "$workspace")" INT TERM EXIT + cd "$workspace" + + mkdir extern + ln -s "$repo_root"/extern/filecoin-ffi extern/filecoin-ffi + ln -s "$repo_root"/extern/test-vectors extern/test-vectors + + echo "Computing old deps..." >&2 + git -C "$repo_root" show "$start:go.mod" >go.mod + mod_deps | resolve_commits | jq -s > old_deps.json + + echo "Computing new deps..." >&2 + git -C "$repo_root" show "$end:go.mod" >go.mod + mod_deps | resolve_commits | jq -s > new_deps.json + + rm -f go.mod go.sum + + printf -- "Generating Changelog for %s %s..%s\n" "$module" "$start" "$end" >&2 + + printf -- "- %s:\n" "$module" + release_log "$module" "$start" "$end" | indent + + + statlog "$module" "$start" "$end" > statlog.json + + dep_changes old_deps.json new_deps.json | + jq --arg filter "$REPO_FILTER" 'select(.Path | match($filter))' | + # Compute changelogs + jq -r '"\(.Path) \(.New.Version) \(.New.Ref) \(.Old.Version) \(.Old.Ref // "")"' | + while read module new new_ref old old_ref; do + if ! ensure "$module" "$new_ref"; then + result=1 + local changelog="failed to fetch repo" + else + statlog "$module" "$old_ref" "$new_ref" >> statlog.json + local changelog="$(release_log "$module" "$old_ref" "$new_ref")" + fi + if [[ -n "$changelog" ]]; then + printf -- "- %s (%s -> %s):\n" "$module" "$old" "$new" + echo "$changelog" | indent + fi + done + + echo + echo "Contributors" + echo + + echo "| Contributor | Commits | Lines Âą | Files Changed |" + echo "|-------------|---------|---------|---------------|" + statsummary "$GATE" diff --git a/tools/packer/scripts/nerpanet/lotus-init.sh b/tools/packer/scripts/nerpanet/lotus-init.sh new file mode 100755 index 00000000000..968ae395ca0 --- /dev/null +++ b/tools/packer/scripts/nerpanet/lotus-init.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +# This script sets up an initial configuraiton for the lotus daemon and miner +# It will only run once. + +GATE="$LOTUS_PATH"/date_initialized + +# Don't init if already initialized. +if [ -f "GATE" ]; then + echo lotus already initialized. + exit 0 +fi + +# Not importing snapshot on nerpanet +# +# echo importing minimal snapshot +# lotus daemon --import-snapshot https://fil-chain-snapshots-fallback.s3.amazonaws.com/mainnet/minimal_finality_stateroots_latest.car --halt-after-import + +# Block future inits +date > "$GATE" diff --git a/tools/packer/setup.sh b/tools/packer/setup.sh index 04d06a7d1fe..6c0742254ff 100644 --- a/tools/packer/setup.sh +++ b/tools/packer/setup.sh @@ -60,7 +60,7 @@ systemctl daemon-reload systemctl enable lotus-daemon # Setup firewall -ufw enable +yes | ufw enable ufw default deny incoming ufw default allow outgoing ufw allow ssh diff --git a/tools/stats/collect.go b/tools/stats/collect.go index 221dc37e2c9..e33ec994b66 100644 --- a/tools/stats/collect.go +++ b/tools/stats/collect.go @@ -5,11 +5,11 @@ import ( "time" "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" client "github.com/influxdata/influxdb1-client/v2" ) -func Collect(ctx context.Context, api api.FullNode, influx client.Client, database string, height int64, headlag int) { +func Collect(ctx context.Context, api v0api.FullNode, influx client.Client, database string, height int64, headlag int) { tipsetsCh, err := GetTips(ctx, api, abi.ChainEpoch(height), headlag) if err != nil { log.Fatal(err) diff --git a/tools/stats/metrics.go b/tools/stats/metrics.go index 795203c40a2..7764c4bcabd 100644 --- a/tools/stats/metrics.go +++ b/tools/stats/metrics.go @@ -11,7 +11,7 @@ import ( "time" "github.com/filecoin-project/go-address" - "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors/builtin/power" "github.com/filecoin-project/lotus/chain/actors/builtin/reward" @@ -115,7 +115,7 @@ func NewPointFrom(p models.Point) *client.Point { return client.NewPointFrom(p) } -func RecordTipsetPoints(ctx context.Context, api api.FullNode, pl *PointList, tipset *types.TipSet) error { +func RecordTipsetPoints(ctx context.Context, api v0api.FullNode, pl *PointList, tipset *types.TipSet) error { cids := []string{} for _, cid := range tipset.Cids() { cids = append(cids, cid.String()) @@ -238,7 +238,7 @@ func (ht *ApiIpldStore) Put(ctx context.Context, v interface{}) (cid.Cid, error) return cid.Undef, fmt.Errorf("Put is not implemented on ApiIpldStore") } -func RecordTipsetStatePoints(ctx context.Context, api api.FullNode, pl *PointList, tipset *types.TipSet) error { +func RecordTipsetStatePoints(ctx context.Context, api v0api.FullNode, pl *PointList, tipset *types.TipSet) error { attoFil := types.NewInt(build.FilecoinPrecision).Int //TODO: StatePledgeCollateral API is not implemented and is commented out - re-enable this block once the API is implemented again. @@ -299,7 +299,7 @@ type msgTag struct { exitcode uint8 } -func RecordTipsetMessagesPoints(ctx context.Context, api api.FullNode, pl *PointList, tipset *types.TipSet) error { +func RecordTipsetMessagesPoints(ctx context.Context, api v0api.FullNode, pl *PointList, tipset *types.TipSet) error { cids := tipset.Cids() if len(cids) == 0 { return fmt.Errorf("no cids in tipset") diff --git a/tools/stats/rpc.go b/tools/stats/rpc.go index b01c07a3579..0aa3d141ee4 100644 --- a/tools/stats/rpc.go +++ b/tools/stats/rpc.go @@ -13,6 +13,7 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/client" + "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" @@ -45,7 +46,7 @@ func getAPI(path string) (string, http.Header, error) { return "ws://" + addr + "/rpc/v0", headers, nil } -func WaitForSyncComplete(ctx context.Context, napi api.FullNode) error { +func WaitForSyncComplete(ctx context.Context, napi v0api.FullNode) error { sync_complete: for { select { @@ -120,7 +121,7 @@ sync_complete: } } -func GetTips(ctx context.Context, api api.FullNode, lastHeight abi.ChainEpoch, headlag int) (<-chan *types.TipSet, error) { +func GetTips(ctx context.Context, api v0api.FullNode, lastHeight abi.ChainEpoch, headlag int) (<-chan *types.TipSet, error) { chmain := make(chan *types.TipSet) hb := newHeadBuffer(headlag) @@ -184,7 +185,7 @@ func GetTips(ctx context.Context, api api.FullNode, lastHeight abi.ChainEpoch, h return chmain, nil } -func loadTipsets(ctx context.Context, api api.FullNode, curr *types.TipSet, lowestHeight abi.ChainEpoch) ([]*types.TipSet, error) { +func loadTipsets(ctx context.Context, api v0api.FullNode, curr *types.TipSet, lowestHeight abi.ChainEpoch) ([]*types.TipSet, error) { tipsets := []*types.TipSet{} for { if curr.Height() == 0 { @@ -214,11 +215,11 @@ func loadTipsets(ctx context.Context, api api.FullNode, curr *types.TipSet, lowe return tipsets, nil } -func GetFullNodeAPI(ctx context.Context, repo string) (api.FullNode, jsonrpc.ClientCloser, error) { +func GetFullNodeAPI(ctx context.Context, repo string) (v0api.FullNode, jsonrpc.ClientCloser, error) { addr, headers, err := getAPI(repo) if err != nil { return nil, nil, err } - return client.NewFullNodeRPC(ctx, addr, headers) + return client.NewFullNodeRPCV0(ctx, addr, headers) }