diff --git a/.circleci/config.yml b/.circleci/config.yml index d59939096cb..133fb4d9607 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -112,7 +112,7 @@ jobs: - run: command: make debug - test: &test + test: description: | Run tests with gotestsum. parameters: &test-params @@ -123,23 +123,20 @@ jobs: type: string default: "-timeout 30m" description: Flags passed to go test. - packages: + target: type: string default: "./..." description: Import paths of packages to be tested. - winpost-test: + proofs-log-test: type: string default: "0" - deadline-test: - type: string - default: "0" - test-suite-name: + suite: type: string default: unit description: Test suite name to report to CircleCI. gotestsum-format: type: string - default: pkgname-and-test-fails + default: standard-verbose description: gotestsum format. https://github.com/gotestyourself/gotestsum#format coverage: type: string @@ -147,7 +144,7 @@ jobs: description: Coverage flag. Set to the empty string to disable. codecov-upload: type: boolean - default: false + default: true description: | Upload coverage report to https://codecov.io/. Requires the codecov API token to be set as an environment variable for private projects. @@ -165,25 +162,24 @@ jobs: - run: name: go test environment: - LOTUS_TEST_WINDOW_POST: << parameters.winpost-test >> - LOTUS_TEST_DEADLINE_TOGGLING: << parameters.deadline-test >> + TEST_RUSTPROOFS_LOGS: << parameters.proofs-log-test >> SKIP_CONFORMANCE: "1" command: | - mkdir -p /tmp/test-reports/<< parameters.test-suite-name >> + mkdir -p /tmp/test-reports/<< parameters.suite >> mkdir -p /tmp/test-artifacts gotestsum \ --format << parameters.gotestsum-format >> \ - --junitfile /tmp/test-reports/<< parameters.test-suite-name >>/junit.xml \ - --jsonfile /tmp/test-artifacts/<< parameters.test-suite-name >>.json \ + --junitfile /tmp/test-reports/<< parameters.suite >>/junit.xml \ + --jsonfile /tmp/test-artifacts/<< parameters.suite >>.json \ -- \ << parameters.coverage >> \ << parameters.go-test-flags >> \ - << parameters.packages >> + << parameters.target >> no_output_timeout: 30m - store_test_results: path: /tmp/test-reports - store_artifacts: - path: /tmp/test-artifacts/<< parameters.test-suite-name >>.json + path: /tmp/test-artifacts/<< parameters.suite >>.json - when: condition: << parameters.codecov-upload >> steps: @@ -194,24 +190,6 @@ jobs: command: | bash <(curl -s https://codecov.io/bash) - test-chain: - <<: *test - test-node: - <<: *test - test-storage: - <<: *test - test-cli: - <<: *test - test-short: - <<: *test - test-window-post: - <<: *test - test-window-post-dispute: - <<: *test - test-deadline-toggling: - <<: *test - test-terminate: - <<: *test test-conformance: description: | Run tests using a corpus of interoperable test vectors for Filecoin @@ -331,7 +309,7 @@ jobs: - run: cd extern/filecoin-ffi && make - run: name: "go get lotus@master" - command: cd testplans/lotus-soup && go mod edit -replace=github.com/filecoin-project/lotus=../.. + command: cd testplans/lotus-soup && go mod edit -replace=github.com/filecoin-project/lotus=../.. && go mod tidy - run: name: "build lotus-soup testplan" command: pushd testplans/lotus-soup && go build -tags=testground . @@ -428,6 +406,41 @@ jobs: - "~/.rustup" - "~/.cargo" + build-appimage: + machine: + image: ubuntu-2004:202104-01 + steps: + - checkout + - attach_workspace: + at: "." + - run: + name: install appimage-builder + command: | + # docs: https://appimage-builder.readthedocs.io/en/latest/intro/install.html + sudo apt update + sudo apt install -y python3-pip python3-setuptools patchelf desktop-file-utils libgdk-pixbuf2.0-dev fakeroot strace + sudo curl -Lo /usr/local/bin/appimagetool https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage + sudo chmod +x /usr/local/bin/appimagetool + sudo pip3 install appimage-builder + - run: + name: install lotus dependencies + command: sudo apt install ocl-icd-opencl-dev libhwloc-dev + - run: + name: build appimage + command: | + sed -i "s/version: latest/version: ${CIRCLE_TAG:-latest}/" AppImageBuilder.yml + make appimage + - run: + name: prepare workspace + command: | + mkdir appimage + mv Lotus-latest-x86_64.AppImage appimage + - persist_to_workspace: + root: "." + paths: + - appimage + + gofmt: executor: golang steps: @@ -530,6 +543,33 @@ jobs: name: Publish release command: ./scripts/publish-release.sh + publish-snapcraft: + description: build and push snapcraft + machine: + image: ubuntu-2004:202104-01 + resource_class: 2xlarge + parameters: + channel: + type: string + default: "edge" + description: snapcraft channel + steps: + - checkout + - run: + name: install snapcraft + command: sudo snap install snapcraft --classic + - run: + name: create snapcraft config file + command: | + mkdir -p ~/.config/snapcraft + echo "$SNAPCRAFT_LOGIN_FILE" | base64 -d > ~/.config/snapcraft/snapcraft.cfg + - run: + name: build snap + command: snapcraft --use-lxd + - run: + name: publish snap + command: snapcraft push *.snap --release << parameters.channel >> + build-and-push-image: description: build and push docker images to public AWS ECR registry executor: aws-cli/default @@ -707,58 +747,120 @@ workflows: - gen-check - docs-check - test: - codecov-upload: true - test-suite-name: full - - test-chain: - codecov-upload: true - test-suite-name: chain - packages: "./chain/..." - - test-node: - codecov-upload: true - test-suite-name: node - packages: "./node/..." - - test-storage: - codecov-upload: true - test-suite-name: storage - packages: "./storage/... ./extern/..." - - test-cli: - codecov-upload: true - test-suite-name: cli - packages: "./cli/... ./cmd/... ./api/..." - - test-window-post: - codecov-upload: true - go-test-flags: "-run=TestWindowedPost" - winpost-test: "1" - test-suite-name: window-post - - test-window-post-dispute: - codecov-upload: true - go-test-flags: "-run=TestWindowPostDispute" - winpost-test: "1" - test-suite-name: window-post-dispute - - test-terminate: - codecov-upload: true - 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 - filters: - tags: - only: - - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + name: test-itest-api + suite: itest-api + target: "./itests/api_test.go" + + - test: + name: test-itest-batch_deal + suite: itest-batch_deal + target: "./itests/batch_deal_test.go" + + - test: + name: test-itest-ccupgrade + suite: itest-ccupgrade + target: "./itests/ccupgrade_test.go" + + - test: + name: test-itest-cli + suite: itest-cli + target: "./itests/cli_test.go" + + - test: + name: test-itest-deadlines + suite: itest-deadlines + target: "./itests/deadlines_test.go" + + - test: + name: test-itest-deals + suite: itest-deals + target: "./itests/deals_test.go" + + - test: + name: test-itest-gateway + suite: itest-gateway + target: "./itests/gateway_test.go" + + - test: + name: test-itest-multisig + suite: itest-multisig + target: "./itests/multisig_test.go" + + - test: + name: test-itest-paych_api + suite: itest-paych_api + target: "./itests/paych_api_test.go" + + - test: + name: test-itest-paych_cli + suite: itest-paych_cli + target: "./itests/paych_cli_test.go" + + - test: + name: test-itest-sdr_upgrade + suite: itest-sdr_upgrade + target: "./itests/sdr_upgrade_test.go" + + - test: + name: test-itest-sector_pledge + suite: itest-sector_pledge + target: "./itests/sector_pledge_test.go" + + - test: + name: test-itest-sector_terminate + suite: itest-sector_terminate + target: "./itests/sector_terminate_test.go" + + - test: + name: test-itest-tape + suite: itest-tape + target: "./itests/tape_test.go" + + - test: + name: test-itest-verifreg + suite: itest-verifreg + target: "./itests/verifreg_test.go" + + - test: + name: test-itest-wdpost_dispute + suite: itest-wdpost_dispute + target: "./itests/wdpost_dispute_test.go" + + - test: + name: test-itest-wdpost + suite: itest-wdpost + target: "./itests/wdpost_test.go" + + - test: + name: test-unit-cli + suite: utest-unit-cli + target: "./cli/... ./cmd/... ./api/..." + - test: + name: test-unit-node + suite: utest-unit-node + target: "./node/..." + - test: + name: test-unit-rest + suite: utest-unit-rest + target: "./api/... ./blockstore/... ./build/... ./chain/... ./cli/... ./cmd/... ./conformance/... ./extern/... ./gateway/... ./journal/... ./lib/... ./markets/... ./node/... ./paychmgr/... ./storage/... ./tools/..." + - test: + name: test-unit-storage + suite: utest-unit-storage + target: "./storage/... ./extern/..." + - test: + go-test-flags: "-run=TestMulticoreSDR" + suite: multicore-sdr-check + target: "./extern/sector-storage/ffiwrapper" + proofs-log-test: "1" - test-conformance: - test-suite-name: conformance - packages: "./conformance" + suite: conformance + codecov-upload: false + target: "./conformance" - test-conformance: name: test-conformance-bleeding-edge - test-suite-name: conformance-bleeding-edge - packages: "./conformance" + codecov-upload: false + suite: conformance-bleeding-edge + target: "./conformance" vectors-branch: master - trigger-testplans: filters: @@ -767,37 +869,35 @@ workflows: - master - build-debug - build-all: - requires: - - test-short filters: tags: only: - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - build-ntwk-calibration: - requires: - - test-short filters: tags: only: - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - build-ntwk-butterfly: - requires: - - test-short filters: tags: only: - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - build-ntwk-nerpa: - requires: - - test-short filters: tags: only: - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - build-lotus-soup - build-macos: - requires: - - test-short + filters: + branches: + ignore: + - /.*/ + tags: + only: + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + - build-appimage: filters: branches: ignore: @@ -809,6 +909,7 @@ workflows: requires: - build-all - build-macos + - build-appimage filters: branches: ignore: @@ -861,3 +962,26 @@ workflows: tags: only: - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + - publish-snapcraft: + name: publish-snapcraft-stable + channel: stable + filters: + branches: + ignore: + - /.*/ + tags: + only: + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + + nightly: + triggers: + - schedule: + cron: "0 0 * * *" + filters: + branches: + only: + - master + jobs: + - publish-snapcraft: + name: publish-snapcraft-nightly + channel: edge diff --git a/.circleci/gen.go b/.circleci/gen.go new file mode 100644 index 00000000000..844348e29ae --- /dev/null +++ b/.circleci/gen.go @@ -0,0 +1,136 @@ +package main + +import ( + "embed" + "fmt" + "os" + "path/filepath" + "sort" + "strings" + "text/template" +) + +//go:generate go run ./gen.go .. + +//go:embed template.yml +var templateFile embed.FS + +type ( + dirs = []string + suite = string +) + +// groupedUnitTests maps suite names to top-level directories that should be +// included in that suite. The program adds an implicit group "rest" that +// includes all other top-level directories. +var groupedUnitTests = map[suite]dirs{ + "unit-node": {"node"}, + "unit-storage": {"storage", "extern"}, + "unit-cli": {"cli", "cmd", "api"}, +} + +func main() { + if len(os.Args) != 2 { + panic("expected path to repo as argument") + } + + repo := os.Args[1] + + tmpl := template.New("template.yml") + tmpl.Delims("[[", "]]") + tmpl.Funcs(template.FuncMap{ + "stripSuffix": func(in string) string { + return strings.TrimSuffix(in, "_test.go") + }, + }) + tmpl = template.Must(tmpl.ParseFS(templateFile, "*")) + + // list all itests. + itests, err := filepath.Glob(filepath.Join(repo, "./itests/*_test.go")) + if err != nil { + panic(err) + } + + // strip the dir from all entries. + for i, f := range itests { + itests[i] = filepath.Base(f) + } + + // calculate the exclusion set of unit test directories to exclude because + // they are already included in a grouped suite. + var excluded = map[string]struct{}{} + for _, ss := range groupedUnitTests { + for _, s := range ss { + e, err := filepath.Abs(filepath.Join(repo, s)) + if err != nil { + panic(err) + } + excluded[e] = struct{}{} + } + } + + // all unit tests top-level dirs that are not itests, nor included in other suites. + var rest = map[string]struct{}{} + err = filepath.Walk(repo, func(path string, f os.FileInfo, err error) error { + // include all tests that aren't in the itests directory. + if strings.Contains(path, "itests") { + return filepath.SkipDir + } + // exclude all tests included in other suites + if f.IsDir() { + if _, ok := excluded[path]; ok { + return filepath.SkipDir + } + } + if strings.HasSuffix(path, "_test.go") { + rel, err := filepath.Rel(repo, path) + if err != nil { + panic(err) + } + // take the first directory + rest[strings.Split(rel, string(os.PathSeparator))[0]] = struct{}{} + } + return err + }) + if err != nil { + panic(err) + } + + // add other directories to a 'rest' suite. + for k := range rest { + groupedUnitTests["unit-rest"] = append(groupedUnitTests["unit-rest"], k) + } + + // map iteration guarantees no order, so sort the array in-place. + sort.Strings(groupedUnitTests["unit-rest"]) + + // form the input data. + type data struct { + ItestFiles []string + UnitSuites map[string]string + } + in := data{ + ItestFiles: itests, + UnitSuites: func() map[string]string { + ret := make(map[string]string) + for name, dirs := range groupedUnitTests { + for i, d := range dirs { + dirs[i] = fmt.Sprintf("./%s/...", d) // turn into package + } + ret[name] = strings.Join(dirs, " ") + } + return ret + }(), + } + + out, err := os.Create("./config.yml") + if err != nil { + panic(err) + } + defer out.Close() + + // execute the template. + if err := tmpl.Execute(out, in); err != nil { + panic(err) + } +} diff --git a/.circleci/template.yml b/.circleci/template.yml new file mode 100644 index 00000000000..75fbdfc765d --- /dev/null +++ b/.circleci/template.yml @@ -0,0 +1,902 @@ +version: 2.1 +orbs: + go: gotest/tools@0.0.13 + aws-cli: circleci/aws-cli@1.3.2 + packer: salaxander/packer@0.0.3 + +executors: + golang: + docker: + - image: circleci/golang:1.16.4 + resource_class: 2xlarge + ubuntu: + docker: + - image: ubuntu:20.04 + +commands: + install-deps: + steps: + - go/install-ssh + - go/install: {package: git} + prepare: + parameters: + linux: + default: true + description: is a linux build environment? + type: boolean + darwin: + default: false + description: is a darwin build environment? + type: boolean + steps: + - checkout + - git_fetch_all_tags + - checkout + - when: + condition: << parameters.linux >> + steps: + - run: sudo apt-get update + - run: sudo apt-get install ocl-icd-opencl-dev libhwloc-dev + - run: git submodule sync + - run: git submodule update --init + download-params: + steps: + - restore_cache: + name: Restore parameters cache + keys: + - 'v25-2k-lotus-params' + paths: + - /var/tmp/filecoin-proof-parameters/ + - run: ./lotus fetch-params 2048 + - save_cache: + name: Save parameters cache + key: 'v25-2k-lotus-params' + paths: + - /var/tmp/filecoin-proof-parameters/ + install_ipfs: + steps: + - run: | + apt update + apt install -y wget + wget https://github.com/ipfs/go-ipfs/releases/download/v0.4.22/go-ipfs_v0.4.22_linux-amd64.tar.gz + wget https://github.com/ipfs/go-ipfs/releases/download/v0.4.22/go-ipfs_v0.4.22_linux-amd64.tar.gz.sha512 + if [ "$(sha512sum go-ipfs_v0.4.22_linux-amd64.tar.gz)" != "$(cat go-ipfs_v0.4.22_linux-amd64.tar.gz.sha512)" ] + then + echo "ipfs failed checksum check" + exit 1 + fi + tar -xf go-ipfs_v0.4.22_linux-amd64.tar.gz + mv go-ipfs/ipfs /usr/local/bin/ipfs + chmod +x /usr/local/bin/ipfs + git_fetch_all_tags: + steps: + - run: + name: fetch all tags + command: | + git fetch --all + +jobs: + mod-tidy-check: + executor: golang + steps: + - install-deps + - prepare + - go/mod-tidy-check + + build-all: + executor: golang + steps: + - install-deps + - prepare + - run: sudo apt-get update + - run: sudo apt-get install npm + - run: + command: make buildall + - store_artifacts: + path: lotus + - store_artifacts: + path: lotus-miner + - store_artifacts: + path: lotus-worker + - run: mkdir linux && mv lotus lotus-miner lotus-worker linux/ + - persist_to_workspace: + root: "." + paths: + - linux + + build-debug: + executor: golang + steps: + - install-deps + - prepare + - run: + command: make debug + + test: + description: | + Run tests with gotestsum. + parameters: &test-params + executor: + type: executor + default: golang + go-test-flags: + type: string + default: "-timeout 30m" + description: Flags passed to go test. + target: + type: string + default: "./..." + description: Import paths of packages to be tested. + proofs-log-test: + type: string + default: "0" + suite: + type: string + default: unit + description: Test suite name to report to CircleCI. + gotestsum-format: + type: string + default: standard-verbose + description: gotestsum format. https://github.com/gotestyourself/gotestsum#format + coverage: + type: string + default: -coverprofile=coverage.txt -coverpkg=github.com/filecoin-project/lotus/... + description: Coverage flag. Set to the empty string to disable. + codecov-upload: + type: boolean + default: true + description: | + Upload coverage report to https://codecov.io/. Requires the codecov API token to be + set as an environment variable for private projects. + executor: << parameters.executor >> + steps: + - install-deps + - prepare + - run: + command: make deps lotus + no_output_timeout: 30m + - download-params + - go/install-gotestsum: + gobin: $HOME/.local/bin + version: 0.5.2 + - run: + name: go test + environment: + TEST_RUSTPROOFS_LOGS: << parameters.proofs-log-test >> + SKIP_CONFORMANCE: "1" + command: | + mkdir -p /tmp/test-reports/<< parameters.suite >> + mkdir -p /tmp/test-artifacts + gotestsum \ + --format << parameters.gotestsum-format >> \ + --junitfile /tmp/test-reports/<< parameters.suite >>/junit.xml \ + --jsonfile /tmp/test-artifacts/<< parameters.suite >>.json \ + -- \ + << parameters.coverage >> \ + << parameters.go-test-flags >> \ + << parameters.target >> + no_output_timeout: 30m + - store_test_results: + path: /tmp/test-reports + - store_artifacts: + path: /tmp/test-artifacts/<< parameters.suite >>.json + - when: + condition: << parameters.codecov-upload >> + steps: + - go/install: {package: bash} + - go/install: {package: curl} + - run: + shell: /bin/bash -eo pipefail + command: | + bash <(curl -s https://codecov.io/bash) + + test-conformance: + description: | + Run tests using a corpus of interoperable test vectors for Filecoin + implementations to test their correctness and compliance with the Filecoin + specifications. + parameters: + <<: *test-params + vectors-branch: + type: string + default: "" + description: | + Branch on github.com/filecoin-project/test-vectors to checkout and + test with. If empty (the default) the commit defined by the git + submodule is used. + executor: << parameters.executor >> + steps: + - install-deps + - prepare + - run: + command: make deps lotus + no_output_timeout: 30m + - download-params + - when: + condition: + not: + equal: [ "", << parameters.vectors-branch >> ] + steps: + - run: + name: checkout vectors branch + command: | + cd extern/test-vectors + git fetch + git checkout origin/<< parameters.vectors-branch >> + - go/install-gotestsum: + gobin: $HOME/.local/bin + version: 0.5.2 + - run: + name: install statediff globally + command: | + ## statediff is optional; we succeed even if compilation fails. + mkdir -p /tmp/statediff + git clone https://github.com/filecoin-project/statediff.git /tmp/statediff + cd /tmp/statediff + go install ./cmd/statediff || exit 0 + - run: + name: go test + environment: + SKIP_CONFORMANCE: "0" + command: | + mkdir -p /tmp/test-reports + mkdir -p /tmp/test-artifacts + gotestsum \ + --format pkgname-and-test-fails \ + --junitfile /tmp/test-reports/junit.xml \ + -- \ + -v -coverpkg ./chain/vm/,github.com/filecoin-project/specs-actors/... -coverprofile=/tmp/conformance.out ./conformance/ + go tool cover -html=/tmp/conformance.out -o /tmp/test-artifacts/conformance-coverage.html + no_output_timeout: 30m + - store_test_results: + path: /tmp/test-reports + - store_artifacts: + path: /tmp/test-artifacts/conformance-coverage.html + build-ntwk-calibration: + description: | + Compile lotus binaries for the calibration network + parameters: + <<: *test-params + executor: << parameters.executor >> + steps: + - install-deps + - prepare + - run: make 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-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 + parameters: + <<: *test-params + executor: << parameters.executor >> + steps: + - install-deps + - prepare + - run: cd extern/filecoin-ffi && make + - run: + name: "go get lotus@master" + command: cd testplans/lotus-soup && go mod edit -replace=github.com/filecoin-project/lotus=../.. && go mod tidy + - run: + name: "build lotus-soup testplan" + command: pushd testplans/lotus-soup && go build -tags=testground . + trigger-testplans: + description: | + Trigger `lotus-soup` test cases on TaaS + parameters: + <<: *test-params + executor: << parameters.executor >> + steps: + - install-deps + - prepare + - run: + name: "download testground" + command: wget https://gist.github.com/nonsense/5fbf3167cac79945f658771aed32fc44/raw/2e17eb0debf7ec6bdf027c1bdafc2c92dd97273b/testground-d3e9603 -O ~/testground-cli && chmod +x ~/testground-cli + - run: + name: "prepare .env.toml" + command: pushd testplans/lotus-soup && mkdir -p $HOME/testground && cp env-ci.toml $HOME/testground/.env.toml && echo 'endpoint="https://ci.testground.ipfs.team"' >> $HOME/testground/.env.toml && echo 'user="circleci"' >> $HOME/testground/.env.toml + - run: + name: "prepare testground home dir and link test plans" + command: mkdir -p $HOME/testground/plans && ln -s $(pwd)/testplans/lotus-soup $HOME/testground/plans/lotus-soup && ln -s $(pwd)/testplans/graphsync $HOME/testground/plans/graphsync + - run: + name: "go get lotus@master" + command: cd testplans/lotus-soup && go get github.com/filecoin-project/lotus@master + - run: + name: "trigger deals baseline testplan on taas" + command: ~/testground-cli run composition -f $HOME/testground/plans/lotus-soup/_compositions/baseline-k8s-3-1.toml --metadata-commit=$CIRCLE_SHA1 --metadata-repo=filecoin-project/lotus --metadata-branch=$CIRCLE_BRANCH + - run: + name: "trigger payment channel stress testplan on taas" + command: ~/testground-cli run composition -f $HOME/testground/plans/lotus-soup/_compositions/paych-stress-k8s.toml --metadata-commit=$CIRCLE_SHA1 --metadata-repo=filecoin-project/lotus --metadata-branch=$CIRCLE_BRANCH + - run: + name: "trigger graphsync testplan on taas" + command: ~/testground-cli run composition -f $HOME/testground/plans/graphsync/_compositions/stress-k8s.toml --metadata-commit=$CIRCLE_SHA1 --metadata-repo=filecoin-project/lotus --metadata-branch=$CIRCLE_BRANCH + + + build-macos: + description: build darwin lotus binary + macos: + xcode: "10.0.0" + working_directory: ~/go/src/github.com/filecoin-project/lotus + steps: + - prepare: + linux: false + darwin: true + - run: + name: Install go + command: | + curl -O https://dl.google.com/go/go1.16.4.darwin-amd64.pkg && \ + sudo installer -pkg go1.16.4.darwin-amd64.pkg -target / + - run: + name: Install pkg-config + command: HOMEBREW_NO_AUTO_UPDATE=1 brew install pkg-config + - run: go version + - run: + name: Install Rust + command: | + curl https://sh.rustup.rs -sSf | sh -s -- -y + - run: + name: Install jq + 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" }} + - install-deps + - run: + command: make build + no_output_timeout: 30m + - store_artifacts: + path: lotus + - store_artifacts: + path: lotus-miner + - store_artifacts: + path: lotus-worker + - run: mkdir darwin && mv lotus lotus-miner lotus-worker darwin/ + - persist_to_workspace: + root: "." + paths: + - darwin + - save_cache: + name: save cargo cache + key: v3-go-deps-{{ arch }}-{{ checksum "~/go/src/github.com/filecoin-project/lotus/go.sum" }} + paths: + - "~/.rustup" + - "~/.cargo" + + build-appimage: + machine: + image: ubuntu-2004:202104-01 + steps: + - checkout + - attach_workspace: + at: "." + - run: + name: install appimage-builder + command: | + # docs: https://appimage-builder.readthedocs.io/en/latest/intro/install.html + sudo apt update + sudo apt install -y python3-pip python3-setuptools patchelf desktop-file-utils libgdk-pixbuf2.0-dev fakeroot strace + sudo curl -Lo /usr/local/bin/appimagetool https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage + sudo chmod +x /usr/local/bin/appimagetool + sudo pip3 install appimage-builder + - run: + name: install lotus dependencies + command: sudo apt install ocl-icd-opencl-dev libhwloc-dev + - run: + name: build appimage + command: | + sed -i "s/version: latest/version: ${CIRCLE_TAG:-latest}/" AppImageBuilder.yml + make appimage + - run: + name: prepare workspace + command: | + mkdir appimage + mv Lotus-latest-x86_64.AppImage appimage + - persist_to_workspace: + root: "." + paths: + - appimage + + + gofmt: + executor: golang + steps: + - install-deps + - prepare + - run: + command: "! go fmt ./... 2>&1 | read" + + gen-check: + executor: golang + steps: + - install-deps + - prepare + - run: make deps + - run: go install golang.org/x/tools/cmd/goimports + - run: go install github.com/hannahhoward/cbor-gen-for + - 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 + + docs-check: + executor: golang + 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 + - run: make deps + - run: make docsgen + - run: zcat build/openrpc/full.json.gz | jq > ../post-openrpc-full + - run: zcat build/openrpc/miner.json.gz | jq > ../post-openrpc-miner + - run: zcat build/openrpc/worker.json.gz | jq > ../post-openrpc-worker + - run: git --no-pager diff + - run: diff ../pre-openrpc-full ../post-openrpc-full + - run: diff ../pre-openrpc-miner ../post-openrpc-miner + - run: diff ../pre-openrpc-worker ../post-openrpc-worker + - run: git --no-pager diff --quiet + + lint: &lint + description: | + Run golangci-lint. + parameters: + executor: + type: executor + default: golang + golangci-lint-version: + type: string + default: 1.27.0 + concurrency: + type: string + default: '2' + description: | + Concurrency used to run linters. Defaults to 2 because NumCPU is not + aware of container CPU limits. + args: + type: string + default: '' + description: | + Arguments to pass to golangci-lint + executor: << parameters.executor >> + steps: + - install-deps + - prepare + - run: + command: make deps + no_output_timeout: 30m + - go/install-golangci-lint: + gobin: $HOME/.local/bin + version: << parameters.golangci-lint-version >> + - run: + name: Lint + command: | + $HOME/.local/bin/golangci-lint run -v --timeout 2m \ + --concurrency << parameters.concurrency >> << parameters.args >> + lint-all: + <<: *lint + + publish: + description: publish binary artifacts + executor: ubuntu + steps: + - run: + name: Install git jq curl + command: apt update && apt install -y git jq curl + - checkout + - git_fetch_all_tags + - checkout + - install_ipfs + - attach_workspace: + at: "." + - run: + name: Create bundles + command: ./scripts/build-bundle.sh + - run: + name: Publish release + command: ./scripts/publish-release.sh + + publish-snapcraft: + description: build and push snapcraft + machine: + image: ubuntu-2004:202104-01 + resource_class: 2xlarge + parameters: + channel: + type: string + default: "edge" + description: snapcraft channel + steps: + - checkout + - run: + name: install snapcraft + command: sudo snap install snapcraft --classic + - run: + name: create snapcraft config file + command: | + mkdir -p ~/.config/snapcraft + echo "$SNAPCRAFT_LOGIN_FILE" | base64 -d > ~/.config/snapcraft/snapcraft.cfg + - run: + name: build snap + command: snapcraft --use-lxd + - run: + name: publish snap + command: snapcraft push *.snap --release << parameters.channel >> + + build-and-push-image: + description: build and push docker images to public AWS ECR registry + executor: aws-cli/default + parameters: + profile-name: + type: string + default: "default" + description: AWS profile name to be configured. + + aws-access-key-id: + type: env_var_name + default: AWS_ACCESS_KEY_ID + description: > + AWS access key id for IAM role. Set this to the name of + the environment variable you will set to hold this + value, i.e. AWS_ACCESS_KEY. + + aws-secret-access-key: + type: env_var_name + default: AWS_SECRET_ACCESS_KEY + description: > + AWS secret key for IAM role. Set this to the name of + the environment variable you will set to hold this + value, i.e. AWS_SECRET_ACCESS_KEY. + + region: + type: env_var_name + default: AWS_REGION + description: > + Name of env var storing your AWS region information, + defaults to AWS_REGION + + account-url: + type: env_var_name + default: AWS_ECR_ACCOUNT_URL + description: > + Env var storing Amazon ECR account URL that maps to an AWS account, + e.g. {awsAccountNum}.dkr.ecr.us-west-2.amazonaws.com + defaults to AWS_ECR_ACCOUNT_URL + + dockerfile: + type: string + default: Dockerfile + description: Name of dockerfile to use. Defaults to Dockerfile. + + path: + type: string + default: . + description: Path to the directory containing your Dockerfile and build context. Defaults to . (working directory). + + extra-build-args: + type: string + default: "" + description: > + Extra flags to pass to docker build. For examples, see + https://docs.docker.com/engine/reference/commandline/build + + repo: + type: string + description: Name of an Amazon ECR repository + + tag: + type: string + default: "latest" + description: A comma-separated string containing docker image tags to build and push (default = latest) + + steps: + - run: + name: Confirm that environment variables are set + command: | + if [ -z "$AWS_ACCESS_KEY_ID" ]; then + echo "No AWS_ACCESS_KEY_ID is set. Skipping build-and-push job ..." + circleci-agent step halt + fi + + - aws-cli/setup: + profile-name: <> + aws-access-key-id: <> + aws-secret-access-key: <> + aws-region: <> + + - run: + name: Log into Amazon ECR + command: | + aws ecr-public get-login-password --region $<> --profile <> | docker login --username AWS --password-stdin $<> + + - checkout + + - setup_remote_docker: + version: 19.03.13 + docker_layer_caching: false + + - run: + name: Build docker image + command: | + registry_id=$(echo $<> | sed "s;\..*;;g") + + docker_tag_args="" + IFS="," read -ra DOCKER_TAGS \<<< "<< parameters.tag >>" + for tag in "${DOCKER_TAGS[@]}"; do + docker_tag_args="$docker_tag_args -t $<>/<>:$tag" + done + + docker build \ + <<#parameters.extra-build-args>><><> \ + -f <>/<> \ + $docker_tag_args \ + <> + + - run: + name: Push image to Amazon ECR + command: | + IFS="," read -ra DOCKER_TAGS \<<< "<< parameters.tag >>" + for tag in "${DOCKER_TAGS[@]}"; do + docker push $<>/<>:${tag} + done + + publish-packer-mainnet: + 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 -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-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 + ci: + jobs: + - lint-all: + concurrency: "16" # expend all docker 2xlarge CPUs. + - mod-tidy-check + - gofmt + - gen-check + - docs-check + + [[- range $file := .ItestFiles -]] + [[ with $name := $file | stripSuffix ]] + - test: + name: test-itest-[[ $name ]] + suite: itest-[[ $name ]] + target: "./itests/[[ $file ]]" + [[ end ]] + [[- end -]] + + [[range $suite, $pkgs := .UnitSuites]] + - test: + name: test-[[ $suite ]] + suite: utest-[[ $suite ]] + target: "[[ $pkgs ]]" + [[- end]] + - test: + go-test-flags: "-run=TestMulticoreSDR" + suite: multicore-sdr-check + target: "./extern/sector-storage/ffiwrapper" + proofs-log-test: "1" + - test-conformance: + suite: conformance + codecov-upload: false + target: "./conformance" + - test-conformance: + name: test-conformance-bleeding-edge + codecov-upload: false + suite: conformance-bleeding-edge + target: "./conformance" + vectors-branch: master + - trigger-testplans: + filters: + branches: + only: + - master + - build-debug + - build-all: + filters: + tags: + only: + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + - build-ntwk-calibration: + filters: + tags: + only: + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + - build-ntwk-butterfly: + filters: + tags: + only: + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + - build-ntwk-nerpa: + filters: + tags: + only: + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + - build-lotus-soup + - build-macos: + filters: + branches: + ignore: + - /.*/ + tags: + only: + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + - build-appimage: + filters: + branches: + ignore: + - /.*/ + tags: + only: + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + - publish: + requires: + - build-all + - build-macos + - build-appimage + filters: + branches: + ignore: + - /.*/ + tags: + only: + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + - build-and-push-image: + dockerfile: Dockerfile.lotus + path: . + repo: lotus-dev + tag: '${CIRCLE_SHA1:0:8}' + - publish-packer-mainnet: + requires: + - build-all + filters: + branches: + ignore: + - /.*/ + tags: + only: + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + - publish-packer-calibrationnet: + requires: + - build-ntwk-calibration + filters: + branches: + ignore: + - /.*/ + tags: + only: + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + - publish-packer-butterflynet: + requires: + - build-ntwk-butterfly + filters: + branches: + ignore: + - /.*/ + tags: + only: + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + - publish-packer-nerpanet: + requires: + - build-ntwk-nerpa + filters: + branches: + ignore: + - /.*/ + tags: + only: + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + - publish-snapcraft: + name: publish-snapcraft-stable + channel: stable + filters: + branches: + ignore: + - /.*/ + tags: + only: + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + + nightly: + triggers: + - schedule: + cron: "0 0 * * *" + filters: + branches: + only: + - master + jobs: + - publish-snapcraft: + name: publish-snapcraft-nightly + channel: edge diff --git a/.github/workflows/testground-on-push.yml b/.github/workflows/testground-on-push.yml index 9d58db9626d..2a3c8af1d51 100644 --- a/.github/workflows/testground-on-push.yml +++ b/.github/workflows/testground-on-push.yml @@ -21,7 +21,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: testground run - uses: coryschwartz/testground-github-action@v1.0 + uses: coryschwartz/testground-github-action@v1.1 with: backend_addr: ${{ matrix.backend_addr }} backend_proto: ${{ matrix.backend_proto }} diff --git a/AppImageBuilder.yml b/AppImageBuilder.yml index 48db6893022..19c74e4a26a 100644 --- a/AppImageBuilder.yml +++ b/AppImageBuilder.yml @@ -1,4 +1,3 @@ -# appimage-builder recipe see https://appimage-builder.readthedocs.io for details version: 1 AppDir: path: ./AppDir @@ -6,31 +5,40 @@ AppDir: id: io.filecoin.lotus name: Lotus icon: icon - version: current + version: latest exec: usr/bin/lotus exec_args: $@ apt: arch: amd64 allow_unauthenticated: true sources: - - sourceline: deb http://us.archive.ubuntu.com/ubuntu bionic main restricted - - sourceline: deb http://us.archive.ubuntu.com/ubuntu bionic-updates main restricted - - sourceline: deb http://us.archive.ubuntu.com/ubuntu bionic universe - - sourceline: deb http://us.archive.ubuntu.com/ubuntu bionic-updates universe - - sourceline: deb http://us.archive.ubuntu.com/ubuntu bionic multiverse - - sourceline: deb http://us.archive.ubuntu.com/ubuntu bionic-updates multiverse - - sourceline: deb http://us.archive.ubuntu.com/ubuntu bionic-backports main restricted + - sourceline: deb http://archive.ubuntu.com/ubuntu/ focal main restricted + - sourceline: deb http://archive.ubuntu.com/ubuntu/ focal-updates main restricted + - sourceline: deb http://archive.ubuntu.com/ubuntu/ focal universe + - sourceline: deb http://archive.ubuntu.com/ubuntu/ focal-updates universe + - sourceline: deb http://archive.ubuntu.com/ubuntu/ focal multiverse + - sourceline: deb http://archive.ubuntu.com/ubuntu/ focal-updates multiverse + - sourceline: deb http://archive.ubuntu.com/ubuntu/ focal-backports main restricted universe multiverse - - sourceline: deb http://security.ubuntu.com/ubuntu bionic-security main restricted - - sourceline: deb http://security.ubuntu.com/ubuntu bionic-security universe - - sourceline: deb http://security.ubuntu.com/ubuntu bionic-security multiverse + - sourceline: deb http://security.ubuntu.com/ubuntu focal-security main restricted + - sourceline: deb http://security.ubuntu.com/ubuntu focal-security universe + - sourceline: deb http://security.ubuntu.com/ubuntu focal-security multiverse + - sourceline: deb https://cli-assets.heroku.com/apt ./ + - sourceline: deb http://ppa.launchpad.net/openjdk-r/ppa/ubuntu focal main + - sourceline: deb http://ppa.launchpad.net/git-core/ppa/ubuntu focal main + - sourceline: deb http://archive.canonical.com/ubuntu focal partner include: - - libgcc1 - - libhwloc5 - ocl-icd-libopencl1 + - libhwloc15 exclude: [] files: - include: [] + include: + - /usr/lib/x86_64-linux-gnu/libgcc_s.so.1 + - /usr/lib/x86_64-linux-gnu/libpthread-2.31.so + - /usr/lib/x86_64-linux-gnu/libm-2.31.so + - /usr/lib/x86_64-linux-gnu/libdl-2.31.so + - /usr/lib/x86_64-linux-gnu/libc-2.31.so + - /usr/lib/x86_64-linux-gnu/libudev.so.1.6.17 exclude: - usr/share/man - usr/share/doc/*/README.* diff --git a/CHANGELOG.md b/CHANGELOG.md index 462e5b816a2..11f7d300b9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,146 +1,144 @@ # Lotus changelog -# 1.9.0 / 2021-05-17 +# 1.10.0 / 2021-06-23 -This is an optional Lotus release that introduces various improvements to the sealing, mining, and deal-making processes. +This is a mandatory release of Lotus that introduces Filecoin network v13, codenamed the HyperDrive upgrade. The +Filecoin mainnet will upgrade, which is epoch 892800, on 2021-06-30T22:00:00Z. The network upgrade introduces the +following FIPs: -## Highlights +- [FIP-0008](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0008.md): Add miner batched sector pre-commit method +- [FIP-0011](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0011.md): Remove reward auction from reporting consensus faults +- [FIP-0012](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0012.md): DataCap Top up for FIL+ Client Addresses +- [FIP-0013](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0013.md): Add ProveCommitSectorAggregated method to reduce on-chain congestion +- [FIP-0015](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0015.md): Revert FIP-0009(Exempt Window PoSts from BaseFee burn) -- OpenRPC Support (https://github.com/filecoin-project/lotus/pull/5843) -- Take latency into account when making interactive deals (https://github.com/filecoin-project/lotus/pull/5876) -- Update go-commp-utils for >10x faster client commp calculation (https://github.com/filecoin-project/lotus/pull/5892) -- add `lotus client cancel-retrieval` cmd to lotus CLI (https://github.com/filecoin-project/lotus/pull/5871) -- add `inspect-deal` command to `lotus client` (https://github.com/filecoin-project/lotus/pull/5833) -- Local retrieval support (https://github.com/filecoin-project/lotus/pull/5917) -- go-fil-markets v1.1.9 -> v1.2.5 - - For a detailed changelog see https://github.com/filecoin-project/go-fil-markets/blob/master/CHANGELOG.md -- rust-fil-proofs v5.4.1 -> v7.0.1 - - For a detailed changelog see https://github.com/filecoin-project/rust-fil-proofs/blob/master/CHANGELOG.md +Note that this release is built on top of Lotus v1.9.0. Enterprising users can use the `master` branch of Lotus to get the latest functionality, including all changes in this release candidate. -## Changes -- storagefsm: Apply global events even in broken states (https://github.com/filecoin-project/lotus/pull/5962) -- Default the AlwaysKeepUnsealedCopy flag to true (https://github.com/filecoin-project/lotus/pull/5743) -- splitstore: compact hotstore prior to garbage collection (https://github.com/filecoin-project/lotus/pull/5778) -- ipfs-force bootstrapper update (https://github.com/filecoin-project/lotus/pull/5799) -- better logging when unsealing fails (https://github.com/filecoin-project/lotus/pull/5851) -- perf: add cache for gas permium estimation (https://github.com/filecoin-project/lotus/pull/5709) -- backupds: Compact log on restart (https://github.com/filecoin-project/lotus/pull/5875) -- backupds: Improve truncated log handling (https://github.com/filecoin-project/lotus/pull/5891) -- State CLI improvements (State CLI improvements) -- API proxy struct codegen (https://github.com/filecoin-project/lotus/pull/5854) -- move DI stuff for paychmgr into modules (https://github.com/filecoin-project/lotus/pull/5791) -- Implement Event observer and Settings for 3rd party dep injection (https://github.com/filecoin-project/lotus/pull/5693) -- Export developer and network commands for consumption by derivatives of Lotus (https://github.com/filecoin-project/lotus/pull/5864) -- mock sealer: Simulate randomness sideeffects (https://github.com/filecoin-project/lotus/pull/5805) -- localstorage: Demote reservation stat error to debug (https://github.com/filecoin-project/lotus/pull/5976) -- shed command to unpack miner info dumps (https://github.com/filecoin-project/lotus/pull/5800) -- Add two utils to Lotus-shed (https://github.com/filecoin-project/lotus/pull/5867) -- add shed election estimate command (https://github.com/filecoin-project/lotus/pull/5092) -- Add --actor flag in lotus-shed sectors terminate (https://github.com/filecoin-project/lotus/pull/5819) -- Move lotus mpool clear to lotus-shed (https://github.com/filecoin-project/lotus/pull/5900) -- Centralize everything on ipfs/go-log/v2 (https://github.com/filecoin-project/lotus/pull/5974) -- expose NextID from nice market actor interface (https://github.com/filecoin-project/lotus/pull/5850) -- add available options for perm on error (https://github.com/filecoin-project/lotus/pull/5814) -- API docs clarification: Document StateSearchMsg replaced message behavior (https://github.com/filecoin-project/lotus/pull/5838) -- api: Document StateReplay replaced message behavior (https://github.com/filecoin-project/lotus/pull/5840) -- add godocs to miner objects (https://github.com/filecoin-project/lotus/pull/2184) -- Add description to the client deal CLI command (https://github.com/filecoin-project/lotus/pull/5999) -- lint: don't skip builtin (https://github.com/filecoin-project/lotus/pull/5881) -- use deal duration from actors (https://github.com/filecoin-project/lotus/pull/5270) -- remote calc winningpost proof (https://github.com/filecoin-project/lotus/pull/5884) -- packer: other network images (https://github.com/filecoin-project/lotus/pull/5930) -- Convert the chainstore lock to RW (https://github.com/filecoin-project/lotus/pull/5971) -- Remove CachedBlockstore (https://github.com/filecoin-project/lotus/pull/5972) -- remove messagepool CapGasFee duplicate code (https://github.com/filecoin-project/lotus/pull/5992) -- Add a mining-heartbeat INFO line at every epoch (https://github.com/filecoin-project/lotus/pull/6183) -- chore(ci): Enable build on RC tags (https://github.com/filecoin-project/lotus/pull/6245) -- Upgrade nerpa to actor v4 and bump the version to rc4 (https://github.com/filecoin-project/lotus/pull/6249) -## Fixes -- return buffers after canceling badger operation (https://github.com/filecoin-project/lotus/pull/5796) -- avoid holding a lock while calling the View callback (https://github.com/filecoin-project/lotus/pull/5792) -- storagefsm: Trigger input processing when below limits (https://github.com/filecoin-project/lotus/pull/5801) -- After importing a previously deleted key, be able to delete it again (https://github.com/filecoin-project/lotus/pull/4653) -- fix StateManager.Replay on reward actor (https://github.com/filecoin-project/lotus/pull/5804) -- make sure atomic 64bit fields are 64bit aligned (https://github.com/filecoin-project/lotus/pull/5794) -- Import secp sigs in paych tests (https://github.com/filecoin-project/lotus/pull/5879) -- fix ci build-macos (https://github.com/filecoin-project/lotus/pull/5934) -- Fix creation of remainder account when it's not a multisig (https://github.com/filecoin-project/lotus/pull/5807) -- Fix fallback chainstore (https://github.com/filecoin-project/lotus/pull/6003) -- fix 4857: show help for set-addrs (https://github.com/filecoin-project/lotus/pull/5943) -- fix health report (https://github.com/filecoin-project/lotus/pull/6011) -- fix(ci): Use recent ubuntu LTS release; Update release params ((https://github.com/filecoin-project/lotus/pull/6011)) +## Proof batching and aggregation -# 1.9.0-rc4 / 2021-05-13 +FIPs [0008](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0008.md) and [0013](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0013.md) combine to allow for a significant increase in the rate of onboarding storage on the Filecoin network. This aims to lead to more useful data being stored on the network, reduced network congestion, and lower network base fee. -This is an optional Lotus release that introduces various improvements to the sealing, mining, and deal-making processes. +**Check out the documentation [here](https://docs.filecoin.io/mine/lotus/miner-configuration/#precommitsectorsbatch) for details on the new Lotus miner sealing config options, [here](https://docs.filecoin.io/mine/lotus/miner-configuration/#fees-section) for fee config options, and explanations of the new features.** -## Highlights +Note: + - We recommend to keep `PreCommitSectorsBatch` as 1. + - We recommend miners to set `PreCommitBatchWait` lower than 30 hours. + - We recommend miners to set a longer `CommitBatchSlack` and `PreCommitBatchSlack` to prevent message failures + due to expirations. -- OpenRPC Support (https://github.com/filecoin-project/lotus/pull/5843) -- Take latency into account when making interactive deals (https://github.com/filecoin-project/lotus/pull/5876) -- Update go-commp-utils for >10x faster client commp calculation (https://github.com/filecoin-project/lotus/pull/5892) -- add `lotus client cancel-retrieval` cmd to lotus CLI (https://github.com/filecoin-project/lotus/pull/5871) -- add `inspect-deal` command to `lotus client` (https://github.com/filecoin-project/lotus/pull/5833) -- Local retrieval support (https://github.com/filecoin-project/lotus/pull/5917) -- go-fil-markets v1.1.9 -> v1.2.5 - - For a detailed changelog see https://github.com/filecoin-project/go-fil-markets/blob/master/CHANGELOG.md -- rust-fil-proofs v5.4.1 -> v7.0.1 - - For a detailed changelog see https://github.com/filecoin-project/rust-fil-proofs/blob/master/CHANGELOG.md +### Projected state tree growth -## Changes -- storagefsm: Apply global events even in broken states (https://github.com/filecoin-project/lotus/pull/5962) -- Default the AlwaysKeepUnsealedCopy flag to true (https://github.com/filecoin-project/lotus/pull/5743) -- splitstore: compact hotstore prior to garbage collection (https://github.com/filecoin-project/lotus/pull/5778) -- ipfs-force bootstrapper update (https://github.com/filecoin-project/lotus/pull/5799) -- better logging when unsealing fails (https://github.com/filecoin-project/lotus/pull/5851) -- perf: add cache for gas permium estimation (https://github.com/filecoin-project/lotus/pull/5709) -- backupds: Compact log on restart (https://github.com/filecoin-project/lotus/pull/5875) -- backupds: Improve truncated log handling (https://github.com/filecoin-project/lotus/pull/5891) -- State CLI improvements (State CLI improvements) -- API proxy struct codegen (https://github.com/filecoin-project/lotus/pull/5854) -- move DI stuff for paychmgr into modules (https://github.com/filecoin-project/lotus/pull/5791) -- Implement Event observer and Settings for 3rd party dep injection (https://github.com/filecoin-project/lotus/pull/5693) -- Export developer and network commands for consumption by derivatives of Lotus (https://github.com/filecoin-project/lotus/pull/5864) -- mock sealer: Simulate randomness sideeffects (https://github.com/filecoin-project/lotus/pull/5805) -- localstorage: Demote reservation stat error to debug (https://github.com/filecoin-project/lotus/pull/5976) -- shed command to unpack miner info dumps (https://github.com/filecoin-project/lotus/pull/5800) -- Add two utils to Lotus-shed (https://github.com/filecoin-project/lotus/pull/5867) -- add shed election estimate command (https://github.com/filecoin-project/lotus/pull/5092) -- Add --actor flag in lotus-shed sectors terminate (https://github.com/filecoin-project/lotus/pull/5819) -- Move lotus mpool clear to lotus-shed (https://github.com/filecoin-project/lotus/pull/5900) -- Centralize everything on ipfs/go-log/v2 (https://github.com/filecoin-project/lotus/pull/5974) -- expose NextID from nice market actor interface (https://github.com/filecoin-project/lotus/pull/5850) -- add available options for perm on error (https://github.com/filecoin-project/lotus/pull/5814) -- API docs clarification: Document StateSearchMsg replaced message behavior (https://github.com/filecoin-project/lotus/pull/5838) -- api: Document StateReplay replaced message behavior (https://github.com/filecoin-project/lotus/pull/5840) -- add godocs to miner objects (https://github.com/filecoin-project/lotus/pull/2184) -- Add description to the client deal CLI command (https://github.com/filecoin-project/lotus/pull/5999) -- lint: don't skip builtin (https://github.com/filecoin-project/lotus/pull/5881) -- use deal duration from actors (https://github.com/filecoin-project/lotus/pull/5270) -- remote calc winningpost proof (https://github.com/filecoin-project/lotus/pull/5884) -- packer: other network images (https://github.com/filecoin-project/lotus/pull/5930) -- Convert the chainstore lock to RW (https://github.com/filecoin-project/lotus/pull/5971) -- Remove CachedBlockstore (https://github.com/filecoin-project/lotus/pull/5972) -- remove messagepool CapGasFee duplicate code (https://github.com/filecoin-project/lotus/pull/5992) -- Add a mining-heartbeat INFO line at every epoch (https://github.com/filecoin-project/lotus/pull/6183) -- chore(ci): Enable build on RC tags (https://github.com/filecoin-project/lotus/pull/6245) -- Upgrade nerpa to actor v4 and bump the version to rc4 (https://github.com/filecoin-project/lotus/pull/6249) -## Fixes -- return buffers after canceling badger operation (https://github.com/filecoin-project/lotus/pull/5796) -- avoid holding a lock while calling the View callback (https://github.com/filecoin-project/lotus/pull/5792) -- storagefsm: Trigger input processing when below limits (https://github.com/filecoin-project/lotus/pull/5801) -- After importing a previously deleted key, be able to delete it again (https://github.com/filecoin-project/lotus/pull/4653) -- fix StateManager.Replay on reward actor (https://github.com/filecoin-project/lotus/pull/5804) -- make sure atomic 64bit fields are 64bit aligned (https://github.com/filecoin-project/lotus/pull/5794) -- Import secp sigs in paych tests (https://github.com/filecoin-project/lotus/pull/5879) -- fix ci build-macos (https://github.com/filecoin-project/lotus/pull/5934) -- Fix creation of remainder account when it's not a multisig (https://github.com/filecoin-project/lotus/pull/5807) -- Fix fallback chainstore (https://github.com/filecoin-project/lotus/pull/6003) -- fix 4857: show help for set-addrs (https://github.com/filecoin-project/lotus/pull/5943) -- fix health report (https://github.com/filecoin-project/lotus/pull/6011) +In order to validate the Hyperdrive changes, we wrote a simulation to seal as many sectors as quickly as possible, assuming the same number and mix of 32GiB and 64GiB miners as the current network. + +Given these assumptions: + +- We'd expect a network storage growth rate of around 530PiB per day. 😳 🎉 🥳 😅 +- We'd expect network bandwidth dedicated to `SubmitWindowedPoSt` to grow by about 0.02% per day. +- We'd expect the [state-tree](https://spec.filecoin.io/#section-systems.filecoin_vm.state_tree) (and therefore [snapshot](https://docs.filecoin.io/get-started/lotus/chain/#lightweight-snapshot)) size to grow by 1.16GiB per day. + - Nearly all of the state-tree growth is expected to come from new sector metadata. +- We'd expect the daily lotus datastore growth rate to increase by about 10-15% (from current ~21GiB/day). + - Most "growth" of the lotus datastore is due to "churn", historical data that's no longer referenced by the latest state-tree. + +### Future improvements +Various Lotus improvements are planned moving forward to mitigate the effects of the growing state tree size. The primary improvement is the [Lotus splitstore](https://github.com/filecoin-project/lotus/discussions/5788), which will soon be enabled by default. The feature allows for [online garbage collection](https://github.com/filecoin-project/lotus/issues/6577) for nodes that do not seek to maintain full chain and state history, thus eliminating the need for users to delete their datastores and sync from snapshots. -# 1.9.0-rc2 / 2021-04-30 +Other improvements including better compressed snapshots, faster pre-migrations, and improved chain exports are in the roadmap. + +## WindowPost base fee burn + +Included in the HyperDrive upgrade is [FIP-0015](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0015.md) which eliminates the special-case gas treatment of `SubmitWindowedPoSt` messages that was introduced in [FIP-0009](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0009.md). Although `SubmitWindowedPoSt` messages will be relatively cheap, thanks to the introduction of optimistic acceptance of these proofs in [FIP-0010](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0010.md), storage providers should pay attention to their `MaxWindowPoStGasFee` config option: too low and PoSts may not land on chain; too high and they may cost an exorbitant amount! + +## Changelog + +### New Features + +- Implement FIP-0015 ([filecoin-project/lotus#6361](https://github.com/filecoin-project/lotus/pull/6361)) +- Integrate FIP0013 and FIP0008 ([filecoin-project/lotus#6235](https://github.com/filecoin-project/lotus/pull/6235)) + - [Configuration docs and cli examples](https://docs.filecoin.io/mine/lotus/miner-configuration/#precommitsectorsbatch) + - [cli docs](https://github.com/filecoin-project/lotus/blob/master/documentation/en/cli-lotus-miner.md#lotus-miner-sectors-batching) + - Introduce gas prices for aggregate verifications ([filecoin-project/lotus#6347](https://github.com/filecoin-project/lotus/pull/6347)) +- Introduce v5 actors ([filecoin-project/lotus#6195](https://github.com/filecoin-project/lotus/pull/6195)) +- Robustify commit batcher ([filecoin-project/lotus#6367](https://github.com/filecoin-project/lotus/pull/6367)) +- Always flush when timer goes off ([filecoin-project/lotus#6563](https://github.com/filecoin-project/lotus/pull/6563)) +- Update default fees for aggregates ([filecoin-project/lotus#6548](https://github.com/filecoin-project/lotus/pull/6548)) +- sealing: Early finalization option ([filecoin-project/lotus#6452](https://github.com/filecoin-project/lotus/pull/6452)) + - `./lotus-miner/config.toml/[Sealing.FinalizeEarly]`: default to false. Enable if you want to FinalizeSector before commiting +- Add filplus utils to CLI ([filecoin-project/lotus#6351](https://github.com/filecoin-project/lotus/pull/6351)) + - cli doc can be found [here](https://github.com/filecoin-project/lotus/blob/master/documentation/en/cli-lotus.md#lotus-filplus) +- Add miner-side MaxDealStartDelay config ([filecoin-project/lotus#6576](https://github.com/filecoin-project/lotus/pull/6576)) + + +### Bug Fixes +- chainstore: Don't take heaviestLk with backlogged reorgCh ([filecoin-project/lotus#6526](https://github.com/filecoin-project/lotus/pull/6526)) +- Backport #6041 - storagefsm: Fix batch deal packing behavior ([filecoin-project/lotus#6519](https://github.com/filecoin-project/lotus/pull/6519)) +- backport: pick the correct partitions-per-post limit ([filecoin-project/lotus#6503](https://github.com/filecoin-project/lotus/pull/6503)) +- failed sectors should be added into res correctly ([filecoin-project/lotus#6472](https://github.com/filecoin-project/lotus/pull/6472)) +- sealing: Fix restartSectors race ([filecoin-project/lotus#6491](https://github.com/filecoin-project/lotus/pull/6491)) +- Fund miners with the aggregate fee when ProveCommitting ([filecoin-project/lotus#6428](https://github.com/filecoin-project/lotus/pull/6428)) +- Commit and Precommit batcher cannot share a getSectorDeadline method ([filecoin-project/lotus#6416](https://github.com/filecoin-project/lotus/pull/6416)) +- Fix supported proof type manipulations for v5 actors ([filecoin-project/lotus#6366](https://github.com/filecoin-project/lotus/pull/6366)) +- events: Fix handling of multiple matched events per epoch ([filecoin-project/lotus#6362](https://github.com/filecoin-project/lotus/pull/6362)) +- Fix randomness fetching around null blocks ([filecoin-project/lotus#6240](https://github.com/filecoin-project/lotus/pull/6240)) + +### Improvements +- Appimage v1.10.0 rc3 ([filecoin-project/lotus#6492](https://github.com/filecoin-project/lotus/pull/6492)) +- Expand on Drand change testing ([filecoin-project/lotus#6500](https://github.com/filecoin-project/lotus/pull/6500)) +- Backport Fix logging around mineOne ([filecoin-project/lotus#6499](https://github.com/filecoin-project/lotus/pull/6499)) +- mpool: Add more metrics ([filecoin-project/lotus#6453](https://github.com/filecoin-project/lotus/pull/6453)) +- Merge backported PRs into v1.10 release branch ([filecoin-project/lotus#6436](https://github.com/filecoin-project/lotus/pull/6436)) +- Fix tests ([filecoin-project/lotus#6371](https://github.com/filecoin-project/lotus/pull/6371)) +- Extend the default deal start epoch delay ([filecoin-project/lotus#6350](https://github.com/filecoin-project/lotus/pull/6350)) +- sealing: Wire up context to batchers ([filecoin-project/lotus#6497](https://github.com/filecoin-project/lotus/pull/6497)) +- Improve address resolution for messages ([filecoin-project/lotus#6364](https://github.com/filecoin-project/lotus/pull/6364)) + +### Dependency Updates +- Proofs v8.0.2 ([filecoin-project/lotus#6524](https://github.com/filecoin-project/lotus/pull/6524)) +- Update to fixed Bellperson ([filecoin-project/lotus#6480](https://github.com/filecoin-project/lotus/pull/6480)) +- Update to go-praamfetch with fslocks ([filecoin-project/lotus#6473](https://github.com/filecoin-project/lotus/pull/6473)) +- Update ffi with fixed multicore sdr support ([filecoin-project/lotus#6471](https://github.com/filecoin-project/lotus/pull/6471)) +- github.com/filecoin-project/go-paramfetch (v0.0.2-0.20200701152213-3e0f0afdc261 -> v0.0.2-0.20210614165157-25a6c7769498) +- github.com/filecoin-project/specs-actors/v5 (v5.0.0-20210512015452-4fe3889fff57 -> v5.0.0) +- github.com/filecoin-project/go-hamt-ipld/v3 (v3.0.1 -> v3.1.0) +- github.com/ipfs/go-log/v2 (v2.1.2-0.20200626104915-0016c0b4b3e4 -> v2.1.3) +- github.com/filecoin-project/go-amt-ipld/v3 (v3.0.0 -> v3.1.0) + +### Network Version v13 HyperDrive Upgrade +- Set HyperDrive upgrade epoch ([filecoin-project/lotus#6565](https://github.com/filecoin-project/lotus/pull/6565)) +- version bump to lotus v1.10.0-rc6 ([filecoin-project/lotus#6529](https://github.com/filecoin-project/lotus/pull/6529)) +- Upgrade epochs for calibration reset ([filecoin-project/lotus#6528](https://github.com/filecoin-project/lotus/pull/6528)) +- Lotus version 1.10.0-rc5 ([filecoin-project/lotus#6504](https://github.com/filecoin-project/lotus/pull/6504)) +- Merge releases into v1.10 release ([filecoin-project/lotus#6494](https://github.com/filecoin-project/lotus/pull/6494)) +- update lotus to v1.10.0-rc3 ([filecoin-project/lotus#6481](https://github.com/filecoin-project/lotus/pull/6481)) +- updated configuration comments for docs +- Lotus version 1.10.0-rc2 ([filecoin-project/lotus#6443](https://github.com/filecoin-project/lotus/pull/6443)) +- Set ntwk v13 HyperDrive Calibration upgrade epoch ([filecoin-project/lotus#6442](https://github.com/filecoin-project/lotus/pull/6442)) + + +## Contributors + +💙Thank you to all the contributors! + +| Contributor | Commits | Lines ± | Files Changed | +|--------------------|---------|-------------|---------------| +| @magik6k | 81 | +9606/-1536 | 361 | +| @arajasek | 41 | +6543/-679 | 189 | +| @ZenGround0 | 11 | +4074/-727 | 110 | +| @anorth | 10 | +2035/-1177 | 55 | +| @iand | 1 | +779/-12 | 5 | +| @frrist | 2 | +722/-6 | 6 | +| @Stebalien | 6 | +368/-24 | 15 | +| @jennijuju | 11 | +204/-111 | 19 | +| @vyzo | 6 | +155/-66 | 13 | +| @coryschwartz | 10 | +171/-27 | 14 | +| @Kubuxu | 4 | +177/-13 | 7 | +| @ribasushi | 4 | +65/-42 | 5 | +| @travisperson | 2 | +11/-11 | 4 | +| @kirk-baird | 1 | +1/-5 | 1 | +| @wangchao | 2 | +3/-2 | 2 | + + +# 1.9.0 / 2021-05-17 This is an optional Lotus release that introduces various improvements to the sealing, mining, and deal-making processes. @@ -154,7 +152,7 @@ This is an optional Lotus release that introduces various improvements to the se - Local retrieval support (https://github.com/filecoin-project/lotus/pull/5917) - go-fil-markets v1.1.9 -> v1.2.5 - For a detailed changelog see https://github.com/filecoin-project/go-fil-markets/blob/master/CHANGELOG.md -- rust-fil-proofs v5.4.1 -> v7 +- rust-fil-proofs v5.4.1 -> v7.0.1 - For a detailed changelog see https://github.com/filecoin-project/rust-fil-proofs/blob/master/CHANGELOG.md ## Changes @@ -192,7 +190,9 @@ This is an optional Lotus release that introduces various improvements to the se - Convert the chainstore lock to RW (https://github.com/filecoin-project/lotus/pull/5971) - Remove CachedBlockstore (https://github.com/filecoin-project/lotus/pull/5972) - remove messagepool CapGasFee duplicate code (https://github.com/filecoin-project/lotus/pull/5992) - +- Add a mining-heartbeat INFO line at every epoch (https://github.com/filecoin-project/lotus/pull/6183) +- chore(ci): Enable build on RC tags (https://github.com/filecoin-project/lotus/pull/6245) +- Upgrade nerpa to actor v4 and bump the version to rc4 (https://github.com/filecoin-project/lotus/pull/6249) ## Fixes - return buffers after canceling badger operation (https://github.com/filecoin-project/lotus/pull/5796) - avoid holding a lock while calling the View callback (https://github.com/filecoin-project/lotus/pull/5792) @@ -206,6 +206,7 @@ This is an optional Lotus release that introduces various improvements to the se - Fix fallback chainstore (https://github.com/filecoin-project/lotus/pull/6003) - fix 4857: show help for set-addrs (https://github.com/filecoin-project/lotus/pull/5943) - fix health report (https://github.com/filecoin-project/lotus/pull/6011) +- fix(ci): Use recent ubuntu LTS release; Update release params ((https://github.com/filecoin-project/lotus/pull/6011)) # 1.8.0 / 2021-04-05 diff --git a/Makefile b/Makefile index 11180f8b03c..1e7cc4cc0fa 100644 --- a/Makefile +++ b/Makefile @@ -42,7 +42,7 @@ BUILD_DEPS+=build/.filecoin-install CLEAN+=build/.filecoin-install ffi-version-check: - @[[ "$$(awk '/const Version/{print $$5}' extern/filecoin-ffi/version.go)" -eq 2 ]] || (echo "FFI version mismatch, update submodules"; exit 1) + @[[ "$$(awk '/const Version/{print $$5}' extern/filecoin-ffi/version.go)" -eq 3 ]] || (echo "FFI version mismatch, update submodules"; exit 1) BUILD_DEPS+=ffi-version-check .PHONY: ffi-version-check @@ -80,6 +80,9 @@ nerpanet: build-devnets butterflynet: GOFLAGS+=-tags=butterflynet butterflynet: build-devnets +interopnet: GOFLAGS+=-tags=interopnet +interopnet: build-devnets + lotus: $(BUILD_DEPS) rm -f lotus go build $(GOFLAGS) -o lotus ./cmd/lotus @@ -361,7 +364,7 @@ docsgen-openrpc-worker: docsgen-openrpc-bin .PHONY: docsgen docsgen-md-bin docsgen-openrpc-bin -gen: actors-gen type-gen method-gen docsgen api-gen +gen: actors-gen type-gen method-gen docsgen api-gen circleci @echo ">>> IF YOU'VE MODIFIED THE CLI, REMEMBER TO ALSO MAKE docsgen-cli" .PHONY: gen @@ -376,3 +379,6 @@ docsgen-cli: lotus lotus-miner lotus-worker print-%: @echo $*=$($*) + +circleci: + go generate -x ./.circleci \ No newline at end of file diff --git a/README.md b/README.md index 76183883468..0218e87e952 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Lotus is an implementation of the Filecoin Distributed Storage Network. For more ## Building & Documentation -For instructions on how to build, install and setup lotus, please visit [https://docs.filecoin.io/get-started/lotus](https://docs.filecoin.io/get-started/lotus/). +For complete instructions on how to build, install and setup lotus, please visit [https://docs.filecoin.io/get-started/lotus](https://docs.filecoin.io/get-started/lotus/). Basic build instructions can be found further down in this readme. ## Reporting a Vulnerability @@ -50,6 +50,88 @@ When implementing a change: 7. Title the PR in a meaningful way and describe the rationale and the thought process in the PR description. 8. Write clean, thoughtful, and detailed [commit messages](https://chris.beams.io/posts/git-commit/). This is even more important than the PR description, because commit messages are stored _inside_ the Git history. One good rule is: if you are happy posting the commit message as the PR description, then it's a good commit message. +## Basic Build Instructions +**System-specific Software Dependencies**: + +Building Lotus requires some system dependencies, usually provided by your distribution. + +Ubuntu/Debian: +``` +sudo apt install mesa-opencl-icd ocl-icd-opencl-dev gcc git bzr jq pkg-config curl clang build-essential hwloc libhwloc-dev wget -y && sudo apt upgrade -y +``` + +Fedora: +``` +sudo dnf -y install gcc make git bzr jq pkgconfig mesa-libOpenCL mesa-libOpenCL-devel opencl-headers ocl-icd ocl-icd-devel clang llvm wget hwloc libhwloc-dev +``` + +For other distributions you can find the required dependencies [here.](https://docs.filecoin.io/get-started/lotus/installation/#system-specific) For instructions specific to macOS, you can find them [here.](https://docs.filecoin.io/get-started/lotus/installation/#macos) + +#### Go + +To build Lotus, you need a working installation of [Go 1.16.4 or higher](https://golang.org/dl/): + +```bash +wget -c https://golang.org/dl/go1.16.4.linux-amd64.tar.gz -O - | sudo tar -xz -C /usr/local +``` + +**TIP:** +You'll need to add `/usr/local/go/bin` to your path. For most Linux distributions you can run something like: + +```shell +echo "export PATH=$PATH:/usr/local/go/bin" >> ~/.bashrc && source ~/.bashrc +``` + +See the [official Golang installation instructions](https://golang.org/doc/install) if you get stuck. + +### Build and install Lotus + +Once all the dependencies are installed, you can build and install the Lotus suite (`lotus`, `lotus-miner`, and `lotus-worker`). + +1. Clone the repository: + + ```sh + git clone https://github.com/filecoin-project/lotus.git + cd lotus/ + ``` + +Note: The default branch `master` is the dev branch where the latest new features, bug fixes and improvement are in. However, if you want to run lotus on Filecoin mainnet and want to run a production-ready lotus, get the latest release[ here](https://github.com/filecoin-project/lotus/releases). + +2. To join mainnet, checkout the [latest release](https://github.com/filecoin-project/lotus/releases). + + If you are changing networks from a previous Lotus installation or there has been a network reset, read the [Switch networks guide](https://docs.filecoin.io/get-started/lotus/switch-networks/) before proceeding. + + For networks other than mainnet, look up the current branch or tag/commit for the network you want to join in the [Filecoin networks dashboard](https://network.filecoin.io), then build Lotus for your specific network below. + + ```sh + git checkout + # For example: + git checkout # tag for a release + ``` + + Currently, the latest code on the _master_ branch corresponds to mainnet. + +3. If you are in China, see "[Lotus: tips when running in China](https://docs.filecoin.io/get-started/lotus/tips-running-in-china/)". +4. This build instruction uses the prebuilt proofs binaries. If you want to build the proof binaries from source check the [complete instructions](https://docs.filecoin.io/get-started/lotus/installation/#build-and-install-lotus). Note, if you are building the proof binaries from source, [installing rustup](https://docs.filecoin.io/get-started/lotus/installation/#rustup) is also needed. + +5. Build and install Lotus: + + ```sh + make clean all #mainnet + + # Or to join a testnet or devnet: + make clean calibnet # Calibration with min 32GiB sectors + make clean nerpanet # Nerpa with min 512MiB sectors + + sudo make install + ``` + + This will put `lotus`, `lotus-miner` and `lotus-worker` in `/usr/local/bin`. + + `lotus` will use the `$HOME/.lotus` folder by default for storage (configuration, chain data, wallets, etc). See [advanced options](https://docs.filecoin.io/get-started/lotus/configuration-and-advanced-usage/) for information on how to customize the Lotus folder. + +6. You should now have Lotus installed. You can now [start the Lotus daemon and sync the chain](https://docs.filecoin.io/get-started/lotus/installation/#start-the-lotus-daemon-and-sync-the-chain). + ## License Dual-licensed under [MIT](https://github.com/filecoin-project/lotus/blob/master/LICENSE-MIT) + [Apache 2.0](https://github.com/filecoin-project/lotus/blob/master/LICENSE-APACHE) diff --git a/api/api_full.go b/api/api_full.go index 328c2fe01b0..8f79f5a9111 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -345,6 +345,10 @@ type FullNode interface { // ClientRetrieveWithEvents initiates the retrieval of a file, as specified in the order, and provides a channel // of status updates. ClientRetrieveWithEvents(ctx context.Context, order RetrievalOrder, ref *FileRef) (<-chan marketevents.RetrievalEvent, error) //perm:admin + // ClientListRetrievals returns information about retrievals made by the local client + ClientListRetrievals(ctx context.Context) ([]RetrievalInfo, error) //perm:write + // ClientGetRetrievalUpdates returns status of updated retrieval deals + ClientGetRetrievalUpdates(ctx context.Context) (<-chan RetrievalInfo, error) //perm:write // 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 diff --git a/api/api_worker.go b/api/api_worker.go index e834b792cfe..4553c30e095 100644 --- a/api/api_worker.go +++ b/api/api_worker.go @@ -2,7 +2,6 @@ package api import ( "context" - "io" "github.com/google/uuid" "github.com/ipfs/go-cid" @@ -43,7 +42,6 @@ type Worker interface { ReleaseUnsealed(ctx context.Context, sector storage.SectorRef, safeToFree []storage.Range) (storiface.CallID, error) //perm:admin MoveStorage(ctx context.Context, sector storage.SectorRef, types storiface.SectorFileType) (storiface.CallID, error) //perm:admin UnsealPiece(context.Context, storage.SectorRef, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) (storiface.CallID, error) //perm:admin - ReadPiece(context.Context, io.Writer, storage.SectorRef, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize) (storiface.CallID, error) //perm:admin Fetch(context.Context, storage.SectorRef, storiface.SectorFileType, storiface.PathType, storiface.AcquireMode) (storiface.CallID, error) //perm:admin TaskDisable(ctx context.Context, tt sealtasks.TaskType) error //perm:admin diff --git a/api/mocks/mock_full.go b/api/mocks/mock_full.go index efe5eb89d7f..bb83a88a242 100644 --- a/api/mocks/mock_full.go +++ b/api/mocks/mock_full.go @@ -37,30 +37,30 @@ import ( protocol "github.com/libp2p/go-libp2p-core/protocol" ) -// MockFullNode is a mock of FullNode interface +// MockFullNode is a mock of FullNode interface. type MockFullNode struct { ctrl *gomock.Controller recorder *MockFullNodeMockRecorder } -// MockFullNodeMockRecorder is the mock recorder for MockFullNode +// MockFullNodeMockRecorder is the mock recorder for MockFullNode. type MockFullNodeMockRecorder struct { mock *MockFullNode } -// NewMockFullNode creates a new mock instance +// 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 +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockFullNode) EXPECT() *MockFullNodeMockRecorder { return m.recorder } -// AuthNew mocks base method +// 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) @@ -69,13 +69,13 @@ func (m *MockFullNode) AuthNew(arg0 context.Context, arg1 []auth.Permission) ([] return ret0, ret1 } -// AuthNew indicates an expected call of AuthNew +// 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 +// 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) @@ -84,13 +84,13 @@ func (m *MockFullNode) AuthVerify(arg0 context.Context, arg1 string) ([]auth.Per return ret0, ret1 } -// AuthVerify indicates an expected call of AuthVerify +// 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 +// 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) @@ -99,13 +99,13 @@ func (m *MockFullNode) BeaconGetEntry(arg0 context.Context, arg1 abi.ChainEpoch) return ret0, ret1 } -// BeaconGetEntry indicates an expected call of BeaconGetEntry +// 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 +// 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) @@ -113,13 +113,13 @@ func (m *MockFullNode) ChainDeleteObj(arg0 context.Context, arg1 cid.Cid) error return ret0 } -// ChainDeleteObj indicates an expected call of ChainDeleteObj +// 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 +// 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) @@ -128,13 +128,13 @@ func (m *MockFullNode) ChainExport(arg0 context.Context, arg1 abi.ChainEpoch, ar return ret0, ret1 } -// ChainExport indicates an expected call of ChainExport +// 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 +// 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) @@ -143,13 +143,13 @@ func (m *MockFullNode) ChainGetBlock(arg0 context.Context, arg1 cid.Cid) (*types return ret0, ret1 } -// ChainGetBlock indicates an expected call of ChainGetBlock +// 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 +// 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) @@ -158,13 +158,13 @@ func (m *MockFullNode) ChainGetBlockMessages(arg0 context.Context, arg1 cid.Cid) return ret0, ret1 } -// ChainGetBlockMessages indicates an expected call of ChainGetBlockMessages +// 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 +// 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) @@ -173,13 +173,13 @@ func (m *MockFullNode) ChainGetGenesis(arg0 context.Context) (*types.TipSet, err return ret0, ret1 } -// ChainGetGenesis indicates an expected call of ChainGetGenesis +// 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 +// 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) @@ -188,13 +188,13 @@ func (m *MockFullNode) ChainGetMessage(arg0 context.Context, arg1 cid.Cid) (*typ return ret0, ret1 } -// ChainGetMessage indicates an expected call of ChainGetMessage +// 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 +// 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) @@ -203,13 +203,13 @@ func (m *MockFullNode) ChainGetNode(arg0 context.Context, arg1 string) (*api.Ipl return ret0, ret1 } -// ChainGetNode indicates an expected call of ChainGetNode +// 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 +// 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) @@ -218,13 +218,13 @@ func (m *MockFullNode) ChainGetParentMessages(arg0 context.Context, arg1 cid.Cid return ret0, ret1 } -// ChainGetParentMessages indicates an expected call of ChainGetParentMessages +// 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 +// 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) @@ -233,13 +233,13 @@ func (m *MockFullNode) ChainGetParentReceipts(arg0 context.Context, arg1 cid.Cid return ret0, ret1 } -// ChainGetParentReceipts indicates an expected call of ChainGetParentReceipts +// 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 +// 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) @@ -248,13 +248,13 @@ func (m *MockFullNode) ChainGetPath(arg0 context.Context, arg1, arg2 types.TipSe return ret0, ret1 } -// ChainGetPath indicates an expected call of ChainGetPath +// 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 +// 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) @@ -263,13 +263,13 @@ func (m *MockFullNode) ChainGetRandomnessFromBeacon(arg0 context.Context, arg1 t return ret0, ret1 } -// ChainGetRandomnessFromBeacon indicates an expected call of ChainGetRandomnessFromBeacon +// 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 +// 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) @@ -278,13 +278,13 @@ func (m *MockFullNode) ChainGetRandomnessFromTickets(arg0 context.Context, arg1 return ret0, ret1 } -// ChainGetRandomnessFromTickets indicates an expected call of ChainGetRandomnessFromTickets +// 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 +// 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) @@ -293,13 +293,13 @@ func (m *MockFullNode) ChainGetTipSet(arg0 context.Context, arg1 types.TipSetKey return ret0, ret1 } -// ChainGetTipSet indicates an expected call of ChainGetTipSet +// 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 +// 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) @@ -308,13 +308,13 @@ func (m *MockFullNode) ChainGetTipSetByHeight(arg0 context.Context, arg1 abi.Cha return ret0, ret1 } -// ChainGetTipSetByHeight indicates an expected call of ChainGetTipSetByHeight +// 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 +// 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) @@ -323,13 +323,13 @@ func (m *MockFullNode) ChainHasObj(arg0 context.Context, arg1 cid.Cid) (bool, er return ret0, ret1 } -// ChainHasObj indicates an expected call of ChainHasObj +// 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 +// 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) @@ -338,13 +338,13 @@ func (m *MockFullNode) ChainHead(arg0 context.Context) (*types.TipSet, error) { return ret0, ret1 } -// ChainHead indicates an expected call of ChainHead +// 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 +// 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) @@ -353,13 +353,13 @@ func (m *MockFullNode) ChainNotify(arg0 context.Context) (<-chan []*api.HeadChan return ret0, ret1 } -// ChainNotify indicates an expected call of ChainNotify +// 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 +// 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) @@ -368,13 +368,13 @@ func (m *MockFullNode) ChainReadObj(arg0 context.Context, arg1 cid.Cid) ([]byte, return ret0, ret1 } -// ChainReadObj indicates an expected call of ChainReadObj +// 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 +// 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) @@ -382,13 +382,13 @@ func (m *MockFullNode) ChainSetHead(arg0 context.Context, arg1 types.TipSetKey) return ret0 } -// ChainSetHead indicates an expected call of ChainSetHead +// 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 +// 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) @@ -397,13 +397,13 @@ func (m *MockFullNode) ChainStatObj(arg0 context.Context, arg1, arg2 cid.Cid) (a return ret0, ret1 } -// ChainStatObj indicates an expected call of ChainStatObj +// 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 +// 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) @@ -412,13 +412,13 @@ func (m *MockFullNode) ChainTipSetWeight(arg0 context.Context, arg1 types.TipSet return ret0, ret1 } -// ChainTipSetWeight indicates an expected call of ChainTipSetWeight +// 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 +// 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) @@ -427,13 +427,13 @@ func (m *MockFullNode) ClientCalcCommP(arg0 context.Context, arg1 string) (*api. return ret0, ret1 } -// ClientCalcCommP indicates an expected call of ClientCalcCommP +// 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 +// 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) @@ -441,13 +441,13 @@ func (m *MockFullNode) ClientCancelDataTransfer(arg0 context.Context, arg1 datat return ret0 } -// ClientCancelDataTransfer indicates an expected call of ClientCancelDataTransfer +// 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 +// 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) @@ -455,13 +455,13 @@ func (m *MockFullNode) ClientCancelRetrievalDeal(arg0 context.Context, arg1 retr return ret0 } -// ClientCancelRetrievalDeal indicates an expected call of ClientCancelRetrievalDeal +// 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 +// 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) @@ -470,13 +470,13 @@ func (m *MockFullNode) ClientDataTransferUpdates(arg0 context.Context) (<-chan a return ret0, ret1 } -// ClientDataTransferUpdates indicates an expected call of ClientDataTransferUpdates +// 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 +// 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) @@ -485,13 +485,13 @@ func (m *MockFullNode) ClientDealPieceCID(arg0 context.Context, arg1 cid.Cid) (a return ret0, ret1 } -// ClientDealPieceCID indicates an expected call of ClientDealPieceCID +// 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 +// 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) @@ -500,13 +500,13 @@ func (m *MockFullNode) ClientDealSize(arg0 context.Context, arg1 cid.Cid) (api.D return ret0, ret1 } -// ClientDealSize indicates an expected call of ClientDealSize +// 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 +// 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) @@ -515,13 +515,13 @@ func (m *MockFullNode) ClientFindData(arg0 context.Context, arg1 cid.Cid, arg2 * return ret0, ret1 } -// ClientFindData indicates an expected call of ClientFindData +// 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 +// 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) @@ -529,13 +529,13 @@ func (m *MockFullNode) ClientGenCar(arg0 context.Context, arg1 api.FileRef, arg2 return ret0 } -// ClientGenCar indicates an expected call of ClientGenCar +// 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 +// 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) @@ -544,13 +544,13 @@ func (m *MockFullNode) ClientGetDealInfo(arg0 context.Context, arg1 cid.Cid) (*a return ret0, ret1 } -// ClientGetDealInfo indicates an expected call of ClientGetDealInfo +// 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 +// 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) @@ -559,13 +559,13 @@ func (m *MockFullNode) ClientGetDealStatus(arg0 context.Context, arg1 uint64) (s return ret0, ret1 } -// ClientGetDealStatus indicates an expected call of ClientGetDealStatus +// 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 +// 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) @@ -574,13 +574,28 @@ func (m *MockFullNode) ClientGetDealUpdates(arg0 context.Context) (<-chan api.De return ret0, ret1 } -// ClientGetDealUpdates indicates an expected call of ClientGetDealUpdates +// 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 +// ClientGetRetrievalUpdates mocks base method. +func (m *MockFullNode) ClientGetRetrievalUpdates(arg0 context.Context) (<-chan api.RetrievalInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientGetRetrievalUpdates", arg0) + ret0, _ := ret[0].(<-chan api.RetrievalInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientGetRetrievalUpdates indicates an expected call of ClientGetRetrievalUpdates. +func (mr *MockFullNodeMockRecorder) ClientGetRetrievalUpdates(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientGetRetrievalUpdates", reflect.TypeOf((*MockFullNode)(nil).ClientGetRetrievalUpdates), 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) @@ -589,13 +604,13 @@ func (m *MockFullNode) ClientHasLocal(arg0 context.Context, arg1 cid.Cid) (bool, return ret0, ret1 } -// ClientHasLocal indicates an expected call of ClientHasLocal +// 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 +// 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) @@ -604,13 +619,13 @@ func (m *MockFullNode) ClientImport(arg0 context.Context, arg1 api.FileRef) (*ap return ret0, ret1 } -// ClientImport indicates an expected call of ClientImport +// 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 +// 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) @@ -619,13 +634,13 @@ func (m *MockFullNode) ClientListDataTransfers(arg0 context.Context) ([]api.Data return ret0, ret1 } -// ClientListDataTransfers indicates an expected call of ClientListDataTransfers +// 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 +// 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) @@ -634,13 +649,13 @@ func (m *MockFullNode) ClientListDeals(arg0 context.Context) ([]api.DealInfo, er return ret0, ret1 } -// ClientListDeals indicates an expected call of ClientListDeals +// 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 +// 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) @@ -649,13 +664,28 @@ func (m *MockFullNode) ClientListImports(arg0 context.Context) ([]api.Import, er return ret0, ret1 } -// ClientListImports indicates an expected call of ClientListImports +// 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 +// ClientListRetrievals mocks base method. +func (m *MockFullNode) ClientListRetrievals(arg0 context.Context) ([]api.RetrievalInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientListRetrievals", arg0) + ret0, _ := ret[0].([]api.RetrievalInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientListRetrievals indicates an expected call of ClientListRetrievals. +func (mr *MockFullNodeMockRecorder) ClientListRetrievals(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientListRetrievals", reflect.TypeOf((*MockFullNode)(nil).ClientListRetrievals), 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) @@ -664,13 +694,13 @@ func (m *MockFullNode) ClientMinerQueryOffer(arg0 context.Context, arg1 address. return ret0, ret1 } -// ClientMinerQueryOffer indicates an expected call of ClientMinerQueryOffer +// 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 +// 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) @@ -679,13 +709,13 @@ func (m *MockFullNode) ClientQueryAsk(arg0 context.Context, arg1 peer.ID, arg2 a return ret0, ret1 } -// ClientQueryAsk indicates an expected call of ClientQueryAsk +// 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 +// 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) @@ -693,13 +723,13 @@ func (m *MockFullNode) ClientRemoveImport(arg0 context.Context, arg1 multistore. return ret0 } -// ClientRemoveImport indicates an expected call of ClientRemoveImport +// 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 +// 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) @@ -707,13 +737,13 @@ func (m *MockFullNode) ClientRestartDataTransfer(arg0 context.Context, arg1 data return ret0 } -// ClientRestartDataTransfer indicates an expected call of ClientRestartDataTransfer +// 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 +// 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) @@ -721,13 +751,13 @@ func (m *MockFullNode) ClientRetrieve(arg0 context.Context, arg1 api.RetrievalOr return ret0 } -// ClientRetrieve indicates an expected call of ClientRetrieve +// 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 +// 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) @@ -735,13 +765,13 @@ func (m *MockFullNode) ClientRetrieveTryRestartInsufficientFunds(arg0 context.Co return ret0 } -// ClientRetrieveTryRestartInsufficientFunds indicates an expected call of ClientRetrieveTryRestartInsufficientFunds +// 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 +// 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) @@ -750,13 +780,13 @@ func (m *MockFullNode) ClientRetrieveWithEvents(arg0 context.Context, arg1 api.R return ret0, ret1 } -// ClientRetrieveWithEvents indicates an expected call of ClientRetrieveWithEvents +// 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 +// 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) @@ -765,13 +795,13 @@ func (m *MockFullNode) ClientStartDeal(arg0 context.Context, arg1 *api.StartDeal return ret0, ret1 } -// ClientStartDeal indicates an expected call of ClientStartDeal +// 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) } -// ClientStatelessDeal mocks base method +// ClientStatelessDeal mocks base method. func (m *MockFullNode) ClientStatelessDeal(arg0 context.Context, arg1 *api.StartDealParams) (*cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientStatelessDeal", arg0, arg1) @@ -780,13 +810,13 @@ func (m *MockFullNode) ClientStatelessDeal(arg0 context.Context, arg1 *api.Start return ret0, ret1 } -// ClientStatelessDeal indicates an expected call of ClientStatelessDeal +// ClientStatelessDeal indicates an expected call of ClientStatelessDeal. func (mr *MockFullNodeMockRecorder) ClientStatelessDeal(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientStatelessDeal", reflect.TypeOf((*MockFullNode)(nil).ClientStatelessDeal), arg0, arg1) } -// Closing mocks base method +// 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) @@ -795,13 +825,13 @@ func (m *MockFullNode) Closing(arg0 context.Context) (<-chan struct{}, error) { return ret0, ret1 } -// Closing indicates an expected call of Closing +// 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 +// 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) @@ -809,13 +839,13 @@ func (m *MockFullNode) CreateBackup(arg0 context.Context, arg1 string) error { return ret0 } -// CreateBackup indicates an expected call of CreateBackup +// 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 +// 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) @@ -824,13 +854,13 @@ func (m *MockFullNode) Discover(arg0 context.Context) (apitypes.OpenRPCDocument, return ret0, ret1 } -// Discover indicates an expected call of Discover +// 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 +// 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) @@ -839,13 +869,13 @@ func (m *MockFullNode) GasEstimateFeeCap(arg0 context.Context, arg1 *types.Messa return ret0, ret1 } -// GasEstimateFeeCap indicates an expected call of GasEstimateFeeCap +// 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 +// 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) @@ -854,13 +884,13 @@ func (m *MockFullNode) GasEstimateGasLimit(arg0 context.Context, arg1 *types.Mes return ret0, ret1 } -// GasEstimateGasLimit indicates an expected call of GasEstimateGasLimit +// 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 +// 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) @@ -869,13 +899,13 @@ func (m *MockFullNode) GasEstimateGasPremium(arg0 context.Context, arg1 uint64, return ret0, ret1 } -// GasEstimateGasPremium indicates an expected call of GasEstimateGasPremium +// 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 +// 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) @@ -884,13 +914,13 @@ func (m *MockFullNode) GasEstimateMessageGas(arg0 context.Context, arg1 *types.M return ret0, ret1 } -// GasEstimateMessageGas indicates an expected call of GasEstimateMessageGas +// 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 +// 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) @@ -899,13 +929,13 @@ func (m *MockFullNode) ID(arg0 context.Context) (peer.ID, error) { return ret0, ret1 } -// ID indicates an expected call of ID +// 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 +// LogList mocks base method. func (m *MockFullNode) LogList(arg0 context.Context) ([]string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "LogList", arg0) @@ -914,13 +944,13 @@ func (m *MockFullNode) LogList(arg0 context.Context) ([]string, error) { return ret0, ret1 } -// LogList indicates an expected call of LogList +// 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 +// 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) @@ -928,13 +958,13 @@ func (m *MockFullNode) LogSetLevel(arg0 context.Context, arg1, arg2 string) erro return ret0 } -// LogSetLevel indicates an expected call of LogSetLevel +// 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 +// 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) @@ -943,13 +973,13 @@ func (m *MockFullNode) MarketAddBalance(arg0 context.Context, arg1, arg2 address return ret0, ret1 } -// MarketAddBalance indicates an expected call of MarketAddBalance +// 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 +// 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) @@ -958,13 +988,13 @@ func (m *MockFullNode) MarketGetReserved(arg0 context.Context, arg1 address.Addr return ret0, ret1 } -// MarketGetReserved indicates an expected call of MarketGetReserved +// 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 +// 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) @@ -972,13 +1002,13 @@ func (m *MockFullNode) MarketReleaseFunds(arg0 context.Context, arg1 address.Add return ret0 } -// MarketReleaseFunds indicates an expected call of MarketReleaseFunds +// 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 +// 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) @@ -987,13 +1017,13 @@ func (m *MockFullNode) MarketReserveFunds(arg0 context.Context, arg1, arg2 addre return ret0, ret1 } -// MarketReserveFunds indicates an expected call of MarketReserveFunds +// 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 +// 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) @@ -1002,13 +1032,13 @@ func (m *MockFullNode) MarketWithdraw(arg0 context.Context, arg1, arg2 address.A return ret0, ret1 } -// MarketWithdraw indicates an expected call of MarketWithdraw +// 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 +// 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) @@ -1017,13 +1047,13 @@ func (m *MockFullNode) MinerCreateBlock(arg0 context.Context, arg1 *api.BlockTem return ret0, ret1 } -// MinerCreateBlock indicates an expected call of MinerCreateBlock +// 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 +// 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) @@ -1032,13 +1062,13 @@ func (m *MockFullNode) MinerGetBaseInfo(arg0 context.Context, arg1 address.Addre return ret0, ret1 } -// MinerGetBaseInfo indicates an expected call of MinerGetBaseInfo +// 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 +// 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) @@ -1047,13 +1077,13 @@ func (m *MockFullNode) MpoolBatchPush(arg0 context.Context, arg1 []*types.Signed return ret0, ret1 } -// MpoolBatchPush indicates an expected call of MpoolBatchPush +// 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 +// 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) @@ -1062,13 +1092,13 @@ func (m *MockFullNode) MpoolBatchPushMessage(arg0 context.Context, arg1 []*types return ret0, ret1 } -// MpoolBatchPushMessage indicates an expected call of MpoolBatchPushMessage +// 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 +// 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) @@ -1077,13 +1107,13 @@ func (m *MockFullNode) MpoolBatchPushUntrusted(arg0 context.Context, arg1 []*typ return ret0, ret1 } -// MpoolBatchPushUntrusted indicates an expected call of MpoolBatchPushUntrusted +// 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) } -// MpoolCheckMessages mocks base method +// 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) @@ -1092,13 +1122,13 @@ func (m *MockFullNode) MpoolCheckMessages(arg0 context.Context, arg1 []*api.Mess return ret0, ret1 } -// MpoolCheckMessages indicates an expected call of MpoolCheckMessages +// 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 +// 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) @@ -1107,13 +1137,13 @@ func (m *MockFullNode) MpoolCheckPendingMessages(arg0 context.Context, arg1 addr return ret0, ret1 } -// MpoolCheckPendingMessages indicates an expected call of MpoolCheckPendingMessages +// 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 +// 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) @@ -1122,13 +1152,13 @@ func (m *MockFullNode) MpoolCheckReplaceMessages(arg0 context.Context, arg1 []*t return ret0, ret1 } -// MpoolCheckReplaceMessages indicates an expected call of MpoolCheckReplaceMessages +// 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 +// 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) @@ -1136,13 +1166,13 @@ func (m *MockFullNode) MpoolClear(arg0 context.Context, arg1 bool) error { return ret0 } -// MpoolClear indicates an expected call of MpoolClear +// 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 +// 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) @@ -1151,13 +1181,13 @@ func (m *MockFullNode) MpoolGetConfig(arg0 context.Context) (*types.MpoolConfig, return ret0, ret1 } -// MpoolGetConfig indicates an expected call of MpoolGetConfig +// 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 +// 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) @@ -1166,13 +1196,13 @@ func (m *MockFullNode) MpoolGetNonce(arg0 context.Context, arg1 address.Address) return ret0, ret1 } -// MpoolGetNonce indicates an expected call of MpoolGetNonce +// 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 +// 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) @@ -1181,13 +1211,13 @@ func (m *MockFullNode) MpoolPending(arg0 context.Context, arg1 types.TipSetKey) return ret0, ret1 } -// MpoolPending indicates an expected call of MpoolPending +// 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 +// 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) @@ -1196,13 +1226,13 @@ func (m *MockFullNode) MpoolPush(arg0 context.Context, arg1 *types.SignedMessage return ret0, ret1 } -// MpoolPush indicates an expected call of MpoolPush +// 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 +// 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) @@ -1211,13 +1241,13 @@ func (m *MockFullNode) MpoolPushMessage(arg0 context.Context, arg1 *types.Messag return ret0, ret1 } -// MpoolPushMessage indicates an expected call of MpoolPushMessage +// 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 +// 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) @@ -1226,13 +1256,13 @@ func (m *MockFullNode) MpoolPushUntrusted(arg0 context.Context, arg1 *types.Sign return ret0, ret1 } -// MpoolPushUntrusted indicates an expected call of MpoolPushUntrusted +// 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 +// 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) @@ -1241,13 +1271,13 @@ func (m *MockFullNode) MpoolSelect(arg0 context.Context, arg1 types.TipSetKey, a return ret0, ret1 } -// MpoolSelect indicates an expected call of MpoolSelect +// 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 +// 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) @@ -1255,13 +1285,13 @@ func (m *MockFullNode) MpoolSetConfig(arg0 context.Context, arg1 *types.MpoolCon return ret0 } -// MpoolSetConfig indicates an expected call of MpoolSetConfig +// 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 +// 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) @@ -1270,13 +1300,13 @@ func (m *MockFullNode) MpoolSub(arg0 context.Context) (<-chan api.MpoolUpdate, e return ret0, ret1 } -// MpoolSub indicates an expected call of MpoolSub +// 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 +// MsigAddApprove mocks base method. 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) @@ -1285,13 +1315,13 @@ func (m *MockFullNode) MsigAddApprove(arg0 context.Context, arg1, arg2 address.A return ret0, ret1 } -// MsigAddApprove indicates an expected call of MsigAddApprove +// 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 +// MsigAddCancel mocks base method. 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) @@ -1300,13 +1330,13 @@ func (m *MockFullNode) MsigAddCancel(arg0 context.Context, arg1, arg2 address.Ad return ret0, ret1 } -// MsigAddCancel indicates an expected call of MsigAddCancel +// 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 +// MsigAddPropose mocks base method. 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) @@ -1315,13 +1345,13 @@ func (m *MockFullNode) MsigAddPropose(arg0 context.Context, arg1, arg2, arg3 add return ret0, ret1 } -// MsigAddPropose indicates an expected call of MsigAddPropose +// 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 +// MsigApprove mocks base method. 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) @@ -1330,13 +1360,13 @@ func (m *MockFullNode) MsigApprove(arg0 context.Context, arg1 address.Address, a return ret0, ret1 } -// MsigApprove indicates an expected call of MsigApprove +// 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 +// 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) (*api.MessagePrototype, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigApproveTxnHash", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) @@ -1345,13 +1375,13 @@ func (m *MockFullNode) MsigApproveTxnHash(arg0 context.Context, arg1 address.Add return ret0, ret1 } -// MsigApproveTxnHash indicates an expected call of MsigApproveTxnHash +// 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 +// 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) (*api.MessagePrototype, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigCancel", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) @@ -1360,13 +1390,13 @@ func (m *MockFullNode) MsigCancel(arg0 context.Context, arg1 address.Address, ar return ret0, ret1 } -// MsigCancel indicates an expected call of MsigCancel +// 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 +// 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) (*api.MessagePrototype, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigCreate", arg0, arg1, arg2, arg3, arg4, arg5, arg6) @@ -1375,13 +1405,13 @@ func (m *MockFullNode) MsigCreate(arg0 context.Context, arg1 uint64, arg2 []addr return ret0, ret1 } -// MsigCreate indicates an expected call of MsigCreate +// 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 +// 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) @@ -1390,13 +1420,13 @@ func (m *MockFullNode) MsigGetAvailableBalance(arg0 context.Context, arg1 addres return ret0, ret1 } -// MsigGetAvailableBalance indicates an expected call of MsigGetAvailableBalance +// 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 +// 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) @@ -1405,13 +1435,13 @@ func (m *MockFullNode) MsigGetPending(arg0 context.Context, arg1 address.Address return ret0, ret1 } -// MsigGetPending indicates an expected call of MsigGetPending +// 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 +// 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) @@ -1420,13 +1450,13 @@ func (m *MockFullNode) MsigGetVested(arg0 context.Context, arg1 address.Address, return ret0, ret1 } -// MsigGetVested indicates an expected call of MsigGetVested +// 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 +// 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) @@ -1435,13 +1465,13 @@ func (m *MockFullNode) MsigGetVestingSchedule(arg0 context.Context, arg1 address return ret0, ret1 } -// MsigGetVestingSchedule indicates an expected call of MsigGetVestingSchedule +// 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 +// 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) (*api.MessagePrototype, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MsigPropose", arg0, arg1, arg2, arg3, arg4, arg5, arg6) @@ -1450,13 +1480,13 @@ func (m *MockFullNode) MsigPropose(arg0 context.Context, arg1, arg2 address.Addr return ret0, ret1 } -// MsigPropose indicates an expected call of MsigPropose +// 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 +// MsigRemoveSigner mocks base method. 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) @@ -1465,13 +1495,13 @@ func (m *MockFullNode) MsigRemoveSigner(arg0 context.Context, arg1, arg2, arg3 a return ret0, ret1 } -// MsigRemoveSigner indicates an expected call of MsigRemoveSigner +// 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 +// MsigSwapApprove mocks base method. 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) @@ -1480,13 +1510,13 @@ func (m *MockFullNode) MsigSwapApprove(arg0 context.Context, arg1, arg2 address. return ret0, ret1 } -// MsigSwapApprove indicates an expected call of MsigSwapApprove +// 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 +// MsigSwapCancel mocks base method. 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) @@ -1495,13 +1525,13 @@ func (m *MockFullNode) MsigSwapCancel(arg0 context.Context, arg1, arg2 address.A return ret0, ret1 } -// MsigSwapCancel indicates an expected call of MsigSwapCancel +// 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 +// MsigSwapPropose mocks base method. 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) @@ -1510,13 +1540,13 @@ func (m *MockFullNode) MsigSwapPropose(arg0 context.Context, arg1, arg2, arg3, a return ret0, ret1 } -// MsigSwapPropose indicates an expected call of MsigSwapPropose +// 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 +// 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) @@ -1525,13 +1555,13 @@ func (m *MockFullNode) NetAddrsListen(arg0 context.Context) (peer.AddrInfo, erro return ret0, ret1 } -// NetAddrsListen indicates an expected call of NetAddrsListen +// 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 +// 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) @@ -1540,13 +1570,13 @@ func (m *MockFullNode) NetAgentVersion(arg0 context.Context, arg1 peer.ID) (stri return ret0, ret1 } -// NetAgentVersion indicates an expected call of NetAgentVersion +// 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 +// 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) @@ -1555,13 +1585,13 @@ func (m *MockFullNode) NetAutoNatStatus(arg0 context.Context) (api.NatInfo, erro return ret0, ret1 } -// NetAutoNatStatus indicates an expected call of NetAutoNatStatus +// 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 +// 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) @@ -1570,13 +1600,13 @@ func (m *MockFullNode) NetBandwidthStats(arg0 context.Context) (metrics.Stats, e return ret0, ret1 } -// NetBandwidthStats indicates an expected call of NetBandwidthStats +// 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 +// 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) @@ -1585,13 +1615,13 @@ func (m *MockFullNode) NetBandwidthStatsByPeer(arg0 context.Context) (map[string return ret0, ret1 } -// NetBandwidthStatsByPeer indicates an expected call of NetBandwidthStatsByPeer +// 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 +// 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) @@ -1600,13 +1630,13 @@ func (m *MockFullNode) NetBandwidthStatsByProtocol(arg0 context.Context) (map[pr return ret0, ret1 } -// NetBandwidthStatsByProtocol indicates an expected call of NetBandwidthStatsByProtocol +// 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 +// 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) @@ -1614,13 +1644,13 @@ func (m *MockFullNode) NetBlockAdd(arg0 context.Context, arg1 api.NetBlockList) return ret0 } -// NetBlockAdd indicates an expected call of NetBlockAdd +// 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 +// 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) @@ -1629,13 +1659,13 @@ func (m *MockFullNode) NetBlockList(arg0 context.Context) (api.NetBlockList, err return ret0, ret1 } -// NetBlockList indicates an expected call of NetBlockList +// 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 +// 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) @@ -1643,13 +1673,13 @@ func (m *MockFullNode) NetBlockRemove(arg0 context.Context, arg1 api.NetBlockLis return ret0 } -// NetBlockRemove indicates an expected call of NetBlockRemove +// 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 +// 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) @@ -1657,13 +1687,13 @@ func (m *MockFullNode) NetConnect(arg0 context.Context, arg1 peer.AddrInfo) erro return ret0 } -// NetConnect indicates an expected call of NetConnect +// 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 +// 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) @@ -1672,13 +1702,13 @@ func (m *MockFullNode) NetConnectedness(arg0 context.Context, arg1 peer.ID) (net return ret0, ret1 } -// NetConnectedness indicates an expected call of NetConnectedness +// 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 +// 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) @@ -1686,13 +1716,13 @@ func (m *MockFullNode) NetDisconnect(arg0 context.Context, arg1 peer.ID) error { return ret0 } -// NetDisconnect indicates an expected call of NetDisconnect +// 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 +// 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) @@ -1701,13 +1731,13 @@ func (m *MockFullNode) NetFindPeer(arg0 context.Context, arg1 peer.ID) (peer.Add return ret0, ret1 } -// NetFindPeer indicates an expected call of NetFindPeer +// 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 +// 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) @@ -1716,13 +1746,13 @@ func (m *MockFullNode) NetPeerInfo(arg0 context.Context, arg1 peer.ID) (*api.Ext return ret0, ret1 } -// NetPeerInfo indicates an expected call of NetPeerInfo +// 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 +// 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) @@ -1731,13 +1761,13 @@ func (m *MockFullNode) NetPeers(arg0 context.Context) ([]peer.AddrInfo, error) { return ret0, ret1 } -// NetPeers indicates an expected call of NetPeers +// 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 +// 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) @@ -1746,13 +1776,13 @@ func (m *MockFullNode) NetPubsubScores(arg0 context.Context) ([]api.PubsubScore, return ret0, ret1 } -// NetPubsubScores indicates an expected call of NetPubsubScores +// 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) } -// NodeStatus mocks base method +// 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) @@ -1761,13 +1791,13 @@ func (m *MockFullNode) NodeStatus(arg0 context.Context, arg1 bool) (api.NodeStat return ret0, ret1 } -// NodeStatus indicates an expected call of NodeStatus +// 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 +// 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) @@ -1776,13 +1806,13 @@ func (m *MockFullNode) PaychAllocateLane(arg0 context.Context, arg1 address.Addr return ret0, ret1 } -// PaychAllocateLane indicates an expected call of PaychAllocateLane +// 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 +// 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) @@ -1791,13 +1821,13 @@ func (m *MockFullNode) PaychAvailableFunds(arg0 context.Context, arg1 address.Ad return ret0, ret1 } -// PaychAvailableFunds indicates an expected call of PaychAvailableFunds +// 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 +// 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) @@ -1806,13 +1836,13 @@ func (m *MockFullNode) PaychAvailableFundsByFromTo(arg0 context.Context, arg1, a return ret0, ret1 } -// PaychAvailableFundsByFromTo indicates an expected call of PaychAvailableFundsByFromTo +// 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 +// 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) @@ -1821,13 +1851,13 @@ func (m *MockFullNode) PaychCollect(arg0 context.Context, arg1 address.Address) return ret0, ret1 } -// PaychCollect indicates an expected call of PaychCollect +// 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 +// 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) @@ -1836,13 +1866,13 @@ func (m *MockFullNode) PaychGet(arg0 context.Context, arg1, arg2 address.Address return ret0, ret1 } -// PaychGet indicates an expected call of PaychGet +// 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 +// 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) @@ -1851,13 +1881,13 @@ func (m *MockFullNode) PaychGetWaitReady(arg0 context.Context, arg1 cid.Cid) (ad return ret0, ret1 } -// PaychGetWaitReady indicates an expected call of PaychGetWaitReady +// 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 +// 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) @@ -1866,13 +1896,13 @@ func (m *MockFullNode) PaychList(arg0 context.Context) ([]address.Address, error return ret0, ret1 } -// PaychList indicates an expected call of PaychList +// 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 +// 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) @@ -1881,13 +1911,13 @@ func (m *MockFullNode) PaychNewPayment(arg0 context.Context, arg1, arg2 address. return ret0, ret1 } -// PaychNewPayment indicates an expected call of PaychNewPayment +// 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 +// 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) @@ -1896,13 +1926,13 @@ func (m *MockFullNode) PaychSettle(arg0 context.Context, arg1 address.Address) ( return ret0, ret1 } -// PaychSettle indicates an expected call of PaychSettle +// 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 +// 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) @@ -1911,13 +1941,13 @@ func (m *MockFullNode) PaychStatus(arg0 context.Context, arg1 address.Address) ( return ret0, ret1 } -// PaychStatus indicates an expected call of PaychStatus +// 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 +// 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) @@ -1926,13 +1956,13 @@ func (m *MockFullNode) PaychVoucherAdd(arg0 context.Context, arg1 address.Addres return ret0, ret1 } -// PaychVoucherAdd indicates an expected call of PaychVoucherAdd +// 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 +// 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) @@ -1941,13 +1971,13 @@ func (m *MockFullNode) PaychVoucherCheckSpendable(arg0 context.Context, arg1 add return ret0, ret1 } -// PaychVoucherCheckSpendable indicates an expected call of PaychVoucherCheckSpendable +// 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 +// 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) @@ -1955,13 +1985,13 @@ func (m *MockFullNode) PaychVoucherCheckValid(arg0 context.Context, arg1 address return ret0 } -// PaychVoucherCheckValid indicates an expected call of PaychVoucherCheckValid +// 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 +// 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) @@ -1970,13 +2000,13 @@ func (m *MockFullNode) PaychVoucherCreate(arg0 context.Context, arg1 address.Add return ret0, ret1 } -// PaychVoucherCreate indicates an expected call of PaychVoucherCreate +// 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 +// 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) @@ -1985,13 +2015,13 @@ func (m *MockFullNode) PaychVoucherList(arg0 context.Context, arg1 address.Addre return ret0, ret1 } -// PaychVoucherList indicates an expected call of PaychVoucherList +// 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 +// 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) @@ -2000,13 +2030,13 @@ func (m *MockFullNode) PaychVoucherSubmit(arg0 context.Context, arg1 address.Add return ret0, ret1 } -// PaychVoucherSubmit indicates an expected call of PaychVoucherSubmit +// 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 +// 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) @@ -2015,13 +2045,13 @@ func (m *MockFullNode) Session(arg0 context.Context) (uuid.UUID, error) { return ret0, ret1 } -// Session indicates an expected call of Session +// 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 +// Shutdown mocks base method. func (m *MockFullNode) Shutdown(arg0 context.Context) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Shutdown", arg0) @@ -2029,13 +2059,13 @@ func (m *MockFullNode) Shutdown(arg0 context.Context) error { return ret0 } -// Shutdown indicates an expected call of Shutdown +// 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 +// 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) @@ -2044,13 +2074,13 @@ func (m *MockFullNode) StateAccountKey(arg0 context.Context, arg1 address.Addres return ret0, ret1 } -// StateAccountKey indicates an expected call of StateAccountKey +// 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 +// 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) @@ -2059,13 +2089,13 @@ func (m *MockFullNode) StateAllMinerFaults(arg0 context.Context, arg1 abi.ChainE return ret0, ret1 } -// StateAllMinerFaults indicates an expected call of StateAllMinerFaults +// 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 +// 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) @@ -2074,13 +2104,13 @@ func (m *MockFullNode) StateCall(arg0 context.Context, arg1 *types.Message, arg2 return ret0, ret1 } -// StateCall indicates an expected call of StateCall +// 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 +// 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) @@ -2089,13 +2119,13 @@ func (m *MockFullNode) StateChangedActors(arg0 context.Context, arg1, arg2 cid.C return ret0, ret1 } -// StateChangedActors indicates an expected call of StateChangedActors +// 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 +// 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) @@ -2104,13 +2134,13 @@ func (m *MockFullNode) StateCirculatingSupply(arg0 context.Context, arg1 types.T return ret0, ret1 } -// StateCirculatingSupply indicates an expected call of StateCirculatingSupply +// 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 +// 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) @@ -2119,13 +2149,13 @@ func (m *MockFullNode) StateCompute(arg0 context.Context, arg1 abi.ChainEpoch, a return ret0, ret1 } -// StateCompute indicates an expected call of StateCompute +// 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 +// 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) @@ -2134,13 +2164,13 @@ func (m *MockFullNode) StateDealProviderCollateralBounds(arg0 context.Context, a return ret0, ret1 } -// StateDealProviderCollateralBounds indicates an expected call of StateDealProviderCollateralBounds +// 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 +// 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) @@ -2149,13 +2179,13 @@ func (m *MockFullNode) StateDecodeParams(arg0 context.Context, arg1 address.Addr return ret0, ret1 } -// StateDecodeParams indicates an expected call of StateDecodeParams +// 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 +// 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) @@ -2164,13 +2194,13 @@ func (m *MockFullNode) StateGetActor(arg0 context.Context, arg1 address.Address, return ret0, ret1 } -// StateGetActor indicates an expected call of StateGetActor +// 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) } -// StateListActors mocks base method +// 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) @@ -2179,13 +2209,13 @@ func (m *MockFullNode) StateListActors(arg0 context.Context, arg1 types.TipSetKe return ret0, ret1 } -// StateListActors indicates an expected call of StateListActors +// 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 +// 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) @@ -2194,13 +2224,13 @@ func (m *MockFullNode) StateListMessages(arg0 context.Context, arg1 *api.Message return ret0, ret1 } -// StateListMessages indicates an expected call of StateListMessages +// 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 +// 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) @@ -2209,13 +2239,13 @@ func (m *MockFullNode) StateListMiners(arg0 context.Context, arg1 types.TipSetKe return ret0, ret1 } -// StateListMiners indicates an expected call of StateListMiners +// 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 +// 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) @@ -2224,13 +2254,13 @@ func (m *MockFullNode) StateLookupID(arg0 context.Context, arg1 address.Address, return ret0, ret1 } -// StateLookupID indicates an expected call of StateLookupID +// 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 +// 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) @@ -2239,13 +2269,13 @@ func (m *MockFullNode) StateMarketBalance(arg0 context.Context, arg1 address.Add return ret0, ret1 } -// StateMarketBalance indicates an expected call of StateMarketBalance +// 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 +// 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) @@ -2254,13 +2284,13 @@ func (m *MockFullNode) StateMarketDeals(arg0 context.Context, arg1 types.TipSetK return ret0, ret1 } -// StateMarketDeals indicates an expected call of StateMarketDeals +// 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 +// 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) @@ -2269,13 +2299,13 @@ func (m *MockFullNode) StateMarketParticipants(arg0 context.Context, arg1 types. return ret0, ret1 } -// StateMarketParticipants indicates an expected call of StateMarketParticipants +// 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 +// 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) @@ -2284,13 +2314,13 @@ func (m *MockFullNode) StateMarketStorageDeal(arg0 context.Context, arg1 abi.Dea return ret0, ret1 } -// StateMarketStorageDeal indicates an expected call of StateMarketStorageDeal +// 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 +// 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) @@ -2299,13 +2329,13 @@ func (m *MockFullNode) StateMinerActiveSectors(arg0 context.Context, arg1 addres return ret0, ret1 } -// StateMinerActiveSectors indicates an expected call of StateMinerActiveSectors +// 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 +// 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) @@ -2314,13 +2344,13 @@ func (m *MockFullNode) StateMinerAvailableBalance(arg0 context.Context, arg1 add return ret0, ret1 } -// StateMinerAvailableBalance indicates an expected call of StateMinerAvailableBalance +// 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 +// 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) @@ -2329,13 +2359,13 @@ func (m *MockFullNode) StateMinerDeadlines(arg0 context.Context, arg1 address.Ad return ret0, ret1 } -// StateMinerDeadlines indicates an expected call of StateMinerDeadlines +// 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 +// 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) @@ -2344,13 +2374,13 @@ func (m *MockFullNode) StateMinerFaults(arg0 context.Context, arg1 address.Addre return ret0, ret1 } -// StateMinerFaults indicates an expected call of StateMinerFaults +// 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 +// 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) @@ -2359,13 +2389,13 @@ func (m *MockFullNode) StateMinerInfo(arg0 context.Context, arg1 address.Address return ret0, ret1 } -// StateMinerInfo indicates an expected call of StateMinerInfo +// 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 +// 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) @@ -2374,13 +2404,13 @@ func (m *MockFullNode) StateMinerInitialPledgeCollateral(arg0 context.Context, a return ret0, ret1 } -// StateMinerInitialPledgeCollateral indicates an expected call of StateMinerInitialPledgeCollateral +// 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 +// 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) @@ -2389,13 +2419,13 @@ func (m *MockFullNode) StateMinerPartitions(arg0 context.Context, arg1 address.A return ret0, ret1 } -// StateMinerPartitions indicates an expected call of StateMinerPartitions +// 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 +// 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) @@ -2404,13 +2434,13 @@ func (m *MockFullNode) StateMinerPower(arg0 context.Context, arg1 address.Addres return ret0, ret1 } -// StateMinerPower indicates an expected call of StateMinerPower +// 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 +// 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) @@ -2419,13 +2449,13 @@ func (m *MockFullNode) StateMinerPreCommitDepositForPower(arg0 context.Context, return ret0, ret1 } -// StateMinerPreCommitDepositForPower indicates an expected call of StateMinerPreCommitDepositForPower +// 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 +// 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) @@ -2434,13 +2464,13 @@ func (m *MockFullNode) StateMinerProvingDeadline(arg0 context.Context, arg1 addr return ret0, ret1 } -// StateMinerProvingDeadline indicates an expected call of StateMinerProvingDeadline +// 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 +// 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) @@ -2449,13 +2479,13 @@ func (m *MockFullNode) StateMinerRecoveries(arg0 context.Context, arg1 address.A return ret0, ret1 } -// StateMinerRecoveries indicates an expected call of StateMinerRecoveries +// 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 +// 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) @@ -2464,13 +2494,13 @@ func (m *MockFullNode) StateMinerSectorAllocated(arg0 context.Context, arg1 addr return ret0, ret1 } -// StateMinerSectorAllocated indicates an expected call of StateMinerSectorAllocated +// 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 +// 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) @@ -2479,13 +2509,13 @@ func (m *MockFullNode) StateMinerSectorCount(arg0 context.Context, arg1 address. return ret0, ret1 } -// StateMinerSectorCount indicates an expected call of StateMinerSectorCount +// 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 +// 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) @@ -2494,13 +2524,13 @@ func (m *MockFullNode) StateMinerSectors(arg0 context.Context, arg1 address.Addr return ret0, ret1 } -// StateMinerSectors indicates an expected call of StateMinerSectors +// 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 +// 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) @@ -2509,13 +2539,13 @@ func (m *MockFullNode) StateNetworkName(arg0 context.Context) (dtypes.NetworkNam return ret0, ret1 } -// StateNetworkName indicates an expected call of StateNetworkName +// 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 +// 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) @@ -2524,13 +2554,13 @@ func (m *MockFullNode) StateNetworkVersion(arg0 context.Context, arg1 types.TipS return ret0, ret1 } -// StateNetworkVersion indicates an expected call of StateNetworkVersion +// 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 +// 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) @@ -2539,13 +2569,13 @@ func (m *MockFullNode) StateReadState(arg0 context.Context, arg1 address.Address return ret0, ret1 } -// StateReadState indicates an expected call of StateReadState +// 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 +// 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) @@ -2554,13 +2584,13 @@ func (m *MockFullNode) StateReplay(arg0 context.Context, arg1 types.TipSetKey, a return ret0, ret1 } -// StateReplay indicates an expected call of StateReplay +// 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 +// StateSearchMsg mocks base method. 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, arg2, arg3, arg4) @@ -2569,13 +2599,13 @@ func (m *MockFullNode) StateSearchMsg(arg0 context.Context, arg1 types.TipSetKey return ret0, ret1 } -// StateSearchMsg indicates an expected call of StateSearchMsg +// StateSearchMsg indicates an expected call of StateSearchMsg. func (mr *MockFullNodeMockRecorder) StateSearchMsg(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSearchMsg", reflect.TypeOf((*MockFullNode)(nil).StateSearchMsg), arg0, arg1, arg2, arg3, arg4) } -// StateSectorExpiration mocks base method +// 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) @@ -2584,13 +2614,13 @@ func (m *MockFullNode) StateSectorExpiration(arg0 context.Context, arg1 address. return ret0, ret1 } -// StateSectorExpiration indicates an expected call of StateSectorExpiration +// 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 +// 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) @@ -2599,13 +2629,13 @@ func (m *MockFullNode) StateSectorGetInfo(arg0 context.Context, arg1 address.Add return ret0, ret1 } -// StateSectorGetInfo indicates an expected call of StateSectorGetInfo +// 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 +// 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) @@ -2614,13 +2644,13 @@ func (m *MockFullNode) StateSectorPartition(arg0 context.Context, arg1 address.A return ret0, ret1 } -// StateSectorPartition indicates an expected call of StateSectorPartition +// 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 +// 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) @@ -2629,13 +2659,13 @@ func (m *MockFullNode) StateSectorPreCommitInfo(arg0 context.Context, arg1 addre return ret0, ret1 } -// StateSectorPreCommitInfo indicates an expected call of StateSectorPreCommitInfo +// 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 +// 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) @@ -2644,13 +2674,13 @@ func (m *MockFullNode) StateVMCirculatingSupplyInternal(arg0 context.Context, ar return ret0, ret1 } -// StateVMCirculatingSupplyInternal indicates an expected call of StateVMCirculatingSupplyInternal +// 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 +// 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) @@ -2659,13 +2689,13 @@ func (m *MockFullNode) StateVerifiedClientStatus(arg0 context.Context, arg1 addr return ret0, ret1 } -// StateVerifiedClientStatus indicates an expected call of StateVerifiedClientStatus +// 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 +// 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) @@ -2674,13 +2704,13 @@ func (m *MockFullNode) StateVerifiedRegistryRootKey(arg0 context.Context, arg1 t return ret0, ret1 } -// StateVerifiedRegistryRootKey indicates an expected call of StateVerifiedRegistryRootKey +// 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 +// 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) @@ -2689,13 +2719,13 @@ func (m *MockFullNode) StateVerifierStatus(arg0 context.Context, arg1 address.Ad return ret0, ret1 } -// StateVerifierStatus indicates an expected call of StateVerifierStatus +// 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 +// StateWaitMsg mocks base method. 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, arg3, arg4) @@ -2704,13 +2734,13 @@ func (m *MockFullNode) StateWaitMsg(arg0 context.Context, arg1 cid.Cid, arg2 uin return ret0, ret1 } -// StateWaitMsg indicates an expected call of StateWaitMsg +// StateWaitMsg indicates an expected call of StateWaitMsg. func (mr *MockFullNodeMockRecorder) StateWaitMsg(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateWaitMsg", reflect.TypeOf((*MockFullNode)(nil).StateWaitMsg), arg0, arg1, arg2, arg3, arg4) } -// SyncCheckBad mocks base method +// 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) @@ -2719,13 +2749,13 @@ func (m *MockFullNode) SyncCheckBad(arg0 context.Context, arg1 cid.Cid) (string, return ret0, ret1 } -// SyncCheckBad indicates an expected call of SyncCheckBad +// 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 +// 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) @@ -2733,13 +2763,13 @@ func (m *MockFullNode) SyncCheckpoint(arg0 context.Context, arg1 types.TipSetKey return ret0 } -// SyncCheckpoint indicates an expected call of SyncCheckpoint +// 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 +// 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) @@ -2748,13 +2778,13 @@ func (m *MockFullNode) SyncIncomingBlocks(arg0 context.Context) (<-chan *types.B return ret0, ret1 } -// SyncIncomingBlocks indicates an expected call of SyncIncomingBlocks +// 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 +// 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) @@ -2762,13 +2792,13 @@ func (m *MockFullNode) SyncMarkBad(arg0 context.Context, arg1 cid.Cid) error { return ret0 } -// SyncMarkBad indicates an expected call of SyncMarkBad +// 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 +// 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) @@ -2777,13 +2807,13 @@ func (m *MockFullNode) SyncState(arg0 context.Context) (*api.SyncState, error) { return ret0, ret1 } -// SyncState indicates an expected call of SyncState +// 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 +// 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) @@ -2791,13 +2821,13 @@ func (m *MockFullNode) SyncSubmitBlock(arg0 context.Context, arg1 *types.BlockMs return ret0 } -// SyncSubmitBlock indicates an expected call of SyncSubmitBlock +// 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 +// SyncUnmarkAllBad mocks base method. func (m *MockFullNode) SyncUnmarkAllBad(arg0 context.Context) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SyncUnmarkAllBad", arg0) @@ -2805,13 +2835,13 @@ func (m *MockFullNode) SyncUnmarkAllBad(arg0 context.Context) error { return ret0 } -// SyncUnmarkAllBad indicates an expected call of SyncUnmarkAllBad +// 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 +// 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) @@ -2819,13 +2849,13 @@ func (m *MockFullNode) SyncUnmarkBad(arg0 context.Context, arg1 cid.Cid) error { return ret0 } -// SyncUnmarkBad indicates an expected call of SyncUnmarkBad +// 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 +// 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) @@ -2834,13 +2864,13 @@ func (m *MockFullNode) SyncValidateTipset(arg0 context.Context, arg1 types.TipSe return ret0, ret1 } -// SyncValidateTipset indicates an expected call of SyncValidateTipset +// 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 +// 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) @@ -2849,13 +2879,13 @@ func (m *MockFullNode) Version(arg0 context.Context) (api.APIVersion, error) { return ret0, ret1 } -// Version indicates an expected call of Version +// 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 +// 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) @@ -2864,13 +2894,13 @@ func (m *MockFullNode) WalletBalance(arg0 context.Context, arg1 address.Address) return ret0, ret1 } -// WalletBalance indicates an expected call of WalletBalance +// 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 +// 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) @@ -2879,13 +2909,13 @@ func (m *MockFullNode) WalletDefaultAddress(arg0 context.Context) (address.Addre return ret0, ret1 } -// WalletDefaultAddress indicates an expected call of WalletDefaultAddress +// 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 +// 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) @@ -2893,13 +2923,13 @@ func (m *MockFullNode) WalletDelete(arg0 context.Context, arg1 address.Address) return ret0 } -// WalletDelete indicates an expected call of WalletDelete +// 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 +// 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) @@ -2908,13 +2938,13 @@ func (m *MockFullNode) WalletExport(arg0 context.Context, arg1 address.Address) return ret0, ret1 } -// WalletExport indicates an expected call of WalletExport +// 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 +// 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) @@ -2923,13 +2953,13 @@ func (m *MockFullNode) WalletHas(arg0 context.Context, arg1 address.Address) (bo return ret0, ret1 } -// WalletHas indicates an expected call of WalletHas +// 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 +// 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) @@ -2938,13 +2968,13 @@ func (m *MockFullNode) WalletImport(arg0 context.Context, arg1 *types.KeyInfo) ( return ret0, ret1 } -// WalletImport indicates an expected call of WalletImport +// 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 +// 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) @@ -2953,13 +2983,13 @@ func (m *MockFullNode) WalletList(arg0 context.Context) ([]address.Address, erro return ret0, ret1 } -// WalletList indicates an expected call of WalletList +// 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 +// 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) @@ -2968,13 +2998,13 @@ func (m *MockFullNode) WalletNew(arg0 context.Context, arg1 types.KeyType) (addr return ret0, ret1 } -// WalletNew indicates an expected call of WalletNew +// 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 +// 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) @@ -2982,13 +3012,13 @@ func (m *MockFullNode) WalletSetDefault(arg0 context.Context, arg1 address.Addre return ret0 } -// WalletSetDefault indicates an expected call of WalletSetDefault +// 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 +// 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) @@ -2997,13 +3027,13 @@ func (m *MockFullNode) WalletSign(arg0 context.Context, arg1 address.Address, ar return ret0, ret1 } -// WalletSign indicates an expected call of WalletSign +// 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 +// 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) @@ -3012,13 +3042,13 @@ func (m *MockFullNode) WalletSignMessage(arg0 context.Context, arg1 address.Addr return ret0, ret1 } -// WalletSignMessage indicates an expected call of WalletSignMessage +// 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 +// 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) @@ -3027,13 +3057,13 @@ func (m *MockFullNode) WalletValidateAddress(arg0 context.Context, arg1 string) return ret0, ret1 } -// WalletValidateAddress indicates an expected call of WalletValidateAddress +// 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 +// 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) @@ -3042,7 +3072,7 @@ func (m *MockFullNode) WalletVerify(arg0 context.Context, arg1 address.Address, return ret0, ret1 } -// WalletVerify indicates an expected call of WalletVerify +// 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/proxy_gen.go b/api/proxy_gen.go index 4fa51a4afa3..6540ae7cd0c 100644 --- a/api/proxy_gen.go +++ b/api/proxy_gen.go @@ -4,7 +4,6 @@ package api import ( "context" - "io" "time" "github.com/filecoin-project/go-address" @@ -180,6 +179,8 @@ type FullNodeStruct struct { ClientGetDealUpdates func(p0 context.Context) (<-chan DealInfo, error) `perm:"write"` + ClientGetRetrievalUpdates func(p0 context.Context) (<-chan RetrievalInfo, 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"` @@ -190,6 +191,8 @@ type FullNodeStruct struct { ClientListImports func(p0 context.Context) ([]Import, error) `perm:"write"` + ClientListRetrievals func(p0 context.Context) ([]RetrievalInfo, 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"` @@ -777,8 +780,6 @@ type WorkerStruct struct { 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"` @@ -1302,6 +1303,14 @@ func (s *FullNodeStub) ClientGetDealUpdates(p0 context.Context) (<-chan DealInfo return nil, xerrors.New("method not supported") } +func (s *FullNodeStruct) ClientGetRetrievalUpdates(p0 context.Context) (<-chan RetrievalInfo, error) { + return s.Internal.ClientGetRetrievalUpdates(p0) +} + +func (s *FullNodeStub) ClientGetRetrievalUpdates(p0 context.Context) (<-chan RetrievalInfo, 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) } @@ -1342,6 +1351,14 @@ func (s *FullNodeStub) ClientListImports(p0 context.Context) ([]Import, error) { return *new([]Import), xerrors.New("method not supported") } +func (s *FullNodeStruct) ClientListRetrievals(p0 context.Context) ([]RetrievalInfo, error) { + return s.Internal.ClientListRetrievals(p0) +} + +func (s *FullNodeStub) ClientListRetrievals(p0 context.Context) ([]RetrievalInfo, error) { + return *new([]RetrievalInfo), 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) } @@ -3534,14 +3551,6 @@ 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) } diff --git a/api/test/blockminer.go b/api/test/blockminer.go deleted file mode 100644 index 23af94a362d..00000000000 --- a/api/test/blockminer.go +++ /dev/null @@ -1,61 +0,0 @@ -package test - -import ( - "context" - "fmt" - "sync/atomic" - "testing" - "time" - - "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/lotus/miner" -) - -type BlockMiner struct { - ctx context.Context - t *testing.T - miner TestStorageNode - blocktime time.Duration - mine int64 - nulls int64 - done chan struct{} -} - -func NewBlockMiner(ctx context.Context, t *testing.T, miner TestStorageNode, blocktime time.Duration) *BlockMiner { - return &BlockMiner{ - ctx: ctx, - t: t, - miner: miner, - blocktime: blocktime, - mine: int64(1), - done: make(chan struct{}), - } -} - -func (bm *BlockMiner) MineBlocks() { - time.Sleep(time.Second) - go func() { - defer close(bm.done) - for atomic.LoadInt64(&bm.mine) == 1 { - select { - case <-bm.ctx.Done(): - return - case <-time.After(bm.blocktime): - } - - nulls := atomic.SwapInt64(&bm.nulls, 0) - if err := bm.miner.MineOne(bm.ctx, miner.MineReq{ - InjectNulls: abi.ChainEpoch(nulls), - Done: func(bool, abi.ChainEpoch, error) {}, - }); err != nil { - bm.t.Error(err) - } - } - }() -} - -func (bm *BlockMiner) Stop() { - atomic.AddInt64(&bm.mine, -1) - fmt.Println("shutting down mining") - <-bm.done -} diff --git a/api/test/deals.go b/api/test/deals.go deleted file mode 100644 index aa7e23bcc99..00000000000 --- a/api/test/deals.go +++ /dev/null @@ -1,621 +0,0 @@ -package test - -import ( - "bytes" - "context" - "fmt" - "io/ioutil" - "math/rand" - "os" - "path/filepath" - "sort" - "testing" - "time" - - "github.com/ipfs/go-cid" - files "github.com/ipfs/go-ipfs-files" - "github.com/ipld/go-car" - "github.com/stretchr/testify/require" - - "github.com/filecoin-project/go-fil-markets/storagemarket" - "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/go-state-types/big" - "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/chain/actors/builtin/market" - "github.com/filecoin-project/lotus/chain/types" - sealing "github.com/filecoin-project/lotus/extern/storage-sealing" - "github.com/filecoin-project/lotus/extern/storage-sealing/sealiface" - "github.com/filecoin-project/lotus/markets/storageadapter" - "github.com/filecoin-project/lotus/node" - "github.com/filecoin-project/lotus/node/impl" - "github.com/filecoin-project/lotus/node/modules/dtypes" - market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market" - ipld "github.com/ipfs/go-ipld-format" - dag "github.com/ipfs/go-merkledag" - dstest "github.com/ipfs/go-merkledag/test" - unixfile "github.com/ipfs/go-unixfs/file" -) - -func TestDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, carExport, fastRet bool, startEpoch abi.ChainEpoch) { - s := setupOneClientOneMiner(t, b, blocktime) - defer s.blockMiner.Stop() - - MakeDeal(t, s.ctx, 6, s.client, s.miner, carExport, fastRet, startEpoch) -} - -func TestDoubleDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, startEpoch abi.ChainEpoch) { - s := setupOneClientOneMiner(t, b, blocktime) - defer s.blockMiner.Stop() - - MakeDeal(t, s.ctx, 6, s.client, s.miner, false, false, startEpoch) - MakeDeal(t, s.ctx, 7, s.client, s.miner, false, false, startEpoch) -} - -func MakeDeal(t *testing.T, ctx context.Context, rseed int, client api.FullNode, miner TestStorageNode, carExport, fastRet bool, startEpoch abi.ChainEpoch) { - res, data, err := CreateClientFile(ctx, client, rseed, 0) - if err != nil { - t.Fatal(err) - } - - fcid := res.Root - fmt.Println("FILE CID: ", fcid) - - deal := startDeal(t, ctx, miner, client, fcid, fastRet, startEpoch) - - // TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this - time.Sleep(time.Second) - waitDealSealed(t, ctx, miner, client, deal, false, false, nil) - - // Retrieval - info, err := client.ClientGetDealInfo(ctx, *deal) - require.NoError(t, err) - - testRetrieval(t, ctx, client, fcid, &info.PieceCID, carExport, data) -} - -func CreateClientFile(ctx context.Context, client api.FullNode, rseed, size int) (*api.ImportRes, []byte, error) { - if size == 0 { - size = 1600 - } - data := make([]byte, size) - rand.New(rand.NewSource(int64(rseed))).Read(data) - - dir, err := ioutil.TempDir(os.TempDir(), "test-make-deal-") - if err != nil { - return nil, nil, err - } - - path := filepath.Join(dir, "sourcefile.dat") - err = ioutil.WriteFile(path, data, 0644) - if err != nil { - return nil, nil, err - } - - res, err := client.ClientImport(ctx, api.FileRef{Path: path}) - if err != nil { - return nil, nil, err - } - return res, data, nil -} - -func TestPublishDealsBatching(t *testing.T, b APIBuilder, blocktime time.Duration, startEpoch abi.ChainEpoch) { - publishPeriod := 10 * time.Second - maxDealsPerMsg := uint64(2) - - // Set max deals per publish deals message to 2 - minerDef := []StorageMiner{{ - Full: 0, - Opts: node.Override( - new(*storageadapter.DealPublisher), - storageadapter.NewDealPublisher(nil, storageadapter.PublishMsgConfig{ - Period: publishPeriod, - MaxDealsPerMsg: maxDealsPerMsg, - })), - Preseal: PresealGenesis, - }} - - // Create a connect client and miner node - n, sn := b(t, OneFull, minerDef) - client := n[0].FullNode.(*impl.FullNodeAPI) - miner := sn[0] - s := connectAndStartMining(t, b, blocktime, client, miner) - defer s.blockMiner.Stop() - - // Starts a deal and waits until it's published - runDealTillPublish := func(rseed int) { - res, _, err := CreateClientFile(s.ctx, s.client, rseed, 0) - require.NoError(t, err) - - upds, err := client.ClientGetDealUpdates(s.ctx) - require.NoError(t, err) - - startDeal(t, s.ctx, s.miner, s.client, res.Root, false, startEpoch) - - // TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this - time.Sleep(time.Second) - - done := make(chan struct{}) - go func() { - for upd := range upds { - if upd.DataRef.Root == res.Root && upd.State == storagemarket.StorageDealAwaitingPreCommit { - done <- struct{}{} - } - } - }() - <-done - } - - // Run three deals in parallel - done := make(chan struct{}, maxDealsPerMsg+1) - for rseed := 1; rseed <= 3; rseed++ { - rseed := rseed - go func() { - runDealTillPublish(rseed) - done <- struct{}{} - }() - } - - // Wait for two of the deals to be published - for i := 0; i < int(maxDealsPerMsg); i++ { - <-done - } - - // Expect a single PublishStorageDeals message that includes the first two deals - msgCids, err := s.client.StateListMessages(s.ctx, &api.MessageMatch{To: market.Address}, types.EmptyTSK, 1) - require.NoError(t, err) - count := 0 - for _, msgCid := range msgCids { - msg, err := s.client.ChainGetMessage(s.ctx, msgCid) - require.NoError(t, err) - - if msg.Method == market.Methods.PublishStorageDeals { - count++ - var pubDealsParams market2.PublishStorageDealsParams - err = pubDealsParams.UnmarshalCBOR(bytes.NewReader(msg.Params)) - require.NoError(t, err) - require.Len(t, pubDealsParams.Deals, int(maxDealsPerMsg)) - } - } - require.Equal(t, 1, count) - - // The third deal should be published once the publish period expires. - // Allow a little padding as it takes a moment for the state change to - // be noticed by the client. - padding := 10 * time.Second - select { - case <-time.After(publishPeriod + padding): - require.Fail(t, "Expected 3rd deal to be published once publish period elapsed") - case <-done: // Success - } -} - -func TestBatchDealInput(t *testing.T, b APIBuilder, blocktime time.Duration, startEpoch abi.ChainEpoch) { - run := func(piece, deals, expectSectors int) func(t *testing.T) { - return func(t *testing.T) { - publishPeriod := 10 * time.Second - maxDealsPerMsg := uint64(deals) - - // Set max deals per publish deals message to maxDealsPerMsg - minerDef := []StorageMiner{{ - Full: 0, - Opts: node.Options( - node.Override( - new(*storageadapter.DealPublisher), - storageadapter.NewDealPublisher(nil, storageadapter.PublishMsgConfig{ - Period: publishPeriod, - MaxDealsPerMsg: maxDealsPerMsg, - })), - node.Override(new(dtypes.GetSealingConfigFunc), func() (dtypes.GetSealingConfigFunc, error) { - return func() (sealiface.Config, error) { - return sealiface.Config{ - MaxWaitDealsSectors: 2, - MaxSealingSectors: 1, - MaxSealingSectorsForDeals: 3, - AlwaysKeepUnsealedCopy: true, - WaitDealsDelay: time.Hour, - }, nil - }, nil - }), - ), - Preseal: PresealGenesis, - }} - - // Create a connect client and miner node - n, sn := b(t, OneFull, minerDef) - client := n[0].FullNode.(*impl.FullNodeAPI) - miner := sn[0] - s := connectAndStartMining(t, b, blocktime, client, miner) - defer s.blockMiner.Stop() - - err := miner.MarketSetAsk(s.ctx, big.Zero(), big.Zero(), 200, 128, 32<<30) - require.NoError(t, err) - - checkNoPadding := func() { - sl, err := sn[0].SectorsList(s.ctx) - require.NoError(t, err) - - sort.Slice(sl, func(i, j int) bool { - return sl[i] < sl[j] - }) - - for _, snum := range sl { - si, err := sn[0].SectorsStatus(s.ctx, snum, false) - require.NoError(t, err) - - // fmt.Printf("S %d: %+v %s\n", snum, si.Deals, si.State) - - for _, deal := range si.Deals { - if deal == 0 { - fmt.Printf("sector %d had a padding piece!\n", snum) - } - } - } - } - - // Starts a deal and waits until it's published - runDealTillSeal := func(rseed int) { - res, _, err := CreateClientFile(s.ctx, s.client, rseed, piece) - require.NoError(t, err) - - dc := startDeal(t, s.ctx, s.miner, s.client, res.Root, false, startEpoch) - waitDealSealed(t, s.ctx, s.miner, s.client, dc, false, true, checkNoPadding) - } - - // Run maxDealsPerMsg deals in parallel - done := make(chan struct{}, maxDealsPerMsg) - for rseed := 0; rseed < int(maxDealsPerMsg); rseed++ { - rseed := rseed - go func() { - runDealTillSeal(rseed) - done <- struct{}{} - }() - } - - // Wait for maxDealsPerMsg of the deals to be published - for i := 0; i < int(maxDealsPerMsg); i++ { - <-done - } - - checkNoPadding() - - sl, err := sn[0].SectorsList(s.ctx) - require.NoError(t, err) - require.Equal(t, len(sl), expectSectors) - } - } - - t.Run("4-p1600B", run(1600, 4, 4)) - t.Run("4-p513B", run(513, 4, 2)) - if !testing.Short() { - t.Run("32-p257B", run(257, 32, 8)) - t.Run("32-p10B", run(10, 32, 2)) - - // fixme: this appears to break data-transfer / markets in some really creative ways - //t.Run("128-p10B", run(10, 128, 8)) - } -} - -func TestFastRetrievalDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, startEpoch abi.ChainEpoch) { - s := setupOneClientOneMiner(t, b, blocktime) - defer s.blockMiner.Stop() - - data := make([]byte, 1600) - rand.New(rand.NewSource(int64(8))).Read(data) - - r := bytes.NewReader(data) - fcid, err := s.client.ClientImportLocal(s.ctx, r) - if err != nil { - t.Fatal(err) - } - - fmt.Println("FILE CID: ", fcid) - - deal := startDeal(t, s.ctx, s.miner, s.client, fcid, true, startEpoch) - - waitDealPublished(t, s.ctx, s.miner, deal) - fmt.Println("deal published, retrieving") - // Retrieval - info, err := s.client.ClientGetDealInfo(s.ctx, *deal) - require.NoError(t, err) - - testRetrieval(t, s.ctx, s.client, fcid, &info.PieceCID, false, data) -} - -func TestSecondDealRetrieval(t *testing.T, b APIBuilder, blocktime time.Duration) { - s := setupOneClientOneMiner(t, b, blocktime) - defer s.blockMiner.Stop() - - { - data1 := make([]byte, 800) - rand.New(rand.NewSource(int64(3))).Read(data1) - r := bytes.NewReader(data1) - - fcid1, err := s.client.ClientImportLocal(s.ctx, r) - if err != nil { - t.Fatal(err) - } - - data2 := make([]byte, 800) - rand.New(rand.NewSource(int64(9))).Read(data2) - r2 := bytes.NewReader(data2) - - fcid2, err := s.client.ClientImportLocal(s.ctx, r2) - if err != nil { - t.Fatal(err) - } - - deal1 := startDeal(t, s.ctx, s.miner, s.client, fcid1, true, 0) - - // TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this - time.Sleep(time.Second) - waitDealSealed(t, s.ctx, s.miner, s.client, deal1, true, false, nil) - - deal2 := startDeal(t, s.ctx, s.miner, s.client, fcid2, true, 0) - - time.Sleep(time.Second) - waitDealSealed(t, s.ctx, s.miner, s.client, deal2, false, false, nil) - - // Retrieval - info, err := s.client.ClientGetDealInfo(s.ctx, *deal2) - require.NoError(t, err) - - rf, _ := s.miner.SectorsRefs(s.ctx) - fmt.Printf("refs: %+v\n", rf) - - testRetrieval(t, s.ctx, s.client, fcid2, &info.PieceCID, false, data2) - } -} - -func TestZeroPricePerByteRetrievalDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, startEpoch abi.ChainEpoch) { - s := setupOneClientOneMiner(t, b, blocktime) - defer s.blockMiner.Stop() - - // Set price-per-byte to zero - ask, err := s.miner.MarketGetRetrievalAsk(s.ctx) - require.NoError(t, err) - - ask.PricePerByte = abi.NewTokenAmount(0) - err = s.miner.MarketSetRetrievalAsk(s.ctx, ask) - require.NoError(t, err) - - MakeDeal(t, s.ctx, 6, s.client, s.miner, false, false, startEpoch) -} - -func startDeal(t *testing.T, ctx context.Context, miner TestStorageNode, client api.FullNode, fcid cid.Cid, fastRet bool, startEpoch abi.ChainEpoch) *cid.Cid { - maddr, err := miner.ActorAddress(ctx) - if err != nil { - t.Fatal(err) - } - - addr, err := client.WalletDefaultAddress(ctx) - if err != nil { - t.Fatal(err) - } - deal, err := client.ClientStartDeal(ctx, &api.StartDealParams{ - Data: &storagemarket.DataRef{ - TransferType: storagemarket.TTGraphsync, - Root: fcid, - }, - Wallet: addr, - Miner: maddr, - EpochPrice: types.NewInt(1000000), - DealStartEpoch: startEpoch, - MinBlocksDuration: uint64(build.MinDealDuration), - FastRetrieval: fastRet, - }) - if err != nil { - t.Fatalf("%+v", err) - } - return deal -} - -func waitDealSealed(t *testing.T, ctx context.Context, miner TestStorageNode, client api.FullNode, deal *cid.Cid, noseal, noSealStart bool, cb func()) { -loop: - for { - di, err := client.ClientGetDealInfo(ctx, *deal) - if err != nil { - t.Fatal(err) - } - switch di.State { - case storagemarket.StorageDealAwaitingPreCommit, storagemarket.StorageDealSealing: - if noseal { - return - } - if !noSealStart { - startSealingWaiting(t, ctx, miner) - } - case storagemarket.StorageDealProposalRejected: - t.Fatal("deal rejected") - case storagemarket.StorageDealFailing: - t.Fatal("deal failed") - case storagemarket.StorageDealError: - t.Fatal("deal errored", di.Message) - case storagemarket.StorageDealActive: - fmt.Println("COMPLETE", di) - break loop - } - - mds, err := miner.MarketListIncompleteDeals(ctx) - if err != nil { - t.Fatal(err) - } - - var minerState storagemarket.StorageDealStatus - for _, md := range mds { - if md.DealID == di.DealID { - minerState = md.State - break - } - } - - fmt.Printf("Deal %d state: client:%s provider:%s\n", di.DealID, storagemarket.DealStates[di.State], storagemarket.DealStates[minerState]) - time.Sleep(time.Second / 2) - if cb != nil { - cb() - } - } -} - -func waitDealPublished(t *testing.T, ctx context.Context, miner TestStorageNode, deal *cid.Cid) { - subCtx, cancel := context.WithCancel(ctx) - defer cancel() - updates, err := miner.MarketGetDealUpdates(subCtx) - if err != nil { - t.Fatal(err) - } - for { - select { - case <-ctx.Done(): - t.Fatal("context timeout") - case di := <-updates: - if deal.Equals(di.ProposalCid) { - switch di.State { - case storagemarket.StorageDealProposalRejected: - t.Fatal("deal rejected") - case storagemarket.StorageDealFailing: - t.Fatal("deal failed") - case storagemarket.StorageDealError: - t.Fatal("deal errored", di.Message) - case storagemarket.StorageDealFinalizing, storagemarket.StorageDealAwaitingPreCommit, storagemarket.StorageDealSealing, storagemarket.StorageDealActive: - fmt.Println("COMPLETE", di) - return - } - fmt.Println("Deal state: ", storagemarket.DealStates[di.State]) - } - } - } -} - -func startSealingWaiting(t *testing.T, ctx context.Context, miner TestStorageNode) { - snums, err := miner.SectorsList(ctx) - require.NoError(t, err) - - for _, snum := range snums { - si, err := miner.SectorsStatus(ctx, snum, false) - require.NoError(t, err) - - t.Logf("Sector %d state: %s", snum, si.State) - if si.State == api.SectorState(sealing.WaitDeals) { - require.NoError(t, miner.SectorStartSealing(ctx, snum)) - } - } - - flushSealingBatches(t, ctx, miner) -} - -func testRetrieval(t *testing.T, ctx context.Context, client api.FullNode, fcid cid.Cid, piece *cid.Cid, carExport bool, data []byte) { - offers, err := client.ClientFindData(ctx, fcid, piece) - if err != nil { - t.Fatal(err) - } - - if len(offers) < 1 { - t.Fatal("no offers") - } - - rpath, err := ioutil.TempDir("", "lotus-retrieve-test-") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(rpath) //nolint:errcheck - - caddr, err := client.WalletDefaultAddress(ctx) - if err != nil { - t.Fatal(err) - } - - ref := &api.FileRef{ - Path: filepath.Join(rpath, "ret"), - IsCAR: carExport, - } - updates, err := client.ClientRetrieveWithEvents(ctx, offers[0].Order(caddr), ref) - if err != nil { - t.Fatal(err) - } - for update := range updates { - if update.Err != "" { - t.Fatalf("retrieval failed: %s", update.Err) - } - } - - rdata, err := ioutil.ReadFile(filepath.Join(rpath, "ret")) - if err != nil { - t.Fatal(err) - } - - if carExport { - rdata = extractCarData(t, ctx, rdata, rpath) - } - - if !bytes.Equal(rdata, data) { - t.Fatal("wrong data retrieved") - } -} - -func extractCarData(t *testing.T, ctx context.Context, rdata []byte, rpath string) []byte { - bserv := dstest.Bserv() - ch, err := car.LoadCar(bserv.Blockstore(), bytes.NewReader(rdata)) - if err != nil { - t.Fatal(err) - } - b, err := bserv.GetBlock(ctx, ch.Roots[0]) - if err != nil { - t.Fatal(err) - } - nd, err := ipld.Decode(b) - if err != nil { - t.Fatal(err) - } - dserv := dag.NewDAGService(bserv) - fil, err := unixfile.NewUnixfsFile(ctx, dserv, nd) - if err != nil { - t.Fatal(err) - } - outPath := filepath.Join(rpath, "retLoadedCAR") - if err := files.WriteTo(fil, outPath); err != nil { - t.Fatal(err) - } - rdata, err = ioutil.ReadFile(outPath) - if err != nil { - t.Fatal(err) - } - return rdata -} - -type dealsScaffold struct { - ctx context.Context - client *impl.FullNodeAPI - miner TestStorageNode - blockMiner *BlockMiner -} - -func setupOneClientOneMiner(t *testing.T, b APIBuilder, blocktime time.Duration) *dealsScaffold { - n, sn := b(t, OneFull, OneMiner) - client := n[0].FullNode.(*impl.FullNodeAPI) - miner := sn[0] - return connectAndStartMining(t, b, blocktime, client, miner) -} - -func connectAndStartMining(t *testing.T, b APIBuilder, blocktime time.Duration, client *impl.FullNodeAPI, miner TestStorageNode) *dealsScaffold { - ctx := context.Background() - addrinfo, err := client.NetAddrsListen(ctx) - if err != nil { - t.Fatal(err) - } - - if err := miner.NetConnect(ctx, addrinfo); err != nil { - t.Fatal(err) - } - time.Sleep(time.Second) - - blockMiner := NewBlockMiner(ctx, t, miner, blocktime) - blockMiner.MineBlocks() - - return &dealsScaffold{ - ctx: ctx, - client: client, - miner: miner, - blockMiner: blockMiner, - } -} diff --git a/api/test/mining.go b/api/test/mining.go deleted file mode 100644 index d6dea9abfd5..00000000000 --- a/api/test/mining.go +++ /dev/null @@ -1,240 +0,0 @@ -package test - -import ( - "bytes" - "context" - "fmt" - "math/rand" - "sync/atomic" - "testing" - "time" - - logging "github.com/ipfs/go-log/v2" - - "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" -) - -//nolint:deadcode,varcheck -var log = logging.Logger("apitest") - -func (ts *testSuite) testMining(t *testing.T) { - ctx := context.Background() - apis, sn := ts.makeNodes(t, OneFull, OneMiner) - api := apis[0] - - newHeads, err := api.ChainNotify(ctx) - require.NoError(t, err) - initHead := (<-newHeads)[0] - baseHeight := initHead.Val.Height() - - h1, err := api.ChainHead(ctx) - require.NoError(t, err) - require.Equal(t, int64(h1.Height()), int64(baseHeight)) - - MineUntilBlock(ctx, t, apis[0], sn[0], nil) - require.NoError(t, err) - - <-newHeads - - h2, err := api.ChainHead(ctx) - require.NoError(t, err) - require.Greater(t, int64(h2.Height()), int64(h1.Height())) -} - -func (ts *testSuite) testMiningReal(t *testing.T) { - build.InsecurePoStValidation = false - defer func() { - build.InsecurePoStValidation = true - }() - - ctx := context.Background() - apis, sn := ts.makeNodes(t, OneFull, OneMiner) - api := apis[0] - - newHeads, err := api.ChainNotify(ctx) - require.NoError(t, err) - at := (<-newHeads)[0].Val.Height() - - h1, err := api.ChainHead(ctx) - require.NoError(t, err) - require.Equal(t, int64(at), int64(h1.Height())) - - MineUntilBlock(ctx, t, apis[0], sn[0], nil) - require.NoError(t, err) - - <-newHeads - - h2, err := api.ChainHead(ctx) - require.NoError(t, err) - require.Greater(t, int64(h2.Height()), int64(h1.Height())) - - MineUntilBlock(ctx, t, apis[0], sn[0], nil) - require.NoError(t, err) - - <-newHeads - - h3, err := api.ChainHead(ctx) - require.NoError(t, err) - require.Greater(t, int64(h3.Height()), int64(h2.Height())) -} - -func TestDealMining(t *testing.T, b APIBuilder, blocktime time.Duration, carExport bool) { - // test making a deal with a fresh miner, and see if it starts to mine - - ctx := context.Background() - n, sn := b(t, OneFull, []StorageMiner{ - {Full: 0, Preseal: PresealGenesis}, - {Full: 0, Preseal: 0}, // TODO: Add support for miners on non-first full node - }) - client := n[0].FullNode.(*impl.FullNodeAPI) - provider := sn[1] - genesisMiner := sn[0] - - addrinfo, err := client.NetAddrsListen(ctx) - if err != nil { - t.Fatal(err) - } - - if err := provider.NetConnect(ctx, addrinfo); err != nil { - t.Fatal(err) - } - - if err := genesisMiner.NetConnect(ctx, addrinfo); err != nil { - t.Fatal(err) - } - - time.Sleep(time.Second) - - data := make([]byte, 600) - rand.New(rand.NewSource(5)).Read(data) - - r := bytes.NewReader(data) - fcid, err := client.ClientImportLocal(ctx, r) - if err != nil { - t.Fatal(err) - } - - fmt.Println("FILE CID: ", fcid) - - var mine int32 = 1 - done := make(chan struct{}) - minedTwo := make(chan struct{}) - - m2addr, err := sn[1].ActorAddress(context.TODO()) - if err != nil { - t.Fatal(err) - } - - go func() { - defer close(done) - - complChan := minedTwo - for atomic.LoadInt32(&mine) != 0 { - wait := make(chan int) - mdone := func(mined bool, _ abi.ChainEpoch, err error) { - n := 0 - if mined { - n = 1 - } - wait <- n - } - - if err := sn[0].MineOne(ctx, miner.MineReq{Done: mdone}); err != nil { - t.Error(err) - } - - if err := sn[1].MineOne(ctx, miner.MineReq{Done: mdone}); err != nil { - t.Error(err) - } - - expect := <-wait - expect += <-wait - - time.Sleep(blocktime) - if expect == 0 { - // null block - continue - } - - var nodeOneMined bool - for _, node := range sn { - mb, err := node.MiningBase(ctx) - if err != nil { - t.Error(err) - return - } - - for _, b := range mb.Blocks() { - if b.Miner == m2addr { - nodeOneMined = true - break - } - } - - } - - if nodeOneMined && complChan != nil { - close(complChan) - complChan = nil - } - - } - }() - - deal := startDeal(t, ctx, provider, client, fcid, false, 0) - - // TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this - time.Sleep(time.Second) - - waitDealSealed(t, ctx, provider, client, deal, false, false, nil) - - <-minedTwo - - atomic.StoreInt32(&mine, 0) - 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/pledge.go b/api/test/pledge.go deleted file mode 100644 index 08548dc6095..00000000000 --- a/api/test/pledge.go +++ /dev/null @@ -1,389 +0,0 @@ -package test - -import ( - "context" - "fmt" - "sort" - "strings" - "sync/atomic" - "testing" - "time" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/go-state-types/network" - - "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/chain/stmgr" - sealing "github.com/filecoin-project/lotus/extern/storage-sealing" - bminer "github.com/filecoin-project/lotus/miner" - "github.com/filecoin-project/lotus/node" - "github.com/filecoin-project/lotus/node/impl" -) - -func TestSDRUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - n, sn := b(t, []FullNodeOpts{FullNodeWithSDRAt(500, 1000)}, OneMiner) - client := n[0].FullNode.(*impl.FullNodeAPI) - miner := sn[0] - - addrinfo, err := client.NetAddrsListen(ctx) - if err != nil { - t.Fatal(err) - } - - if err := miner.NetConnect(ctx, addrinfo); err != nil { - t.Fatal(err) - } - build.Clock.Sleep(time.Second) - - pledge := make(chan struct{}) - mine := int64(1) - done := make(chan struct{}) - go func() { - defer close(done) - round := 0 - for atomic.LoadInt64(&mine) != 0 { - build.Clock.Sleep(blocktime) - if err := sn[0].MineOne(ctx, bminer.MineReq{Done: func(bool, abi.ChainEpoch, error) { - - }}); err != nil { - t.Error(err) - } - - // 3 sealing rounds: before, during after. - if round >= 3 { - continue - } - - head, err := client.ChainHead(ctx) - assert.NoError(t, err) - - // rounds happen every 100 blocks, with a 50 block offset. - if head.Height() >= abi.ChainEpoch(round*500+50) { - round++ - pledge <- struct{}{} - - ver, err := client.StateNetworkVersion(ctx, head.Key()) - assert.NoError(t, err) - switch round { - case 1: - assert.Equal(t, network.Version6, ver) - case 2: - assert.Equal(t, network.Version7, ver) - case 3: - assert.Equal(t, network.Version8, ver) - } - } - - } - }() - - // before. - pledgeSectors(t, ctx, miner, 9, 0, pledge) - - s, err := miner.SectorsList(ctx) - require.NoError(t, err) - sort.Slice(s, func(i, j int) bool { - return s[i] < s[j] - }) - - for i, id := range s { - info, err := miner.SectorsStatus(ctx, id, true) - require.NoError(t, err) - expectProof := abi.RegisteredSealProof_StackedDrg2KiBV1 - if i >= 3 { - // after - expectProof = abi.RegisteredSealProof_StackedDrg2KiBV1_1 - } - assert.Equal(t, expectProof, info.SealProof, "sector %d, id %d", i, id) - } - - atomic.StoreInt64(&mine, 0) - <-done -} - -func TestPledgeBatching(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - n, sn := b(t, []FullNodeOpts{FullNodeWithLatestActorsAt(-1)}, OneMiner) - client := n[0].FullNode.(*impl.FullNodeAPI) - miner := sn[0] - - addrinfo, err := client.NetAddrsListen(ctx) - if err != nil { - t.Fatal(err) - } - - if err := miner.NetConnect(ctx, addrinfo); err != nil { - t.Fatal(err) - } - build.Clock.Sleep(time.Second) - - mine := int64(1) - done := make(chan struct{}) - go func() { - defer close(done) - for atomic.LoadInt64(&mine) != 0 { - build.Clock.Sleep(blocktime) - if err := sn[0].MineOne(ctx, bminer.MineReq{Done: func(bool, abi.ChainEpoch, error) { - - }}); err != nil { - t.Error(err) - } - } - }() - - for { - h, err := client.ChainHead(ctx) - require.NoError(t, err) - if h.Height() > 10 { - break - } - } - - toCheck := startPledge(t, ctx, miner, nSectors, 0, nil) - - for len(toCheck) > 0 { - states := map[api.SectorState]int{} - - for n := range toCheck { - st, err := miner.SectorsStatus(ctx, n, false) - require.NoError(t, err) - states[st.State]++ - if st.State == api.SectorState(sealing.Proving) { - delete(toCheck, n) - } - if strings.Contains(string(st.State), "Fail") { - t.Fatal("sector in a failed state", st.State) - } - } - if states[api.SectorState(sealing.SubmitPreCommitBatch)] == nSectors || - (states[api.SectorState(sealing.SubmitPreCommitBatch)] > 0 && states[api.SectorState(sealing.PreCommit1)] == 0 && states[api.SectorState(sealing.PreCommit2)] == 0) { - pcb, err := miner.SectorPreCommitFlush(ctx) - require.NoError(t, err) - if pcb != nil { - fmt.Printf("PRECOMMIT BATCH: %+v\n", pcb) - } - } - - if states[api.SectorState(sealing.SubmitCommitAggregate)] == nSectors || - (states[api.SectorState(sealing.SubmitCommitAggregate)] > 0 && states[api.SectorState(sealing.WaitSeed)] == 0 && states[api.SectorState(sealing.Committing)] == 0) { - cb, err := miner.SectorCommitFlush(ctx) - require.NoError(t, err) - if cb != nil { - fmt.Printf("COMMIT BATCH: %+v\n", cb) - } - } - - build.Clock.Sleep(100 * time.Millisecond) - fmt.Printf("WaitSeal: %d %+v\n", len(toCheck), states) - } - - atomic.StoreInt64(&mine, 0) - <-done -} - -func TestPledgeBeforeNv13(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - n, sn := b(t, []FullNodeOpts{ - { - Opts: func(nodes []TestNode) node.Option { - return node.Override(new(stmgr.UpgradeSchedule), stmgr.UpgradeSchedule{{ - Network: network.Version9, - Height: 1, - Migration: stmgr.UpgradeActorsV2, - }, { - Network: network.Version10, - Height: 2, - Migration: stmgr.UpgradeActorsV3, - }, { - Network: network.Version12, - Height: 3, - Migration: stmgr.UpgradeActorsV4, - }, { - Network: network.Version13, - Height: 1000000000, - Migration: stmgr.UpgradeActorsV5, - }}) - }, - }, - }, OneMiner) - client := n[0].FullNode.(*impl.FullNodeAPI) - miner := sn[0] - - addrinfo, err := client.NetAddrsListen(ctx) - if err != nil { - t.Fatal(err) - } - - if err := miner.NetConnect(ctx, addrinfo); err != nil { - t.Fatal(err) - } - build.Clock.Sleep(time.Second) - - mine := int64(1) - done := make(chan struct{}) - go func() { - defer close(done) - for atomic.LoadInt64(&mine) != 0 { - build.Clock.Sleep(blocktime) - if err := sn[0].MineOne(ctx, bminer.MineReq{Done: func(bool, abi.ChainEpoch, error) { - - }}); err != nil { - t.Error(err) - } - } - }() - - for { - h, err := client.ChainHead(ctx) - require.NoError(t, err) - if h.Height() > 10 { - break - } - } - - toCheck := startPledge(t, ctx, miner, nSectors, 0, nil) - - for len(toCheck) > 0 { - states := map[api.SectorState]int{} - - for n := range toCheck { - st, err := miner.SectorsStatus(ctx, n, false) - require.NoError(t, err) - states[st.State]++ - if st.State == api.SectorState(sealing.Proving) { - delete(toCheck, n) - } - if strings.Contains(string(st.State), "Fail") { - t.Fatal("sector in a failed state", st.State) - } - } - - build.Clock.Sleep(100 * time.Millisecond) - fmt.Printf("WaitSeal: %d %+v\n", len(toCheck), states) - } - - atomic.StoreInt64(&mine, 0) - <-done -} - -func TestPledgeSector(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - n, sn := b(t, OneFull, OneMiner) - client := n[0].FullNode.(*impl.FullNodeAPI) - miner := sn[0] - - addrinfo, err := client.NetAddrsListen(ctx) - if err != nil { - t.Fatal(err) - } - - if err := miner.NetConnect(ctx, addrinfo); err != nil { - t.Fatal(err) - } - build.Clock.Sleep(time.Second) - - mine := int64(1) - done := make(chan struct{}) - go func() { - defer close(done) - for atomic.LoadInt64(&mine) != 0 { - build.Clock.Sleep(blocktime) - if err := sn[0].MineOne(ctx, bminer.MineReq{Done: func(bool, abi.ChainEpoch, error) { - - }}); err != nil { - t.Error(err) - } - } - }() - - pledgeSectors(t, ctx, miner, nSectors, 0, nil) - - atomic.StoreInt64(&mine, 0) - <-done -} - -func flushSealingBatches(t *testing.T, ctx context.Context, miner TestStorageNode) { - pcb, err := miner.SectorPreCommitFlush(ctx) - require.NoError(t, err) - if pcb != nil { - fmt.Printf("PRECOMMIT BATCH: %+v\n", pcb) - } - - cb, err := miner.SectorCommitFlush(ctx) - require.NoError(t, err) - if cb != nil { - fmt.Printf("COMMIT BATCH: %+v\n", cb) - } -} - -func startPledge(t *testing.T, ctx context.Context, miner TestStorageNode, n, existing int, blockNotif <-chan struct{}) map[abi.SectorNumber]struct{} { - for i := 0; i < n; i++ { - if i%3 == 0 && blockNotif != nil { - <-blockNotif - log.Errorf("WAIT") - } - log.Errorf("PLEDGING %d", i) - _, err := miner.PledgeSector(ctx) - require.NoError(t, err) - } - - for { - s, err := miner.SectorsList(ctx) // Note - the test builder doesn't import genesis sectors into FSM - require.NoError(t, err) - fmt.Printf("Sectors: %d\n", len(s)) - if len(s) >= n+existing { - break - } - - build.Clock.Sleep(100 * time.Millisecond) - } - - fmt.Printf("All sectors is fsm\n") - - s, err := miner.SectorsList(ctx) - require.NoError(t, err) - - toCheck := map[abi.SectorNumber]struct{}{} - for _, number := range s { - toCheck[number] = struct{}{} - } - - return toCheck -} - -func pledgeSectors(t *testing.T, ctx context.Context, miner TestStorageNode, n, existing int, blockNotif <-chan struct{}) { - toCheck := startPledge(t, ctx, miner, n, existing, blockNotif) - - for len(toCheck) > 0 { - flushSealingBatches(t, ctx, miner) - - states := map[api.SectorState]int{} - for n := range toCheck { - st, err := miner.SectorsStatus(ctx, n, false) - require.NoError(t, err) - states[st.State]++ - if st.State == api.SectorState(sealing.Proving) { - delete(toCheck, n) - } - if strings.Contains(string(st.State), "Fail") { - t.Fatal("sector in a failed state", st.State) - } - } - - build.Clock.Sleep(100 * time.Millisecond) - fmt.Printf("WaitSeal: %d %+v\n", len(toCheck), states) - } -} diff --git a/api/test/test.go b/api/test/test.go deleted file mode 100644 index 64062e4ff23..00000000000 --- a/api/test/test.go +++ /dev/null @@ -1,313 +0,0 @@ -package test - -import ( - "context" - "fmt" - "os" - "strings" - "testing" - "time" - - 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" - - 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" -) - -func init() { - logging.SetAllLoggers(logging.LevelInfo) - err := os.Setenv("BELLMAN_NO_GPU", "1") - if err != nil { - panic(fmt.Sprintf("failed to set BELLMAN_NO_GPU env variable: %s", err)) - } - build.InsecurePoStValidation = true -} - -type StorageBuilder func(context.Context, *testing.T, abi.RegisteredSealProof, address.Address) TestStorageNode - -type TestNode struct { - 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 { - 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 - - MineOne func(context.Context, miner.MineReq) error - Stop func(context.Context) error -} - -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 - Opts node.Option - Preseal int -} - -type OptionGenerator func([]TestNode) node.Option - -// Options for setting up a mock full node -type FullNodeOpts struct { - Lite bool // run node in "lite" mode - Opts OptionGenerator // generate dependency injection options -} - -// APIBuilder is a function which is invoked in test suite to provide -// test nodes and networks -// -// fullOpts array defines options for each full node -// storage array defines storage nodes, numbers in the array specify full node -// index the storage node 'belongs' to -type APIBuilder func(t *testing.T, full []FullNodeOpts, storage []StorageMiner) ([]TestNode, []TestStorageNode) -type testSuite struct { - makeNodes APIBuilder -} - -// TestApis is the entry point to API test suite -func TestApis(t *testing.T, b APIBuilder) { - ts := testSuite{ - makeNodes: b, - } - - t.Run("version", ts.testVersion) - t.Run("id", ts.testID) - t.Run("testConnectTwo", ts.testConnectTwo) - 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 { - full := make([]FullNodeOpts, nFull) - for i := range full { - full[i] = FullNodeOpts{ - Opts: func(nodes []TestNode) node.Option { - return node.Options() - }, - } - } - return full -} - -var OneMiner = []StorageMiner{{Full: 0, Preseal: PresealGenesis}} -var OneFull = DefaultFullOpts(1) -var TwoFull = DefaultFullOpts(2) - -var FullNodeWithLatestActorsAt = func(upgradeHeight abi.ChainEpoch) FullNodeOpts { - // Attention: Update this when introducing new actor versions or your tests will be sad - return FullNodeWithNetworkUpgradeAt(network.Version13, upgradeHeight) -} - -var FullNodeWithNetworkUpgradeAt = func(version network.Version, upgradeHeight abi.ChainEpoch) FullNodeOpts { - fullSchedule := stmgr.UpgradeSchedule{{ - // prepare for upgrade. - Network: network.Version9, - Height: 1, - Migration: stmgr.UpgradeActorsV2, - }, { - Network: network.Version10, - Height: 2, - Migration: stmgr.UpgradeActorsV3, - }, { - Network: network.Version12, - Height: 3, - Migration: stmgr.UpgradeActorsV4, - }, { - Network: network.Version13, - Height: 4, - Migration: stmgr.UpgradeActorsV5, - }} - - schedule := stmgr.UpgradeSchedule{} - for _, upgrade := range fullSchedule { - if upgrade.Network > version { - break - } - - schedule = append(schedule, upgrade) - } - - if upgradeHeight > 0 { - schedule[len(schedule)-1].Height = upgradeHeight - } - - return FullNodeOpts{ - Opts: func(nodes []TestNode) node.Option { - return node.Override(new(stmgr.UpgradeSchedule), schedule) - }, - } -} - -var FullNodeWithSDRAt = func(calico, persian abi.ChainEpoch) FullNodeOpts { - return FullNodeOpts{ - Opts: func(nodes []TestNode) node.Option { - return node.Override(new(stmgr.UpgradeSchedule), stmgr.UpgradeSchedule{{ - Network: network.Version6, - Height: 1, - Migration: stmgr.UpgradeActorsV2, - }, { - Network: network.Version7, - Height: calico, - Migration: stmgr.UpgradeCalico, - }, { - Network: network.Version8, - Height: persian, - }}) - }, - } -} - -var MineNext = miner.MineReq{ - InjectNulls: 0, - Done: func(bool, abi.ChainEpoch, error) {}, -} - -func (ts *testSuite) testVersion(t *testing.T) { - lapi.RunningNodeType = lapi.NodeFull - t.Cleanup(func() { - lapi.RunningNodeType = lapi.NodeUnknown - }) - - ctx := context.Background() - apis, _ := ts.makeNodes(t, OneFull, OneMiner) - napi := apis[0] - - v, err := napi.Version(ctx) - if err != nil { - t.Fatal(err) - } - versions := strings.Split(v.Version, "+") - if len(versions) <= 0 { - t.Fatal("empty version") - } - require.Equal(t, versions[0], build.BuildVersion) -} - -func (ts *testSuite) testSearchMsg(t *testing.T) { - apis, miners := ts.makeNodes(t, OneFull, OneMiner) - - api := apis[0] - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - senderAddr, err := api.WalletDefaultAddress(ctx) - if err != nil { - t.Fatal(err) - } - - msg := &types.Message{ - From: senderAddr, - To: senderAddr, - Value: big.Zero(), - } - bm := NewBlockMiner(ctx, t, miners[0], 100*time.Millisecond) - bm.MineBlocks() - defer bm.Stop() - - sm, err := api.MpoolPushMessage(ctx, msg, nil) - if err != nil { - t.Fatal(err) - } - res, err := api.StateWaitMsg(ctx, sm.Cid(), 1, lapi.LookbackNoLimit, true) - if err != nil { - t.Fatal(err) - } - if res.Receipt.ExitCode != 0 { - t.Fatal("did not successfully send message") - } - - searchRes, err := api.StateSearchMsg(ctx, types.EmptyTSK, sm.Cid(), lapi.LookbackNoLimit, true) - if err != nil { - t.Fatal(err) - } - - if searchRes.TipSet != res.TipSet { - t.Fatalf("search ts: %s, different from wait ts: %s", searchRes.TipSet, res.TipSet) - } - -} - -func (ts *testSuite) testID(t *testing.T) { - ctx := context.Background() - apis, _ := ts.makeNodes(t, OneFull, OneMiner) - api := apis[0] - - id, err := api.ID(ctx) - if err != nil { - t.Fatal(err) - } - assert.Regexp(t, "^12", id.Pretty()) -} - -func (ts *testSuite) testConnectTwo(t *testing.T) { - ctx := context.Background() - apis, _ := ts.makeNodes(t, TwoFull, OneMiner) - - p, err := apis[0].NetPeers(ctx) - if err != nil { - t.Fatal(err) - } - if len(p) != 0 { - t.Error("Node 0 has a peer") - } - - p, err = apis[1].NetPeers(ctx) - if err != nil { - t.Fatal(err) - } - if len(p) != 0 { - t.Error("Node 1 has a peer") - } - - addrs, err := apis[1].NetAddrsListen(ctx) - if err != nil { - t.Fatal(err) - } - - if err := apis[0].NetConnect(ctx, addrs); err != nil { - t.Fatal(err) - } - - p, err = apis[0].NetPeers(ctx) - if err != nil { - t.Fatal(err) - } - if len(p) != 1 { - t.Error("Node 0 doesn't have 1 peer") - } - - p, err = apis[1].NetPeers(ctx) - if err != nil { - t.Fatal(err) - } - if len(p) != 1 { - t.Error("Node 0 doesn't have 1 peer") - } -} diff --git a/api/test/util.go b/api/test/util.go deleted file mode 100644 index 219dcf9ed73..00000000000 --- a/api/test/util.go +++ /dev/null @@ -1,87 +0,0 @@ -package test - -import ( - "context" - "testing" - "time" - - "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" -) - -func SendFunds(ctx context.Context, t *testing.T, sender TestNode, addr address.Address, amount abi.TokenAmount) { - senderAddr, err := sender.WalletDefaultAddress(ctx) - if err != nil { - t.Fatal(err) - } - - msg := &types.Message{ - From: senderAddr, - To: addr, - Value: amount, - } - - sm, err := sender.MpoolPushMessage(ctx, msg, nil) - if err != nil { - t.Fatal(err) - } - res, err := sender.StateWaitMsg(ctx, sm.Cid(), 3, lapi.LookbackNoLimit, true) - if err != nil { - t.Fatal(err) - } - if res.Receipt.ExitCode != 0 { - t.Fatal("did not successfully send money") - } -} - -func MineUntilBlock(ctx context.Context, t *testing.T, fn TestNode, sn TestStorageNode, cb func(abi.ChainEpoch)) { - for i := 0; i < 1000; i++ { - var success bool - var err error - var epoch abi.ChainEpoch - wait := make(chan struct{}) - mineErr := sn.MineOne(ctx, miner.MineReq{ - Done: func(win bool, ep abi.ChainEpoch, e error) { - success = win - err = e - epoch = ep - wait <- struct{}{} - }, - }) - if mineErr != nil { - t.Fatal(mineErr) - } - <-wait - if err != nil { - t.Fatal(err) - } - if success { - // Wait until it shows up on the given full nodes ChainHead - nloops := 50 - for i := 0; i < nloops; i++ { - ts, err := fn.ChainHead(ctx) - if err != nil { - t.Fatal(err) - } - if ts.Height() == epoch { - break - } - if i == nloops-1 { - t.Fatal("block never managed to sync to node") - } - time.Sleep(time.Millisecond * 10) - } - - if cb != nil { - cb(epoch) - } - return - } - t.Log("did not mine block, trying again", i) - } - t.Fatal("failed to mine 1000 times in a row...") -} diff --git a/api/test/window_post.go b/api/test/window_post.go deleted file mode 100644 index 6d317676ea0..00000000000 --- a/api/test/window_post.go +++ /dev/null @@ -1,1002 +0,0 @@ -package test - -import ( - "context" - "fmt" - "testing" - "time" - - "github.com/filecoin-project/go-state-types/big" - - "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/crypto" - "github.com/filecoin-project/go-state-types/dline" - "github.com/filecoin-project/lotus/extern/sector-storage/mock" - sealing "github.com/filecoin-project/lotus/extern/storage-sealing" - proof3 "github.com/filecoin-project/specs-actors/v3/actors/runtime/proof" - "github.com/filecoin-project/specs-storage/storage" - - "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/chain/actors" - minerActor "github.com/filecoin-project/lotus/chain/actors/builtin/miner" - "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/node/impl" -) - -func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int) { - for _, height := range []abi.ChainEpoch{ - -1, // before - 162, // while sealing - 5000, // while proving - } { - height := height // copy to satisfy lints - t.Run(fmt.Sprintf("upgrade-%d", height), func(t *testing.T) { - testWindowPostUpgrade(t, b, blocktime, nSectors, height) - }) - } - -} - -func testWindowPostUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int, - upgradeHeight abi.ChainEpoch) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - n, sn := b(t, []FullNodeOpts{FullNodeWithLatestActorsAt(upgradeHeight)}, OneMiner) - - client := n[0].FullNode.(*impl.FullNodeAPI) - miner := sn[0] - - addrinfo, err := client.NetAddrsListen(ctx) - if err != nil { - t.Fatal(err) - } - - if err := miner.NetConnect(ctx, addrinfo); err != nil { - t.Fatal(err) - } - build.Clock.Sleep(time.Second) - - done := make(chan struct{}) - go func() { - defer close(done) - for ctx.Err() == nil { - build.Clock.Sleep(blocktime) - if err := sn[0].MineOne(ctx, MineNext); err != nil { - if ctx.Err() != nil { - // context was canceled, ignore the error. - return - } - t.Error(err) - } - } - }() - defer func() { - cancel() - <-done - }() - - pledgeSectors(t, ctx, miner, nSectors, 0, nil) - - maddr, err := miner.ActorAddress(ctx) - require.NoError(t, err) - - di, err := client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK) - require.NoError(t, err) - - mid, err := address.IDFromAddress(maddr) - require.NoError(t, err) - - fmt.Printf("Running one proving period\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+di.WPoStProvingPeriod+2 { - fmt.Printf("Now head.Height = %d\n", head.Height()) - break - } - build.Clock.Sleep(blocktime) - } - - p, err := client.StateMinerPower(ctx, maddr, types.EmptyTSK) - require.NoError(t, err) - - ssz, err := miner.ActorSectorSize(ctx, maddr) - require.NoError(t, err) - - require.Equal(t, p.MinerPower, p.TotalPower) - require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz)*uint64(nSectors+GenesisPreseals))) - - fmt.Printf("Drop some sectors\n") - - // Drop 2 sectors from deadline 2 partition 0 (full partition / deadline) - { - parts, err := client.StateMinerPartitions(ctx, maddr, 2, types.EmptyTSK) - require.NoError(t, err) - require.Greater(t, len(parts), 0) - - secs := parts[0].AllSectors - n, err := secs.Count() - require.NoError(t, err) - require.Equal(t, uint64(2), n) - - // Drop the partition - err = secs.ForEach(func(sid uint64) error { - return miner.StorageMiner.(*impl.StorageMinerAPI).IStorageMgr.(*mock.SectorMgr).MarkCorrupted(storage.SectorRef{ - ID: abi.SectorID{ - Miner: abi.ActorID(mid), - Number: abi.SectorNumber(sid), - }, - }, true) - }) - require.NoError(t, err) - } - - var s storage.SectorRef - - // Drop 1 sectors from deadline 3 partition 0 - { - parts, err := client.StateMinerPartitions(ctx, maddr, 3, types.EmptyTSK) - require.NoError(t, err) - require.Greater(t, len(parts), 0) - - secs := parts[0].AllSectors - n, err := secs.Count() - require.NoError(t, err) - require.Equal(t, uint64(2), n) - - // Drop the sector - sn, err := secs.First() - require.NoError(t, err) - - all, err := secs.All(2) - require.NoError(t, err) - fmt.Println("the sectors", all) - - s = storage.SectorRef{ - ID: abi.SectorID{ - Miner: abi.ActorID(mid), - Number: abi.SectorNumber(sn), - }, - } - - err = miner.StorageMiner.(*impl.StorageMinerAPI).IStorageMgr.(*mock.SectorMgr).MarkFailed(s, true) - require.NoError(t, err) - } - - di, err = client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK) - require.NoError(t, err) - - fmt.Printf("Go through another PP, wait for sectors to become faulty\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+(di.WPoStProvingPeriod)+2 { - fmt.Printf("Now head.Height = %d\n", head.Height()) - break - } - - build.Clock.Sleep(blocktime) - } - - p, err = client.StateMinerPower(ctx, maddr, types.EmptyTSK) - require.NoError(t, err) - - require.Equal(t, p.MinerPower, p.TotalPower) - - sectors := p.MinerPower.RawBytePower.Uint64() / uint64(ssz) - require.Equal(t, nSectors+GenesisPreseals-3, int(sectors)) // -3 just removed sectors - - fmt.Printf("Recover one sector\n") - - err = miner.StorageMiner.(*impl.StorageMinerAPI).IStorageMgr.(*mock.SectorMgr).MarkFailed(s, false) - require.NoError(t, err) - - di, err = client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK) - require.NoError(t, err) - - 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+di.WPoStProvingPeriod+2 { - fmt.Printf("Now head.Height = %d\n", head.Height()) - break - } - - build.Clock.Sleep(blocktime) - } - - p, err = client.StateMinerPower(ctx, maddr, types.EmptyTSK) - require.NoError(t, err) - - require.Equal(t, p.MinerPower, p.TotalPower) - - sectors = p.MinerPower.RawBytePower.Uint64() / uint64(ssz) - require.Equal(t, nSectors+GenesisPreseals-2, int(sectors)) // -2 not recovered sectors - - // pledge a sector after recovery - - pledgeSectors(t, ctx, miner, 1, nSectors, nil) - - { - // Wait until proven. - di, err = client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK) - require.NoError(t, err) - - waitUntil := di.PeriodStart + di.WPoStProvingPeriod + 2 - fmt.Printf("End for head.Height > %d\n", waitUntil) - - for { - head, err := client.ChainHead(ctx) - require.NoError(t, err) - - if head.Height() > waitUntil { - fmt.Printf("Now head.Height = %d\n", head.Height()) - break - } - } - } - - p, err = client.StateMinerPower(ctx, maddr, types.EmptyTSK) - require.NoError(t, err) - - require.Equal(t, p.MinerPower, p.TotalPower) - - sectors = p.MinerPower.RawBytePower.Uint64() / uint64(ssz) - require.Equal(t, nSectors+GenesisPreseals-2+1, int(sectors)) // -2 not recovered sectors + 1 just pledged -} - -func TestTerminate(t *testing.T, b APIBuilder, blocktime time.Duration) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - nSectors := uint64(2) - - n, sn := b(t, []FullNodeOpts{FullNodeWithLatestActorsAt(-1)}, []StorageMiner{{Full: 0, Preseal: int(nSectors)}}) - - client := n[0].FullNode.(*impl.FullNodeAPI) - miner := sn[0] - - addrinfo, err := client.NetAddrsListen(ctx) - if err != nil { - t.Fatal(err) - } - - if err := miner.NetConnect(ctx, addrinfo); err != nil { - t.Fatal(err) - } - build.Clock.Sleep(time.Second) - - done := make(chan struct{}) - go func() { - defer close(done) - for ctx.Err() == nil { - build.Clock.Sleep(blocktime) - if err := sn[0].MineOne(ctx, MineNext); err != nil { - if ctx.Err() != nil { - // context was canceled, ignore the error. - return - } - t.Error(err) - } - } - }() - defer func() { - cancel() - <-done - }() - - maddr, err := miner.ActorAddress(ctx) - require.NoError(t, err) - - ssz, err := miner.ActorSectorSize(ctx, maddr) - require.NoError(t, err) - - p, err := client.StateMinerPower(ctx, maddr, types.EmptyTSK) - require.NoError(t, err) - require.Equal(t, p.MinerPower, p.TotalPower) - require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz)*nSectors)) - - fmt.Printf("Seal a sector\n") - - pledgeSectors(t, ctx, miner, 1, 0, nil) - - fmt.Printf("wait for power\n") - - { - // Wait until proven. - di, err := client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK) - require.NoError(t, err) - - waitUntil := di.PeriodStart + di.WPoStProvingPeriod + 2 - fmt.Printf("End for head.Height > %d\n", waitUntil) - - for { - head, err := client.ChainHead(ctx) - require.NoError(t, err) - - if head.Height() > waitUntil { - fmt.Printf("Now head.Height = %d\n", head.Height()) - break - } - } - } - - nSectors++ - - p, err = client.StateMinerPower(ctx, maddr, types.EmptyTSK) - require.NoError(t, err) - require.Equal(t, p.MinerPower, p.TotalPower) - require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz)*nSectors)) - - fmt.Println("Terminate a sector") - - toTerminate := abi.SectorNumber(3) - - err = miner.SectorTerminate(ctx, toTerminate) - require.NoError(t, err) - - msgTriggerred := false -loop: - for { - si, err := miner.SectorsStatus(ctx, toTerminate, false) - require.NoError(t, err) - - fmt.Println("state: ", si.State, msgTriggerred) - - switch sealing.SectorState(si.State) { - case sealing.Terminating: - if !msgTriggerred { - { - p, err := miner.SectorTerminatePending(ctx) - require.NoError(t, err) - require.Len(t, p, 1) - require.Equal(t, abi.SectorNumber(3), p[0].Number) - } - - c, err := miner.SectorTerminateFlush(ctx) - require.NoError(t, err) - if c != nil { - msgTriggerred = true - fmt.Println("terminate message:", c) - - { - p, err := miner.SectorTerminatePending(ctx) - require.NoError(t, err) - require.Len(t, p, 0) - } - } - } - case sealing.TerminateWait, sealing.TerminateFinality, sealing.Removed: - break loop - } - - time.Sleep(100 * time.Millisecond) - } - - // check power decreased - p, err = client.StateMinerPower(ctx, maddr, types.EmptyTSK) - require.NoError(t, err) - require.Equal(t, p.MinerPower, p.TotalPower) - require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz)*(nSectors-1))) - - // check in terminated set - { - parts, err := client.StateMinerPartitions(ctx, maddr, 1, types.EmptyTSK) - require.NoError(t, err) - require.Greater(t, len(parts), 0) - - bflen := func(b bitfield.BitField) uint64 { - l, err := b.Count() - require.NoError(t, err) - return l - } - - require.Equal(t, uint64(1), bflen(parts[0].AllSectors)) - require.Equal(t, uint64(0), bflen(parts[0].LiveSectors)) - } - - di, err := client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK) - require.NoError(t, err) - for { - head, err := client.ChainHead(ctx) - require.NoError(t, err) - - if head.Height() > di.PeriodStart+di.WPoStProvingPeriod+2 { - fmt.Printf("Now head.Height = %d\n", head.Height()) - break - } - build.Clock.Sleep(blocktime) - } - require.NoError(t, err) - fmt.Printf("End for head.Height > %d\n", di.PeriodStart+di.WPoStProvingPeriod+2) - - p, err = client.StateMinerPower(ctx, maddr, types.EmptyTSK) - require.NoError(t, err) - - require.Equal(t, p.MinerPower, p.TotalPower) - require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz)*(nSectors-1))) -} - -func TestWindowPostDispute(t *testing.T, b APIBuilder, blocktime time.Duration) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - // First, we configure two miners. After sealing, we're going to turn off the first miner so - // it doesn't submit proofs. - /// - // Then we're going to manually submit bad proofs. - n, sn := b(t, []FullNodeOpts{ - FullNodeWithLatestActorsAt(-1), - }, []StorageMiner{ - {Full: 0, Preseal: PresealGenesis}, - {Full: 0}, - }) - - client := n[0].FullNode.(*impl.FullNodeAPI) - chainMiner := sn[0] - evilMiner := sn[1] - - { - addrinfo, err := client.NetAddrsListen(ctx) - if err != nil { - t.Fatal(err) - } - - if err := chainMiner.NetConnect(ctx, addrinfo); err != nil { - t.Fatal(err) - } - - if err := evilMiner.NetConnect(ctx, addrinfo); err != nil { - t.Fatal(err) - } - } - - defaultFrom, err := client.WalletDefaultAddress(ctx) - require.NoError(t, err) - - build.Clock.Sleep(time.Second) - - // Mine with the _second_ node (the good one). - done := make(chan struct{}) - go func() { - defer close(done) - for ctx.Err() == nil { - build.Clock.Sleep(blocktime) - if err := chainMiner.MineOne(ctx, MineNext); err != nil { - if ctx.Err() != nil { - // context was canceled, ignore the error. - return - } - t.Error(err) - } - } - }() - defer func() { - cancel() - <-done - }() - - // Give the chain miner enough sectors to win every block. - pledgeSectors(t, ctx, chainMiner, 10, 0, nil) - // And the evil one 1 sector. No cookie for you. - pledgeSectors(t, ctx, evilMiner, 1, 0, nil) - - // Let the evil miner's sectors gain power. - evilMinerAddr, err := evilMiner.ActorAddress(ctx) - require.NoError(t, err) - - di, err := client.StateMinerProvingDeadline(ctx, evilMinerAddr, types.EmptyTSK) - require.NoError(t, err) - - fmt.Printf("Running one proving period\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+di.WPoStProvingPeriod*2 { - fmt.Printf("Now head.Height = %d\n", head.Height()) - break - } - build.Clock.Sleep(blocktime) - } - - p, err := client.StateMinerPower(ctx, evilMinerAddr, types.EmptyTSK) - require.NoError(t, err) - - ssz, err := evilMiner.ActorSectorSize(ctx, evilMinerAddr) - require.NoError(t, err) - - // make sure it has gained power. - require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz))) - - evilSectors, err := evilMiner.SectorsList(ctx) - require.NoError(t, err) - evilSectorNo := evilSectors[0] // only one. - evilSectorLoc, err := client.StateSectorPartition(ctx, evilMinerAddr, evilSectorNo, types.EmptyTSK) - require.NoError(t, err) - - fmt.Println("evil miner stopping") - - // Now stop the evil miner, and start manually submitting bad proofs. - require.NoError(t, evilMiner.Stop(ctx)) - - fmt.Println("evil miner stopped") - - // Wait until we need to prove our sector. - for { - di, err = client.StateMinerProvingDeadline(ctx, evilMinerAddr, types.EmptyTSK) - require.NoError(t, err) - if di.Index == evilSectorLoc.Deadline && di.CurrentEpoch-di.PeriodStart > 1 { - break - } - build.Clock.Sleep(blocktime) - } - - err = submitBadProof(ctx, client, evilMinerAddr, di, evilSectorLoc.Deadline, evilSectorLoc.Partition) - require.NoError(t, err, "evil proof not accepted") - - // Wait until after the proving period. - for { - di, err = client.StateMinerProvingDeadline(ctx, evilMinerAddr, types.EmptyTSK) - require.NoError(t, err) - if di.Index != evilSectorLoc.Deadline { - break - } - build.Clock.Sleep(blocktime) - } - - fmt.Println("accepted evil proof") - - // Make sure the evil node didn't lose any power. - p, err = client.StateMinerPower(ctx, evilMinerAddr, types.EmptyTSK) - require.NoError(t, err) - require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz))) - - // OBJECTION! The good miner files a DISPUTE!!!! - { - params := &minerActor.DisputeWindowedPoStParams{ - Deadline: evilSectorLoc.Deadline, - PoStIndex: 0, - } - - enc, aerr := actors.SerializeParams(params) - require.NoError(t, aerr) - - msg := &types.Message{ - To: evilMinerAddr, - Method: minerActor.Methods.DisputeWindowedPoSt, - Params: enc, - Value: types.NewInt(0), - From: defaultFrom, - } - sm, err := client.MpoolPushMessage(ctx, msg, nil) - require.NoError(t, err) - - fmt.Println("waiting dispute") - 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()) - } - - // Objection SUSTAINED! - // Make sure the evil node lost power. - p, err = client.StateMinerPower(ctx, evilMinerAddr, types.EmptyTSK) - require.NoError(t, err) - require.True(t, p.MinerPower.RawBytePower.IsZero()) - - // Now we begin the redemption arc. - require.True(t, p.MinerPower.RawBytePower.IsZero()) - - // First, recover the sector. - - { - minerInfo, err := client.StateMinerInfo(ctx, evilMinerAddr, types.EmptyTSK) - require.NoError(t, err) - - params := &minerActor.DeclareFaultsRecoveredParams{ - Recoveries: []minerActor.RecoveryDeclaration{{ - Deadline: evilSectorLoc.Deadline, - Partition: evilSectorLoc.Partition, - Sectors: bitfield.NewFromSet([]uint64{uint64(evilSectorNo)}), - }}, - } - - enc, aerr := actors.SerializeParams(params) - require.NoError(t, aerr) - - msg := &types.Message{ - To: evilMinerAddr, - Method: minerActor.Methods.DeclareFaultsRecovered, - Params: enc, - Value: types.FromFil(30), // repay debt. - From: minerInfo.Owner, - } - sm, err := client.MpoolPushMessage(ctx, msg, nil) - require.NoError(t, err) - - 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()) - } - - // Then wait for the deadline. - for { - di, err = client.StateMinerProvingDeadline(ctx, evilMinerAddr, types.EmptyTSK) - require.NoError(t, err) - if di.Index == evilSectorLoc.Deadline && di.CurrentEpoch-di.PeriodStart > 1 { - break - } - build.Clock.Sleep(blocktime) - } - - // Now try to be evil again - err = submitBadProof(ctx, client, evilMinerAddr, di, evilSectorLoc.Deadline, evilSectorLoc.Partition) - require.Error(t, err) - require.Contains(t, err.Error(), "message execution failed: exit 16, reason: window post failed: invalid PoSt") - - // It didn't work because we're recovering. -} - -func submitBadProof( - ctx context.Context, - client api.FullNode, maddr address.Address, - di *dline.Info, dlIdx, partIdx uint64, -) error { - head, err := client.ChainHead(ctx) - if err != nil { - return err - } - - from, err := client.WalletDefaultAddress(ctx) - if err != nil { - return err - } - - minerInfo, err := client.StateMinerInfo(ctx, maddr, head.Key()) - if err != nil { - return err - } - - commEpoch := di.Open - commRand, err := client.ChainGetRandomnessFromTickets( - ctx, head.Key(), crypto.DomainSeparationTag_PoStChainCommit, - commEpoch, nil, - ) - if err != nil { - return err - } - params := &minerActor.SubmitWindowedPoStParams{ - ChainCommitEpoch: commEpoch, - ChainCommitRand: commRand, - Deadline: dlIdx, - Partitions: []minerActor.PoStPartition{{Index: partIdx}}, - Proofs: []proof3.PoStProof{{ - PoStProof: minerInfo.WindowPoStProofType, - ProofBytes: []byte("I'm soooo very evil."), - }}, - } - - enc, aerr := actors.SerializeParams(params) - if aerr != nil { - return aerr - } - - msg := &types.Message{ - To: maddr, - Method: minerActor.Methods.SubmitWindowedPoSt, - Params: enc, - Value: types.NewInt(0), - From: from, - } - sm, err := client.MpoolPushMessage(ctx, msg, nil) - if err != nil { - return err - } - - rec, err := client.StateWaitMsg(ctx, sm.Cid(), build.MessageConfidence, api.LookbackNoLimit, true) - if err != nil { - return err - } - if rec.Receipt.ExitCode.IsError() { - return rec.Receipt.ExitCode - } - return nil -} - -func TestWindowPostDisputeFails(t *testing.T, b APIBuilder, blocktime time.Duration) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - n, sn := b(t, []FullNodeOpts{FullNodeWithLatestActorsAt(-1)}, OneMiner) - - client := n[0].FullNode.(*impl.FullNodeAPI) - miner := sn[0] - - { - addrinfo, err := client.NetAddrsListen(ctx) - if err != nil { - t.Fatal(err) - } - - if err := miner.NetConnect(ctx, addrinfo); err != nil { - t.Fatal(err) - } - } - - defaultFrom, err := client.WalletDefaultAddress(ctx) - require.NoError(t, err) - - maddr, err := miner.ActorAddress(ctx) - require.NoError(t, err) - - build.Clock.Sleep(time.Second) - - // Mine with the _second_ node (the good one). - done := make(chan struct{}) - go func() { - defer close(done) - for ctx.Err() == nil { - build.Clock.Sleep(blocktime) - if err := miner.MineOne(ctx, MineNext); err != nil { - if ctx.Err() != nil { - // context was canceled, ignore the error. - return - } - t.Error(err) - } - } - }() - defer func() { - cancel() - <-done - }() - - pledgeSectors(t, ctx, miner, 10, 0, nil) - - di, err := client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK) - require.NoError(t, err) - - fmt.Printf("Running one proving period\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+di.WPoStProvingPeriod*2 { - fmt.Printf("Now head.Height = %d\n", head.Height()) - break - } - build.Clock.Sleep(blocktime) - } - - ssz, err := miner.ActorSectorSize(ctx, maddr) - require.NoError(t, err) - expectedPower := types.NewInt(uint64(ssz) * (GenesisPreseals + 10)) - - p, err := client.StateMinerPower(ctx, maddr, types.EmptyTSK) - require.NoError(t, err) - - // make sure it has gained power. - require.Equal(t, p.MinerPower.RawBytePower, expectedPower) - - // Wait until a proof has been submitted. - var targetDeadline uint64 -waitForProof: - for { - deadlines, err := client.StateMinerDeadlines(ctx, maddr, types.EmptyTSK) - require.NoError(t, err) - for dlIdx, dl := range deadlines { - nonEmpty, err := dl.PostSubmissions.IsEmpty() - require.NoError(t, err) - if nonEmpty { - targetDeadline = uint64(dlIdx) - break waitForProof - } - } - - build.Clock.Sleep(blocktime) - } - - for { - di, err := client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK) - require.NoError(t, err) - // wait until the deadline finishes. - if di.Index == ((targetDeadline + 1) % di.WPoStPeriodDeadlines) { - break - } - - build.Clock.Sleep(blocktime) - } - - // Try to object to the proof. This should fail. - { - params := &minerActor.DisputeWindowedPoStParams{ - Deadline: targetDeadline, - PoStIndex: 0, - } - - enc, aerr := actors.SerializeParams(params) - require.NoError(t, aerr) - - msg := &types.Message{ - To: maddr, - Method: minerActor.Methods.DisputeWindowedPoSt, - Params: enc, - Value: types.NewInt(0), - From: defaultFrom, - } - _, err := client.MpoolPushMessage(ctx, msg, nil) - require.Error(t, err) - require.Contains(t, err.Error(), "failed to dispute valid post (RetCode=16)") - } -} - -func TestWindowPostBaseFeeNoBurn(t *testing.T, b APIBuilder, blocktime time.Duration) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - och := build.UpgradeClausHeight - build.UpgradeClausHeight = 10 - n, sn := b(t, DefaultFullOpts(1), OneMiner) - - client := n[0].FullNode.(*impl.FullNodeAPI) - miner := sn[0] - - { - addrinfo, err := client.NetAddrsListen(ctx) - if err != nil { - t.Fatal(err) - } - - if err := miner.NetConnect(ctx, addrinfo); err != nil { - t.Fatal(err) - } - } - - maddr, err := miner.ActorAddress(ctx) - require.NoError(t, err) - - mi, err := client.StateMinerInfo(ctx, maddr, types.EmptyTSK) - 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 := miner.MineOne(ctx, MineNext); err != nil { - if ctx.Err() != nil { - // context was canceled, ignore the error. - return - } - t.Error(err) - } - } - }() - defer func() { - cancel() - <-done - }() - - pledgeSectors(t, ctx, miner, 10, 0, nil) - wact, err := client.StateGetActor(ctx, mi.Worker, types.EmptyTSK) - require.NoError(t, err) - en := wact.Nonce - - // wait for a new message to be sent from worker address, it will be a PoSt - -waitForProof: - for { - wact, err := client.StateGetActor(ctx, mi.Worker, types.EmptyTSK) - require.NoError(t, err) - if wact.Nonce > en { - break waitForProof - } - - build.Clock.Sleep(blocktime) - } - - slm, err := client.StateListMessages(ctx, &api.MessageMatch{To: maddr}, types.EmptyTSK, 0) - require.NoError(t, err) - - pmr, err := client.StateReplay(ctx, types.EmptyTSK, slm[0]) - require.NoError(t, err) - - require.Equal(t, pmr.GasCost.BaseFeeBurn, big.Zero()) - - build.UpgradeClausHeight = och -} - -func TestWindowPostBaseFeeBurn(t *testing.T, b APIBuilder, blocktime time.Duration) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - n, sn := b(t, []FullNodeOpts{FullNodeWithLatestActorsAt(-1)}, OneMiner) - - client := n[0].FullNode.(*impl.FullNodeAPI) - miner := sn[0] - - { - addrinfo, err := client.NetAddrsListen(ctx) - if err != nil { - t.Fatal(err) - } - - if err := miner.NetConnect(ctx, addrinfo); err != nil { - t.Fatal(err) - } - } - - maddr, err := miner.ActorAddress(ctx) - require.NoError(t, err) - - mi, err := client.StateMinerInfo(ctx, maddr, types.EmptyTSK) - 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 := miner.MineOne(ctx, MineNext); err != nil { - if ctx.Err() != nil { - // context was canceled, ignore the error. - return - } - t.Error(err) - } - } - }() - defer func() { - cancel() - <-done - }() - - pledgeSectors(t, ctx, miner, 10, 0, nil) - wact, err := client.StateGetActor(ctx, mi.Worker, types.EmptyTSK) - require.NoError(t, err) - en := wact.Nonce - - // wait for a new message to be sent from worker address, it will be a PoSt - -waitForProof: - for { - wact, err := client.StateGetActor(ctx, mi.Worker, types.EmptyTSK) - require.NoError(t, err) - if wact.Nonce > en { - break waitForProof - } - - build.Clock.Sleep(blocktime) - } - - slm, err := client.StateListMessages(ctx, &api.MessageMatch{To: maddr}, types.EmptyTSK, 0) - require.NoError(t, err) - - pmr, err := client.StateReplay(ctx, types.EmptyTSK, slm[0]) - require.NoError(t, err) - - require.NotEqual(t, pmr.GasCost.BaseFeeBurn, big.Zero()) -} diff --git a/api/types.go b/api/types.go index 83de131a243..9d887b0a117 100644 --- a/api/types.go +++ b/api/types.go @@ -5,6 +5,7 @@ import ( "fmt" "time" + "github.com/filecoin-project/go-fil-markets/retrievalmarket" "github.com/filecoin-project/lotus/chain/types" datatransfer "github.com/filecoin-project/go-data-transfer" @@ -176,3 +177,21 @@ type MessagePrototype struct { Message types.Message ValidNonce bool } + +type RetrievalInfo struct { + PayloadCID cid.Cid + ID retrievalmarket.DealID + PieceCID *cid.Cid + PricePerByte abi.TokenAmount + UnsealPrice abi.TokenAmount + + Status retrievalmarket.DealStatus + Message string // more information about deal state, particularly errors + Provider peer.ID + BytesReceived uint64 + BytesPaidFor uint64 + TotalPaid abi.TokenAmount + + TransferChannelID *datatransfer.ChannelID + DataTransfer *DataTransferChannel +} diff --git a/api/v0api/full.go b/api/v0api/full.go index 5e5d6159516..f646aa9fd2f 100644 --- a/api/v0api/full.go +++ b/api/v0api/full.go @@ -326,6 +326,10 @@ type FullNode interface { // 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. + // ClientListRetrievals returns information about retrievals made by the local client + ClientListRetrievals(ctx context.Context) ([]api.RetrievalInfo, error) //perm:write + // ClientGetRetrievalUpdates returns status of updated retrieval deals + ClientGetRetrievalUpdates(ctx context.Context) (<-chan api.RetrievalInfo, error) //perm:write 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 @@ -625,7 +629,7 @@ type FullNode interface { // 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 diff --git a/api/v0api/proxy_gen.go b/api/v0api/proxy_gen.go index bd0da070e4a..fc2fc41864c 100644 --- a/api/v0api/proxy_gen.go +++ b/api/v0api/proxy_gen.go @@ -97,6 +97,8 @@ type FullNodeStruct struct { ClientGetDealUpdates func(p0 context.Context) (<-chan api.DealInfo, error) `perm:"write"` + ClientGetRetrievalUpdates func(p0 context.Context) (<-chan api.RetrievalInfo, error) `perm:"write"` + ClientHasLocal func(p0 context.Context, p1 cid.Cid) (bool, error) `perm:"write"` ClientImport func(p0 context.Context, p1 api.FileRef) (*api.ImportRes, error) `perm:"admin"` @@ -107,6 +109,8 @@ type FullNodeStruct struct { ClientListImports func(p0 context.Context) ([]api.Import, error) `perm:"write"` + ClientListRetrievals func(p0 context.Context) ([]api.RetrievalInfo, error) `perm:"write"` + ClientMinerQueryOffer func(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (api.QueryOffer, error) `perm:"read"` ClientQueryAsk func(p0 context.Context, p1 peer.ID, p2 address.Address) (*storagemarket.StorageAsk, error) `perm:"read"` @@ -716,6 +720,14 @@ func (s *FullNodeStub) ClientGetDealUpdates(p0 context.Context) (<-chan api.Deal return nil, xerrors.New("method not supported") } +func (s *FullNodeStruct) ClientGetRetrievalUpdates(p0 context.Context) (<-chan api.RetrievalInfo, error) { + return s.Internal.ClientGetRetrievalUpdates(p0) +} + +func (s *FullNodeStub) ClientGetRetrievalUpdates(p0 context.Context) (<-chan api.RetrievalInfo, 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) } @@ -756,6 +768,14 @@ func (s *FullNodeStub) ClientListImports(p0 context.Context) ([]api.Import, erro return *new([]api.Import), xerrors.New("method not supported") } +func (s *FullNodeStruct) ClientListRetrievals(p0 context.Context) ([]api.RetrievalInfo, error) { + return s.Internal.ClientListRetrievals(p0) +} + +func (s *FullNodeStub) ClientListRetrievals(p0 context.Context) ([]api.RetrievalInfo, error) { + return *new([]api.RetrievalInfo), xerrors.New("method not supported") +} + 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) } diff --git a/api/v0api/v0mocks/mock_full.go b/api/v0api/v0mocks/mock_full.go index 7a1fa55dbb5..a268d4a8a82 100644 --- a/api/v0api/v0mocks/mock_full.go +++ b/api/v0api/v0mocks/mock_full.go @@ -37,30 +37,30 @@ import ( protocol "github.com/libp2p/go-libp2p-core/protocol" ) -// MockFullNode is a mock of FullNode interface +// MockFullNode is a mock of FullNode interface. type MockFullNode struct { ctrl *gomock.Controller recorder *MockFullNodeMockRecorder } -// MockFullNodeMockRecorder is the mock recorder for MockFullNode +// MockFullNodeMockRecorder is the mock recorder for MockFullNode. type MockFullNodeMockRecorder struct { mock *MockFullNode } -// NewMockFullNode creates a new mock instance +// 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 +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockFullNode) EXPECT() *MockFullNodeMockRecorder { return m.recorder } -// AuthNew mocks base method +// 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) @@ -69,13 +69,13 @@ func (m *MockFullNode) AuthNew(arg0 context.Context, arg1 []auth.Permission) ([] return ret0, ret1 } -// AuthNew indicates an expected call of AuthNew +// 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 +// 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) @@ -84,13 +84,13 @@ func (m *MockFullNode) AuthVerify(arg0 context.Context, arg1 string) ([]auth.Per return ret0, ret1 } -// AuthVerify indicates an expected call of AuthVerify +// 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 +// 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) @@ -99,13 +99,13 @@ func (m *MockFullNode) BeaconGetEntry(arg0 context.Context, arg1 abi.ChainEpoch) return ret0, ret1 } -// BeaconGetEntry indicates an expected call of BeaconGetEntry +// 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 +// 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) @@ -113,13 +113,13 @@ func (m *MockFullNode) ChainDeleteObj(arg0 context.Context, arg1 cid.Cid) error return ret0 } -// ChainDeleteObj indicates an expected call of ChainDeleteObj +// 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 +// 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) @@ -128,13 +128,13 @@ func (m *MockFullNode) ChainExport(arg0 context.Context, arg1 abi.ChainEpoch, ar return ret0, ret1 } -// ChainExport indicates an expected call of ChainExport +// 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 +// 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) @@ -143,13 +143,13 @@ func (m *MockFullNode) ChainGetBlock(arg0 context.Context, arg1 cid.Cid) (*types return ret0, ret1 } -// ChainGetBlock indicates an expected call of ChainGetBlock +// 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 +// 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) @@ -158,13 +158,13 @@ func (m *MockFullNode) ChainGetBlockMessages(arg0 context.Context, arg1 cid.Cid) return ret0, ret1 } -// ChainGetBlockMessages indicates an expected call of ChainGetBlockMessages +// 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 +// 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) @@ -173,13 +173,13 @@ func (m *MockFullNode) ChainGetGenesis(arg0 context.Context) (*types.TipSet, err return ret0, ret1 } -// ChainGetGenesis indicates an expected call of ChainGetGenesis +// 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 +// 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) @@ -188,13 +188,13 @@ func (m *MockFullNode) ChainGetMessage(arg0 context.Context, arg1 cid.Cid) (*typ return ret0, ret1 } -// ChainGetMessage indicates an expected call of ChainGetMessage +// 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 +// 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) @@ -203,13 +203,13 @@ func (m *MockFullNode) ChainGetNode(arg0 context.Context, arg1 string) (*api.Ipl return ret0, ret1 } -// ChainGetNode indicates an expected call of ChainGetNode +// 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 +// 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) @@ -218,13 +218,13 @@ func (m *MockFullNode) ChainGetParentMessages(arg0 context.Context, arg1 cid.Cid return ret0, ret1 } -// ChainGetParentMessages indicates an expected call of ChainGetParentMessages +// 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 +// 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) @@ -233,13 +233,13 @@ func (m *MockFullNode) ChainGetParentReceipts(arg0 context.Context, arg1 cid.Cid return ret0, ret1 } -// ChainGetParentReceipts indicates an expected call of ChainGetParentReceipts +// 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 +// 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) @@ -248,13 +248,13 @@ func (m *MockFullNode) ChainGetPath(arg0 context.Context, arg1, arg2 types.TipSe return ret0, ret1 } -// ChainGetPath indicates an expected call of ChainGetPath +// 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 +// 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) @@ -263,13 +263,13 @@ func (m *MockFullNode) ChainGetRandomnessFromBeacon(arg0 context.Context, arg1 t return ret0, ret1 } -// ChainGetRandomnessFromBeacon indicates an expected call of ChainGetRandomnessFromBeacon +// 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 +// 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) @@ -278,13 +278,13 @@ func (m *MockFullNode) ChainGetRandomnessFromTickets(arg0 context.Context, arg1 return ret0, ret1 } -// ChainGetRandomnessFromTickets indicates an expected call of ChainGetRandomnessFromTickets +// 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 +// 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) @@ -293,13 +293,13 @@ func (m *MockFullNode) ChainGetTipSet(arg0 context.Context, arg1 types.TipSetKey return ret0, ret1 } -// ChainGetTipSet indicates an expected call of ChainGetTipSet +// 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 +// 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) @@ -308,13 +308,13 @@ func (m *MockFullNode) ChainGetTipSetByHeight(arg0 context.Context, arg1 abi.Cha return ret0, ret1 } -// ChainGetTipSetByHeight indicates an expected call of ChainGetTipSetByHeight +// 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 +// 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) @@ -323,13 +323,13 @@ func (m *MockFullNode) ChainHasObj(arg0 context.Context, arg1 cid.Cid) (bool, er return ret0, ret1 } -// ChainHasObj indicates an expected call of ChainHasObj +// 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 +// 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) @@ -338,13 +338,13 @@ func (m *MockFullNode) ChainHead(arg0 context.Context) (*types.TipSet, error) { return ret0, ret1 } -// ChainHead indicates an expected call of ChainHead +// 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 +// 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) @@ -353,13 +353,13 @@ func (m *MockFullNode) ChainNotify(arg0 context.Context) (<-chan []*api.HeadChan return ret0, ret1 } -// ChainNotify indicates an expected call of ChainNotify +// 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 +// 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) @@ -368,13 +368,13 @@ func (m *MockFullNode) ChainReadObj(arg0 context.Context, arg1 cid.Cid) ([]byte, return ret0, ret1 } -// ChainReadObj indicates an expected call of ChainReadObj +// 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 +// 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) @@ -382,13 +382,13 @@ func (m *MockFullNode) ChainSetHead(arg0 context.Context, arg1 types.TipSetKey) return ret0 } -// ChainSetHead indicates an expected call of ChainSetHead +// 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 +// 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) @@ -397,13 +397,13 @@ func (m *MockFullNode) ChainStatObj(arg0 context.Context, arg1, arg2 cid.Cid) (a return ret0, ret1 } -// ChainStatObj indicates an expected call of ChainStatObj +// 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 +// 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) @@ -412,13 +412,13 @@ func (m *MockFullNode) ChainTipSetWeight(arg0 context.Context, arg1 types.TipSet return ret0, ret1 } -// ChainTipSetWeight indicates an expected call of ChainTipSetWeight +// 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 +// 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) @@ -427,13 +427,13 @@ func (m *MockFullNode) ClientCalcCommP(arg0 context.Context, arg1 string) (*api. return ret0, ret1 } -// ClientCalcCommP indicates an expected call of ClientCalcCommP +// 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 +// 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) @@ -441,13 +441,13 @@ func (m *MockFullNode) ClientCancelDataTransfer(arg0 context.Context, arg1 datat return ret0 } -// ClientCancelDataTransfer indicates an expected call of ClientCancelDataTransfer +// 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 +// 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) @@ -455,13 +455,13 @@ func (m *MockFullNode) ClientCancelRetrievalDeal(arg0 context.Context, arg1 retr return ret0 } -// ClientCancelRetrievalDeal indicates an expected call of ClientCancelRetrievalDeal +// 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 +// 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) @@ -470,13 +470,13 @@ func (m *MockFullNode) ClientDataTransferUpdates(arg0 context.Context) (<-chan a return ret0, ret1 } -// ClientDataTransferUpdates indicates an expected call of ClientDataTransferUpdates +// 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 +// 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) @@ -485,13 +485,13 @@ func (m *MockFullNode) ClientDealPieceCID(arg0 context.Context, arg1 cid.Cid) (a return ret0, ret1 } -// ClientDealPieceCID indicates an expected call of ClientDealPieceCID +// 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 +// 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) @@ -500,13 +500,13 @@ func (m *MockFullNode) ClientDealSize(arg0 context.Context, arg1 cid.Cid) (api.D return ret0, ret1 } -// ClientDealSize indicates an expected call of ClientDealSize +// 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 +// 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) @@ -515,13 +515,13 @@ func (m *MockFullNode) ClientFindData(arg0 context.Context, arg1 cid.Cid, arg2 * return ret0, ret1 } -// ClientFindData indicates an expected call of ClientFindData +// 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 +// 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) @@ -529,13 +529,13 @@ func (m *MockFullNode) ClientGenCar(arg0 context.Context, arg1 api.FileRef, arg2 return ret0 } -// ClientGenCar indicates an expected call of ClientGenCar +// 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 +// 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) @@ -544,13 +544,13 @@ func (m *MockFullNode) ClientGetDealInfo(arg0 context.Context, arg1 cid.Cid) (*a return ret0, ret1 } -// ClientGetDealInfo indicates an expected call of ClientGetDealInfo +// 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 +// 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) @@ -559,13 +559,13 @@ func (m *MockFullNode) ClientGetDealStatus(arg0 context.Context, arg1 uint64) (s return ret0, ret1 } -// ClientGetDealStatus indicates an expected call of ClientGetDealStatus +// 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 +// 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) @@ -574,13 +574,28 @@ func (m *MockFullNode) ClientGetDealUpdates(arg0 context.Context) (<-chan api.De return ret0, ret1 } -// ClientGetDealUpdates indicates an expected call of ClientGetDealUpdates +// 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 +// ClientGetRetrievalUpdates mocks base method. +func (m *MockFullNode) ClientGetRetrievalUpdates(arg0 context.Context) (<-chan api.RetrievalInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientGetRetrievalUpdates", arg0) + ret0, _ := ret[0].(<-chan api.RetrievalInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientGetRetrievalUpdates indicates an expected call of ClientGetRetrievalUpdates. +func (mr *MockFullNodeMockRecorder) ClientGetRetrievalUpdates(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientGetRetrievalUpdates", reflect.TypeOf((*MockFullNode)(nil).ClientGetRetrievalUpdates), 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) @@ -589,13 +604,13 @@ func (m *MockFullNode) ClientHasLocal(arg0 context.Context, arg1 cid.Cid) (bool, return ret0, ret1 } -// ClientHasLocal indicates an expected call of ClientHasLocal +// 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 +// 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) @@ -604,13 +619,13 @@ func (m *MockFullNode) ClientImport(arg0 context.Context, arg1 api.FileRef) (*ap return ret0, ret1 } -// ClientImport indicates an expected call of ClientImport +// 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 +// 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) @@ -619,13 +634,13 @@ func (m *MockFullNode) ClientListDataTransfers(arg0 context.Context) ([]api.Data return ret0, ret1 } -// ClientListDataTransfers indicates an expected call of ClientListDataTransfers +// 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 +// 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) @@ -634,13 +649,13 @@ func (m *MockFullNode) ClientListDeals(arg0 context.Context) ([]api.DealInfo, er return ret0, ret1 } -// ClientListDeals indicates an expected call of ClientListDeals +// 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 +// 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) @@ -649,13 +664,28 @@ func (m *MockFullNode) ClientListImports(arg0 context.Context) ([]api.Import, er return ret0, ret1 } -// ClientListImports indicates an expected call of ClientListImports +// 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 +// ClientListRetrievals mocks base method. +func (m *MockFullNode) ClientListRetrievals(arg0 context.Context) ([]api.RetrievalInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientListRetrievals", arg0) + ret0, _ := ret[0].([]api.RetrievalInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ClientListRetrievals indicates an expected call of ClientListRetrievals. +func (mr *MockFullNodeMockRecorder) ClientListRetrievals(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientListRetrievals", reflect.TypeOf((*MockFullNode)(nil).ClientListRetrievals), 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) @@ -664,13 +694,13 @@ func (m *MockFullNode) ClientMinerQueryOffer(arg0 context.Context, arg1 address. return ret0, ret1 } -// ClientMinerQueryOffer indicates an expected call of ClientMinerQueryOffer +// 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 +// 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) @@ -679,13 +709,13 @@ func (m *MockFullNode) ClientQueryAsk(arg0 context.Context, arg1 peer.ID, arg2 a return ret0, ret1 } -// ClientQueryAsk indicates an expected call of ClientQueryAsk +// 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 +// 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) @@ -693,13 +723,13 @@ func (m *MockFullNode) ClientRemoveImport(arg0 context.Context, arg1 multistore. return ret0 } -// ClientRemoveImport indicates an expected call of ClientRemoveImport +// 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 +// 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) @@ -707,13 +737,13 @@ func (m *MockFullNode) ClientRestartDataTransfer(arg0 context.Context, arg1 data return ret0 } -// ClientRestartDataTransfer indicates an expected call of ClientRestartDataTransfer +// 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 +// 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) @@ -721,13 +751,13 @@ func (m *MockFullNode) ClientRetrieve(arg0 context.Context, arg1 api.RetrievalOr return ret0 } -// ClientRetrieve indicates an expected call of ClientRetrieve +// 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 +// 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) @@ -735,13 +765,13 @@ func (m *MockFullNode) ClientRetrieveTryRestartInsufficientFunds(arg0 context.Co return ret0 } -// ClientRetrieveTryRestartInsufficientFunds indicates an expected call of ClientRetrieveTryRestartInsufficientFunds +// 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 +// 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) @@ -750,13 +780,13 @@ func (m *MockFullNode) ClientRetrieveWithEvents(arg0 context.Context, arg1 api.R return ret0, ret1 } -// ClientRetrieveWithEvents indicates an expected call of ClientRetrieveWithEvents +// 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 +// 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) @@ -765,13 +795,13 @@ func (m *MockFullNode) ClientStartDeal(arg0 context.Context, arg1 *api.StartDeal return ret0, ret1 } -// ClientStartDeal indicates an expected call of ClientStartDeal +// 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) } -// ClientStatelessDeal mocks base method +// ClientStatelessDeal mocks base method. func (m *MockFullNode) ClientStatelessDeal(arg0 context.Context, arg1 *api.StartDealParams) (*cid.Cid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientStatelessDeal", arg0, arg1) @@ -780,13 +810,13 @@ func (m *MockFullNode) ClientStatelessDeal(arg0 context.Context, arg1 *api.Start return ret0, ret1 } -// ClientStatelessDeal indicates an expected call of ClientStatelessDeal +// ClientStatelessDeal indicates an expected call of ClientStatelessDeal. func (mr *MockFullNodeMockRecorder) ClientStatelessDeal(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientStatelessDeal", reflect.TypeOf((*MockFullNode)(nil).ClientStatelessDeal), arg0, arg1) } -// Closing mocks base method +// 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) @@ -795,13 +825,13 @@ func (m *MockFullNode) Closing(arg0 context.Context) (<-chan struct{}, error) { return ret0, ret1 } -// Closing indicates an expected call of Closing +// 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 +// 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) @@ -809,13 +839,13 @@ func (m *MockFullNode) CreateBackup(arg0 context.Context, arg1 string) error { return ret0 } -// CreateBackup indicates an expected call of CreateBackup +// 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 +// 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) @@ -824,13 +854,13 @@ func (m *MockFullNode) Discover(arg0 context.Context) (apitypes.OpenRPCDocument, return ret0, ret1 } -// Discover indicates an expected call of Discover +// 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 +// 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) @@ -839,13 +869,13 @@ func (m *MockFullNode) GasEstimateFeeCap(arg0 context.Context, arg1 *types.Messa return ret0, ret1 } -// GasEstimateFeeCap indicates an expected call of GasEstimateFeeCap +// 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 +// 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) @@ -854,13 +884,13 @@ func (m *MockFullNode) GasEstimateGasLimit(arg0 context.Context, arg1 *types.Mes return ret0, ret1 } -// GasEstimateGasLimit indicates an expected call of GasEstimateGasLimit +// 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 +// 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) @@ -869,13 +899,13 @@ func (m *MockFullNode) GasEstimateGasPremium(arg0 context.Context, arg1 uint64, return ret0, ret1 } -// GasEstimateGasPremium indicates an expected call of GasEstimateGasPremium +// 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 +// 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) @@ -884,13 +914,13 @@ func (m *MockFullNode) GasEstimateMessageGas(arg0 context.Context, arg1 *types.M return ret0, ret1 } -// GasEstimateMessageGas indicates an expected call of GasEstimateMessageGas +// 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 +// 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) @@ -899,13 +929,13 @@ func (m *MockFullNode) ID(arg0 context.Context) (peer.ID, error) { return ret0, ret1 } -// ID indicates an expected call of ID +// 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 +// LogList mocks base method. func (m *MockFullNode) LogList(arg0 context.Context) ([]string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "LogList", arg0) @@ -914,13 +944,13 @@ func (m *MockFullNode) LogList(arg0 context.Context) ([]string, error) { return ret0, ret1 } -// LogList indicates an expected call of LogList +// 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 +// 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) @@ -928,13 +958,13 @@ func (m *MockFullNode) LogSetLevel(arg0 context.Context, arg1, arg2 string) erro return ret0 } -// LogSetLevel indicates an expected call of LogSetLevel +// 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 +// 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) @@ -943,13 +973,13 @@ func (m *MockFullNode) MarketAddBalance(arg0 context.Context, arg1, arg2 address return ret0, ret1 } -// MarketAddBalance indicates an expected call of MarketAddBalance +// 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 +// 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) @@ -958,13 +988,13 @@ func (m *MockFullNode) MarketGetReserved(arg0 context.Context, arg1 address.Addr return ret0, ret1 } -// MarketGetReserved indicates an expected call of MarketGetReserved +// 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 +// 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) @@ -972,13 +1002,13 @@ func (m *MockFullNode) MarketReleaseFunds(arg0 context.Context, arg1 address.Add return ret0 } -// MarketReleaseFunds indicates an expected call of MarketReleaseFunds +// 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 +// 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) @@ -987,13 +1017,13 @@ func (m *MockFullNode) MarketReserveFunds(arg0 context.Context, arg1, arg2 addre return ret0, ret1 } -// MarketReserveFunds indicates an expected call of MarketReserveFunds +// 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 +// 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) @@ -1002,13 +1032,13 @@ func (m *MockFullNode) MarketWithdraw(arg0 context.Context, arg1, arg2 address.A return ret0, ret1 } -// MarketWithdraw indicates an expected call of MarketWithdraw +// 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 +// 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) @@ -1017,13 +1047,13 @@ func (m *MockFullNode) MinerCreateBlock(arg0 context.Context, arg1 *api.BlockTem return ret0, ret1 } -// MinerCreateBlock indicates an expected call of MinerCreateBlock +// 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 +// 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) @@ -1032,13 +1062,13 @@ func (m *MockFullNode) MinerGetBaseInfo(arg0 context.Context, arg1 address.Addre return ret0, ret1 } -// MinerGetBaseInfo indicates an expected call of MinerGetBaseInfo +// 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 +// 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) @@ -1047,13 +1077,13 @@ func (m *MockFullNode) MpoolBatchPush(arg0 context.Context, arg1 []*types.Signed return ret0, ret1 } -// MpoolBatchPush indicates an expected call of MpoolBatchPush +// 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 +// 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) @@ -1062,13 +1092,13 @@ func (m *MockFullNode) MpoolBatchPushMessage(arg0 context.Context, arg1 []*types return ret0, ret1 } -// MpoolBatchPushMessage indicates an expected call of MpoolBatchPushMessage +// 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 +// 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) @@ -1077,13 +1107,13 @@ func (m *MockFullNode) MpoolBatchPushUntrusted(arg0 context.Context, arg1 []*typ return ret0, ret1 } -// MpoolBatchPushUntrusted indicates an expected call of MpoolBatchPushUntrusted +// 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 +// 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) @@ -1091,13 +1121,13 @@ func (m *MockFullNode) MpoolClear(arg0 context.Context, arg1 bool) error { return ret0 } -// MpoolClear indicates an expected call of MpoolClear +// 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 +// 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) @@ -1106,13 +1136,13 @@ func (m *MockFullNode) MpoolGetConfig(arg0 context.Context) (*types.MpoolConfig, return ret0, ret1 } -// MpoolGetConfig indicates an expected call of MpoolGetConfig +// 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 +// 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) @@ -1121,13 +1151,13 @@ func (m *MockFullNode) MpoolGetNonce(arg0 context.Context, arg1 address.Address) return ret0, ret1 } -// MpoolGetNonce indicates an expected call of MpoolGetNonce +// 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 +// 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) @@ -1136,13 +1166,13 @@ func (m *MockFullNode) MpoolPending(arg0 context.Context, arg1 types.TipSetKey) return ret0, ret1 } -// MpoolPending indicates an expected call of MpoolPending +// 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 +// 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) @@ -1151,13 +1181,13 @@ func (m *MockFullNode) MpoolPush(arg0 context.Context, arg1 *types.SignedMessage return ret0, ret1 } -// MpoolPush indicates an expected call of MpoolPush +// 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 +// 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) @@ -1166,13 +1196,13 @@ func (m *MockFullNode) MpoolPushMessage(arg0 context.Context, arg1 *types.Messag return ret0, ret1 } -// MpoolPushMessage indicates an expected call of MpoolPushMessage +// 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 +// 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) @@ -1181,13 +1211,13 @@ func (m *MockFullNode) MpoolPushUntrusted(arg0 context.Context, arg1 *types.Sign return ret0, ret1 } -// MpoolPushUntrusted indicates an expected call of MpoolPushUntrusted +// 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 +// 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) @@ -1196,13 +1226,13 @@ func (m *MockFullNode) MpoolSelect(arg0 context.Context, arg1 types.TipSetKey, a return ret0, ret1 } -// MpoolSelect indicates an expected call of MpoolSelect +// 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 +// 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) @@ -1210,13 +1240,13 @@ func (m *MockFullNode) MpoolSetConfig(arg0 context.Context, arg1 *types.MpoolCon return ret0 } -// MpoolSetConfig indicates an expected call of MpoolSetConfig +// 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 +// 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) @@ -1225,13 +1255,13 @@ func (m *MockFullNode) MpoolSub(arg0 context.Context) (<-chan api.MpoolUpdate, e return ret0, ret1 } -// MpoolSub indicates an expected call of MpoolSub +// 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 +// 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) @@ -1240,13 +1270,13 @@ func (m *MockFullNode) MsigAddApprove(arg0 context.Context, arg1, arg2 address.A return ret0, ret1 } -// MsigAddApprove indicates an expected call of MsigAddApprove +// 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 +// 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) @@ -1255,13 +1285,13 @@ func (m *MockFullNode) MsigAddCancel(arg0 context.Context, arg1, arg2 address.Ad return ret0, ret1 } -// MsigAddCancel indicates an expected call of MsigAddCancel +// 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 +// 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) @@ -1270,13 +1300,13 @@ func (m *MockFullNode) MsigAddPropose(arg0 context.Context, arg1, arg2, arg3 add return ret0, ret1 } -// MsigAddPropose indicates an expected call of MsigAddPropose +// 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 +// 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) @@ -1285,13 +1315,13 @@ func (m *MockFullNode) MsigApprove(arg0 context.Context, arg1 address.Address, a return ret0, ret1 } -// MsigApprove indicates an expected call of MsigApprove +// 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 +// 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) @@ -1300,13 +1330,13 @@ func (m *MockFullNode) MsigApproveTxnHash(arg0 context.Context, arg1 address.Add return ret0, ret1 } -// MsigApproveTxnHash indicates an expected call of MsigApproveTxnHash +// 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 +// 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) @@ -1315,13 +1345,13 @@ func (m *MockFullNode) MsigCancel(arg0 context.Context, arg1 address.Address, ar return ret0, ret1 } -// MsigCancel indicates an expected call of MsigCancel +// 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 +// 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) @@ -1330,13 +1360,13 @@ func (m *MockFullNode) MsigCreate(arg0 context.Context, arg1 uint64, arg2 []addr return ret0, ret1 } -// MsigCreate indicates an expected call of MsigCreate +// 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 +// 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) @@ -1345,13 +1375,13 @@ func (m *MockFullNode) MsigGetAvailableBalance(arg0 context.Context, arg1 addres return ret0, ret1 } -// MsigGetAvailableBalance indicates an expected call of MsigGetAvailableBalance +// 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 +// 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) @@ -1360,13 +1390,13 @@ func (m *MockFullNode) MsigGetPending(arg0 context.Context, arg1 address.Address return ret0, ret1 } -// MsigGetPending indicates an expected call of MsigGetPending +// 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 +// 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) @@ -1375,13 +1405,13 @@ func (m *MockFullNode) MsigGetVested(arg0 context.Context, arg1 address.Address, return ret0, ret1 } -// MsigGetVested indicates an expected call of MsigGetVested +// 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 +// 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) @@ -1390,13 +1420,13 @@ func (m *MockFullNode) MsigGetVestingSchedule(arg0 context.Context, arg1 address return ret0, ret1 } -// MsigGetVestingSchedule indicates an expected call of MsigGetVestingSchedule +// 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 +// 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) @@ -1405,13 +1435,13 @@ func (m *MockFullNode) MsigPropose(arg0 context.Context, arg1, arg2 address.Addr return ret0, ret1 } -// MsigPropose indicates an expected call of MsigPropose +// 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 +// 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) @@ -1420,13 +1450,13 @@ func (m *MockFullNode) MsigRemoveSigner(arg0 context.Context, arg1, arg2, arg3 a return ret0, ret1 } -// MsigRemoveSigner indicates an expected call of MsigRemoveSigner +// 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 +// 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) @@ -1435,13 +1465,13 @@ func (m *MockFullNode) MsigSwapApprove(arg0 context.Context, arg1, arg2 address. return ret0, ret1 } -// MsigSwapApprove indicates an expected call of MsigSwapApprove +// 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 +// 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) @@ -1450,13 +1480,13 @@ func (m *MockFullNode) MsigSwapCancel(arg0 context.Context, arg1, arg2 address.A return ret0, ret1 } -// MsigSwapCancel indicates an expected call of MsigSwapCancel +// 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 +// 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) @@ -1465,13 +1495,13 @@ func (m *MockFullNode) MsigSwapPropose(arg0 context.Context, arg1, arg2, arg3, a return ret0, ret1 } -// MsigSwapPropose indicates an expected call of MsigSwapPropose +// 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 +// 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) @@ -1480,13 +1510,13 @@ func (m *MockFullNode) NetAddrsListen(arg0 context.Context) (peer.AddrInfo, erro return ret0, ret1 } -// NetAddrsListen indicates an expected call of NetAddrsListen +// 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 +// 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) @@ -1495,13 +1525,13 @@ func (m *MockFullNode) NetAgentVersion(arg0 context.Context, arg1 peer.ID) (stri return ret0, ret1 } -// NetAgentVersion indicates an expected call of NetAgentVersion +// 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 +// 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) @@ -1510,13 +1540,13 @@ func (m *MockFullNode) NetAutoNatStatus(arg0 context.Context) (api.NatInfo, erro return ret0, ret1 } -// NetAutoNatStatus indicates an expected call of NetAutoNatStatus +// 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 +// 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) @@ -1525,13 +1555,13 @@ func (m *MockFullNode) NetBandwidthStats(arg0 context.Context) (metrics.Stats, e return ret0, ret1 } -// NetBandwidthStats indicates an expected call of NetBandwidthStats +// 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 +// 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) @@ -1540,13 +1570,13 @@ func (m *MockFullNode) NetBandwidthStatsByPeer(arg0 context.Context) (map[string return ret0, ret1 } -// NetBandwidthStatsByPeer indicates an expected call of NetBandwidthStatsByPeer +// 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 +// 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) @@ -1555,13 +1585,13 @@ func (m *MockFullNode) NetBandwidthStatsByProtocol(arg0 context.Context) (map[pr return ret0, ret1 } -// NetBandwidthStatsByProtocol indicates an expected call of NetBandwidthStatsByProtocol +// 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 +// 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) @@ -1569,13 +1599,13 @@ func (m *MockFullNode) NetBlockAdd(arg0 context.Context, arg1 api.NetBlockList) return ret0 } -// NetBlockAdd indicates an expected call of NetBlockAdd +// 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 +// 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) @@ -1584,13 +1614,13 @@ func (m *MockFullNode) NetBlockList(arg0 context.Context) (api.NetBlockList, err return ret0, ret1 } -// NetBlockList indicates an expected call of NetBlockList +// 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 +// 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) @@ -1598,13 +1628,13 @@ func (m *MockFullNode) NetBlockRemove(arg0 context.Context, arg1 api.NetBlockLis return ret0 } -// NetBlockRemove indicates an expected call of NetBlockRemove +// 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 +// 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) @@ -1612,13 +1642,13 @@ func (m *MockFullNode) NetConnect(arg0 context.Context, arg1 peer.AddrInfo) erro return ret0 } -// NetConnect indicates an expected call of NetConnect +// 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 +// 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) @@ -1627,13 +1657,13 @@ func (m *MockFullNode) NetConnectedness(arg0 context.Context, arg1 peer.ID) (net return ret0, ret1 } -// NetConnectedness indicates an expected call of NetConnectedness +// 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 +// 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) @@ -1641,13 +1671,13 @@ func (m *MockFullNode) NetDisconnect(arg0 context.Context, arg1 peer.ID) error { return ret0 } -// NetDisconnect indicates an expected call of NetDisconnect +// 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 +// 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) @@ -1656,13 +1686,13 @@ func (m *MockFullNode) NetFindPeer(arg0 context.Context, arg1 peer.ID) (peer.Add return ret0, ret1 } -// NetFindPeer indicates an expected call of NetFindPeer +// 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 +// 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) @@ -1671,13 +1701,13 @@ func (m *MockFullNode) NetPeerInfo(arg0 context.Context, arg1 peer.ID) (*api.Ext return ret0, ret1 } -// NetPeerInfo indicates an expected call of NetPeerInfo +// 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 +// 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) @@ -1686,13 +1716,13 @@ func (m *MockFullNode) NetPeers(arg0 context.Context) ([]peer.AddrInfo, error) { return ret0, ret1 } -// NetPeers indicates an expected call of NetPeers +// 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 +// 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) @@ -1701,13 +1731,13 @@ func (m *MockFullNode) NetPubsubScores(arg0 context.Context) ([]api.PubsubScore, return ret0, ret1 } -// NetPubsubScores indicates an expected call of NetPubsubScores +// 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 +// 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) @@ -1716,13 +1746,13 @@ func (m *MockFullNode) PaychAllocateLane(arg0 context.Context, arg1 address.Addr return ret0, ret1 } -// PaychAllocateLane indicates an expected call of PaychAllocateLane +// 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 +// 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) @@ -1731,13 +1761,13 @@ func (m *MockFullNode) PaychAvailableFunds(arg0 context.Context, arg1 address.Ad return ret0, ret1 } -// PaychAvailableFunds indicates an expected call of PaychAvailableFunds +// 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 +// 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) @@ -1746,13 +1776,13 @@ func (m *MockFullNode) PaychAvailableFundsByFromTo(arg0 context.Context, arg1, a return ret0, ret1 } -// PaychAvailableFundsByFromTo indicates an expected call of PaychAvailableFundsByFromTo +// 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 +// 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) @@ -1761,13 +1791,13 @@ func (m *MockFullNode) PaychCollect(arg0 context.Context, arg1 address.Address) return ret0, ret1 } -// PaychCollect indicates an expected call of PaychCollect +// 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 +// 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) @@ -1776,13 +1806,13 @@ func (m *MockFullNode) PaychGet(arg0 context.Context, arg1, arg2 address.Address return ret0, ret1 } -// PaychGet indicates an expected call of PaychGet +// 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 +// 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) @@ -1791,13 +1821,13 @@ func (m *MockFullNode) PaychGetWaitReady(arg0 context.Context, arg1 cid.Cid) (ad return ret0, ret1 } -// PaychGetWaitReady indicates an expected call of PaychGetWaitReady +// 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 +// 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) @@ -1806,13 +1836,13 @@ func (m *MockFullNode) PaychList(arg0 context.Context) ([]address.Address, error return ret0, ret1 } -// PaychList indicates an expected call of PaychList +// 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 +// 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) @@ -1821,13 +1851,13 @@ func (m *MockFullNode) PaychNewPayment(arg0 context.Context, arg1, arg2 address. return ret0, ret1 } -// PaychNewPayment indicates an expected call of PaychNewPayment +// 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 +// 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) @@ -1836,13 +1866,13 @@ func (m *MockFullNode) PaychSettle(arg0 context.Context, arg1 address.Address) ( return ret0, ret1 } -// PaychSettle indicates an expected call of PaychSettle +// 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 +// 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) @@ -1851,13 +1881,13 @@ func (m *MockFullNode) PaychStatus(arg0 context.Context, arg1 address.Address) ( return ret0, ret1 } -// PaychStatus indicates an expected call of PaychStatus +// 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 +// 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) @@ -1866,13 +1896,13 @@ func (m *MockFullNode) PaychVoucherAdd(arg0 context.Context, arg1 address.Addres return ret0, ret1 } -// PaychVoucherAdd indicates an expected call of PaychVoucherAdd +// 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 +// 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) @@ -1881,13 +1911,13 @@ func (m *MockFullNode) PaychVoucherCheckSpendable(arg0 context.Context, arg1 add return ret0, ret1 } -// PaychVoucherCheckSpendable indicates an expected call of PaychVoucherCheckSpendable +// 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 +// 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) @@ -1895,13 +1925,13 @@ func (m *MockFullNode) PaychVoucherCheckValid(arg0 context.Context, arg1 address return ret0 } -// PaychVoucherCheckValid indicates an expected call of PaychVoucherCheckValid +// 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 +// 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) @@ -1910,13 +1940,13 @@ func (m *MockFullNode) PaychVoucherCreate(arg0 context.Context, arg1 address.Add return ret0, ret1 } -// PaychVoucherCreate indicates an expected call of PaychVoucherCreate +// 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 +// 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) @@ -1925,13 +1955,13 @@ func (m *MockFullNode) PaychVoucherList(arg0 context.Context, arg1 address.Addre return ret0, ret1 } -// PaychVoucherList indicates an expected call of PaychVoucherList +// 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 +// 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) @@ -1940,13 +1970,13 @@ func (m *MockFullNode) PaychVoucherSubmit(arg0 context.Context, arg1 address.Add return ret0, ret1 } -// PaychVoucherSubmit indicates an expected call of PaychVoucherSubmit +// 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 +// 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) @@ -1955,13 +1985,13 @@ func (m *MockFullNode) Session(arg0 context.Context) (uuid.UUID, error) { return ret0, ret1 } -// Session indicates an expected call of Session +// 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 +// Shutdown mocks base method. func (m *MockFullNode) Shutdown(arg0 context.Context) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Shutdown", arg0) @@ -1969,13 +1999,13 @@ func (m *MockFullNode) Shutdown(arg0 context.Context) error { return ret0 } -// Shutdown indicates an expected call of Shutdown +// 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 +// 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) @@ -1984,13 +2014,13 @@ func (m *MockFullNode) StateAccountKey(arg0 context.Context, arg1 address.Addres return ret0, ret1 } -// StateAccountKey indicates an expected call of StateAccountKey +// 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 +// 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) @@ -1999,13 +2029,13 @@ func (m *MockFullNode) StateAllMinerFaults(arg0 context.Context, arg1 abi.ChainE return ret0, ret1 } -// StateAllMinerFaults indicates an expected call of StateAllMinerFaults +// 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 +// 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) @@ -2014,13 +2044,13 @@ func (m *MockFullNode) StateCall(arg0 context.Context, arg1 *types.Message, arg2 return ret0, ret1 } -// StateCall indicates an expected call of StateCall +// 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 +// 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) @@ -2029,13 +2059,13 @@ func (m *MockFullNode) StateChangedActors(arg0 context.Context, arg1, arg2 cid.C return ret0, ret1 } -// StateChangedActors indicates an expected call of StateChangedActors +// 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 +// 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) @@ -2044,13 +2074,13 @@ func (m *MockFullNode) StateCirculatingSupply(arg0 context.Context, arg1 types.T return ret0, ret1 } -// StateCirculatingSupply indicates an expected call of StateCirculatingSupply +// 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 +// 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) @@ -2059,13 +2089,13 @@ func (m *MockFullNode) StateCompute(arg0 context.Context, arg1 abi.ChainEpoch, a return ret0, ret1 } -// StateCompute indicates an expected call of StateCompute +// 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 +// 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) @@ -2074,13 +2104,13 @@ func (m *MockFullNode) StateDealProviderCollateralBounds(arg0 context.Context, a return ret0, ret1 } -// StateDealProviderCollateralBounds indicates an expected call of StateDealProviderCollateralBounds +// 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 +// 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) @@ -2089,13 +2119,13 @@ func (m *MockFullNode) StateDecodeParams(arg0 context.Context, arg1 address.Addr return ret0, ret1 } -// StateDecodeParams indicates an expected call of StateDecodeParams +// 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 +// 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) @@ -2104,13 +2134,13 @@ func (m *MockFullNode) StateGetActor(arg0 context.Context, arg1 address.Address, return ret0, ret1 } -// StateGetActor indicates an expected call of StateGetActor +// 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 +// 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) @@ -2119,13 +2149,13 @@ func (m *MockFullNode) StateGetReceipt(arg0 context.Context, arg1 cid.Cid, arg2 return ret0, ret1 } -// StateGetReceipt indicates an expected call of StateGetReceipt +// 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 +// 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) @@ -2134,13 +2164,13 @@ func (m *MockFullNode) StateListActors(arg0 context.Context, arg1 types.TipSetKe return ret0, ret1 } -// StateListActors indicates an expected call of StateListActors +// 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 +// 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) @@ -2149,13 +2179,13 @@ func (m *MockFullNode) StateListMessages(arg0 context.Context, arg1 *api.Message return ret0, ret1 } -// StateListMessages indicates an expected call of StateListMessages +// 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 +// 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) @@ -2164,13 +2194,13 @@ func (m *MockFullNode) StateListMiners(arg0 context.Context, arg1 types.TipSetKe return ret0, ret1 } -// StateListMiners indicates an expected call of StateListMiners +// 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 +// 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) @@ -2179,13 +2209,13 @@ func (m *MockFullNode) StateLookupID(arg0 context.Context, arg1 address.Address, return ret0, ret1 } -// StateLookupID indicates an expected call of StateLookupID +// 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 +// 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) @@ -2194,13 +2224,13 @@ func (m *MockFullNode) StateMarketBalance(arg0 context.Context, arg1 address.Add return ret0, ret1 } -// StateMarketBalance indicates an expected call of StateMarketBalance +// 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 +// 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) @@ -2209,13 +2239,13 @@ func (m *MockFullNode) StateMarketDeals(arg0 context.Context, arg1 types.TipSetK return ret0, ret1 } -// StateMarketDeals indicates an expected call of StateMarketDeals +// 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 +// 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) @@ -2224,13 +2254,13 @@ func (m *MockFullNode) StateMarketParticipants(arg0 context.Context, arg1 types. return ret0, ret1 } -// StateMarketParticipants indicates an expected call of StateMarketParticipants +// 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 +// 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) @@ -2239,13 +2269,13 @@ func (m *MockFullNode) StateMarketStorageDeal(arg0 context.Context, arg1 abi.Dea return ret0, ret1 } -// StateMarketStorageDeal indicates an expected call of StateMarketStorageDeal +// 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 +// 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) @@ -2254,13 +2284,13 @@ func (m *MockFullNode) StateMinerActiveSectors(arg0 context.Context, arg1 addres return ret0, ret1 } -// StateMinerActiveSectors indicates an expected call of StateMinerActiveSectors +// 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 +// 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) @@ -2269,13 +2299,13 @@ func (m *MockFullNode) StateMinerAvailableBalance(arg0 context.Context, arg1 add return ret0, ret1 } -// StateMinerAvailableBalance indicates an expected call of StateMinerAvailableBalance +// 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 +// 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) @@ -2284,13 +2314,13 @@ func (m *MockFullNode) StateMinerDeadlines(arg0 context.Context, arg1 address.Ad return ret0, ret1 } -// StateMinerDeadlines indicates an expected call of StateMinerDeadlines +// 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 +// 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) @@ -2299,13 +2329,13 @@ func (m *MockFullNode) StateMinerFaults(arg0 context.Context, arg1 address.Addre return ret0, ret1 } -// StateMinerFaults indicates an expected call of StateMinerFaults +// 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 +// 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) @@ -2314,13 +2344,13 @@ func (m *MockFullNode) StateMinerInfo(arg0 context.Context, arg1 address.Address return ret0, ret1 } -// StateMinerInfo indicates an expected call of StateMinerInfo +// 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 +// 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) @@ -2329,13 +2359,13 @@ func (m *MockFullNode) StateMinerInitialPledgeCollateral(arg0 context.Context, a return ret0, ret1 } -// StateMinerInitialPledgeCollateral indicates an expected call of StateMinerInitialPledgeCollateral +// 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 +// 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) @@ -2344,13 +2374,13 @@ func (m *MockFullNode) StateMinerPartitions(arg0 context.Context, arg1 address.A return ret0, ret1 } -// StateMinerPartitions indicates an expected call of StateMinerPartitions +// 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 +// 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) @@ -2359,13 +2389,13 @@ func (m *MockFullNode) StateMinerPower(arg0 context.Context, arg1 address.Addres return ret0, ret1 } -// StateMinerPower indicates an expected call of StateMinerPower +// 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 +// 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) @@ -2374,13 +2404,13 @@ func (m *MockFullNode) StateMinerPreCommitDepositForPower(arg0 context.Context, return ret0, ret1 } -// StateMinerPreCommitDepositForPower indicates an expected call of StateMinerPreCommitDepositForPower +// 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 +// 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) @@ -2389,13 +2419,13 @@ func (m *MockFullNode) StateMinerProvingDeadline(arg0 context.Context, arg1 addr return ret0, ret1 } -// StateMinerProvingDeadline indicates an expected call of StateMinerProvingDeadline +// 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 +// 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) @@ -2404,13 +2434,13 @@ func (m *MockFullNode) StateMinerRecoveries(arg0 context.Context, arg1 address.A return ret0, ret1 } -// StateMinerRecoveries indicates an expected call of StateMinerRecoveries +// 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 +// 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) @@ -2419,13 +2449,13 @@ func (m *MockFullNode) StateMinerSectorAllocated(arg0 context.Context, arg1 addr return ret0, ret1 } -// StateMinerSectorAllocated indicates an expected call of StateMinerSectorAllocated +// 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 +// 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) @@ -2434,13 +2464,13 @@ func (m *MockFullNode) StateMinerSectorCount(arg0 context.Context, arg1 address. return ret0, ret1 } -// StateMinerSectorCount indicates an expected call of StateMinerSectorCount +// 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 +// 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) @@ -2449,13 +2479,13 @@ func (m *MockFullNode) StateMinerSectors(arg0 context.Context, arg1 address.Addr return ret0, ret1 } -// StateMinerSectors indicates an expected call of StateMinerSectors +// 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 +// 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) @@ -2464,13 +2494,13 @@ func (m *MockFullNode) StateNetworkName(arg0 context.Context) (dtypes.NetworkNam return ret0, ret1 } -// StateNetworkName indicates an expected call of StateNetworkName +// 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 +// 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) @@ -2479,13 +2509,13 @@ func (m *MockFullNode) StateNetworkVersion(arg0 context.Context, arg1 types.TipS return ret0, ret1 } -// StateNetworkVersion indicates an expected call of StateNetworkVersion +// 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 +// 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) @@ -2494,13 +2524,13 @@ func (m *MockFullNode) StateReadState(arg0 context.Context, arg1 address.Address return ret0, ret1 } -// StateReadState indicates an expected call of StateReadState +// 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 +// 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) @@ -2509,13 +2539,13 @@ func (m *MockFullNode) StateReplay(arg0 context.Context, arg1 types.TipSetKey, a return ret0, ret1 } -// StateReplay indicates an expected call of StateReplay +// 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 +// 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) @@ -2524,13 +2554,13 @@ func (m *MockFullNode) StateSearchMsg(arg0 context.Context, arg1 cid.Cid) (*api. return ret0, ret1 } -// StateSearchMsg indicates an expected call of StateSearchMsg +// 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 +// 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) @@ -2539,13 +2569,13 @@ func (m *MockFullNode) StateSearchMsgLimited(arg0 context.Context, arg1 cid.Cid, return ret0, ret1 } -// StateSearchMsgLimited indicates an expected call of StateSearchMsgLimited +// 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 +// 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) @@ -2554,13 +2584,13 @@ func (m *MockFullNode) StateSectorExpiration(arg0 context.Context, arg1 address. return ret0, ret1 } -// StateSectorExpiration indicates an expected call of StateSectorExpiration +// 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 +// 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) @@ -2569,13 +2599,13 @@ func (m *MockFullNode) StateSectorGetInfo(arg0 context.Context, arg1 address.Add return ret0, ret1 } -// StateSectorGetInfo indicates an expected call of StateSectorGetInfo +// 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 +// 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) @@ -2584,13 +2614,13 @@ func (m *MockFullNode) StateSectorPartition(arg0 context.Context, arg1 address.A return ret0, ret1 } -// StateSectorPartition indicates an expected call of StateSectorPartition +// 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 +// 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) @@ -2599,13 +2629,13 @@ func (m *MockFullNode) StateSectorPreCommitInfo(arg0 context.Context, arg1 addre return ret0, ret1 } -// StateSectorPreCommitInfo indicates an expected call of StateSectorPreCommitInfo +// 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 +// 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) @@ -2614,13 +2644,13 @@ func (m *MockFullNode) StateVMCirculatingSupplyInternal(arg0 context.Context, ar return ret0, ret1 } -// StateVMCirculatingSupplyInternal indicates an expected call of StateVMCirculatingSupplyInternal +// 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 +// 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) @@ -2629,13 +2659,13 @@ func (m *MockFullNode) StateVerifiedClientStatus(arg0 context.Context, arg1 addr return ret0, ret1 } -// StateVerifiedClientStatus indicates an expected call of StateVerifiedClientStatus +// 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 +// 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) @@ -2644,13 +2674,13 @@ func (m *MockFullNode) StateVerifiedRegistryRootKey(arg0 context.Context, arg1 t return ret0, ret1 } -// StateVerifiedRegistryRootKey indicates an expected call of StateVerifiedRegistryRootKey +// 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 +// 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) @@ -2659,13 +2689,13 @@ func (m *MockFullNode) StateVerifierStatus(arg0 context.Context, arg1 address.Ad return ret0, ret1 } -// StateVerifierStatus indicates an expected call of StateVerifierStatus +// 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 +// 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) @@ -2674,13 +2704,13 @@ func (m *MockFullNode) StateWaitMsg(arg0 context.Context, arg1 cid.Cid, arg2 uin return ret0, ret1 } -// StateWaitMsg indicates an expected call of StateWaitMsg +// 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 +// 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) @@ -2689,13 +2719,13 @@ func (m *MockFullNode) StateWaitMsgLimited(arg0 context.Context, arg1 cid.Cid, a return ret0, ret1 } -// StateWaitMsgLimited indicates an expected call of StateWaitMsgLimited +// 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 +// 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) @@ -2704,13 +2734,13 @@ func (m *MockFullNode) SyncCheckBad(arg0 context.Context, arg1 cid.Cid) (string, return ret0, ret1 } -// SyncCheckBad indicates an expected call of SyncCheckBad +// 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 +// 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) @@ -2718,13 +2748,13 @@ func (m *MockFullNode) SyncCheckpoint(arg0 context.Context, arg1 types.TipSetKey return ret0 } -// SyncCheckpoint indicates an expected call of SyncCheckpoint +// 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 +// 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) @@ -2733,13 +2763,13 @@ func (m *MockFullNode) SyncIncomingBlocks(arg0 context.Context) (<-chan *types.B return ret0, ret1 } -// SyncIncomingBlocks indicates an expected call of SyncIncomingBlocks +// 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 +// 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) @@ -2747,13 +2777,13 @@ func (m *MockFullNode) SyncMarkBad(arg0 context.Context, arg1 cid.Cid) error { return ret0 } -// SyncMarkBad indicates an expected call of SyncMarkBad +// 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 +// 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) @@ -2762,13 +2792,13 @@ func (m *MockFullNode) SyncState(arg0 context.Context) (*api.SyncState, error) { return ret0, ret1 } -// SyncState indicates an expected call of SyncState +// 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 +// 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) @@ -2776,13 +2806,13 @@ func (m *MockFullNode) SyncSubmitBlock(arg0 context.Context, arg1 *types.BlockMs return ret0 } -// SyncSubmitBlock indicates an expected call of SyncSubmitBlock +// 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 +// SyncUnmarkAllBad mocks base method. func (m *MockFullNode) SyncUnmarkAllBad(arg0 context.Context) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SyncUnmarkAllBad", arg0) @@ -2790,13 +2820,13 @@ func (m *MockFullNode) SyncUnmarkAllBad(arg0 context.Context) error { return ret0 } -// SyncUnmarkAllBad indicates an expected call of SyncUnmarkAllBad +// 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 +// 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) @@ -2804,13 +2834,13 @@ func (m *MockFullNode) SyncUnmarkBad(arg0 context.Context, arg1 cid.Cid) error { return ret0 } -// SyncUnmarkBad indicates an expected call of SyncUnmarkBad +// 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 +// 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) @@ -2819,13 +2849,13 @@ func (m *MockFullNode) SyncValidateTipset(arg0 context.Context, arg1 types.TipSe return ret0, ret1 } -// SyncValidateTipset indicates an expected call of SyncValidateTipset +// 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 +// 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) @@ -2834,13 +2864,13 @@ func (m *MockFullNode) Version(arg0 context.Context) (api.APIVersion, error) { return ret0, ret1 } -// Version indicates an expected call of Version +// 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 +// 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) @@ -2849,13 +2879,13 @@ func (m *MockFullNode) WalletBalance(arg0 context.Context, arg1 address.Address) return ret0, ret1 } -// WalletBalance indicates an expected call of WalletBalance +// 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 +// 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) @@ -2864,13 +2894,13 @@ func (m *MockFullNode) WalletDefaultAddress(arg0 context.Context) (address.Addre return ret0, ret1 } -// WalletDefaultAddress indicates an expected call of WalletDefaultAddress +// 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 +// 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) @@ -2878,13 +2908,13 @@ func (m *MockFullNode) WalletDelete(arg0 context.Context, arg1 address.Address) return ret0 } -// WalletDelete indicates an expected call of WalletDelete +// 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 +// 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) @@ -2893,13 +2923,13 @@ func (m *MockFullNode) WalletExport(arg0 context.Context, arg1 address.Address) return ret0, ret1 } -// WalletExport indicates an expected call of WalletExport +// 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 +// 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) @@ -2908,13 +2938,13 @@ func (m *MockFullNode) WalletHas(arg0 context.Context, arg1 address.Address) (bo return ret0, ret1 } -// WalletHas indicates an expected call of WalletHas +// 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 +// 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) @@ -2923,13 +2953,13 @@ func (m *MockFullNode) WalletImport(arg0 context.Context, arg1 *types.KeyInfo) ( return ret0, ret1 } -// WalletImport indicates an expected call of WalletImport +// 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 +// 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) @@ -2938,13 +2968,13 @@ func (m *MockFullNode) WalletList(arg0 context.Context) ([]address.Address, erro return ret0, ret1 } -// WalletList indicates an expected call of WalletList +// 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 +// 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) @@ -2953,13 +2983,13 @@ func (m *MockFullNode) WalletNew(arg0 context.Context, arg1 types.KeyType) (addr return ret0, ret1 } -// WalletNew indicates an expected call of WalletNew +// 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 +// 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) @@ -2967,13 +2997,13 @@ func (m *MockFullNode) WalletSetDefault(arg0 context.Context, arg1 address.Addre return ret0 } -// WalletSetDefault indicates an expected call of WalletSetDefault +// 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 +// 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) @@ -2982,13 +3012,13 @@ func (m *MockFullNode) WalletSign(arg0 context.Context, arg1 address.Address, ar return ret0, ret1 } -// WalletSign indicates an expected call of WalletSign +// 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 +// 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) @@ -2997,13 +3027,13 @@ func (m *MockFullNode) WalletSignMessage(arg0 context.Context, arg1 address.Addr return ret0, ret1 } -// WalletSignMessage indicates an expected call of WalletSignMessage +// 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 +// 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) @@ -3012,13 +3042,13 @@ func (m *MockFullNode) WalletValidateAddress(arg0 context.Context, arg1 string) return ret0, ret1 } -// WalletValidateAddress indicates an expected call of WalletValidateAddress +// 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 +// 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) @@ -3027,7 +3057,7 @@ func (m *MockFullNode) WalletVerify(arg0 context.Context, arg1 address.Address, return ret0, ret1 } -// WalletVerify indicates an expected call of WalletVerify +// 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/version.go b/api/version.go index 743170f049f..e8011204d1e 100644 --- a/api/version.go +++ b/api/version.go @@ -57,8 +57,8 @@ var ( FullAPIVersion0 = newVer(1, 3, 0) FullAPIVersion1 = newVer(2, 1, 0) - MinerAPIVersion0 = newVer(1, 0, 1) - WorkerAPIVersion0 = newVer(1, 0, 0) + MinerAPIVersion0 = newVer(1, 1, 0) + WorkerAPIVersion0 = newVer(1, 1, 0) ) //nolint:varcheck,deadcode diff --git a/build/bootstrap/butterflynet.pi b/build/bootstrap/butterflynet.pi index 0de3043a3ef..cc4ce4f1d22 100644 --- a/build/bootstrap/butterflynet.pi +++ b/build/bootstrap/butterflynet.pi @@ -1,2 +1,2 @@ -/dns4/bootstrap-0.butterfly.fildev.network/tcp/1347/p2p/12D3KooWRkaF18SR3E6qL6dkGrozT8QJUV5VbhE9E7BZtPmHqdWJ -/dns4/bootstrap-1.butterfly.fildev.network/tcp/1347/p2p/12D3KooWJcJUc23WJjJHGSboGcU3t76z9Lb7CghrH2tiBiDCY4ux +/dns4/bootstrap-0.butterfly.fildev.network/tcp/1347/p2p/12D3KooWBbZd7Su9XfLUQ12RynGQ3ZmGY1nGqFntmqop9pLNJE6g +/dns4/bootstrap-1.butterfly.fildev.network/tcp/1347/p2p/12D3KooWGKRzEY4tJFTmAmrYUpa1CVVohmV9YjJbC9v5XWY2gUji diff --git a/build/bootstrap/calibnet.pi b/build/bootstrap/calibnet.pi index 0eb9fd2f3a0..20473eaaa61 100644 --- a/build/bootstrap/calibnet.pi +++ b/build/bootstrap/calibnet.pi @@ -1,4 +1,4 @@ -/dns4/bootstrap-0.calibration.fildev.network/tcp/1347/p2p/12D3KooWRLZAseMo9h7fRD6ojn6YYDXHsBSavX5YmjBZ9ngtAEec -/dns4/bootstrap-1.calibration.fildev.network/tcp/1347/p2p/12D3KooWJFtDXgZEQMEkjJPSrbfdvh2xfjVKrXeNFG1t8ioJXAzv -/dns4/bootstrap-2.calibration.fildev.network/tcp/1347/p2p/12D3KooWP1uB9Lo7yCA3S17TD4Y5wStP5Nk7Vqh53m8GsFjkyujD -/dns4/bootstrap-3.calibration.fildev.network/tcp/1347/p2p/12D3KooWLrPM4WPK1YRGPCUwndWcDX8GCYgms3DiuofUmxwvhMCn +/dns4/bootstrap-0.calibration.fildev.network/tcp/1347/p2p/12D3KooWJkikQQkxS58spo76BYzFt4fotaT5NpV2zngvrqm4u5ow +/dns4/bootstrap-1.calibration.fildev.network/tcp/1347/p2p/12D3KooWLce5FDHR4EX4CrYavphA5xS3uDsX6aoowXh5tzDUxJav +/dns4/bootstrap-2.calibration.fildev.network/tcp/1347/p2p/12D3KooWA9hFfQG9GjP6bHeuQQbMD3FDtZLdW1NayxKXUT26PQZu +/dns4/bootstrap-3.calibration.fildev.network/tcp/1347/p2p/12D3KooWMHDi3LVTFG8Szqogt7RkNXvonbQYqSazxBx41A5aeuVz diff --git a/build/bootstrap/interopnet.pi b/build/bootstrap/interopnet.pi new file mode 100644 index 00000000000..112d9611382 --- /dev/null +++ b/build/bootstrap/interopnet.pi @@ -0,0 +1,2 @@ +/dns4/bootstrap-0.interop.fildev.network/tcp/1347/p2p/12D3KooWN86wA54r3v9M8bBYbc1vK9W1ehHDxVGPRaoeUYuXF8R7 +/dns4/bootstrap-1.interop.fildev.network/tcp/1347/p2p/12D3KooWNZ41kev8mtBZgWe43qam1VX9pJyf87jnaisQP2urZZ2M diff --git a/build/genesis/butterflynet.car b/build/genesis/butterflynet.car index 6654d7195a7..7c2d19251f7 100644 Binary files a/build/genesis/butterflynet.car and b/build/genesis/butterflynet.car differ diff --git a/build/genesis/calibnet.car b/build/genesis/calibnet.car index d2fe7c3afe3..cbade953f86 100644 Binary files a/build/genesis/calibnet.car and b/build/genesis/calibnet.car differ diff --git a/build/genesis/interopnet.car b/build/genesis/interopnet.car new file mode 100644 index 00000000000..80ecd6e7297 Binary files /dev/null and b/build/genesis/interopnet.car differ diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz index 5d32e910df3..b7c053d81c3 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 fa6f28aff51..411964f6549 100644 Binary files a/build/openrpc/worker.json.gz and b/build/openrpc/worker.json.gz differ diff --git a/build/params_calibnet.go b/build/params_calibnet.go index 4685ec30cf2..df334a516a7 100644 --- a/build/params_calibnet.go +++ b/build/params_calibnet.go @@ -33,19 +33,20 @@ const UpgradeLiftoffHeight = -5 const UpgradeKumquatHeight = 90 -const UpgradeCalicoHeight = 100 +const UpgradeCalicoHeight = 120 const UpgradePersianHeight = UpgradeCalicoHeight + (builtin2.EpochsInHour * 1) -const UpgradeClausHeight = 250 +const UpgradeClausHeight = 270 const UpgradeOrangeHeight = 300 -const UpgradeTrustHeight = 600 -const UpgradeNorwegianHeight = 114000 +const UpgradeTrustHeight = 330 -const UpgradeTurboHeight = 193789 +const UpgradeNorwegianHeight = 360 -const UpgradeHyperdriveHeight = 9999999 +const UpgradeTurboHeight = 390 + +const UpgradeHyperdriveHeight = 420 func init() { policy.SetConsensusMinerMinPower(abi.NewStoragePower(32 << 30)) diff --git a/build/params_interop.go b/build/params_interop.go new file mode 100644 index 00000000000..73cc1c7d9ca --- /dev/null +++ b/build/params_interop.go @@ -0,0 +1,104 @@ +// +build interopnet + +package build + +import ( + "os" + "strconv" + + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + + "github.com/filecoin-project/lotus/chain/actors/policy" +) + +const BootstrappersFile = "interopnet.pi" +const GenesisFile = "interopnet.car" + +var UpgradeBreezeHeight = abi.ChainEpoch(-1) + +const BreezeGasTampingDuration = 0 + +var UpgradeSmokeHeight = abi.ChainEpoch(-1) +var UpgradeIgnitionHeight = abi.ChainEpoch(-2) +var UpgradeRefuelHeight = abi.ChainEpoch(-3) +var UpgradeTapeHeight = abi.ChainEpoch(-4) + +var UpgradeAssemblyHeight = abi.ChainEpoch(-5) +var UpgradeLiftoffHeight = abi.ChainEpoch(-6) + +var UpgradeKumquatHeight = abi.ChainEpoch(-7) +var UpgradeCalicoHeight = abi.ChainEpoch(-8) +var UpgradePersianHeight = abi.ChainEpoch(-9) +var UpgradeOrangeHeight = abi.ChainEpoch(-10) +var UpgradeClausHeight = abi.ChainEpoch(-11) + +var UpgradeTrustHeight = abi.ChainEpoch(-12) + +var UpgradeNorwegianHeight = abi.ChainEpoch(-13) + +var UpgradeTurboHeight = abi.ChainEpoch(-14) + +var UpgradeHyperdriveHeight = abi.ChainEpoch(-15) + +var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ + 0: DrandMainnet, +} + +func init() { + policy.SetSupportedProofTypes( + abi.RegisteredSealProof_StackedDrg2KiBV1, + abi.RegisteredSealProof_StackedDrg8MiBV1, + abi.RegisteredSealProof_StackedDrg512MiBV1, + ) + 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) + UpgradeAssemblyHeight = getUpgradeHeight("LOTUS_ACTORSV2_HEIGHT", UpgradeAssemblyHeight) + 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) + UpgradeTrustHeight = getUpgradeHeight("LOTUS_ACTORSV3_HEIGHT", UpgradeTrustHeight) + UpgradeNorwegianHeight = getUpgradeHeight("LOTUS_NORWEGIAN_HEIGHT", UpgradeNorwegianHeight) + UpgradeTurboHeight = getUpgradeHeight("LOTUS_ACTORSV4_HEIGHT", UpgradeTurboHeight) + UpgradeHyperdriveHeight = getUpgradeHeight("LOTUS_HYPERDRIVE_HEIGHT", UpgradeHyperdriveHeight) + + BuildType |= BuildInteropnet + SetAddressNetwork(address.Testnet) + Devnet = true +} + +const BlockDelaySecs = uint64(builtin2.EpochDurationSeconds) + +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_mainnet.go b/build/params_mainnet.go index 52c6224798c..1c9b6946267 100644 --- a/build/params_mainnet.go +++ b/build/params_mainnet.go @@ -4,6 +4,7 @@ // +build !calibnet // +build !nerpanet // +build !butterflynet +// +build !interopnet package build @@ -61,8 +62,8 @@ const UpgradeNorwegianHeight = 665280 // 2021-04-29T06:00:00Z const UpgradeTurboHeight = 712320 -// ??? -var UpgradeHyperdriveHeight = abi.ChainEpoch(9999999) +// 2021-06-30T22:00:00Z +var UpgradeHyperdriveHeight = abi.ChainEpoch(892800) func init() { if os.Getenv("LOTUS_USE_TEST_ADDRESSES") != "1" { diff --git a/build/version.go b/build/version.go index 12b1058b314..5a4a494fcda 100644 --- a/build/version.go +++ b/build/version.go @@ -6,11 +6,12 @@ var CurrentCommit string var BuildType int const ( - BuildDefault = 0 - BuildMainnet = 0x1 - Build2k = 0x2 - BuildDebug = 0x3 - BuildCalibnet = 0x4 + BuildDefault = 0 + BuildMainnet = 0x1 + Build2k = 0x2 + BuildDebug = 0x3 + BuildCalibnet = 0x4 + BuildInteropnet = 0x5 ) func buildType() string { @@ -25,6 +26,8 @@ func buildType() string { return "+debug" case BuildCalibnet: return "+calibnet" + case BuildInteropnet: + return "+interopnet" default: return "+huh?" } diff --git a/chain/actors/policy/policy.go b/chain/actors/policy/policy.go index bb35025ecb5..c159dc98f22 100644 --- a/chain/actors/policy/policy.go +++ b/chain/actors/policy/policy.go @@ -3,6 +3,8 @@ package policy import ( "sort" + "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/lotus/chain/actors" @@ -276,13 +278,13 @@ func GetMaxSectorExpirationExtension() abi.ChainEpoch { return miner5.MaxSectorExpirationExtension } -// TODO: we'll probably need to abstract over this better in the future. -func GetMaxPoStPartitions(p abi.RegisteredPoStProof) (int, error) { +func GetMaxPoStPartitions(nv network.Version, p abi.RegisteredPoStProof) (int, error) { sectorsPerPart, err := builtin5.PoStProofWindowPoStPartitionSectors(p) if err != nil { return 0, err } - return int(miner5.AddressedSectorsMax / sectorsPerPart), nil + maxSectors := uint64(GetAddressedSectorsMax(nv)) + return int(maxSectors / sectorsPerPart), nil } func GetDefaultSectorSize() abi.SectorSize { @@ -367,3 +369,31 @@ func GetDeclarationsMax(nwVer network.Version) int { panic("unsupported network version") } } + +func AggregateNetworkFee(nwVer network.Version, aggregateSize int, baseFee abi.TokenAmount) abi.TokenAmount { + switch actors.VersionForNetwork(nwVer) { + + case actors.Version0: + + return big.Zero() + + case actors.Version2: + + return big.Zero() + + case actors.Version3: + + return big.Zero() + + case actors.Version4: + + return big.Zero() + + case actors.Version5: + + return miner5.AggregateNetworkFee(aggregateSize, baseFee) + + default: + panic("unsupported network version") + } +} diff --git a/chain/actors/policy/policy.go.template b/chain/actors/policy/policy.go.template index 6b8f80bd06c..17b3eb0ff70 100644 --- a/chain/actors/policy/policy.go.template +++ b/chain/actors/policy/policy.go.template @@ -3,6 +3,8 @@ package policy import ( "sort" + "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/lotus/chain/actors" @@ -180,13 +182,13 @@ 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) { +func GetMaxPoStPartitions(nv network.Version, p abi.RegisteredPoStProof) (int, error) { sectorsPerPart, err := builtin{{.latestVersion}}.PoStProofWindowPoStPartitionSectors(p) if err != nil { return 0, err } - return int(miner{{.latestVersion}}.AddressedSectorsMax / sectorsPerPart), nil + maxSectors := uint64(GetAddressedSectorsMax(nv)) + return int(maxSectors / sectorsPerPart), nil } func GetDefaultSectorSize() abi.SectorSize { @@ -246,3 +248,18 @@ func GetDeclarationsMax(nwVer network.Version) int { panic("unsupported network version") } } + +func AggregateNetworkFee(nwVer network.Version, aggregateSize int, baseFee abi.TokenAmount) abi.TokenAmount { + switch actors.VersionForNetwork(nwVer) { + {{range .versions}} + case actors.Version{{.}}: + {{if (le . 4)}} + return big.Zero() + {{else}} + return miner{{.}}.AggregateNetworkFee(aggregateSize, baseFee) + {{end}} + {{end}} + default: + panic("unsupported network version") + } +} diff --git a/chain/actors/policy/policy_test.go b/chain/actors/policy/policy_test.go index 24e47aaa035..f40250fba8e 100644 --- a/chain/actors/policy/policy_test.go +++ b/chain/actors/policy/policy_test.go @@ -6,6 +6,7 @@ import ( "github.com/stretchr/testify/require" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/network" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych" @@ -68,3 +69,12 @@ func TestPartitionSizes(t *testing.T) { require.Equal(t, sizeOld, sizeNew) } } + +func TestPoStSize(t *testing.T) { + v12PoStSize, err := GetMaxPoStPartitions(network.Version12, abi.RegisteredPoStProof_StackedDrgWindow64GiBV1) + require.Equal(t, 4, v12PoStSize) + require.NoError(t, err) + v13PoStSize, err := GetMaxPoStPartitions(network.Version13, abi.RegisteredPoStProof_StackedDrgWindow64GiBV1) + require.NoError(t, err) + require.Equal(t, 10, v13PoStSize) +} diff --git a/chain/messagepool/check.go b/chain/messagepool/check.go index 8d64636912d..11203e7dffd 100644 --- a/chain/messagepool/check.go +++ b/chain/messagepool/check.go @@ -19,18 +19,18 @@ import ( 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) { +func (mp *MessagePool) CheckMessages(ctx context.Context, 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) + return mp.checkMessages(ctx, 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) { +func (mp *MessagePool) CheckPendingMessages(ctx context.Context, from address.Address) ([][]api.MessageCheckStatus, error) { var msgs []*types.Message mp.lk.Lock() mset, ok := mp.pending[from] @@ -49,12 +49,12 @@ func (mp *MessagePool) CheckPendingMessages(from address.Address) ([][]api.Messa return msgs[i].Nonce < msgs[j].Nonce }) - return mp.checkMessages(msgs, true, nil) + return mp.checkMessages(ctx, 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) { +func (mp *MessagePool) CheckReplaceMessages(ctx context.Context, replace []*types.Message) ([][]api.MessageCheckStatus, error) { msgMap := make(map[address.Address]map[uint64]*types.Message) count := 0 @@ -94,12 +94,12 @@ func (mp *MessagePool) CheckReplaceMessages(replace []*types.Message) ([][]api.M start = end } - return mp.checkMessages(msgs, true, nil) + return mp.checkMessages(ctx, 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) { +func (mp *MessagePool) checkMessages(ctx context.Context, msgs []*types.Message, interned bool, flexibleNonces []bool) (result [][]api.MessageCheckStatus, err error) { if mp.api.IsLite() { return nil, nil } @@ -160,7 +160,7 @@ func (mp *MessagePool) checkMessages(msgs []*types.Message, interned bool, flexi } else { mp.lk.Unlock() - stateNonce, err := mp.getStateNonce(m.From, curTs) + stateNonce, err := mp.getStateNonce(ctx, m.From, curTs) if err != nil { check.OK = false check.Err = fmt.Sprintf("error retrieving state nonce: %s", err.Error()) @@ -193,7 +193,7 @@ func (mp *MessagePool) checkMessages(msgs []*types.Message, interned bool, flexi balance, ok := balances[m.From] if !ok { - balance, err = mp.getStateBalance(m.From, curTs) + balance, err = mp.getStateBalance(ctx, m.From, curTs) if err != nil { check.OK = false check.Err = fmt.Sprintf("error retrieving state balance: %s", err) @@ -243,7 +243,7 @@ func (mp *MessagePool) checkMessages(msgs []*types.Message, interned bool, flexi }, } - if len(bytes) > 32*1024-128 { // 128 bytes to account for signature size + if len(bytes) > MaxMessageSize-128 { // 128 bytes to account for signature size check.OK = false check.Err = "message too big" } else { diff --git a/chain/messagepool/messagepool.go b/chain/messagepool/messagepool.go index 0180d1abf9c..865c18a3a0f 100644 --- a/chain/messagepool/messagepool.go +++ b/chain/messagepool/messagepool.go @@ -34,6 +34,7 @@ import ( "github.com/filecoin-project/lotus/chain/vm" "github.com/filecoin-project/lotus/journal" "github.com/filecoin-project/lotus/lib/sigs" + "github.com/filecoin-project/lotus/metrics" "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/raulk/clock" @@ -59,6 +60,8 @@ var MaxUntrustedActorPendingMessages = 10 var MaxNonceGap = uint64(4) +const MaxMessageSize = 64 << 10 // 64KiB + var ( ErrMessageTooBig = errors.New("message too big") @@ -575,7 +578,7 @@ func (mp *MessagePool) addLocal(ctx context.Context, m *types.SignedMessage) err return nil } -// verifyMsgBeforeAdd verifies that the message meets the minimum criteria for block inclusio +// verifyMsgBeforeAdd verifies that the message meets the minimum criteria for block inclusion // and whether the message has enough funds to be included in the next 20 blocks. // If the message is not valid for block inclusion, it returns an error. // For local messages, if the message can be included in the next 20 blocks, it returns true to @@ -629,6 +632,9 @@ func (mp *MessagePool) verifyMsgBeforeAdd(m *types.SignedMessage, curTs *types.T } func (mp *MessagePool) Push(ctx context.Context, m *types.SignedMessage) (cid.Cid, error) { + done := metrics.Timer(ctx, metrics.MpoolPushDuration) + defer done() + err := mp.checkMessage(m) if err != nil { return cid.Undef, err @@ -665,7 +671,7 @@ func (mp *MessagePool) Push(ctx context.Context, m *types.SignedMessage) (cid.Ci func (mp *MessagePool) checkMessage(m *types.SignedMessage) error { // big messages are bad, anti DOS - if m.Size() > 32*1024 { + if m.Size() > MaxMessageSize { return xerrors.Errorf("mpool message too large (%dB): %w", m.Size(), ErrMessageTooBig) } @@ -695,6 +701,9 @@ func (mp *MessagePool) checkMessage(m *types.SignedMessage) error { } func (mp *MessagePool) Add(ctx context.Context, m *types.SignedMessage) error { + done := metrics.Timer(ctx, metrics.MpoolAddDuration) + defer done() + err := mp.checkMessage(m) if err != nil { return err @@ -750,7 +759,7 @@ func (mp *MessagePool) VerifyMsgSig(m *types.SignedMessage) error { } func (mp *MessagePool) checkBalance(ctx context.Context, m *types.SignedMessage, curTs *types.TipSet) error { - balance, err := mp.getStateBalance(m.Message.From, curTs) + balance, err := mp.getStateBalance(ctx, m.Message.From, curTs) if err != nil { return xerrors.Errorf("failed to check sender balance: %s: %w", err, ErrSoftValidationFailure) } @@ -783,7 +792,10 @@ func (mp *MessagePool) checkBalance(ctx context.Context, m *types.SignedMessage, } func (mp *MessagePool) addTs(ctx context.Context, m *types.SignedMessage, curTs *types.TipSet, local, untrusted bool) (bool, error) { - snonce, err := mp.getStateNonce(m.Message.From, curTs) + done := metrics.Timer(ctx, metrics.MpoolAddTsDuration) + defer done() + + snonce, err := mp.getStateNonce(ctx, m.Message.From, curTs) if err != nil { return false, xerrors.Errorf("failed to look up actor state nonce: %s: %w", err, ErrSoftValidationFailure) } @@ -831,7 +843,7 @@ func (mp *MessagePool) addLoaded(ctx context.Context, m *types.SignedMessage) er return xerrors.Errorf("current tipset not loaded") } - snonce, err := mp.getStateNonce(m.Message.From, curTs) + snonce, err := mp.getStateNonce(ctx, m.Message.From, curTs) if err != nil { return xerrors.Errorf("failed to look up actor state nonce: %s: %w", err, ErrSoftValidationFailure) } @@ -883,7 +895,7 @@ func (mp *MessagePool) addLocked(ctx context.Context, m *types.SignedMessage, st } if !ok { - nonce, err := mp.getStateNonce(m.Message.From, mp.curTs) + nonce, err := mp.getStateNonce(ctx, m.Message.From, mp.curTs) if err != nil { return xerrors.Errorf("failed to get initial actor nonce: %w", err) } @@ -944,7 +956,7 @@ func (mp *MessagePool) GetActor(_ context.Context, addr address.Address, _ types } func (mp *MessagePool) getNonceLocked(ctx context.Context, addr address.Address, curTs *types.TipSet) (uint64, error) { - stateNonce, err := mp.getStateNonce(addr, curTs) // sanity check + stateNonce, err := mp.getStateNonce(ctx, addr, curTs) // sanity check if err != nil { return 0, err } @@ -968,7 +980,10 @@ func (mp *MessagePool) getNonceLocked(ctx context.Context, addr address.Address, return stateNonce, nil } -func (mp *MessagePool) getStateNonce(addr address.Address, ts *types.TipSet) (uint64, error) { +func (mp *MessagePool) getStateNonce(ctx context.Context, addr address.Address, ts *types.TipSet) (uint64, error) { + done := metrics.Timer(ctx, metrics.MpoolGetNonceDuration) + defer done() + act, err := mp.api.GetActorAfter(addr, ts) if err != nil { return 0, err @@ -977,7 +992,10 @@ func (mp *MessagePool) getStateNonce(addr address.Address, ts *types.TipSet) (ui return act.Nonce, nil } -func (mp *MessagePool) getStateBalance(addr address.Address, ts *types.TipSet) (types.BigInt, error) { +func (mp *MessagePool) getStateBalance(ctx context.Context, addr address.Address, ts *types.TipSet) (types.BigInt, error) { + done := metrics.Timer(ctx, metrics.MpoolGetBalanceDuration) + defer done() + act, err := mp.api.GetActorAfter(addr, ts) if err != nil { return types.EmptyInt, err diff --git a/chain/messagepool/messagepool_test.go b/chain/messagepool/messagepool_test.go index b48685069a3..f271249dffd 100644 --- a/chain/messagepool/messagepool_test.go +++ b/chain/messagepool/messagepool_test.go @@ -14,12 +14,14 @@ import ( builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/messagepool/gasguess" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types/mock" "github.com/filecoin-project/lotus/chain/wallet" _ "github.com/filecoin-project/lotus/lib/sigs/bls" _ "github.com/filecoin-project/lotus/lib/sigs/secp" + "github.com/stretchr/testify/assert" ) func init() { @@ -260,6 +262,72 @@ func TestMessagePool(t *testing.T) { assertNonce(t, mp, sender, 2) } +func TestCheckMessageBig(t *testing.T) { + tma := newTestMpoolAPI() + + w, err := wallet.NewWallet(wallet.NewMemKeyStore()) + assert.NoError(t, err) + + from, err := w.WalletNew(context.Background(), types.KTBLS) + assert.NoError(t, err) + + tma.setBalance(from, 1000e9) + + ds := datastore.NewMapDatastore() + + mp, err := New(tma, ds, "mptest", nil) + assert.NoError(t, err) + + to := mock.Address(1001) + + { + msg := &types.Message{ + To: to, + From: from, + Value: types.NewInt(1), + Nonce: 0, + GasLimit: 50000000, + GasFeeCap: types.NewInt(100), + GasPremium: types.NewInt(1), + Params: make([]byte, 41<<10), // 41KiB payload + } + + sig, err := w.WalletSign(context.TODO(), from, msg.Cid().Bytes(), api.MsgMeta{}) + if err != nil { + panic(err) + } + sm := &types.SignedMessage{ + Message: *msg, + Signature: *sig, + } + mustAdd(t, mp, sm) + } + + { + msg := &types.Message{ + To: to, + From: from, + Value: types.NewInt(1), + Nonce: 0, + GasLimit: 50000000, + GasFeeCap: types.NewInt(100), + GasPremium: types.NewInt(1), + Params: make([]byte, 64<<10), // 64KiB payload + } + + sig, err := w.WalletSign(context.TODO(), from, msg.Cid().Bytes(), api.MsgMeta{}) + if err != nil { + panic(err) + } + sm := &types.SignedMessage{ + Message: *msg, + Signature: *sig, + } + err = mp.Add(context.TODO(), sm) + assert.ErrorIs(t, err, ErrMessageTooBig) + } +} + func TestMessagePoolMessagesInEachBlock(t *testing.T) { tma := newTestMpoolAPI() diff --git a/chain/stmgr/call.go b/chain/stmgr/call.go index cfbf60a9594..dc6da0f9c19 100644 --- a/chain/stmgr/call.go +++ b/chain/stmgr/call.go @@ -39,25 +39,29 @@ func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types. } bstate := ts.ParentState() - bheight := ts.Height() + pts, err := sm.cs.LoadTipSet(ts.Parents()) + if err != nil { + return nil, xerrors.Errorf("failed to load parent tipset: %w", err) + } + pheight := pts.Height() // If we have to run an expensive migration, and we're not at genesis, // return an error because the migration will take too long. // // We allow this at height 0 for at-genesis migrations (for testing). - if bheight-1 > 0 && sm.hasExpensiveFork(ctx, bheight-1) { + if pheight > 0 && sm.hasExpensiveFork(ctx, pheight) { return nil, ErrExpensiveFork } // Run the (not expensive) migration. - bstate, err := sm.handleStateForks(ctx, bstate, bheight-1, nil, ts) + bstate, err = sm.handleStateForks(ctx, bstate, pheight, nil, ts) if err != nil { return nil, fmt.Errorf("failed to handle fork: %w", err) } vmopt := &vm.VMOpts{ StateBase: bstate, - Epoch: bheight, + Epoch: pheight + 1, Rand: store.NewChainRand(sm.cs, ts.Cids()), Bstore: sm.cs.StateBlockstore(), Syscalls: sm.cs.VMSys(), @@ -155,6 +159,11 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri return nil, xerrors.Errorf("computing tipset state: %w", err) } + state, err = sm.handleStateForks(ctx, state, ts.Height(), nil, ts) + if err != nil { + return nil, fmt.Errorf("failed to handle fork: %w", err) + } + r := store.NewChainRand(sm.cs, ts.Cids()) if span.IsRecordingEvents() { @@ -167,7 +176,7 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri vmopt := &vm.VMOpts{ StateBase: state, - Epoch: ts.Height(), + Epoch: ts.Height() + 1, Rand: r, Bstore: sm.cs.StateBlockstore(), Syscalls: sm.cs.VMSys(), @@ -239,24 +248,18 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri var errHaltExecution = fmt.Errorf("halt") func (sm *StateManager) Replay(ctx context.Context, ts *types.TipSet, mcid cid.Cid) (*types.Message, *vm.ApplyRet, error) { - var outm *types.Message - var outr *vm.ApplyRet - - _, _, err := sm.computeTipSetState(ctx, ts, func(c cid.Cid, m *types.Message, ret *vm.ApplyRet) error { - if c == mcid { - outm = m - outr = ret - return errHaltExecution - } - return nil - }) + var finder messageFinder + // message to find + finder.mcid = mcid + + _, _, err := sm.computeTipSetState(ctx, ts, &finder) if err != nil && !xerrors.Is(err, errHaltExecution) { return nil, nil, xerrors.Errorf("unexpected error during execution: %w", err) } - if outr == nil { + if finder.outr == nil { return nil, nil, xerrors.Errorf("given message not found in tipset") } - return outm, outr, nil + return finder.outm, finder.outr, nil } diff --git a/chain/stmgr/forks.go b/chain/stmgr/forks.go index ee5a26deaed..bb87da44cf4 100644 --- a/chain/stmgr/forks.go +++ b/chain/stmgr/forks.go @@ -61,7 +61,7 @@ type MigrationCache interface { type MigrationFunc func( ctx context.Context, sm *StateManager, cache MigrationCache, - cb ExecCallback, oldState cid.Cid, + cb ExecMonitor, oldState cid.Cid, height abi.ChainEpoch, ts *types.TipSet, ) (newState cid.Cid, err error) @@ -292,7 +292,7 @@ func (us UpgradeSchedule) Validate() error { return nil } -func (sm *StateManager) handleStateForks(ctx context.Context, root cid.Cid, height abi.ChainEpoch, cb ExecCallback, ts *types.TipSet) (cid.Cid, error) { +func (sm *StateManager) handleStateForks(ctx context.Context, root cid.Cid, height abi.ChainEpoch, cb ExecMonitor, ts *types.TipSet) (cid.Cid, error) { retCid := root var err error u := sm.stateMigrations[height] @@ -472,7 +472,7 @@ func doTransfer(tree types.StateTree, from, to address.Address, amt abi.TokenAmo return nil } -func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, _ MigrationCache, cb ExecCallback, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { +func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, _ MigrationCache, em ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { // Some initial parameters FundsForMiners := types.FromFil(1_000_000) LookbackEpoch := abi.ChainEpoch(32000) @@ -722,12 +722,12 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, _ Migratio return cid.Undef, xerrors.Errorf("resultant state tree account balance was not correct: %s", total) } - if cb != nil { + if em != nil { // record the transfer in execution traces fakeMsg := makeFakeMsg(builtin.SystemActorAddr, builtin.SystemActorAddr, big.Zero(), uint64(epoch)) - if err := cb(fakeMsg.Cid(), fakeMsg, &vm.ApplyRet{ + if err := em.MessageApplied(ctx, ts, fakeMsg.Cid(), fakeMsg, &vm.ApplyRet{ MessageReceipt: *makeFakeRct(), ActorErr: nil, ExecutionTrace: types.ExecutionTrace{ @@ -740,7 +740,7 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, _ Migratio }, Duration: 0, GasCosts: nil, - }); err != nil { + }, false); err != nil { return cid.Undef, xerrors.Errorf("recording transfers: %w", err) } } @@ -748,7 +748,7 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, _ Migratio return tree.Flush(ctx) } -func UpgradeIgnition(ctx context.Context, sm *StateManager, _ MigrationCache, cb ExecCallback, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { +func UpgradeIgnition(ctx context.Context, sm *StateManager, _ MigrationCache, cb ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { store := sm.cs.ActorStore(ctx) if build.UpgradeLiftoffHeight <= epoch { @@ -785,12 +785,12 @@ func UpgradeIgnition(ctx context.Context, sm *StateManager, _ MigrationCache, cb return cid.Undef, xerrors.Errorf("resetting genesis msig start epochs: %w", err) } - err = splitGenesisMultisig0(ctx, cb, split1, store, tree, 50, epoch) + err = splitGenesisMultisig0(ctx, cb, split1, store, tree, 50, epoch, ts) if err != nil { return cid.Undef, xerrors.Errorf("splitting first msig: %w", err) } - err = splitGenesisMultisig0(ctx, cb, split2, store, tree, 50, epoch) + err = splitGenesisMultisig0(ctx, cb, split2, store, tree, 50, epoch, ts) if err != nil { return cid.Undef, xerrors.Errorf("splitting second msig: %w", err) } @@ -803,7 +803,7 @@ func UpgradeIgnition(ctx context.Context, sm *StateManager, _ MigrationCache, cb return tree.Flush(ctx) } -func UpgradeRefuel(ctx context.Context, sm *StateManager, _ MigrationCache, cb ExecCallback, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { +func UpgradeRefuel(ctx context.Context, sm *StateManager, _ MigrationCache, cb ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { store := sm.cs.ActorStore(ctx) tree, err := sm.StateTree(root) @@ -829,7 +829,7 @@ func UpgradeRefuel(ctx context.Context, sm *StateManager, _ MigrationCache, cb E return tree.Flush(ctx) } -func UpgradeActorsV2(ctx context.Context, sm *StateManager, _ MigrationCache, cb ExecCallback, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { +func UpgradeActorsV2(ctx context.Context, sm *StateManager, _ MigrationCache, cb ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { buf := blockstore.NewTieredBstore(sm.cs.StateBlockstore(), blockstore.NewMemorySync()) store := store.ActorStore(ctx, buf) @@ -875,7 +875,7 @@ func UpgradeActorsV2(ctx context.Context, sm *StateManager, _ MigrationCache, cb return newRoot, nil } -func UpgradeLiftoff(ctx context.Context, sm *StateManager, _ MigrationCache, cb ExecCallback, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { +func UpgradeLiftoff(ctx context.Context, sm *StateManager, _ MigrationCache, cb ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { tree, err := sm.StateTree(root) if err != nil { return cid.Undef, xerrors.Errorf("getting state tree: %w", err) @@ -889,7 +889,7 @@ func UpgradeLiftoff(ctx context.Context, sm *StateManager, _ MigrationCache, cb return tree.Flush(ctx) } -func UpgradeCalico(ctx context.Context, sm *StateManager, _ MigrationCache, cb ExecCallback, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { +func UpgradeCalico(ctx context.Context, sm *StateManager, _ MigrationCache, cb ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { if build.BuildType != build.BuildMainnet { return root, nil } @@ -935,7 +935,7 @@ func UpgradeCalico(ctx context.Context, sm *StateManager, _ MigrationCache, cb E return newRoot, nil } -func terminateActor(ctx context.Context, tree *state.StateTree, addr address.Address, cb ExecCallback, epoch abi.ChainEpoch) error { +func terminateActor(ctx context.Context, tree *state.StateTree, addr address.Address, em ExecMonitor, epoch abi.ChainEpoch, ts *types.TipSet) error { a, err := tree.GetActor(addr) if xerrors.Is(err, types.ErrActorNotFound) { return types.ErrActorNotFound @@ -950,18 +950,18 @@ func terminateActor(ctx context.Context, tree *state.StateTree, addr address.Add return xerrors.Errorf("transferring terminated actor's balance: %w", err) } - if cb != nil { + if em != nil { // record the transfer in execution traces fakeMsg := makeFakeMsg(builtin.SystemActorAddr, addr, big.Zero(), uint64(epoch)) - if err := cb(fakeMsg.Cid(), fakeMsg, &vm.ApplyRet{ + if err := em.MessageApplied(ctx, ts, fakeMsg.Cid(), fakeMsg, &vm.ApplyRet{ MessageReceipt: *makeFakeRct(), ActorErr: nil, ExecutionTrace: trace, Duration: 0, GasCosts: nil, - }); err != nil { + }, false); err != nil { return xerrors.Errorf("recording transfers: %w", err) } } @@ -995,7 +995,7 @@ func terminateActor(ctx context.Context, tree *state.StateTree, addr address.Add return tree.SetActor(init_.Address, ia) } -func UpgradeActorsV3(ctx context.Context, sm *StateManager, cache MigrationCache, cb ExecCallback, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { +func UpgradeActorsV3(ctx context.Context, sm *StateManager, cache MigrationCache, cb ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { // Use all the CPUs except 3. workerCount := runtime.NumCPU() - 3 if workerCount <= 0 { @@ -1019,7 +1019,7 @@ func UpgradeActorsV3(ctx context.Context, sm *StateManager, cache MigrationCache } if build.BuildType == build.BuildMainnet { - err := terminateActor(ctx, tree, build.ZeroAddress, cb, epoch) + err := terminateActor(ctx, tree, build.ZeroAddress, cb, epoch, ts) if err != nil && !xerrors.Is(err, types.ErrActorNotFound) { return cid.Undef, xerrors.Errorf("deleting zero bls actor: %w", err) } @@ -1097,7 +1097,7 @@ 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) { +func UpgradeActorsV4(ctx context.Context, sm *StateManager, cache MigrationCache, cb ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { // Use all the CPUs except 3. workerCount := runtime.NumCPU() - 3 if workerCount <= 0 { @@ -1183,7 +1183,7 @@ func upgradeActorsV4Common( return newRoot, nil } -func UpgradeActorsV5(ctx context.Context, sm *StateManager, cache MigrationCache, cb ExecCallback, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { +func UpgradeActorsV5(ctx context.Context, sm *StateManager, cache MigrationCache, cb ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { // Use all the CPUs except 3. workerCount := runtime.NumCPU() - 3 if workerCount <= 0 { @@ -1296,7 +1296,7 @@ func setNetworkName(ctx context.Context, store adt.Store, tree *state.StateTree, return nil } -func splitGenesisMultisig0(ctx context.Context, cb ExecCallback, addr address.Address, store adt0.Store, tree *state.StateTree, portions uint64, epoch abi.ChainEpoch) error { +func splitGenesisMultisig0(ctx context.Context, em ExecMonitor, addr address.Address, store adt0.Store, tree *state.StateTree, portions uint64, epoch abi.ChainEpoch, ts *types.TipSet) error { if portions < 1 { return xerrors.Errorf("cannot split into 0 portions") } @@ -1393,12 +1393,12 @@ func splitGenesisMultisig0(ctx context.Context, cb ExecCallback, addr address.Ad i++ } - if cb != nil { + if em != nil { // record the transfer in execution traces fakeMsg := makeFakeMsg(builtin.SystemActorAddr, addr, big.Zero(), uint64(epoch)) - if err := cb(fakeMsg.Cid(), fakeMsg, &vm.ApplyRet{ + if err := em.MessageApplied(ctx, ts, fakeMsg.Cid(), fakeMsg, &vm.ApplyRet{ MessageReceipt: *makeFakeRct(), ActorErr: nil, ExecutionTrace: types.ExecutionTrace{ @@ -1411,7 +1411,7 @@ func splitGenesisMultisig0(ctx context.Context, cb ExecCallback, addr address.Ad }, Duration: 0, GasCosts: nil, - }); err != nil { + }, false); err != nil { return xerrors.Errorf("recording transfers: %w", err) } } diff --git a/chain/stmgr/forks_test.go b/chain/stmgr/forks_test.go index fe96ad610d0..dd2e47a57ab 100644 --- a/chain/stmgr/forks_test.go +++ b/chain/stmgr/forks_test.go @@ -123,7 +123,7 @@ func TestForkHeightTriggers(t *testing.T) { cg.ChainStore(), UpgradeSchedule{{ Network: 1, Height: testForkHeight, - Migration: func(ctx context.Context, sm *StateManager, cache MigrationCache, cb ExecCallback, + Migration: func(ctx context.Context, sm *StateManager, cache MigrationCache, cb ExecMonitor, root cid.Cid, height abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { cst := ipldcbor.NewCborStore(sm.ChainStore().StateBlockstore()) @@ -253,7 +253,7 @@ func TestForkRefuseCall(t *testing.T) { Network: 1, Expensive: true, Height: testForkHeight, - Migration: func(ctx context.Context, sm *StateManager, cache MigrationCache, cb ExecCallback, + Migration: func(ctx context.Context, sm *StateManager, cache MigrationCache, cb ExecMonitor, root cid.Cid, height abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { return root, nil }}}) @@ -363,7 +363,7 @@ func TestForkPreMigration(t *testing.T) { cg.ChainStore(), UpgradeSchedule{{ Network: 1, Height: testForkHeight, - Migration: func(ctx context.Context, sm *StateManager, cache MigrationCache, cb ExecCallback, + Migration: func(ctx context.Context, sm *StateManager, cache MigrationCache, cb ExecMonitor, root cid.Cid, height abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { // Make sure the test that should be canceled, is canceled. diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index 6690a4ad3c7..4f1351d2c58 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -103,6 +103,8 @@ type StateManager struct { genesisPledge abi.TokenAmount genesisMarketFunds abi.TokenAmount + + tsExecMonitor ExecMonitor } // Caches a single state tree @@ -171,6 +173,15 @@ func NewStateManagerWithUpgradeSchedule(cs *store.ChainStore, us UpgradeSchedule }, nil } +func NewStateManagerWithUpgradeScheduleAndMonitor(cs *store.ChainStore, us UpgradeSchedule, em ExecMonitor) (*StateManager, error) { + sm, err := NewStateManagerWithUpgradeSchedule(cs, us) + if err != nil { + return nil, err + } + sm.tsExecMonitor = em + return sm, nil +} + func cidsToKey(cids []cid.Cid) string { var out string for _, c := range cids { @@ -255,7 +266,7 @@ func (sm *StateManager) TipSetState(ctx context.Context, ts *types.TipSet) (st c return ts.Blocks()[0].ParentStateRoot, ts.Blocks()[0].ParentMessageReceipts, nil } - st, rec, err = sm.computeTipSetState(ctx, ts, nil) + st, rec, err = sm.computeTipSetState(ctx, ts, sm.tsExecMonitor) if err != nil { return cid.Undef, cid.Undef, err } @@ -263,39 +274,21 @@ func (sm *StateManager) TipSetState(ctx context.Context, ts *types.TipSet) (st c return st, rec, nil } -func traceFunc(trace *[]*api.InvocResult) func(mcid cid.Cid, msg *types.Message, ret *vm.ApplyRet) error { - return func(mcid cid.Cid, msg *types.Message, ret *vm.ApplyRet) error { - ir := &api.InvocResult{ - MsgCid: mcid, - Msg: msg, - MsgRct: &ret.MessageReceipt, - ExecutionTrace: ret.ExecutionTrace, - Duration: ret.Duration, - } - if ret.ActorErr != nil { - ir.Error = ret.ActorErr.Error() - } - if ret.GasCosts != nil { - ir.GasCost = MakeMsgGasCost(msg, ret) - } - *trace = append(*trace, ir) - return nil - } +func (sm *StateManager) ExecutionTraceWithMonitor(ctx context.Context, ts *types.TipSet, em ExecMonitor) (cid.Cid, error) { + st, _, err := sm.computeTipSetState(ctx, ts, em) + return st, err } func (sm *StateManager) ExecutionTrace(ctx context.Context, ts *types.TipSet) (cid.Cid, []*api.InvocResult, error) { - var trace []*api.InvocResult - st, _, err := sm.computeTipSetState(ctx, ts, traceFunc(&trace)) + var invocTrace []*api.InvocResult + st, err := sm.ExecutionTraceWithMonitor(ctx, ts, &InvocationTracer{trace: &invocTrace}) if err != nil { return cid.Undef, nil, err } - - return st, trace, nil + return st, invocTrace, nil } -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) { +func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEpoch, pstate cid.Cid, bms []store.BlockMessages, epoch abi.ChainEpoch, r vm.Rand, em ExecMonitor, baseFee abi.TokenAmount, ts *types.TipSet) (cid.Cid, cid.Cid, error) { done := metrics.Timer(ctx, metrics.VMApplyBlocksTotal) defer done() @@ -341,8 +334,8 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp if err != nil { return err } - if cb != nil { - if err := cb(cronMsg.Cid(), cronMsg, ret); err != nil { + if em != nil { + if err := em.MessageApplied(ctx, ts, cronMsg.Cid(), cronMsg, ret, true); err != nil { return xerrors.Errorf("callback failed on cron message: %w", err) } } @@ -368,7 +361,7 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp // handle state forks // XXX: The state tree - newState, err := sm.handleStateForks(ctx, pstate, i, cb, ts) + newState, err := sm.handleStateForks(ctx, pstate, i, em, ts) if err != nil { return cid.Undef, cid.Undef, xerrors.Errorf("error handling state forks: %w", err) } @@ -407,8 +400,8 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp gasReward = big.Add(gasReward, r.GasCosts.MinerTip) penalty = big.Add(penalty, r.GasCosts.MinerPenalty) - if cb != nil { - if err := cb(cm.Cid(), m, r); err != nil { + if em != nil { + if err := em.MessageApplied(ctx, ts, cm.Cid(), m, r, false); err != nil { return cid.Undef, cid.Undef, err } } @@ -440,8 +433,8 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp if actErr != nil { return cid.Undef, cid.Undef, xerrors.Errorf("failed to apply reward message for miner %s: %w", b.Miner, actErr) } - if cb != nil { - if err := cb(rwMsg.Cid(), rwMsg, ret); err != nil { + if em != nil { + if err := em.MessageApplied(ctx, ts, rwMsg.Cid(), rwMsg, ret, true); err != nil { return cid.Undef, cid.Undef, xerrors.Errorf("callback failed on reward message: %w", err) } } @@ -483,7 +476,7 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp return st, rectroot, nil } -func (sm *StateManager) computeTipSetState(ctx context.Context, ts *types.TipSet, cb ExecCallback) (cid.Cid, cid.Cid, error) { +func (sm *StateManager) computeTipSetState(ctx context.Context, ts *types.TipSet, em ExecMonitor) (cid.Cid, cid.Cid, error) { ctx, span := trace.StartSpan(ctx, "computeTipSetState") defer span.End() @@ -519,7 +512,7 @@ func (sm *StateManager) computeTipSetState(ctx context.Context, ts *types.TipSet baseFee := blks[0].ParentBaseFee - return sm.ApplyBlocks(ctx, parentEpoch, pstate, blkmsgs, blks[0].Height, r, cb, baseFee, ts) + return sm.ApplyBlocks(ctx, parentEpoch, pstate, blkmsgs, blks[0].Height, r, em, baseFee, ts) } func (sm *StateManager) parentState(ts *types.TipSet) cid.Cid { diff --git a/chain/stmgr/tracers.go b/chain/stmgr/tracers.go new file mode 100644 index 00000000000..6bcd7bc1595 --- /dev/null +++ b/chain/stmgr/tracers.go @@ -0,0 +1,56 @@ +package stmgr + +import ( + "context" + + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/chain/vm" + "github.com/ipfs/go-cid" +) + +type ExecMonitor interface { + // MessageApplied is called after a message has been applied. Returning an error will halt execution of any further messages. + MessageApplied(ctx context.Context, ts *types.TipSet, mcid cid.Cid, msg *types.Message, ret *vm.ApplyRet, implicit bool) error +} + +var _ ExecMonitor = (*InvocationTracer)(nil) + +type InvocationTracer struct { + trace *[]*api.InvocResult +} + +func (i *InvocationTracer) MessageApplied(ctx context.Context, ts *types.TipSet, mcid cid.Cid, msg *types.Message, ret *vm.ApplyRet, implicit bool) error { + ir := &api.InvocResult{ + MsgCid: mcid, + Msg: msg, + MsgRct: &ret.MessageReceipt, + ExecutionTrace: ret.ExecutionTrace, + Duration: ret.Duration, + } + if ret.ActorErr != nil { + ir.Error = ret.ActorErr.Error() + } + if ret.GasCosts != nil { + ir.GasCost = MakeMsgGasCost(msg, ret) + } + *i.trace = append(*i.trace, ir) + return nil +} + +var _ ExecMonitor = (*messageFinder)(nil) + +type messageFinder struct { + mcid cid.Cid // the message cid to find + outm *types.Message + outr *vm.ApplyRet +} + +func (m *messageFinder) MessageApplied(ctx context.Context, ts *types.TipSet, mcid cid.Cid, msg *types.Message, ret *vm.ApplyRet, implicit bool) error { + if m.mcid == mcid { + m.outm = msg + m.outr = ret + return errHaltExecution // message was found, no need to continue + } + return nil +} diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index f73554d3bc8..d2a2c6e604c 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -342,7 +342,7 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch, for i := ts.Height(); i < height; i++ { // handle state forks - base, err = sm.handleStateForks(ctx, base, i, traceFunc(&trace), ts) + base, err = sm.handleStateForks(ctx, base, i, &InvocationTracer{trace: &trace}, ts) if err != nil { return cid.Undef, nil, xerrors.Errorf("error handling state forks: %w", err) } diff --git a/chain/store/store.go b/chain/store/store.go index 71fa0397ac7..523726863f1 100644 --- a/chain/store/store.go +++ b/chain/store/store.go @@ -11,6 +11,7 @@ import ( "strconv" "strings" "sync" + "time" "github.com/filecoin-project/lotus/chain/state" @@ -404,7 +405,20 @@ func (cs *ChainStore) PutTipSet(ctx context.Context, ts *types.TipSet) error { // internal state as our new head, if and only if it is heavier than the current // head and does not exceed the maximum fork length. func (cs *ChainStore) MaybeTakeHeavierTipSet(ctx context.Context, ts *types.TipSet) error { - cs.heaviestLk.Lock() + for { + cs.heaviestLk.Lock() + if len(cs.reorgCh) < reorgChBuf/2 { + break + } + cs.heaviestLk.Unlock() + log.Errorf("reorg channel is heavily backlogged, waiting a bit before trying to take process new tipsets") + select { + case <-time.After(time.Second / 2): + case <-ctx.Done(): + return ctx.Err() + } + } + defer cs.heaviestLk.Unlock() w, err := cs.Weight(ctx, ts) if err != nil { @@ -529,8 +543,10 @@ type reorg struct { new *types.TipSet } +const reorgChBuf = 32 + func (cs *ChainStore) reorgWorker(ctx context.Context, initialNotifees []ReorgNotifee) chan<- reorg { - out := make(chan reorg, 32) + out := make(chan reorg, reorgChBuf) notifees := make([]ReorgNotifee, len(initialNotifees)) copy(notifees, initialNotifees) diff --git a/chain/sub/incoming.go b/chain/sub/incoming.go index 7744fe1b977..115c3326193 100644 --- a/chain/sub/incoming.go +++ b/chain/sub/incoming.go @@ -507,6 +507,12 @@ func (mv *MessageValidator) Validate(ctx context.Context, pid peer.ID, msg *pubs return mv.validateLocalMessage(ctx, msg) } + start := time.Now() + defer func() { + ms := time.Now().Sub(start).Microseconds() + stats.Record(ctx, metrics.MessageValidationDuration.M(float64(ms)/1000)) + }() + stats.Record(ctx, metrics.MessageReceived.M(1)) m, err := types.DecodeSignedMessage(msg.Message.GetData()) if err != nil { @@ -538,6 +544,12 @@ func (mv *MessageValidator) Validate(ctx context.Context, pid peer.ID, msg *pubs return pubsub.ValidationReject } } + + ctx, _ = tag.New( + ctx, + tag.Upsert(metrics.MsgValid, "true"), + ) + stats.Record(ctx, metrics.MessageValidationSuccess.M(1)) return pubsub.ValidationAccept } @@ -547,6 +559,13 @@ func (mv *MessageValidator) validateLocalMessage(ctx context.Context, msg *pubsu ctx, tag.Upsert(metrics.Local, "true"), ) + + start := time.Now() + defer func() { + ms := time.Now().Sub(start).Microseconds() + stats.Record(ctx, metrics.MessageValidationDuration.M(float64(ms)/1000)) + }() + // do some lightweight validation stats.Record(ctx, metrics.MessagePublished.M(1)) @@ -557,7 +576,7 @@ func (mv *MessageValidator) validateLocalMessage(ctx context.Context, msg *pubsu return pubsub.ValidationIgnore } - if m.Size() > 32*1024 { + if m.Size() > messagepool.MaxMessageSize { log.Warnf("local message is too large! (%dB)", m.Size()) recordFailure(ctx, metrics.MessageValidationFailure, "oversize") return pubsub.ValidationIgnore @@ -581,6 +600,11 @@ func (mv *MessageValidator) validateLocalMessage(ctx context.Context, msg *pubsu return pubsub.ValidationIgnore } + ctx, _ = tag.New( + ctx, + tag.Upsert(metrics.MsgValid, "true"), + ) + stats.Record(ctx, metrics.MessageValidationSuccess.M(1)) return pubsub.ValidationAccept } diff --git a/chain/sync_test.go b/chain/sync_test.go index 2289d6350f2..ae4b6cc2e06 100644 --- a/chain/sync_test.go +++ b/chain/sync_test.go @@ -85,6 +85,7 @@ type syncTestUtil struct { blocks []*store.FullTipSet nds []api.FullNode + us stmgr.UpgradeSchedule } func prepSyncTest(t testing.TB, h int) *syncTestUtil { @@ -104,9 +105,10 @@ func prepSyncTest(t testing.TB, h int) *syncTestUtil { mn: mocknet.New(ctx), g: g, + us: stmgr.DefaultUpgradeSchedule(), } - tu.addSourceNode(stmgr.DefaultUpgradeSchedule(), h) + tu.addSourceNode(h) //tu.checkHeight("source", source, h) @@ -119,7 +121,7 @@ func prepSyncTest(t testing.TB, h int) *syncTestUtil { func prepSyncTestWithV5Height(t testing.TB, h int, v5height abi.ChainEpoch) *syncTestUtil { logging.SetLogLevel("*", "INFO") - us := stmgr.UpgradeSchedule{{ + sched := stmgr.UpgradeSchedule{{ // prepare for upgrade. Network: network.Version9, Height: 1, @@ -138,7 +140,7 @@ func prepSyncTestWithV5Height(t testing.TB, h int, v5height abi.ChainEpoch) *syn Migration: stmgr.UpgradeActorsV5, }} - g, err := gen.NewGeneratorWithUpgradeSchedule(us) + g, err := gen.NewGeneratorWithUpgradeSchedule(sched) if err != nil { t.Fatalf("%+v", err) @@ -153,9 +155,10 @@ func prepSyncTestWithV5Height(t testing.TB, h int, v5height abi.ChainEpoch) *syn mn: mocknet.New(ctx), g: g, + us: sched, } - tu.addSourceNode(us, h) + tu.addSourceNode(h) //tu.checkHeight("source", source, h) // separate logs @@ -266,7 +269,7 @@ func (tu *syncTestUtil) mineNewBlock(src int, miners []int) { tu.g.CurTipset = mts } -func (tu *syncTestUtil) addSourceNode(us stmgr.UpgradeSchedule, gen int) { +func (tu *syncTestUtil) addSourceNode(gen int) { if tu.genesis != nil { tu.t.Fatal("source node already exists") } @@ -282,7 +285,7 @@ func (tu *syncTestUtil) addSourceNode(us stmgr.UpgradeSchedule, gen int) { node.Test(), node.Override(new(modules.Genesis), modules.LoadGenesis(genesis)), - node.Override(new(stmgr.UpgradeSchedule), us), + node.Override(new(stmgr.UpgradeSchedule), tu.us), ) require.NoError(tu.t, err) tu.t.Cleanup(func() { _ = stop(context.Background()) }) @@ -315,6 +318,7 @@ func (tu *syncTestUtil) addClientNode() int { node.Test(), node.Override(new(modules.Genesis), modules.LoadGenesis(tu.genesis)), + node.Override(new(stmgr.UpgradeSchedule), tu.us), ) require.NoError(tu.t, err) tu.t.Cleanup(func() { _ = stop(context.Background()) }) @@ -433,12 +437,18 @@ func (tu *syncTestUtil) waitUntilSyncTarget(to int, target *types.TipSet) { tu.t.Fatal(err) } - // TODO: some sort of timeout? - for n := range hc { - for _, c := range n { - if c.Val.Equals(target) { - return + timeout := time.After(5 * time.Second) + + for { + select { + case n := <-hc: + for _, c := range n { + if c.Val.Equals(target) { + return + } } + case <-timeout: + tu.t.Fatal("waitUntilSyncTarget timeout") } } } @@ -575,15 +585,20 @@ func TestSyncFork(t *testing.T) { tu.loadChainToNode(p1) tu.loadChainToNode(p2) - phead := func() { + printHead := func() { h1, err := tu.nds[1].ChainHead(tu.ctx) require.NoError(tu.t, err) h2, err := tu.nds[2].ChainHead(tu.ctx) require.NoError(tu.t, err) - fmt.Println("Node 1: ", h1.Cids(), h1.Parents(), h1.Height()) - fmt.Println("Node 2: ", h2.Cids(), h1.Parents(), h2.Height()) + w1, err := tu.nds[1].(*impl.FullNodeAPI).ChainAPI.Chain.Weight(tu.ctx, h1) + require.NoError(tu.t, err) + w2, err := tu.nds[2].(*impl.FullNodeAPI).ChainAPI.Chain.Weight(tu.ctx, h2) + require.NoError(tu.t, err) + + fmt.Println("Node 1: ", h1.Cids(), h1.Parents(), h1.Height(), w1) + fmt.Println("Node 2: ", h2.Cids(), h2.Parents(), h2.Height(), w2) //time.Sleep(time.Second * 2) fmt.Println() fmt.Println() @@ -591,7 +606,7 @@ func TestSyncFork(t *testing.T) { fmt.Println() } - phead() + printHead() base := tu.g.CurTipset fmt.Println("Mining base: ", base.TipSet().Cids(), base.TipSet().Height()) @@ -611,6 +626,8 @@ func TestSyncFork(t *testing.T) { fmt.Println("A: ", a.Cids(), a.TipSet().Height()) fmt.Println("B: ", b.Cids(), b.TipSet().Height()) + printHead() + // Now for the fun part!! require.NoError(t, tu.mn.LinkAll()) @@ -618,7 +635,7 @@ func TestSyncFork(t *testing.T) { tu.waitUntilSyncTarget(p1, b.TipSet()) tu.waitUntilSyncTarget(p2, b.TipSet()) - phead() + printHead() } // This test crafts a tipset with 2 blocks, A and B. @@ -1019,18 +1036,24 @@ func TestDrandNull(t *testing.T) { build.UpgradeHyperdriveHeight = v5h tu := prepSyncTestWithV5Height(t, H, v5h) + p0 := tu.addClientNode() + p1 := tu.addClientNode() + + tu.loadChainToNode(p0) + tu.loadChainToNode(p1) + entropy := []byte{0, 2, 3, 4} // arbitrarily chosen pers := crypto.DomainSeparationTag_WinningPoStChallengeSeed beforeNull := tu.g.CurTipset - afterNull := tu.mineOnBlock(beforeNull, 0, nil, false, false, nil, 2) + afterNull := tu.mineOnBlock(beforeNull, p0, nil, false, false, nil, 2) nullHeight := beforeNull.TipSet().Height() + 1 if afterNull.TipSet().Height() == nullHeight { t.Fatal("didn't inject nulls as expected") } - rand, err := tu.nds[0].ChainGetRandomnessFromBeacon(tu.ctx, afterNull.TipSet().Key(), pers, nullHeight, entropy) + rand, err := tu.nds[p0].ChainGetRandomnessFromBeacon(tu.ctx, afterNull.TipSet().Key(), pers, nullHeight, entropy) require.NoError(t, err) // calculate the expected randomness based on the beacon BEFORE the null @@ -1041,20 +1064,20 @@ func TestDrandNull(t *testing.T) { require.Equal(t, []byte(rand), expectedRand) // zoom zoom to past the v5 upgrade by injecting many many nulls - postUpgrade := tu.mineOnBlock(afterNull, 0, nil, false, false, nil, v5h) - nv, err := tu.nds[0].StateNetworkVersion(tu.ctx, types.EmptyTSK) + postUpgrade := tu.mineOnBlock(afterNull, p0, nil, false, false, nil, v5h) + nv, err := tu.nds[p0].StateNetworkVersion(tu.ctx, postUpgrade.TipSet().Key()) require.NoError(t, err) if nv != network.Version13 { t.Fatal("expect to be v13 by now") } - afterNull = tu.mineOnBlock(postUpgrade, 0, nil, false, false, nil, 2) + afterNull = tu.mineOnBlock(postUpgrade, p0, nil, false, false, nil, 2) nullHeight = postUpgrade.TipSet().Height() + 1 if afterNull.TipSet().Height() == nullHeight { t.Fatal("didn't inject nulls as expected") } - rand, err = tu.nds[0].ChainGetRandomnessFromBeacon(tu.ctx, afterNull.TipSet().Key(), pers, nullHeight, entropy) + rand0, err := tu.nds[p0].ChainGetRandomnessFromBeacon(tu.ctx, afterNull.TipSet().Key(), pers, nullHeight, entropy) require.NoError(t, err) // calculate the expected randomness based on the beacon AFTER the null @@ -1062,7 +1085,21 @@ func TestDrandNull(t *testing.T) { expectedRand, err = store.DrawRandomness(expectedBE[len(expectedBE)-1].Data, pers, nullHeight, entropy) require.NoError(t, err) - require.Equal(t, []byte(rand), expectedRand) - build.UpgradeHyperdriveHeight = ov5h + require.Equal(t, []byte(rand0), expectedRand) + + // Introduce p1 to friendly p0 who has all the blocks + require.NoError(t, tu.mn.LinkAll()) + tu.connect(p0, p1) + tu.waitUntilNodeHasTs(p1, afterNull.TipSet().Key()) + p1Head := tu.getHead(p1) + // Yes, p1 syncs well to p0's chain + require.Equal(tu.t, p1Head.Key(), afterNull.TipSet().Key()) + + // Yes, p1 sources the same randomness as p0 + rand1, err := tu.nds[p1].ChainGetRandomnessFromBeacon(tu.ctx, afterNull.TipSet().Key(), pers, nullHeight, entropy) + require.NoError(t, err) + require.Equal(t, rand0, rand1) + + build.UpgradeHyperdriveHeight = ov5h } diff --git a/chain/types/bigint.go b/chain/types/bigint.go index da4857d5b4d..72ef5212862 100644 --- a/chain/types/bigint.go +++ b/chain/types/bigint.go @@ -47,6 +47,11 @@ func BigDiv(a, b BigInt) BigInt { return BigInt{Int: big.NewInt(0).Div(a.Int, b.Int)} } +func BigDivFloat(num, den BigInt) float64 { + res, _ := new(big.Rat).SetFrac(num.Int, den.Int).Float64() + return res +} + func BigMod(a, b BigInt) BigInt { return BigInt{Int: big.NewInt(0).Mod(a.Int, b.Int)} } diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index 7c40fed62de..2845c7696ea 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -229,7 +229,7 @@ func (rt *Runtime) GetRandomnessFromTickets(personalization crypto.DomainSeparat func (rt *Runtime) GetRandomnessFromBeacon(personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) abi.Randomness { var err error var res []byte - if rt.vm.GetNtwkVersion(rt.ctx, randEpoch) >= network.Version13 { + if randEpoch > build.UpgradeHyperdriveHeight { res, err = rt.vm.rand.GetBeaconRandomnessLookingForward(rt.ctx, personalization, randEpoch, entropy) } else { res, err = rt.vm.rand.GetBeaconRandomnessLookingBack(rt.ctx, personalization, randEpoch, entropy) diff --git a/chain/vm/syscalls.go b/chain/vm/syscalls.go index bb93fce8ddc..0cbefd1fd7f 100644 --- a/chain/vm/syscalls.go +++ b/chain/vm/syscalls.go @@ -267,7 +267,7 @@ func (ss *syscallShim) VerifySeal(info proof5.SealVerifyInfo) error { proof := info.Proof seed := []byte(info.InteractiveRandomness) - log.Debugf("Verif r:%x; d:%x; m:%s; t:%x; s:%x; N:%d; p:%x", info.SealedCID, info.UnsealedCID, miner, ticket, seed, info.SectorID.Number, proof) + log.Debugf("Verif r:%s; d:%s; m:%s; t:%x; s:%x; N:%d; p:%x", info.SealedCID, info.UnsealedCID, miner, ticket, seed, info.SectorID.Number, proof) //func(ctx context.Context, maddr address.Address, ssize abi.SectorSize, commD, commR, ticket, proof, seed []byte, sectorID abi.SectorNumber) ok, err := ss.verifier.VerifySeal(info) diff --git a/cli/chain.go b/cli/chain.go index 6651a77649e..0fca73406f2 100644 --- a/cli/chain.go +++ b/cli/chain.go @@ -536,7 +536,7 @@ var ChainListCmd = &cli.Command{ Aliases: []string{"love"}, Usage: "View a segment of the chain", Flags: []cli.Flag{ - &cli.Uint64Flag{Name: "height"}, + &cli.Uint64Flag{Name: "height", DefaultText: "current head"}, &cli.IntFlag{Name: "count", Value: 30}, &cli.StringFlag{ Name: "format", diff --git a/cli/client.go b/cli/client.go index b270b730e46..590a092680b 100644 --- a/cli/client.go +++ b/cli/client.go @@ -93,6 +93,7 @@ var clientCmd = &cli.Command{ WithCategory("retrieval", clientFindCmd), WithCategory("retrieval", clientRetrieveCmd), WithCategory("retrieval", clientCancelRetrievalDealCmd), + WithCategory("retrieval", clientListRetrievalsCmd), WithCategory("util", clientCommPCmd), WithCategory("util", clientCarGenCmd), WithCategory("util", clientBalancesCmd), @@ -308,8 +309,8 @@ var clientDealCmd = &cli.Command{ 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 +price is measured in FIL/Epoch. Miners usually don't accept a bid +lower than their advertised ask (which is in FIL/GiB/Epoch). 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).`, @@ -1193,6 +1194,8 @@ var clientRetrieveCmd = &cli.Command{ return xerrors.Errorf("error setting up retrieval: %w", err) } + var prevStatus retrievalmarket.DealStatus + for { select { case evt, ok := <-updates: @@ -1203,14 +1206,23 @@ var clientRetrieveCmd = &cli.Command{ retrievalmarket.ClientEvents[evt.Event], retrievalmarket.DealStatuses[evt.Status], ) - } else { - afmt.Println("Success") - return nil + prevStatus = evt.Status } if evt.Err != "" { return xerrors.Errorf("retrieval failed: %s", evt.Err) } + + if !ok { + if prevStatus == retrievalmarket.DealStatusCompleted { + afmt.Println("Success") + } else { + afmt.Printf("saw final deal state %s instead of expected success state DealStatusCompleted\n", + retrievalmarket.DealStatuses[prevStatus]) + } + return nil + } + case <-ctx.Done(): return xerrors.Errorf("retrieval timed out") } @@ -1218,6 +1230,197 @@ var clientRetrieveCmd = &cli.Command{ }, } +var clientListRetrievalsCmd = &cli.Command{ + Name: "list-retrievals", + Usage: "List retrieval market deals", + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "verbose", + Aliases: []string{"v"}, + Usage: "print verbose deal details", + }, + &cli.BoolFlag{ + Name: "color", + Usage: "use color in display output", + Value: true, + }, + &cli.BoolFlag{ + Name: "show-failed", + Usage: "show failed/failing deals", + Value: true, + }, + &cli.BoolFlag{ + Name: "completed", + Usage: "show completed retrievals", + }, + &cli.BoolFlag{ + Name: "watch", + Usage: "watch deal updates in real-time, rather than a one time list", + }, + }, + Action: func(cctx *cli.Context) error { + api, closer, err := GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer closer() + ctx := ReqContext(cctx) + + verbose := cctx.Bool("verbose") + color := cctx.Bool("color") + watch := cctx.Bool("watch") + showFailed := cctx.Bool("show-failed") + completed := cctx.Bool("completed") + + localDeals, err := api.ClientListRetrievals(ctx) + if err != nil { + return err + } + + if watch { + updates, err := api.ClientGetRetrievalUpdates(ctx) + if err != nil { + return err + } + + for { + tm.Clear() + tm.MoveCursor(1, 1) + + err = outputRetrievalDeals(ctx, tm.Screen, localDeals, verbose, color, showFailed, completed) + if err != nil { + return err + } + + tm.Flush() + + select { + case <-ctx.Done(): + return nil + case updated := <-updates: + var found bool + for i, existing := range localDeals { + if existing.ID == updated.ID { + localDeals[i] = updated + found = true + break + } + } + if !found { + localDeals = append(localDeals, updated) + } + } + } + } + + return outputRetrievalDeals(ctx, cctx.App.Writer, localDeals, verbose, color, showFailed, completed) + }, +} + +func isTerminalError(status retrievalmarket.DealStatus) bool { + // should patch this in go-fil-markets but to solve the problem immediate and not have buggy output + return retrievalmarket.IsTerminalError(status) || status == retrievalmarket.DealStatusErrored || status == retrievalmarket.DealStatusCancelled +} +func outputRetrievalDeals(ctx context.Context, out io.Writer, localDeals []lapi.RetrievalInfo, verbose bool, color bool, showFailed bool, completed bool) error { + var deals []api.RetrievalInfo + for _, deal := range localDeals { + if !showFailed && isTerminalError(deal.Status) { + continue + } + if !completed && retrievalmarket.IsTerminalSuccess(deal.Status) { + continue + } + deals = append(deals, deal) + } + + tableColumns := []tablewriter.Column{ + tablewriter.Col("PayloadCID"), + tablewriter.Col("DealId"), + tablewriter.Col("Provider"), + tablewriter.Col("Status"), + tablewriter.Col("PricePerByte"), + tablewriter.Col("Received"), + tablewriter.Col("TotalPaid"), + } + + if verbose { + tableColumns = append(tableColumns, + tablewriter.Col("PieceCID"), + tablewriter.Col("UnsealPrice"), + tablewriter.Col("BytesPaidFor"), + tablewriter.Col("TransferChannelID"), + tablewriter.Col("TransferStatus"), + ) + } + tableColumns = append(tableColumns, tablewriter.NewLineCol("Message")) + + w := tablewriter.New(tableColumns...) + + for _, d := range deals { + w.Write(toRetrievalOutput(d, color, verbose)) + } + + return w.Flush(out) +} + +func toRetrievalOutput(d api.RetrievalInfo, color bool, verbose bool) map[string]interface{} { + + payloadCID := d.PayloadCID.String() + provider := d.Provider.String() + if !verbose { + payloadCID = ellipsis(payloadCID, 8) + provider = ellipsis(provider, 8) + } + + retrievalOutput := map[string]interface{}{ + "PayloadCID": payloadCID, + "DealId": d.ID, + "Provider": provider, + "Status": retrievalStatusString(color, d.Status), + "PricePerByte": types.FIL(d.PricePerByte), + "Received": units.BytesSize(float64(d.BytesReceived)), + "TotalPaid": types.FIL(d.TotalPaid), + "Message": d.Message, + } + + if verbose { + transferChannelID := "" + if d.TransferChannelID != nil { + transferChannelID = d.TransferChannelID.String() + } + transferStatus := "" + if d.DataTransfer != nil { + transferStatus = datatransfer.Statuses[d.DataTransfer.Status] + } + pieceCID := "" + if d.PieceCID != nil { + pieceCID = d.PieceCID.String() + } + + retrievalOutput["PieceCID"] = pieceCID + retrievalOutput["UnsealPrice"] = types.FIL(d.UnsealPrice) + retrievalOutput["BytesPaidFor"] = units.BytesSize(float64(d.BytesPaidFor)) + retrievalOutput["TransferChannelID"] = transferChannelID + retrievalOutput["TransferStatus"] = transferStatus + } + return retrievalOutput +} + +func retrievalStatusString(c bool, status retrievalmarket.DealStatus) string { + s := retrievalmarket.DealStatuses[status] + if !c { + return s + } + + if isTerminalError(status) { + return color.RedString(s) + } + if retrievalmarket.IsTerminalSuccess(status) { + return color.GreenString(s) + } + return s +} + var clientInspectDealCmd = &cli.Command{ Name: "inspect-deal", Usage: "Inspect detailed information about deal's lifecycle and the various stages it goes through", diff --git a/cli/client_test.go b/cli/client_test.go deleted file mode 100644 index f0e8efda846..00000000000 --- a/cli/client_test.go +++ /dev/null @@ -1,22 +0,0 @@ -package cli - -import ( - "context" - "os" - "testing" - "time" - - clitest "github.com/filecoin-project/lotus/cli/test" -) - -// TestClient does a basic test to exercise the client CLI -// commands -func TestClient(t *testing.T) { - _ = os.Setenv("BELLMAN_NO_GPU", "1") - clitest.QuietMiningLogs() - - blocktime := 5 * time.Millisecond - ctx := context.Background() - clientNode, _ := clitest.StartOneNodeOneMiner(ctx, t, blocktime) - clitest.RunClientTest(t, Commands, clientNode) -} diff --git a/cli/multisig.go b/cli/multisig.go index 9ddfcdfc146..c51677d85ca 100644 --- a/cli/multisig.go +++ b/cli/multisig.go @@ -1428,7 +1428,7 @@ var msigLockCancelCmd = &cli.Command{ }, }, Action: func(cctx *cli.Context) error { - if cctx.Args().Len() != 6 { + if cctx.Args().Len() != 5 { return ShowHelp(cctx, fmt.Errorf("must pass multisig address, tx id, start epoch, unlock duration, and amount")) } diff --git a/cli/multisig_test.go b/cli/multisig_test.go deleted file mode 100644 index 82472cd627b..00000000000 --- a/cli/multisig_test.go +++ /dev/null @@ -1,22 +0,0 @@ -package cli - -import ( - "context" - "os" - "testing" - "time" - - clitest "github.com/filecoin-project/lotus/cli/test" -) - -// TestMultisig does a basic test to exercise the multisig CLI -// commands -func TestMultisig(t *testing.T) { - _ = os.Setenv("BELLMAN_NO_GPU", "1") - clitest.QuietMiningLogs() - - blocktime := 5 * time.Millisecond - ctx := context.Background() - clientNode, _ := clitest.StartOneNodeOneMiner(ctx, t, blocktime) - clitest.RunMultisigTest(t, Commands, clientNode) -} diff --git a/cli/servicesmock_test.go b/cli/servicesmock_test.go index 4bd4b79c9e2..5bae52a5ebc 100644 --- a/cli/servicesmock_test.go +++ b/cli/servicesmock_test.go @@ -6,39 +6,40 @@ package cli import ( context "context" + reflect "reflect" + 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" - reflect "reflect" ) -// MockServicesAPI is a mock of ServicesAPI interface +// MockServicesAPI is a mock of ServicesAPI interface. type MockServicesAPI struct { ctrl *gomock.Controller recorder *MockServicesAPIMockRecorder } -// MockServicesAPIMockRecorder is the mock recorder for MockServicesAPI +// MockServicesAPIMockRecorder is the mock recorder for MockServicesAPI. type MockServicesAPIMockRecorder struct { mock *MockServicesAPI } -// NewMockServicesAPI creates a new mock instance +// NewMockServicesAPI creates a new mock instance. func NewMockServicesAPI(ctrl *gomock.Controller) *MockServicesAPI { mock := &MockServicesAPI{ctrl: ctrl} mock.recorder = &MockServicesAPIMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockServicesAPI) EXPECT() *MockServicesAPIMockRecorder { return m.recorder } -// Close mocks base method +// Close mocks base method. func (m *MockServicesAPI) Close() error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Close") @@ -46,13 +47,13 @@ func (m *MockServicesAPI) Close() error { return ret0 } -// Close indicates an expected call of Close +// Close indicates an expected call of Close. func (mr *MockServicesAPIMockRecorder) Close() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockServicesAPI)(nil).Close)) } -// DecodeTypedParamsFromJSON mocks base method +// DecodeTypedParamsFromJSON mocks base method. func (m *MockServicesAPI) DecodeTypedParamsFromJSON(arg0 context.Context, arg1 go_address.Address, arg2 abi.MethodNum, arg3 string) ([]byte, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DecodeTypedParamsFromJSON", arg0, arg1, arg2, arg3) @@ -61,13 +62,13 @@ func (m *MockServicesAPI) DecodeTypedParamsFromJSON(arg0 context.Context, arg1 g return ret0, ret1 } -// DecodeTypedParamsFromJSON indicates an expected call of DecodeTypedParamsFromJSON +// DecodeTypedParamsFromJSON indicates an expected call of DecodeTypedParamsFromJSON. func (mr *MockServicesAPIMockRecorder) DecodeTypedParamsFromJSON(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecodeTypedParamsFromJSON", reflect.TypeOf((*MockServicesAPI)(nil).DecodeTypedParamsFromJSON), arg0, arg1, arg2, arg3) } -// FullNodeAPI mocks base method +// FullNodeAPI mocks base method. func (m *MockServicesAPI) FullNodeAPI() api.FullNode { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "FullNodeAPI") @@ -75,13 +76,13 @@ func (m *MockServicesAPI) FullNodeAPI() api.FullNode { return ret0 } -// FullNodeAPI indicates an expected call of FullNodeAPI +// 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 +// 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) @@ -90,13 +91,13 @@ func (m *MockServicesAPI) GetBaseFee(arg0 context.Context) (big.Int, error) { return ret0, ret1 } -// GetBaseFee indicates an expected call of GetBaseFee +// 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 +// 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) @@ -106,13 +107,13 @@ func (m *MockServicesAPI) LocalAddresses(arg0 context.Context) (go_address.Addre return ret0, ret1, ret2 } -// LocalAddresses indicates an expected call of LocalAddresses +// 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 +// 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) @@ -121,13 +122,13 @@ func (m *MockServicesAPI) MessageForSend(arg0 context.Context, arg1 SendParams) return ret0, ret1 } -// MessageForSend indicates an expected call of MessageForSend +// 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 +// 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) @@ -136,13 +137,13 @@ func (m *MockServicesAPI) MpoolCheckPendingMessages(arg0 context.Context, arg1 g return ret0, ret1 } -// MpoolCheckPendingMessages indicates an expected call of MpoolCheckPendingMessages +// 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 +// 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) @@ -151,13 +152,13 @@ func (m *MockServicesAPI) MpoolPendingFilter(arg0 context.Context, arg1 func(*ty return ret0, ret1 } -// MpoolPendingFilter indicates an expected call of MpoolPendingFilter +// 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 +// 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) @@ -167,13 +168,13 @@ func (m *MockServicesAPI) PublishMessage(arg0 context.Context, arg1 *api.Message return ret0, ret1, ret2 } -// PublishMessage indicates an expected call of PublishMessage +// 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 +// 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) @@ -182,7 +183,7 @@ func (m *MockServicesAPI) RunChecksForPrototype(arg0 context.Context, arg1 *api. return ret0, ret1 } -// RunChecksForPrototype indicates an expected call of RunChecksForPrototype +// 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, "RunChecksForPrototype", reflect.TypeOf((*MockServicesAPI)(nil).RunChecksForPrototype), arg0, arg1) diff --git a/cli/state.go b/cli/state.go index 6c3c4b11190..6bf23d798db 100644 --- a/cli/state.go +++ b/cli/state.go @@ -17,6 +17,8 @@ import ( "strings" "time" + "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/lotus/api/v0api" "github.com/fatih/color" @@ -183,18 +185,23 @@ var StateMinerInfo = &cli.Command{ return err } - rpercI := types.BigDiv(types.BigMul(pow.MinerPower.RawBytePower, types.NewInt(1000000)), pow.TotalPower.RawBytePower) - qpercI := types.BigDiv(types.BigMul(pow.MinerPower.QualityAdjPower, types.NewInt(1000000)), pow.TotalPower.QualityAdjPower) - fmt.Printf("Byte Power: %s / %s (%0.4f%%)\n", color.BlueString(types.SizeStr(pow.MinerPower.RawBytePower)), types.SizeStr(pow.TotalPower.RawBytePower), - float64(rpercI.Int64())/10000) + types.BigDivFloat( + types.BigMul(pow.MinerPower.RawBytePower, big.NewInt(100)), + pow.TotalPower.RawBytePower, + ), + ) fmt.Printf("Actual Power: %s / %s (%0.4f%%)\n", color.GreenString(types.DeciStr(pow.MinerPower.QualityAdjPower)), types.DeciStr(pow.TotalPower.QualityAdjPower), - float64(qpercI.Int64())/10000) + types.BigDivFloat( + types.BigMul(pow.MinerPower.QualityAdjPower, big.NewInt(100)), + pow.TotalPower.QualityAdjPower, + ), + ) fmt.Println() @@ -281,17 +288,26 @@ var StatePowerCmd = &cli.Command{ ctx := ReqContext(cctx) + ts, err := LoadTipSet(ctx, cctx, api) + if err != nil { + return err + } + var maddr address.Address if cctx.Args().Present() { maddr, err = address.NewFromString(cctx.Args().First()) if err != nil { return err } - } - ts, err := LoadTipSet(ctx, cctx, api) - if err != nil { - return err + ma, err := api.StateGetActor(ctx, maddr, ts.Key()) + if err != nil { + return err + } + + if !builtin.IsStorageMinerActor(ma.Code) { + return xerrors.New("provided address does not correspond to a miner actor") + } } power, err := api.StateMinerPower(ctx, maddr, ts.Key()) @@ -302,8 +318,15 @@ var StatePowerCmd = &cli.Command{ tp := power.TotalPower if cctx.Args().Present() { mp := power.MinerPower - percI := types.BigDiv(types.BigMul(mp.QualityAdjPower, types.NewInt(1000000)), tp.QualityAdjPower) - fmt.Printf("%s(%s) / %s(%s) ~= %0.4f%%\n", mp.QualityAdjPower.String(), types.SizeStr(mp.QualityAdjPower), tp.QualityAdjPower.String(), types.SizeStr(tp.QualityAdjPower), float64(percI.Int64())/10000) + fmt.Printf( + "%s(%s) / %s(%s) ~= %0.4f%%\n", + mp.QualityAdjPower.String(), types.SizeStr(mp.QualityAdjPower), + tp.QualityAdjPower.String(), types.SizeStr(tp.QualityAdjPower), + types.BigDivFloat( + types.BigMul(mp.QualityAdjPower, big.NewInt(100)), + tp.QualityAdjPower, + ), + ) } else { fmt.Printf("%s(%s)\n", tp.QualityAdjPower.String(), types.SizeStr(tp.QualityAdjPower)) } @@ -345,7 +368,7 @@ var StateSectorsCmd = &cli.Command{ } for _, s := range sectors { - fmt.Printf("%d: %x\n", s.SectorNumber, s.SealedCID) + fmt.Printf("%d: %s\n", s.SectorNumber, s.SealedCID) } return nil @@ -385,7 +408,7 @@ var StateActiveSectorsCmd = &cli.Command{ } for _, s := range sectors { - fmt.Printf("%d: %x\n", s.SectorNumber, s.SealedCID) + fmt.Printf("%d: %s\n", s.SectorNumber, s.SealedCID) } return nil diff --git a/cli/test/util.go b/cli/test/util.go deleted file mode 100644 index d7959b9d572..00000000000 --- a/cli/test/util.go +++ /dev/null @@ -1,14 +0,0 @@ -package test - -import "github.com/ipfs/go-log/v2" - -func QuietMiningLogs() { - _ = log.SetLogLevel("miner", "ERROR") - _ = log.SetLogLevel("chainstore", "ERROR") - _ = log.SetLogLevel("chain", "ERROR") - _ = log.SetLogLevel("sub", "ERROR") - _ = log.SetLogLevel("storageminer", "ERROR") - _ = log.SetLogLevel("pubsub", "ERROR") - _ = log.SetLogLevel("gen", "ERROR") - _ = log.SetLogLevel("dht/RtRefreshManager", "ERROR") -} diff --git a/cmd/lotus-gateway/main.go b/cmd/lotus-gateway/main.go index b21b2cacca4..cfda02d86d8 100644 --- a/cmd/lotus-gateway/main.go +++ b/cmd/lotus-gateway/main.go @@ -4,32 +4,29 @@ import ( "context" "fmt" "net" - "net/http" "os" - "contrib.go.opencensus.io/exporter/prometheus" - "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/lotus/gateway" - "github.com/gorilla/mux" - logging "github.com/ipfs/go-log/v2" - promclient "github.com/prometheus/client_golang/prometheus" "github.com/urfave/cli/v2" "go.opencensus.io/stats/view" - "go.opencensus.io/tag" + "golang.org/x/xerrors" + + logging "github.com/ipfs/go-log/v2" - "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-jsonrpc" + "github.com/filecoin-project/go-state-types/abi" + + manet "github.com/multiformats/go-multiaddr/net" - lapi "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/go-address" "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/build" "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" cliutil "github.com/filecoin-project/lotus/cli/util" + "github.com/filecoin-project/lotus/gateway" "github.com/filecoin-project/lotus/lib/lotuslog" "github.com/filecoin-project/lotus/metrics" + "github.com/filecoin-project/lotus/node" ) var log = logging.Logger("gateway") @@ -140,10 +137,6 @@ var runCmd = &cli.Command{ Action: func(cctx *cli.Context) error { log.Info("Starting lotus gateway") - ctx := lcli.ReqContext(cctx) - ctx, cancel := context.WithCancel(ctx) - defer cancel() - // Register all metric views if err := view.Register( metrics.ChainNodeViews..., @@ -157,70 +150,44 @@ var runCmd = &cli.Command{ } defer closer() - address := cctx.String("listen") - mux := mux.NewRouter() - - log.Info("Setting up API endpoint at " + address) + var ( + lookbackCap = cctx.Duration("api-max-lookback") + address = cctx.String("listen") + waitLookback = abi.ChainEpoch(cctx.Int64("api-wait-lookback-limit")) + ) - 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) + serverOptions := make([]jsonrpc.ServerOption, 0) + if maxRequestSize := cctx.Int("api-max-req-size"); maxRequestSize != 0 { + serverOptions = append(serverOptions, jsonrpc.WithMaxRequestSize(int64(maxRequestSize))) } - lookbackCap := cctx.Duration("api-max-lookback") - - waitLookback := abi.ChainEpoch(cctx.Int64("api-wait-lookback-limit")) - - ma := metrics.MetricedGatewayAPI(gateway.NewNode(api, lookbackCap, waitLookback)) - - serveRpc("/rpc/v1", ma) - serveRpc("/rpc/v0", lapi.Wrap(new(v1api.FullNodeStruct), new(v0api.WrapperV1Full), ma)) + log.Info("setting up API endpoint at " + address) - registry := promclient.DefaultRegisterer.(*promclient.Registry) - exporter, err := prometheus.NewExporter(prometheus.Options{ - Registry: registry, - Namespace: "lotus_gw", - }) + addr, err := net.ResolveTCPAddr("tcp", address) if err != nil { - return err + return xerrors.Errorf("failed to resolve endpoint address: %w", err) } - mux.Handle("/debug/metrics", exporter) - - mux.PathPrefix("/").Handler(http.DefaultServeMux) - - /*ah := &auth.Handler{ - Verify: nodeApi.AuthVerify, - Next: mux.ServeHTTP, - }*/ - srv := &http.Server{ - Handler: mux, - BaseContext: func(listener net.Listener) context.Context { - ctx, _ := tag.New(context.Background(), tag.Upsert(metrics.APIInterface, "lotus-gateway")) - return ctx - }, + maddr, err := manet.FromNetAddr(addr) + if err != nil { + return xerrors.Errorf("failed to convert endpoint address to multiaddr: %w", err) } - go func() { - <-ctx.Done() - log.Warn("Shutting down...") - if err := srv.Shutdown(context.TODO()); err != nil { - log.Errorf("shutting down RPC server failed: %s", err) - } - log.Warn("Graceful shutdown successful") - }() + gwapi := gateway.NewNode(api, lookbackCap, waitLookback) + h, err := gateway.Handler(gwapi, serverOptions...) + if err != nil { + return xerrors.Errorf("failed to set up gateway HTTP handler") + } - nl, err := net.Listen("tcp", address) + stopFunc, err := node.ServeRPC(h, "lotus-gateway", maddr) if err != nil { - return err + return xerrors.Errorf("failed to serve rpc endpoint: %w", err) } - return srv.Serve(nl) + <-node.MonitorShutdown(nil, node.ShutdownHandler{ + Component: "rpc", + StopFunc: stopFunc, + }) + return nil }, } diff --git a/cmd/lotus-seal-worker/main.go b/cmd/lotus-seal-worker/main.go index df00928a50c..adcf0f86934 100644 --- a/cmd/lotus-seal-worker/main.go +++ b/cmd/lotus-seal-worker/main.go @@ -362,9 +362,10 @@ var runCmd = &cli.Command{ return xerrors.Errorf("could not get api info: %w", err) } - remote := stores.NewRemote(localStore, nodeApi, sminfo.AuthHeader(), cctx.Int("parallel-fetch-limit")) + remote := stores.NewRemote(localStore, nodeApi, sminfo.AuthHeader(), cctx.Int("parallel-fetch-limit"), + &stores.DefaultPartialFileHandler{}) - fh := &stores.FetchHandler{Local: localStore} + fh := &stores.FetchHandler{Local: localStore, PfHandler: &stores.DefaultPartialFileHandler{}} remoteHandler := func(w http.ResponseWriter, r *http.Request) { if !auth.HasPerm(r.Context(), nil, api.PermAdmin) { w.WriteHeader(401) diff --git a/cmd/lotus-shed/export-car.go b/cmd/lotus-shed/export-car.go new file mode 100644 index 00000000000..97e4fb6c608 --- /dev/null +++ b/cmd/lotus-shed/export-car.go @@ -0,0 +1,103 @@ +package main + +import ( + "fmt" + "io" + "os" + + "github.com/ipfs/go-blockservice" + "github.com/ipfs/go-cid" + offline "github.com/ipfs/go-ipfs-exchange-offline" + format "github.com/ipfs/go-ipld-format" + "github.com/ipfs/go-merkledag" + "github.com/ipld/go-car" + "github.com/urfave/cli/v2" + "golang.org/x/xerrors" + + lcli "github.com/filecoin-project/lotus/cli" + "github.com/filecoin-project/lotus/node/repo" +) + +func carWalkFunc(nd format.Node) (out []*format.Link, err error) { + for _, link := range nd.Links() { + if link.Cid.Prefix().Codec == cid.FilCommitmentSealed || link.Cid.Prefix().Codec == cid.FilCommitmentUnsealed { + continue + } + out = append(out, link) + } + return out, nil +} + +var exportCarCmd = &cli.Command{ + Name: "export-car", + Description: "Export a car from repo (requires node to be offline)", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "repo", + Value: "~/.lotus", + }, + }, + Action: func(cctx *cli.Context) error { + if cctx.Args().Len() != 2 { + return lcli.ShowHelp(cctx, fmt.Errorf("must specify file name and object")) + } + + outfile := cctx.Args().First() + var roots []cid.Cid + for _, arg := range cctx.Args().Tail() { + c, err := cid.Decode(arg) + if err != nil { + return err + } + roots = append(roots, c) + } + + ctx := lcli.ReqContext(cctx) + + r, err := repo.NewFS(cctx.String("repo")) + if err != nil { + return xerrors.Errorf("opening fs repo: %w", err) + } + + exists, err := r.Exists() + if err != nil { + return err + } + if !exists { + return xerrors.Errorf("lotus repo doesn't exist") + } + + lr, err := r.Lock(repo.FullNode) + if err != nil { + return err + } + defer lr.Close() //nolint:errcheck + + fi, err := os.Create(outfile) + if err != nil { + return xerrors.Errorf("opening the output file: %w", err) + } + + defer fi.Close() //nolint:errcheck + + bs, err := lr.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) + } + } + }() + + dag := merkledag.NewDAGService(blockservice.New(bs, offline.Exchange(bs))) + err = car.WriteCarWithWalker(ctx, dag, roots, fi, carWalkFunc) + if err != nil { + return err + } + return nil + }, +} diff --git a/cmd/lotus-shed/main.go b/cmd/lotus-shed/main.go index da896b4cb40..e06b630800c 100644 --- a/cmd/lotus-shed/main.go +++ b/cmd/lotus-shed/main.go @@ -43,6 +43,7 @@ func main() { minerCmd, mpoolStatsCmd, exportChainCmd, + exportCarCmd, consensusCmd, storageStatsCmd, syncCmd, @@ -58,6 +59,7 @@ func main() { signaturesCmd, actorCmd, minerTypesCmd, + minerMultisigsCmd, } app := &cli.App{ diff --git a/cmd/lotus-shed/miner-multisig.go b/cmd/lotus-shed/miner-multisig.go new file mode 100644 index 00000000000..d9f15809021 --- /dev/null +++ b/cmd/lotus-shed/miner-multisig.go @@ -0,0 +1,388 @@ +package main + +import ( + "bytes" + "fmt" + "strconv" + + "github.com/filecoin-project/go-state-types/abi" + miner5 "github.com/filecoin-project/specs-actors/v5/actors/builtin/miner" + + msig5 "github.com/filecoin-project/specs-actors/v5/actors/builtin/multisig" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + "github.com/filecoin-project/lotus/chain/types" + lcli "github.com/filecoin-project/lotus/cli" + "github.com/urfave/cli/v2" + "golang.org/x/xerrors" +) + +var minerMultisigsCmd = &cli.Command{ + Name: "miner-multisig", + Description: "a collection of utilities for using multisigs as owner addresses of miners", + Subcommands: []*cli.Command{ + mmProposeWithdrawBalance, + mmApproveWithdrawBalance, + mmProposeChangeOwner, + mmApproveChangeOwner, + }, + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "from", + Usage: "specify address to send message from", + Required: true, + }, + &cli.StringFlag{ + Name: "multisig", + Usage: "specify multisig that will receive the message", + Required: true, + }, + &cli.StringFlag{ + Name: "miner", + Usage: "specify miner being acted upon", + Required: true, + }, + }, +} + +var mmProposeWithdrawBalance = &cli.Command{ + Name: "propose-withdraw", + Usage: "Propose to withdraw FIL from the miner", + ArgsUsage: "[amount]", + Action: func(cctx *cli.Context) error { + if !cctx.Args().Present() { + return fmt.Errorf("must pass amount to withdraw") + } + + api, closer, err := lcli.GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer closer() + + ctx := lcli.ReqContext(cctx) + + multisigAddr, sender, minerAddr, err := getInputs(cctx) + if err != nil { + return err + } + + val, err := types.ParseFIL(cctx.Args().First()) + if err != nil { + return err + } + + sp, err := actors.SerializeParams(&miner5.WithdrawBalanceParams{ + AmountRequested: abi.TokenAmount(val), + }) + if err != nil { + return err + } + + pcid, err := api.MsigPropose(ctx, multisigAddr, minerAddr, big.Zero(), sender, uint64(miner.Methods.WithdrawBalance), sp) + if err != nil { + return xerrors.Errorf("proposing message: %w", err) + } + + fmt.Fprintln(cctx.App.Writer, "Propose Message CID:", pcid) + + // wait for it to get mined into a block + wait, err := api.StateWaitMsg(ctx, pcid, build.MessageConfidence) + if err != nil { + return err + } + + // check it executed successfully + if wait.Receipt.ExitCode != 0 { + fmt.Fprintln(cctx.App.Writer, "Propose owner change tx failed!") + return err + } + + var retval msig5.ProposeReturn + if err := retval.UnmarshalCBOR(bytes.NewReader(wait.Receipt.Return)); err != nil { + return fmt.Errorf("failed to unmarshal propose return value: %w", err) + } + + fmt.Printf("Transaction ID: %d\n", retval.TxnID) + if retval.Applied { + fmt.Printf("Transaction was executed during propose\n") + fmt.Printf("Exit Code: %d\n", retval.Code) + fmt.Printf("Return Value: %x\n", retval.Ret) + } + + return nil + }, +} + +var mmApproveWithdrawBalance = &cli.Command{ + Name: "approve-withdraw", + Usage: "Approve to withdraw FIL from the miner", + ArgsUsage: "[amount txnId proposer]", + Action: func(cctx *cli.Context) error { + if cctx.NArg() != 3 { + return fmt.Errorf("must pass amount, txn Id, and proposer address") + } + + api, closer, err := lcli.GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer closer() + + ctx := lcli.ReqContext(cctx) + + multisigAddr, sender, minerAddr, err := getInputs(cctx) + if err != nil { + return err + } + + val, err := types.ParseFIL(cctx.Args().First()) + if err != nil { + return err + } + + sp, err := actors.SerializeParams(&miner5.WithdrawBalanceParams{ + AmountRequested: abi.TokenAmount(val), + }) + if err != nil { + return err + } + + txid, err := strconv.ParseUint(cctx.Args().Get(1), 10, 64) + if err != nil { + return err + } + + proposer, err := address.NewFromString(cctx.Args().Get(2)) + if err != nil { + return err + } + + acid, err := api.MsigApproveTxnHash(ctx, multisigAddr, txid, proposer, minerAddr, big.Zero(), sender, uint64(miner.Methods.WithdrawBalance), sp) + if err != nil { + return xerrors.Errorf("approving message: %w", err) + } + + fmt.Fprintln(cctx.App.Writer, "Approve Message CID:", acid) + + // wait for it to get mined into a block + wait, err := api.StateWaitMsg(ctx, acid, build.MessageConfidence) + if err != nil { + return err + } + + // check it executed successfully + if wait.Receipt.ExitCode != 0 { + fmt.Fprintln(cctx.App.Writer, "Approve owner change tx failed!") + return err + } + + var retval msig5.ApproveReturn + if err := retval.UnmarshalCBOR(bytes.NewReader(wait.Receipt.Return)); err != nil { + return fmt.Errorf("failed to unmarshal approve return value: %w", err) + } + + if retval.Applied { + fmt.Printf("Transaction was executed with the approve\n") + fmt.Printf("Exit Code: %d\n", retval.Code) + fmt.Printf("Return Value: %x\n", retval.Ret) + } else { + fmt.Println("Transaction was approved, but not executed") + } + return nil + }, +} + +var mmProposeChangeOwner = &cli.Command{ + Name: "propose-change-owner", + Usage: "Propose an owner address change", + ArgsUsage: "[newOwner]", + Action: func(cctx *cli.Context) error { + if !cctx.Args().Present() { + return fmt.Errorf("must pass new owner address") + } + + api, closer, err := lcli.GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer closer() + + ctx := lcli.ReqContext(cctx) + + multisigAddr, sender, minerAddr, err := getInputs(cctx) + if err != nil { + return err + } + + na, err := address.NewFromString(cctx.Args().First()) + if err != nil { + return err + } + + newAddr, err := api.StateLookupID(ctx, na, types.EmptyTSK) + if err != nil { + return err + } + + mi, err := api.StateMinerInfo(ctx, minerAddr, types.EmptyTSK) + if err != nil { + return err + } + + if mi.Owner == newAddr { + return fmt.Errorf("owner address already set to %s", na) + } + + sp, err := actors.SerializeParams(&newAddr) + if err != nil { + return xerrors.Errorf("serializing params: %w", err) + } + + pcid, err := api.MsigPropose(ctx, multisigAddr, minerAddr, big.Zero(), sender, uint64(miner.Methods.ChangeOwnerAddress), sp) + if err != nil { + return xerrors.Errorf("proposing message: %w", err) + } + + fmt.Fprintln(cctx.App.Writer, "Propose Message CID:", pcid) + + // wait for it to get mined into a block + wait, err := api.StateWaitMsg(ctx, pcid, build.MessageConfidence) + if err != nil { + return err + } + + // check it executed successfully + if wait.Receipt.ExitCode != 0 { + fmt.Fprintln(cctx.App.Writer, "Propose owner change tx failed!") + return err + } + + var retval msig5.ProposeReturn + if err := retval.UnmarshalCBOR(bytes.NewReader(wait.Receipt.Return)); err != nil { + return fmt.Errorf("failed to unmarshal propose return value: %w", err) + } + + fmt.Printf("Transaction ID: %d\n", retval.TxnID) + if retval.Applied { + fmt.Printf("Transaction was executed during propose\n") + fmt.Printf("Exit Code: %d\n", retval.Code) + fmt.Printf("Return Value: %x\n", retval.Ret) + } + return nil + }, +} + +var mmApproveChangeOwner = &cli.Command{ + Name: "approve-change-owner", + Usage: "Approve an owner address change", + ArgsUsage: "[newOwner txnId proposer]", + Action: func(cctx *cli.Context) error { + if cctx.NArg() != 3 { + return fmt.Errorf("must pass new owner address, txn Id, and proposer address") + } + + api, closer, err := lcli.GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer closer() + + ctx := lcli.ReqContext(cctx) + + multisigAddr, sender, minerAddr, err := getInputs(cctx) + if err != nil { + return err + } + + na, err := address.NewFromString(cctx.Args().First()) + if err != nil { + return err + } + + newAddr, err := api.StateLookupID(ctx, na, types.EmptyTSK) + if err != nil { + return err + } + + txid, err := strconv.ParseUint(cctx.Args().Get(1), 10, 64) + if err != nil { + return err + } + + proposer, err := address.NewFromString(cctx.Args().Get(2)) + if err != nil { + return err + } + + mi, err := api.StateMinerInfo(ctx, minerAddr, types.EmptyTSK) + if err != nil { + return err + } + + if mi.Owner == newAddr { + return fmt.Errorf("owner address already set to %s", na) + } + + sp, err := actors.SerializeParams(&newAddr) + if err != nil { + return xerrors.Errorf("serializing params: %w", err) + } + + acid, err := api.MsigApproveTxnHash(ctx, multisigAddr, txid, proposer, minerAddr, big.Zero(), sender, uint64(miner.Methods.ChangeOwnerAddress), sp) + if err != nil { + return xerrors.Errorf("approving message: %w", err) + } + + fmt.Fprintln(cctx.App.Writer, "Approve Message CID:", acid) + + // wait for it to get mined into a block + wait, err := api.StateWaitMsg(ctx, acid, build.MessageConfidence) + if err != nil { + return err + } + + // check it executed successfully + if wait.Receipt.ExitCode != 0 { + fmt.Fprintln(cctx.App.Writer, "Approve owner change tx failed!") + return err + } + + var retval msig5.ApproveReturn + if err := retval.UnmarshalCBOR(bytes.NewReader(wait.Receipt.Return)); err != nil { + return fmt.Errorf("failed to unmarshal approve return value: %w", err) + } + + if retval.Applied { + fmt.Printf("Transaction was executed with the approve\n") + fmt.Printf("Exit Code: %d\n", retval.Code) + fmt.Printf("Return Value: %x\n", retval.Ret) + } else { + fmt.Println("Transaction was approved, but not executed") + } + return nil + }, +} + +func getInputs(cctx *cli.Context) (address.Address, address.Address, address.Address, error) { + multisigAddr, err := address.NewFromString(cctx.String("multisig")) + if err != nil { + return address.Undef, address.Undef, address.Undef, err + } + + sender, err := address.NewFromString(cctx.String("from")) + if err != nil { + return address.Undef, address.Undef, address.Undef, err + } + + minerAddr, err := address.NewFromString(cctx.String("miner")) + if err != nil { + return address.Undef, address.Undef, address.Undef, err + } + + return multisigAddr, sender, minerAddr, nil +} diff --git a/cmd/lotus-shed/sync.go b/cmd/lotus-shed/sync.go index 65d2b6d6f50..cab3bd29ead 100644 --- a/cmd/lotus-shed/sync.go +++ b/cmd/lotus-shed/sync.go @@ -172,12 +172,13 @@ var syncScrapePowerCmd = &cli.Command{ return err } - qpercI := types.BigDiv(types.BigMul(totalWonPower.QualityAdjPower, types.NewInt(1000000)), totalPower.TotalPower.QualityAdjPower) - fmt.Println("Number of winning miners: ", len(miners)) fmt.Println("QAdjPower of winning miners: ", totalWonPower.QualityAdjPower) fmt.Println("QAdjPower of all miners: ", totalPower.TotalPower.QualityAdjPower) - fmt.Println("Percentage of winning QAdjPower: ", float64(qpercI.Int64())/10000) + fmt.Println("Percentage of winning QAdjPower: ", types.BigDivFloat( + types.BigMul(totalWonPower.QualityAdjPower, big.NewInt(100)), + totalPower.TotalPower.QualityAdjPower, + )) return nil }, diff --git a/cmd/lotus-storage-miner/actor_test.go b/cmd/lotus-storage-miner/actor_test.go index 5bc82d842c2..7f36812bc01 100644 --- a/cmd/lotus-storage-miner/actor_test.go +++ b/cmd/lotus-storage-miner/actor_test.go @@ -7,7 +7,6 @@ import ( "fmt" "regexp" "strconv" - "sync/atomic" "testing" "time" @@ -18,13 +17,11 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/api/test" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/lib/lotuslog" + "github.com/filecoin-project/lotus/itests/kit" "github.com/filecoin-project/lotus/node/repo" - builder "github.com/filecoin-project/lotus/node/test" ) func TestWorkerKeyChange(t *testing.T) { @@ -41,20 +38,16 @@ func TestWorkerKeyChange(t *testing.T) { policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1) policy.SetMinVerifiedDealSize(abi.NewStoragePower(256)) - lotuslog.SetupLogLevels() - logging.SetLogLevel("miner", "ERROR") - logging.SetLogLevel("chainstore", "ERROR") - logging.SetLogLevel("chain", "ERROR") - logging.SetLogLevel("pubsub", "ERROR") - logging.SetLogLevel("sub", "ERROR") - logging.SetLogLevel("storageminer", "ERROR") + kit.QuietMiningLogs() blocktime := 1 * time.Millisecond - n, sn := builder.MockSbBuilder(t, []test.FullNodeOpts{test.FullNodeWithLatestActorsAt(-1), test.FullNodeWithLatestActorsAt(-1)}, test.OneMiner) + clients, miners := kit.MockMinerBuilder(t, + []kit.FullNodeOpts{kit.FullNodeWithLatestActorsAt(-1), kit.FullNodeWithLatestActorsAt(-1)}, + kit.OneMiner) - client1 := n[0] - client2 := n[1] + client1 := clients[0] + client2 := clients[1] // Connect the nodes. addrinfo, err := client1.NetAddrsListen(ctx) @@ -67,8 +60,8 @@ func TestWorkerKeyChange(t *testing.T) { app := cli.NewApp() app.Metadata = map[string]interface{}{ "repoType": repo.StorageMiner, - "testnode-full": n[0], - "testnode-storage": sn[0], + "testnode-full": clients[0], + "testnode-storage": miners[0], } app.Writer = output api.RunningNodeType = api.NodeMiner @@ -85,29 +78,14 @@ func TestWorkerKeyChange(t *testing.T) { return cmd.Action(cctx) } - // setup miner - mine := int64(1) - done := make(chan struct{}) - go func() { - defer close(done) - for atomic.LoadInt64(&mine) == 1 { - time.Sleep(blocktime) - if err := sn[0].MineOne(ctx, test.MineNext); err != nil { - t.Error(err) - } - } - }() - defer func() { - atomic.AddInt64(&mine, -1) - fmt.Println("shutting down mining") - <-done - }() + // start mining + kit.ConnectAndStartMining(t, blocktime, miners[0], client1, client2) newKey, err := client1.WalletNew(ctx, types.KTBLS) require.NoError(t, err) // Initialize wallet. - test.SendFunds(ctx, t, client1, newKey, abi.NewTokenAmount(0)) + kit.SendFunds(ctx, t, client1, newKey, abi.NewTokenAmount(0)) require.NoError(t, run(actorProposeChangeWorker, "--really-do-it", newKey.String())) diff --git a/cmd/lotus-storage-miner/allinfo_test.go b/cmd/lotus-storage-miner/allinfo_test.go index 6fa3136d330..9f2dc626ed6 100644 --- a/cmd/lotus-storage-miner/allinfo_test.go +++ b/cmd/lotus-storage-miner/allinfo_test.go @@ -1,10 +1,13 @@ package main import ( + "context" "flag" "testing" "time" + "github.com/filecoin-project/lotus/itests/kit" + "github.com/filecoin-project/lotus/node/impl" logging "github.com/ipfs/go-log/v2" "github.com/stretchr/testify/require" "github.com/urfave/cli/v2" @@ -12,11 +15,8 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/api/test" "github.com/filecoin-project/lotus/chain/actors/policy" - "github.com/filecoin-project/lotus/lib/lotuslog" "github.com/filecoin-project/lotus/node/repo" - builder "github.com/filecoin-project/lotus/node/test" ) func TestMinerAllInfo(t *testing.T) { @@ -32,12 +32,7 @@ func TestMinerAllInfo(t *testing.T) { _test = true - lotuslog.SetupLogLevels() - logging.SetLogLevel("miner", "ERROR") - logging.SetLogLevel("chainstore", "ERROR") - logging.SetLogLevel("chain", "ERROR") - logging.SetLogLevel("sub", "ERROR") - logging.SetLogLevel("storageminer", "ERROR") + kit.QuietMiningLogs() oldDelay := policy.GetPreCommitChallengeDelay() policy.SetPreCommitChallengeDelay(5) @@ -45,8 +40,9 @@ func TestMinerAllInfo(t *testing.T) { policy.SetPreCommitChallengeDelay(oldDelay) }) - var n []test.TestNode - var sn []test.TestStorageNode + n, sn := kit.Builder(t, kit.OneFull, kit.OneMiner) + client, miner := n[0].FullNode, sn[0] + kit.ConnectAndStartMining(t, time.Second, miner, client.(*impl.FullNodeAPI)) run := func(t *testing.T) { app := cli.NewApp() @@ -62,15 +58,17 @@ func TestMinerAllInfo(t *testing.T) { require.NoError(t, infoAllCmd.Action(cctx)) } - bp := func(t *testing.T, fullOpts []test.FullNodeOpts, storage []test.StorageMiner) ([]test.TestNode, []test.TestStorageNode) { - n, sn = builder.Builder(t, fullOpts, storage) + t.Run("pre-info-all", run) - t.Run("pre-info-all", run) - - return n, sn - } - - test.TestDealFlow(t, bp, time.Second, false, false, 0) + dh := kit.NewDealHarness(t, client, miner) + _, _, _ = dh.MakeFullDeal(kit.MakeFullDealParams{ + Ctx: context.Background(), + Rseed: 6, + CarExport: false, + FastRet: false, + StartEpoch: 0, + DoRetrieval: true, + }) t.Run("post-info-all", run) } diff --git a/cmd/lotus-storage-miner/info.go b/cmd/lotus-storage-miner/info.go index 0fe14f1ff28..0d8cdf07bc6 100644 --- a/cmd/lotus-storage-miner/info.go +++ b/cmd/lotus-storage-miner/info.go @@ -3,6 +3,8 @@ package main import ( "context" "fmt" + "math" + corebig "math/big" "sort" "time" @@ -21,6 +23,7 @@ import ( "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" @@ -120,19 +123,23 @@ func infoCmdAct(cctx *cli.Context) error { return err } - rpercI := types.BigDiv(types.BigMul(pow.MinerPower.RawBytePower, types.NewInt(1000000)), pow.TotalPower.RawBytePower) - qpercI := types.BigDiv(types.BigMul(pow.MinerPower.QualityAdjPower, types.NewInt(1000000)), pow.TotalPower.QualityAdjPower) - fmt.Printf("Power: %s / %s (%0.4f%%)\n", color.GreenString(types.DeciStr(pow.MinerPower.QualityAdjPower)), types.DeciStr(pow.TotalPower.QualityAdjPower), - float64(qpercI.Int64())/10000) + types.BigDivFloat( + types.BigMul(pow.MinerPower.QualityAdjPower, big.NewInt(100)), + pow.TotalPower.QualityAdjPower, + ), + ) fmt.Printf("\tRaw: %s / %s (%0.4f%%)\n", color.BlueString(types.SizeStr(pow.MinerPower.RawBytePower)), types.SizeStr(pow.TotalPower.RawBytePower), - float64(rpercI.Int64())/10000) - + types.BigDivFloat( + types.BigMul(pow.MinerPower.RawBytePower, big.NewInt(100)), + pow.TotalPower.RawBytePower, + ), + ) secCounts, err := api.StateMinerSectorCount(ctx, maddr, types.EmptyTSK) if err != nil { return err @@ -146,7 +153,7 @@ func infoCmdAct(cctx *cli.Context) error { } else { var faultyPercentage float64 if secCounts.Live != 0 { - faultyPercentage = float64(10000*nfaults/secCounts.Live) / 100. + faultyPercentage = float64(100*nfaults) / float64(secCounts.Live) } fmt.Printf("\tProving: %s (%s Faulty, %.2f%%)\n", types.SizeStr(types.BigMul(types.NewInt(proving), types.NewInt(uint64(mi.SectorSize)))), @@ -157,16 +164,54 @@ func infoCmdAct(cctx *cli.Context) error { if !pow.HasMinPower { fmt.Print("Below minimum power threshold, no blocks will be won") } else { - expWinChance := float64(types.BigMul(qpercI, types.NewInt(build.BlocksPerEpoch)).Int64()) / 1000000 - if expWinChance > 0 { - if expWinChance > 1 { - expWinChance = 1 + + winRatio := new(corebig.Rat).SetFrac( + types.BigMul(pow.MinerPower.QualityAdjPower, types.NewInt(build.BlocksPerEpoch)).Int, + pow.TotalPower.QualityAdjPower.Int, + ) + + if winRatioFloat, _ := winRatio.Float64(); winRatioFloat > 0 { + + // if the corresponding poisson distribution isn't infinitely small then + // throw it into the mix as well, accounting for multi-wins + winRationWithPoissonFloat := -math.Expm1(-winRatioFloat) + winRationWithPoisson := new(corebig.Rat).SetFloat64(winRationWithPoissonFloat) + if winRationWithPoisson != nil { + winRatio = winRationWithPoisson + winRatioFloat = winRationWithPoissonFloat } - winRate := time.Duration(float64(time.Second*time.Duration(build.BlockDelaySecs)) / expWinChance) - winPerDay := float64(time.Hour*24) / float64(winRate) - fmt.Print("Expected block win rate: ") - color.Blue("%.4f/day (every %s)", winPerDay, winRate.Truncate(time.Second)) + weekly, _ := new(corebig.Rat).Mul( + winRatio, + new(corebig.Rat).SetInt64(7*builtin.EpochsInDay), + ).Float64() + + avgDuration, _ := new(corebig.Rat).Mul( + new(corebig.Rat).SetInt64(builtin.EpochDurationSeconds), + new(corebig.Rat).Inv(winRatio), + ).Float64() + + fmt.Print("Projected average block win rate: ") + color.Blue( + "%.02f/week (every %s)", + weekly, + (time.Second * time.Duration(avgDuration)).Truncate(time.Second).String(), + ) + + // Geometric distribution of P(Y < k) calculated as described in https://en.wikipedia.org/wiki/Geometric_distribution#Probability_Outcomes_Examples + // https://www.wolframalpha.com/input/?i=t+%3E+0%3B+p+%3E+0%3B+p+%3C+1%3B+c+%3E+0%3B+c+%3C1%3B+1-%281-p%29%5E%28t%29%3Dc%3B+solve+t + // t == how many dice-rolls (epochs) before win + // p == winRate == ( minerPower / netPower ) + // c == target probability of win ( 99.9% in this case ) + fmt.Print("Projected block win with ") + color.Green( + "99.9%% probability every %s", + (time.Second * time.Duration( + builtin.EpochDurationSeconds*math.Log(1-0.999)/ + math.Log(1-winRatioFloat), + )).Truncate(time.Second).String(), + ) + fmt.Println("(projections DO NOT account for future network and miner growth)") } } @@ -295,6 +340,7 @@ var stateList = []stateMeta{ {col: color.FgYellow, state: sealing.PreCommitBatchWait}, {col: color.FgYellow, state: sealing.WaitSeed}, {col: color.FgYellow, state: sealing.Committing}, + {col: color.FgYellow, state: sealing.CommitFinalize}, {col: color.FgYellow, state: sealing.SubmitCommit}, {col: color.FgYellow, state: sealing.CommitWait}, {col: color.FgYellow, state: sealing.SubmitCommitAggregate}, @@ -315,6 +361,7 @@ var stateList = []stateMeta{ {col: color.FgRed, state: sealing.PreCommitFailed}, {col: color.FgRed, state: sealing.ComputeProofFailed}, {col: color.FgRed, state: sealing.CommitFailed}, + {col: color.FgRed, state: sealing.CommitFinalizeFailed}, {col: color.FgRed, state: sealing.PackingFailed}, {col: color.FgRed, state: sealing.FinalizeFailed}, {col: color.FgRed, state: sealing.Faulty}, diff --git a/cmd/lotus-storage-miner/init.go b/cmd/lotus-storage-miner/init.go index 76451f418b8..249f0ee03c9 100644 --- a/cmd/lotus-storage-miner/init.go +++ b/cmd/lotus-storage-miner/init.go @@ -8,6 +8,7 @@ import ( "encoding/json" "fmt" "io/ioutil" + "net/http" "os" "path/filepath" "strconv" @@ -453,14 +454,23 @@ func storageMinerInit(ctx context.Context, cctx *cli.Context, api v1api.FullNode wsts := statestore.New(namespace.Wrap(mds, modules.WorkerCallsPrefix)) smsts := statestore.New(namespace.Wrap(mds, modules.ManagerWorkPrefix)) - smgr, err := sectorstorage.New(ctx, lr, stores.NewIndex(), sectorstorage.SealerConfig{ + si := stores.NewIndex() + + lstor, err := stores.NewLocal(ctx, lr, si, nil) + if err != nil { + return err + } + stor := stores.NewRemote(lstor, si, http.Header(sa), 10, &stores.DefaultPartialFileHandler{}) + + smgr, err := sectorstorage.New(ctx, lstor, stor, lr, si, sectorstorage.SealerConfig{ ParallelFetchLimit: 10, AllowAddPiece: true, AllowPreCommit1: true, AllowPreCommit2: true, AllowCommit: true, AllowUnseal: true, - }, nil, sa, wsts, smsts) + }, wsts, smsts) + if err != nil { return err } diff --git a/cmd/lotus-storage-miner/proving.go b/cmd/lotus-storage-miner/proving.go index 66007b63dc1..0e36c6508d5 100644 --- a/cmd/lotus-storage-miner/proving.go +++ b/cmd/lotus-storage-miner/proving.go @@ -171,7 +171,7 @@ var provingInfoCmd = &cli.Command{ var faultPerc float64 if proving > 0 { - faultPerc = float64(faults*10000/proving) / 100 + faultPerc = float64(faults * 100 / proving) } fmt.Printf("Current Epoch: %d\n", cd.CurrentEpoch) diff --git a/cmd/lotus-storage-miner/retrieval-deals.go b/cmd/lotus-storage-miner/retrieval-deals.go index 03d397852d8..0411f7f130a 100644 --- a/cmd/lotus-storage-miner/retrieval-deals.go +++ b/cmd/lotus-storage-miner/retrieval-deals.go @@ -235,7 +235,7 @@ var retrievalSetAskCmd = &cli.Command{ var retrievalGetAskCmd = &cli.Command{ Name: "get-ask", - Usage: "Get the provider's current retrieval ask", + Usage: "Get the provider's current retrieval ask configured by the provider in the ask-store using the set-ask CLI command", Flags: []cli.Flag{}, Action: func(cctx *cli.Context) error { ctx := lcli.DaemonContext(cctx) diff --git a/cmd/lotus-storage-miner/run.go b/cmd/lotus-storage-miner/run.go index 5d67cf33dfd..3daf9a91142 100644 --- a/cmd/lotus-storage-miner/run.go +++ b/cmd/lotus-storage-miner/run.go @@ -1,37 +1,27 @@ package main import ( - "context" - "net" - "net/http" + "fmt" _ "net/http/pprof" "os" - "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" "github.com/urfave/cli/v2" "go.opencensus.io/stats" "go.opencensus.io/stats/view" "go.opencensus.io/tag" "golang.org/x/xerrors" - "github.com/filecoin-project/go-jsonrpc" - "github.com/filecoin-project/go-jsonrpc/auth" - "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" lcli "github.com/filecoin-project/lotus/cli" "github.com/filecoin-project/lotus/lib/ulimit" "github.com/filecoin-project/lotus/metrics" "github.com/filecoin-project/lotus/node" - "github.com/filecoin-project/lotus/node/impl" "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/node/repo" ) @@ -164,54 +154,25 @@ var runCmd = &cli.Command{ log.Infof("Remote version %s", v) - lst, err := manet.Listen(endpoint) + // Instantiate the miner node handler. + handler, err := node.MinerHandler(minerapi, true) if err != nil { - return xerrors.Errorf("could not listen: %w", err) - } - - mux := mux.NewRouter() - - rpcServer := jsonrpc.NewServer() - rpcServer.Register("Filecoin", api.PermissionedStorMinerAPI(metrics.MetricedStorMinerAPI(minerapi))) - - mux.Handle("/rpc/v0", rpcServer) - mux.PathPrefix("/remote").HandlerFunc(minerapi.(*impl.StorageMinerAPI).ServeRemote) - mux.Handle("/debug/metrics", metrics.Exporter()) - mux.PathPrefix("/").Handler(http.DefaultServeMux) // pprof - - ah := &auth.Handler{ - Verify: minerapi.AuthVerify, - Next: mux.ServeHTTP, + return xerrors.Errorf("failed to instantiate rpc handler: %w", err) } - srv := &http.Server{ - Handler: ah, - BaseContext: func(listener net.Listener) context.Context { - ctx, _ := tag.New(context.Background(), tag.Upsert(metrics.APIInterface, "lotus-miner")) - return ctx - }, + // Serve the RPC. + rpcStopper, err := node.ServeRPC(handler, "lotus-miner", endpoint) + if err != nil { + return fmt.Errorf("failed to start json-rpc endpoint: %s", err) } - sigChan := make(chan os.Signal, 2) - go func() { - select { - case sig := <-sigChan: - log.Warnw("received shutdown", "signal", sig) - case <-shutdownChan: - log.Warn("received shutdown") - } - - log.Warn("Shutting down...") - if err := stop(context.TODO()); err != nil { - log.Errorf("graceful shutting down failed: %s", err) - } - if err := srv.Shutdown(context.TODO()); err != nil { - log.Errorf("shutting down RPC server failed: %s", err) - } - log.Warn("Graceful shutdown successful") - }() - signal.Notify(sigChan, syscall.SIGTERM, syscall.SIGINT) + // Monitor for shutdown. + finishCh := node.MonitorShutdown(shutdownChan, + node.ShutdownHandler{Component: "rpc server", StopFunc: rpcStopper}, + node.ShutdownHandler{Component: "miner", StopFunc: stop}, + ) - return srv.Serve(manet.NetListener(lst)) + <-finishCh + return nil }, } diff --git a/cmd/lotus/daemon.go b/cmd/lotus/daemon.go index 644892ee24f..0504c341863 100644 --- a/cmd/lotus/daemon.go +++ b/cmd/lotus/daemon.go @@ -15,6 +15,7 @@ import ( "runtime/pprof" "strings" + "github.com/filecoin-project/go-jsonrpc" paramfetch "github.com/filecoin-project/go-paramfetch" metricsprom "github.com/ipfs/go-metrics-prometheus" "github.com/mitchellh/go-homedir" @@ -351,8 +352,37 @@ var DaemonCmd = &cli.Command{ return xerrors.Errorf("getting api endpoint: %w", err) } + // + // Instantiate JSON-RPC endpoint. + // ---- + + // Populate JSON-RPC options. + serverOptions := make([]jsonrpc.ServerOption, 0) + if maxRequestSize := cctx.Int("api-max-req-size"); maxRequestSize != 0 { + serverOptions = append(serverOptions, jsonrpc.WithMaxRequestSize(int64(maxRequestSize))) + } + + // Instantiate the full node handler. + h, err := node.FullNodeHandler(api, true, serverOptions...) + if err != nil { + return fmt.Errorf("failed to instantiate rpc handler: %s", err) + } + + // Serve the RPC. + rpcStopper, err := node.ServeRPC(h, "lotus-daemon", endpoint) + if err != nil { + return fmt.Errorf("failed to start json-rpc endpoint: %s", err) + } + + // Monitor for shutdown. + finishCh := node.MonitorShutdown(shutdownChan, + node.ShutdownHandler{Component: "rpc server", StopFunc: rpcStopper}, + node.ShutdownHandler{Component: "node", StopFunc: stop}, + ) + <-finishCh // fires when shutdown is complete. + // TODO: properly parse api endpoint (or make it a URL) - return serveRPC(api, stop, endpoint, shutdownChan, int64(cctx.Int("api-max-req-size"))) + return nil }, Subcommands: []*cli.Command{ daemonStopCmd, diff --git a/cmd/lotus/main.go b/cmd/lotus/main.go index c1dab8e940e..63d01f89162 100644 --- a/cmd/lotus/main.go +++ b/cmd/lotus/main.go @@ -4,6 +4,7 @@ import ( "context" "os" + logging "github.com/ipfs/go-log/v2" "github.com/mattn/go-isatty" "github.com/urfave/cli/v2" "go.opencensus.io/trace" @@ -16,6 +17,8 @@ import ( "github.com/filecoin-project/lotus/node/repo" ) +var log = logging.Logger("main") + var AdvanceBlockCmd *cli.Command func main() { diff --git a/cmd/lotus/pprof.go b/cmd/lotus/pprof.go deleted file mode 100644 index ea6823e48e4..00000000000 --- a/cmd/lotus/pprof.go +++ /dev/null @@ -1,33 +0,0 @@ -package main - -import ( - "net/http" - "strconv" -) - -func handleFractionOpt(name string, setter func(int)) http.HandlerFunc { - return func(rw http.ResponseWriter, r *http.Request) { - if r.Method != http.MethodPost { - http.Error(rw, "only POST allowed", http.StatusMethodNotAllowed) - return - } - if err := r.ParseForm(); err != nil { - http.Error(rw, err.Error(), http.StatusBadRequest) - return - } - - asfr := r.Form.Get("x") - if len(asfr) == 0 { - http.Error(rw, "parameter 'x' must be set", http.StatusBadRequest) - return - } - - fr, err := strconv.Atoi(asfr) - if err != nil { - http.Error(rw, err.Error(), http.StatusBadRequest) - return - } - log.Infof("setting %s to %d", name, fr) - setter(fr) - } -} diff --git a/cmd/lotus/rpc.go b/cmd/lotus/rpc.go deleted file mode 100644 index 95050d63936..00000000000 --- a/cmd/lotus/rpc.go +++ /dev/null @@ -1,138 +0,0 @@ -package main - -import ( - "context" - "encoding/json" - "net" - "net/http" - _ "net/http/pprof" - "os" - "os/signal" - "runtime" - "syscall" - - "github.com/ipfs/go-cid" - logging "github.com/ipfs/go-log/v2" - "github.com/multiformats/go-multiaddr" - manet "github.com/multiformats/go-multiaddr/net" - "go.opencensus.io/tag" - "golang.org/x/xerrors" - - "github.com/filecoin-project/go-jsonrpc" - "github.com/filecoin-project/go-jsonrpc/auth" - - "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/metrics" - "github.com/filecoin-project/lotus/node" - "github.com/filecoin-project/lotus/node/impl" -) - -var log = logging.Logger("main") - -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)) - } - serveRpc := func(path string, hnd interface{}) { - rpcServer := jsonrpc.NewServer(serverOptions...) - rpcServer.Register("Filecoin", hnd) - - ah := &auth.Handler{ - Verify: a.AuthVerify, - Next: rpcServer.ServeHTTP, - } - - http.Handle(path, ah) - } - - pma := api.PermissionedFullAPI(metrics.MetricedFullAPI(a)) - - serveRpc("/rpc/v1", pma) - serveRpc("/rpc/v0", &v0api.WrapperV1Full{FullNode: pma}) - - importAH := &auth.Handler{ - Verify: a.AuthVerify, - Next: handleImport(a.(*impl.FullNodeAPI)), - } - - http.Handle("/rest/v0/import", importAH) - - http.Handle("/debug/metrics", metrics.Exporter()) - http.Handle("/debug/pprof-set/block", handleFractionOpt("BlockProfileRate", runtime.SetBlockProfileRate)) - http.Handle("/debug/pprof-set/mutex", handleFractionOpt("MutexProfileFraction", - func(x int) { runtime.SetMutexProfileFraction(x) }, - )) - - lst, err := manet.Listen(addr) - if err != nil { - return xerrors.Errorf("could not listen: %w", err) - } - - srv := &http.Server{ - Handler: http.DefaultServeMux, - BaseContext: func(listener net.Listener) context.Context { - ctx, _ := tag.New(context.Background(), tag.Upsert(metrics.APIInterface, "lotus-daemon")) - return ctx - }, - } - - sigCh := make(chan os.Signal, 2) - shutdownDone := make(chan struct{}) - go func() { - select { - case sig := <-sigCh: - log.Warnw("received shutdown", "signal", sig) - case <-shutdownCh: - log.Warn("received shutdown") - } - - log.Warn("Shutting down...") - if err := srv.Shutdown(context.TODO()); err != nil { - log.Errorf("shutting down RPC server failed: %s", err) - } - if err := stop(context.TODO()); err != nil { - log.Errorf("graceful shutting down failed: %s", err) - } - log.Warn("Graceful shutdown successful") - _ = log.Sync() //nolint:errcheck - close(shutdownDone) - }() - signal.Notify(sigCh, syscall.SIGTERM, syscall.SIGINT) - - err = srv.Serve(manet.NetListener(lst)) - if err == http.ErrServerClosed { - <-shutdownDone - return nil - } - return err -} - -func handleImport(a *impl.FullNodeAPI) func(w http.ResponseWriter, r *http.Request) { - return func(w http.ResponseWriter, r *http.Request) { - if r.Method != "PUT" { - w.WriteHeader(404) - return - } - if !auth.HasPerm(r.Context(), nil, api.PermWrite) { - w.WriteHeader(401) - _ = json.NewEncoder(w).Encode(struct{ Error string }{"unauthorized: missing write permission"}) - return - } - - c, err := a.ClientImportLocal(r.Context(), r.Body) - if err != nil { - w.WriteHeader(500) - _ = json.NewEncoder(w).Encode(struct{ Error string }{err.Error()}) - return - } - w.WriteHeader(200) - err = json.NewEncoder(w).Encode(struct{ Cid cid.Cid }{c}) - if err != nil { - log.Errorf("/rest/v0/import: Writing response failed: %+v", err) - return - } - } -} diff --git a/conformance/driver.go b/conformance/driver.go index 70100700e83..c7fc0d6c43a 100644 --- a/conformance/driver.go +++ b/conformance/driver.go @@ -141,16 +141,11 @@ func (d *Driver) ExecuteTipset(bs blockstore.Blockstore, ds ds.Batching, params blocks = append(blocks, sb) } - var ( - messages []*types.Message - results []*vm.ApplyRet - ) - - recordOutputs := func(_ cid.Cid, msg *types.Message, ret *vm.ApplyRet) error { - messages = append(messages, msg) - results = append(results, ret) - return nil + recordOutputs := &outputRecorder{ + messages: []*types.Message{}, + results: []*vm.ApplyRet{}, } + postcid, receiptsroot, err := sm.ApplyBlocks(context.Background(), params.ParentEpoch, params.Preroot, @@ -169,8 +164,8 @@ func (d *Driver) ExecuteTipset(bs blockstore.Blockstore, ds ds.Batching, params ret := &ExecuteTipsetResult{ ReceiptsRoot: receiptsroot, PostStateRoot: postcid, - AppliedMessages: messages, - AppliedResults: results, + AppliedMessages: recordOutputs.messages, + AppliedResults: recordOutputs.results, } return ret, nil } @@ -284,3 +279,14 @@ func CircSupplyOrDefault(circSupply *gobig.Int) abi.TokenAmount { } return big.NewFromGo(circSupply) } + +type outputRecorder struct { + messages []*types.Message + results []*vm.ApplyRet +} + +func (o *outputRecorder) MessageApplied(ctx context.Context, ts *types.TipSet, mcid cid.Cid, msg *types.Message, ret *vm.ApplyRet, implicit bool) error { + o.messages = append(o.messages, msg) + o.results = append(o.results, ret) + return nil +} diff --git a/documentation/en/api-v0-methods-miner.md b/documentation/en/api-v0-methods-miner.md index 388213666fd..496f63a0851 100644 --- a/documentation/en/api-v0-methods-miner.md +++ b/documentation/en/api-v0-methods-miner.md @@ -2205,6 +2205,7 @@ Response: "ef8d99a2-6865-4189-8ffa-9fef0f806eee": { "Info": { "Hostname": "host", + "IgnoreResources": false, "Resources": { "MemPhysical": 274877906944, "MemSwap": 128849018880, diff --git a/documentation/en/api-v0-methods-worker.md b/documentation/en/api-v0-methods-worker.md index b0130a2a06e..c620113f489 100644 --- a/documentation/en/api-v0-methods-worker.md +++ b/documentation/en/api-v0-methods-worker.md @@ -15,8 +15,6 @@ * [MoveStorage](#MoveStorage) * [Process](#Process) * [ProcessSession](#ProcessSession) -* [Read](#Read) - * [ReadPiece](#ReadPiece) * [Release](#Release) * [ReleaseUnsealed](#ReleaseUnsealed) * [Seal](#Seal) @@ -91,6 +89,7 @@ Response: ```json { "Hostname": "string value", + "IgnoreResources": true, "Resources": { "MemPhysical": 42, "MemSwap": 42, @@ -263,41 +262,6 @@ Inputs: `null` Response: `"07070707-0707-0707-0707-070707070707"` -## Read - - -### ReadPiece - - -Perms: admin - -Inputs: -```json -[ - {}, - { - "ID": { - "Miner": 1000, - "Number": 9 - }, - "ProofType": 8 - }, - 1040384, - 1024 -] -``` - -Response: -```json -{ - "Sector": { - "Miner": 1000, - "Number": 9 - }, - "ID": "07070707-0707-0707-0707-070707070707" -} -``` - ## Release diff --git a/documentation/en/api-v0-methods.md b/documentation/en/api-v0-methods.md index b4a19a59e71..ac7c233119f 100644 --- a/documentation/en/api-v0-methods.md +++ b/documentation/en/api-v0-methods.md @@ -44,11 +44,13 @@ * [ClientGetDealInfo](#ClientGetDealInfo) * [ClientGetDealStatus](#ClientGetDealStatus) * [ClientGetDealUpdates](#ClientGetDealUpdates) + * [ClientGetRetrievalUpdates](#ClientGetRetrievalUpdates) * [ClientHasLocal](#ClientHasLocal) * [ClientImport](#ClientImport) * [ClientListDataTransfers](#ClientListDataTransfers) * [ClientListDeals](#ClientListDeals) * [ClientListImports](#ClientListImports) + * [ClientListRetrievals](#ClientListRetrievals) * [ClientMinerQueryOffer](#ClientMinerQueryOffer) * [ClientQueryAsk](#ClientQueryAsk) * [ClientRemoveImport](#ClientRemoveImport) @@ -1197,6 +1199,54 @@ Response: } ``` +### ClientGetRetrievalUpdates +ClientGetRetrievalUpdates returns status of updated retrieval deals + + +Perms: write + +Inputs: `null` + +Response: +```json +{ + "PayloadCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "ID": 5, + "PieceCID": null, + "PricePerByte": "0", + "UnsealPrice": "0", + "Status": 0, + "Message": "string value", + "Provider": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "BytesReceived": 42, + "BytesPaidFor": 42, + "TotalPaid": "0", + "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. @@ -1264,6 +1314,17 @@ Response: `null` ClientListImports lists imported files and their root CIDs +Perms: write + +Inputs: `null` + +Response: `null` + +### ClientListRetrievals +ClientQueryAsk returns a signed StorageAsk from the specified miner. +ClientListRetrievals returns information about retrievals made by the local client + + Perms: write Inputs: `null` @@ -1310,7 +1371,6 @@ Response: ``` ### ClientQueryAsk -ClientQueryAsk returns a signed StorageAsk from the specified miner. Perms: read @@ -2447,7 +2507,7 @@ 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 diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index 7a77fe1e41b..549184e61f6 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -44,11 +44,13 @@ * [ClientGetDealInfo](#ClientGetDealInfo) * [ClientGetDealStatus](#ClientGetDealStatus) * [ClientGetDealUpdates](#ClientGetDealUpdates) + * [ClientGetRetrievalUpdates](#ClientGetRetrievalUpdates) * [ClientHasLocal](#ClientHasLocal) * [ClientImport](#ClientImport) * [ClientListDataTransfers](#ClientListDataTransfers) * [ClientListDeals](#ClientListDeals) * [ClientListImports](#ClientListImports) + * [ClientListRetrievals](#ClientListRetrievals) * [ClientMinerQueryOffer](#ClientMinerQueryOffer) * [ClientQueryAsk](#ClientQueryAsk) * [ClientRemoveImport](#ClientRemoveImport) @@ -1199,6 +1201,54 @@ Response: } ``` +### ClientGetRetrievalUpdates +ClientGetRetrievalUpdates returns status of updated retrieval deals + + +Perms: write + +Inputs: `null` + +Response: +```json +{ + "PayloadCID": { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + "ID": 5, + "PieceCID": null, + "PricePerByte": "0", + "UnsealPrice": "0", + "Status": 0, + "Message": "string value", + "Provider": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", + "BytesReceived": 42, + "BytesPaidFor": 42, + "TotalPaid": "0", + "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. @@ -1266,6 +1316,16 @@ Response: `null` ClientListImports lists imported files and their root CIDs +Perms: write + +Inputs: `null` + +Response: `null` + +### ClientListRetrievals +ClientListRetrievals returns information about retrievals made by the local client + + Perms: write Inputs: `null` diff --git a/documentation/en/cli-lotus-miner.md b/documentation/en/cli-lotus-miner.md index b4b2455147c..c8abb574bab 100644 --- a/documentation/en/cli-lotus-miner.md +++ b/documentation/en/cli-lotus-miner.md @@ -745,7 +745,7 @@ 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 + get-ask Get the provider's current retrieval ask configured by the provider in the ask-store using the set-ask CLI command help, h Shows a list of commands or help for one command OPTIONS: @@ -848,7 +848,7 @@ OPTIONS: ### lotus-miner retrieval-deals get-ask ``` NAME: - lotus-miner retrieval-deals get-ask - Get the provider's current retrieval ask + lotus-miner retrieval-deals get-ask - Get the provider's current retrieval ask configured by the provider in the ask-store using the set-ask CLI command USAGE: lotus-miner retrieval-deals get-ask [command options] [arguments...] diff --git a/documentation/en/cli-lotus.md b/documentation/en/cli-lotus.md index ec118eb7266..b4c4cf9358e 100644 --- a/documentation/en/cli-lotus.md +++ b/documentation/en/cli-lotus.md @@ -377,6 +377,7 @@ COMMANDS: 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 + list-retrievals List retrieval market deals STORAGE: deal Initialize storage deal with a miner query-ask Find a miners ask @@ -522,6 +523,27 @@ OPTIONS: ``` +### lotus client list-retrievals +``` +NAME: + lotus client list-retrievals - List retrieval market deals + +USAGE: + lotus client list-retrievals [command options] [arguments...] + +CATEGORY: + RETRIEVAL + +OPTIONS: + --verbose, -v print verbose deal details (default: false) + --color use color in display output (default: true) + --show-failed show failed/failing deals (default: true) + --completed show completed retrievals (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 deal ``` NAME: @@ -537,8 +559,8 @@ 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 +price is measured in FIL/Epoch. Miners usually don't accept a bid +lower than their advertised ask (which is in FIL/GiB/Epoch). 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). diff --git a/documentation/misc/RELEASE_ISSUE_TEMPLATE.md b/documentation/misc/RELEASE_ISSUE_TEMPLATE.md index 4731c4edb27..0912a8681a6 100644 --- a/documentation/misc/RELEASE_ISSUE_TEMPLATE.md +++ b/documentation/misc/RELEASE_ISSUE_TEMPLATE.md @@ -25,7 +25,6 @@ We're happy to announce Lotus X.Y.Z... 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: @@ -93,7 +92,7 @@ Testing an RC: - [ ] 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 + - [ ] Prep the changelog using `scripts/mkreleaselog`, and add it to `CHANGELOG.md` - [ ] 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). diff --git a/documentation/misc/gas_balancing.md b/documentation/misc/gas_balancing.md new file mode 100644 index 00000000000..64d9fcf0e4b --- /dev/null +++ b/documentation/misc/gas_balancing.md @@ -0,0 +1,54 @@ +## Gas Balancing + +The gas balancing process targets to set gas costs of syscalls to be in line with +10 gas per nanosecond on reference hardware. +The process can be either performed for all syscalls based on existing messages and chain or targeted +at single syscall. + +#### Reference hardware + +The reference hardware is TR3970x with 128GB of RAM. This is what was available at the time and +may be subject to change. + +### Complete gas balancing + +Complete gas balancing is performed using `lotus-bench` the process is based on importing a chain export +and collecting gas traces which are later aggregated. + +Before building `lotus-bench` make sure `EnableGasTracing` in `chain/vm/runtime.go` is set to `true`. + +The process can be started using `./lotus-bench import` with `--car` flag set to the location of +CAR chain export. `--start-epoch` and `--end-epoch` can be used to to limit the range of epochs to run +the benchmark. Note that state tree of `start-epoch` needs to be in the CAR file or has to be previously computed +to work. + +The output will be a `bench.json` file containing information about every syscall invoked +and the time taken by these invocations. This file can grow to be quite big in size so make sure you have +spare space. + +After the bench run is complete the `bench.json` file can be analyzed with `./lotus-bench import analyze bench.json`. + +It will compute means, standard deviations and co-variances (when applicable) of syscall runtimes. +The output is in nanoseconds, so the gas values for syscalls should be 10x that. In cases where co-variance of +execution time to some parameter is evaluated, the strength of the correlation should be taken into account. + +#### Special cases + +OnImplPut compute gas is based on the flush time to disk of objects created, +during block execution (when gas traces are formed) objects are only written to memory. Use `vm/flush_copy_ms` and `vm/flush_copy_count` to estimate OnIpldPut compute cost. + + +### Targeted gas balancing + +In some cases complete gas balancing is infeasible, either new syscall gets introduced or +complete balancing is too time consuming. + +In these cases the recommended way to estimate gas for given syscall is to perform an `in-vivo` benchmark. +In the past `in-vitro` as in standalone benchmarks were found to be highly inaccurate when compared to results +of real execution. + +A in-vivo benchmark can be performed by running an example of such syscall during block execution. +The best place to hook-in such benchmark is message execution loop in +`chain/stmgr/stmgr.go` in `ApplyBlocks()`. Depending of time required to complete the syscall it might be +advisable to run the execution only once every few messages. + diff --git a/extern/filecoin-ffi b/extern/filecoin-ffi index 8b97bd8230b..d60fc680aa8 160000 --- a/extern/filecoin-ffi +++ b/extern/filecoin-ffi @@ -1 +1 @@ -Subproject commit 8b97bd8230b77bd32f4f27e4766a6d8a03b4e801 +Subproject commit d60fc680aa8abeafba698f738fed5b94c9bda33d diff --git a/extern/sector-storage/ffiwrapper/sealer_cgo.go b/extern/sector-storage/ffiwrapper/sealer_cgo.go index 36fbacb3055..10fcad6fd3d 100644 --- a/extern/sector-storage/ffiwrapper/sealer_cgo.go +++ b/extern/sector-storage/ffiwrapper/sealer_cgo.go @@ -11,6 +11,7 @@ import ( "os" "runtime" + "github.com/filecoin-project/lotus/extern/sector-storage/partialfile" "github.com/ipfs/go-cid" "golang.org/x/xerrors" @@ -66,7 +67,7 @@ func (sb *Sealer) AddPiece(ctx context.Context, sector storage.SectorRef, existi } var done func() - var stagedFile *partialFile + var stagedFile *partialfile.PartialFile defer func() { if done != nil { @@ -87,7 +88,7 @@ func (sb *Sealer) AddPiece(ctx context.Context, sector storage.SectorRef, existi return abi.PieceInfo{}, xerrors.Errorf("acquire unsealed sector: %w", err) } - stagedFile, err = createPartialFile(maxPieceSize, stagedPath.Unsealed) + stagedFile, err = partialfile.CreatePartialFile(maxPieceSize, stagedPath.Unsealed) if err != nil { return abi.PieceInfo{}, xerrors.Errorf("creating unsealed sector file: %w", err) } @@ -97,7 +98,7 @@ func (sb *Sealer) AddPiece(ctx context.Context, sector storage.SectorRef, existi return abi.PieceInfo{}, xerrors.Errorf("acquire unsealed sector: %w", err) } - stagedFile, err = openPartialFile(maxPieceSize, stagedPath.Unsealed) + stagedFile, err = partialfile.OpenPartialFile(maxPieceSize, stagedPath.Unsealed) if err != nil { return abi.PieceInfo{}, xerrors.Errorf("opening unsealed sector file: %w", err) } @@ -257,7 +258,7 @@ func (sb *Sealer) UnsealPiece(ctx context.Context, sector storage.SectorRef, off // try finding existing unsealedPath, done, err := sb.sectors.AcquireSector(ctx, sector, storiface.FTUnsealed, storiface.FTNone, storiface.PathStorage) - var pf *partialFile + var pf *partialfile.PartialFile switch { case xerrors.Is(err, storiface.ErrSectorNotFound): @@ -267,7 +268,7 @@ func (sb *Sealer) UnsealPiece(ctx context.Context, sector storage.SectorRef, off } defer done() - pf, err = createPartialFile(maxPieceSize, unsealedPath.Unsealed) + pf, err = partialfile.CreatePartialFile(maxPieceSize, unsealedPath.Unsealed) if err != nil { return xerrors.Errorf("create unsealed file: %w", err) } @@ -275,7 +276,7 @@ func (sb *Sealer) UnsealPiece(ctx context.Context, sector storage.SectorRef, off case err == nil: defer done() - pf, err = openPartialFile(maxPieceSize, unsealedPath.Unsealed) + pf, err = partialfile.OpenPartialFile(maxPieceSize, unsealedPath.Unsealed) if err != nil { return xerrors.Errorf("opening partial file: %w", err) } @@ -427,7 +428,7 @@ func (sb *Sealer) ReadPiece(ctx context.Context, writer io.Writer, sector storag } maxPieceSize := abi.PaddedPieceSize(ssize) - pf, err := openPartialFile(maxPieceSize, path.Unsealed) + pf, err := partialfile.OpenPartialFile(maxPieceSize, path.Unsealed) if err != nil { if xerrors.Is(err, os.ErrNotExist) { return false, nil @@ -589,7 +590,7 @@ func (sb *Sealer) FinalizeSector(ctx context.Context, sector storage.SectorRef, if len(keepUnsealed) > 0 { - sr := pieceRun(0, maxPieceSize) + sr := partialfile.PieceRun(0, maxPieceSize) for _, s := range keepUnsealed { si := &rlepluslazy.RunSliceIterator{} @@ -611,7 +612,7 @@ func (sb *Sealer) FinalizeSector(ctx context.Context, sector storage.SectorRef, } defer done() - pf, err := openPartialFile(maxPieceSize, paths.Unsealed) + pf, err := partialfile.OpenPartialFile(maxPieceSize, paths.Unsealed) if err == nil { var at uint64 for sr.HasNext() { diff --git a/extern/sector-storage/ffiwrapper/sealer_test.go b/extern/sector-storage/ffiwrapper/sealer_test.go index 5d96f187fe3..a6034cc79ad 100644 --- a/extern/sector-storage/ffiwrapper/sealer_test.go +++ b/extern/sector-storage/ffiwrapper/sealer_test.go @@ -31,6 +31,7 @@ import ( "github.com/filecoin-project/specs-storage/storage" ffi "github.com/filecoin-project/filecoin-ffi" + "github.com/filecoin-project/filecoin-ffi/generated" "github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper/basicfs" @@ -544,6 +545,7 @@ func TestSealAndVerifyAggregate(t *testing.T) { avi.Proof, err = ProofProver.AggregateSealProofs(avi, toAggregate) require.NoError(t, err) + require.Len(t, avi.Proof, 11188) aggDone := time.Now() @@ -853,3 +855,87 @@ func TestAddPiece512MPadded(t *testing.T) { require.Equal(t, "baga6ea4seaqonenxyku4o7hr5xkzbqsceipf6xgli3on54beqbk6k246sbooobq", c.PieceCID.String()) } + +func setupLogger(t *testing.T) *bytes.Buffer { + _ = os.Setenv("RUST_LOG", "info") + + var bb bytes.Buffer + r, w, err := os.Pipe() + if err != nil { + t.Fatal(err) + } + + go func() { + _, _ = io.Copy(&bb, r) + runtime.KeepAlive(w) + }() + + resp := generated.FilInitLogFd(int32(w.Fd())) + resp.Deref() + + defer generated.FilDestroyInitLogFdResponse(resp) + + if resp.StatusCode != generated.FCPResponseStatusFCPNoError { + t.Fatal(generated.RawString(resp.ErrorMsg).Copy()) + } + + return &bb +} + +func TestMulticoreSDR(t *testing.T) { + if os.Getenv("TEST_RUSTPROOFS_LOGS") != "1" { + t.Skip("skipping test without TEST_RUSTPROOFS_LOGS=1") + } + + rustLogger := setupLogger(t) + + getGrothParamFileAndVerifyingKeys(sectorSize) + + dir, err := ioutil.TempDir("", "sbtest") + if err != nil { + t.Fatal(err) + } + + miner := abi.ActorID(123) + + sp := &basicfs.Provider{ + Root: dir, + } + sb, err := New(sp) + if err != nil { + t.Fatalf("%+v", err) + } + + cleanup := func() { + if t.Failed() { + fmt.Printf("not removing %s\n", dir) + return + } + if err := os.RemoveAll(dir); err != nil { + t.Error(err) + } + } + defer cleanup() + + si := storage.SectorRef{ + ID: abi.SectorID{Miner: miner, Number: 1}, + ProofType: sealProofType, + } + + s := seal{ref: si} + + // check multicore + _ = os.Setenv("FIL_PROOFS_USE_MULTICORE_SDR", "1") + rustLogger.Reset() + s.precommit(t, sb, si, func() {}) + + ok := false + for _, s := range strings.Split(rustLogger.String(), "\n") { + if strings.Contains(s, "create_label::multi") { + ok = true + break + } + } + + require.True(t, ok) +} diff --git a/extern/sector-storage/ffiwrapper/unseal_ranges.go b/extern/sector-storage/ffiwrapper/unseal_ranges.go index 4519fc21e6a..bc39abde229 100644 --- a/extern/sector-storage/ffiwrapper/unseal_ranges.go +++ b/extern/sector-storage/ffiwrapper/unseal_ranges.go @@ -1,6 +1,7 @@ package ffiwrapper import ( + "github.com/filecoin-project/lotus/extern/sector-storage/partialfile" "golang.org/x/xerrors" rlepluslazy "github.com/filecoin-project/go-bitfield/rle" @@ -17,7 +18,7 @@ const mergeGaps = 32 << 20 // TODO const expandRuns = 16 << 20 // unseal more than requested for future requests func computeUnsealRanges(unsealed rlepluslazy.RunIterator, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (rlepluslazy.RunIterator, error) { - todo := pieceRun(offset.Padded(), size.Padded()) + todo := partialfile.PieceRun(offset.Padded(), size.Padded()) todo, err := rlepluslazy.Subtract(todo, unsealed) if err != nil { return nil, xerrors.Errorf("compute todo-unsealed: %w", err) diff --git a/extern/sector-storage/fr32/readers.go b/extern/sector-storage/fr32/readers.go index 20f3e9b3185..f14d5bf1cbd 100644 --- a/extern/sector-storage/fr32/readers.go +++ b/extern/sector-storage/fr32/readers.go @@ -51,13 +51,12 @@ func (r *unpadReader) Read(out []byte) (int, error) { r.left -= uint64(todo) - n, err := r.src.Read(r.work[:todo]) + n, err := io.ReadAtLeast(r.src, r.work[:todo], int(todo)) if err != nil && err != io.EOF { return n, err } - - if n != int(todo) { - return 0, xerrors.Errorf("didn't read enough: %w", err) + if n < int(todo) { + return 0, xerrors.Errorf("didn't read enough: %d / %d, left %d, out %d", n, todo, r.left, len(out)) } Unpad(r.work[:todo], out[:todo.Unpadded()]) diff --git a/extern/sector-storage/manager.go b/extern/sector-storage/manager.go index d3fef8533f6..136c00252ec 100644 --- a/extern/sector-storage/manager.go +++ b/extern/sector-storage/manager.go @@ -47,8 +47,6 @@ type Worker interface { } type SectorManager interface { - ReadPiece(context.Context, io.Writer, storage.SectorRef, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) error - ffiwrapper.StorageSealer storage.Prover storiface.WorkerReturn @@ -89,6 +87,20 @@ type result struct { err error } +// ResourceFilteringStrategy is an enum indicating the kinds of resource +// filtering strategies that can be configured for workers. +type ResourceFilteringStrategy string + +const ( + // ResourceFilteringHardware specifies that available hardware resources + // should be evaluated when scheduling a task against the worker. + ResourceFilteringHardware = ResourceFilteringStrategy("hardware") + + // ResourceFilteringDisabled disables resource filtering against this + // worker. The scheduler may assign any task to this worker. + ResourceFilteringDisabled = ResourceFilteringStrategy("disabled") +) + type SealerConfig struct { ParallelFetchLimit int @@ -98,6 +110,11 @@ type SealerConfig struct { AllowPreCommit2 bool AllowCommit bool AllowUnseal bool + + // ResourceFiltering instructs the system which resource filtering strategy + // to use when evaluating tasks against this worker. An empty value defaults + // to "hardware". + ResourceFiltering ResourceFilteringStrategy } type StorageAuth http.Header @@ -105,24 +122,17 @@ type StorageAuth http.Header type WorkerStateStore *statestore.StateStore type ManagerStateStore *statestore.StateStore -func New(ctx context.Context, ls stores.LocalStorage, si stores.SectorIndex, sc SealerConfig, urls URLs, sa StorageAuth, wss WorkerStateStore, mss ManagerStateStore) (*Manager, error) { - lstor, err := stores.NewLocal(ctx, ls, si, urls) - if err != nil { - return nil, err - } - +func New(ctx context.Context, lstor *stores.Local, stor *stores.Remote, ls stores.LocalStorage, si stores.SectorIndex, sc SealerConfig, wss WorkerStateStore, mss ManagerStateStore) (*Manager, error) { prover, err := ffiwrapper.New(&readonlyProvider{stor: lstor, index: si}) if err != nil { return nil, xerrors.Errorf("creating prover instance: %w", err) } - stor := stores.NewRemote(lstor, si, http.Header(sa), sc.ParallelFetchLimit) - m := &Manager{ ls: ls, storage: stor, localStore: lstor, - remoteHnd: &stores.FetchHandler{Local: lstor}, + remoteHnd: &stores.FetchHandler{Local: lstor, PfHandler: &stores.DefaultPartialFileHandler{}}, index: si, sched: newScheduler(), @@ -141,7 +151,7 @@ func New(ctx context.Context, ls stores.LocalStorage, si stores.SectorIndex, sc go m.sched.runSched() localTasks := []sealtasks.TaskType{ - sealtasks.TTCommit1, sealtasks.TTFinalize, sealtasks.TTFetch, sealtasks.TTReadUnsealed, + sealtasks.TTCommit1, sealtasks.TTFinalize, sealtasks.TTFetch, } if sc.AllowAddPiece { localTasks = append(localTasks, sealtasks.TTAddPiece) @@ -159,9 +169,12 @@ func New(ctx context.Context, ls stores.LocalStorage, si stores.SectorIndex, sc localTasks = append(localTasks, sealtasks.TTUnseal) } - err = m.AddWorker(ctx, NewLocalWorker(WorkerConfig{ - TaskTypes: localTasks, - }, stor, lstor, si, m, wss)) + wcfg := WorkerConfig{ + IgnoreResourceFiltering: sc.ResourceFiltering == ResourceFilteringDisabled, + TaskTypes: localTasks, + } + worker := NewLocalWorker(wcfg, stor, lstor, si, m, wss) + err = m.AddWorker(ctx, worker) if err != nil { return nil, xerrors.Errorf("adding local worker: %w", err) } @@ -206,71 +219,11 @@ 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 - } - 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 - } -} - -func (m *Manager) tryReadUnsealedPiece(ctx context.Context, sink io.Writer, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (foundUnsealed bool, readOk bool, selector WorkerSelector, returnErr error) { - - // acquire a lock purely for reading unsealed sectors - 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 { - returnErr = xerrors.Errorf("read piece: checking for already existing unsealed sector: %w", err) - return - } - - 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 - } +// SectorsUnsealPiece will Unseal the Sealed sector file for the given sector. +// It will schedule the Unsealing task on a worker that either already has the sealed sector files or has space in +// one of it's sealing scratch spaces to store them after fetching them from another worker. +// If the chosen worker already has the Unsealed sector file, we will NOT Unseal the sealed sector file again. +func (m *Manager) SectorsUnsealPiece(ctx context.Context, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, ticket abi.SealRandomness, unsealed *cid.Cid) error { ctx, cancel := context.WithCancel(ctx) defer cancel() @@ -279,22 +232,18 @@ func (m *Manager) ReadPiece(ctx context.Context, sink io.Writer, sector storage. return xerrors.Errorf("acquiring unseal sector lock: %w", err) } - unsealFetch := func(ctx context.Context, worker Worker) error { + // if the selected worker does NOT have the sealed files for the sector, instruct it to fetch it from a worker that has them and + // put it in the sealing scratch space. + sealFetch := 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) - } - } return nil } - if unsealed == cid.Undef { + if unsealed == nil { return xerrors.Errorf("cannot unseal piece (sector: %d, offset: %d size: %d) - unsealed cid is undefined", sector, offset, size) } @@ -303,36 +252,28 @@ 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 { + // selector will schedule the Unseal task on a worker that either already has the sealed sector files or has space in + // one of it's sealing scratch spaces to store them after fetching them from another worker. + selector := newExistingSelector(m.index, sector.ID, storiface.FTSealed|storiface.FTCache, true) + + log.Debugf("will schedule unseal for sector %d", sector.ID) + err = m.sched.Schedule(ctx, sector, sealtasks.TTUnseal, selector, sealFetch, 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("calling unseal sector on worker, sectoID=%d", sector.ID) + + // Note: This unseal piece call will essentially become a no-op if the worker already has an Unsealed sector file for the given sector. + _, 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 { - return err - } - - 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 { - return xerrors.Errorf("reading piece from sealed sector: %w", err) - } - - if !readOk { - return xerrors.Errorf("failed to read unsealed piece") + return xerrors.Errorf("worker UnsealPiece call: %s", err) } - log.Debugf("completed read of piece in sector %d, offset %d, size %d", sector.ID, offset, size) return nil } @@ -767,4 +708,5 @@ func (m *Manager) Close(ctx context.Context) error { return m.sched.Close(ctx) } +var _ Unsealer = &Manager{} var _ SectorManager = &Manager{} diff --git a/extern/sector-storage/manager_test.go b/extern/sector-storage/manager_test.go index 1cf9d0aad6c..d4044bbaebb 100644 --- a/extern/sector-storage/manager_test.go +++ b/extern/sector-storage/manager_test.go @@ -98,7 +98,7 @@ func newTestMgr(ctx context.Context, t *testing.T, ds datastore.Datastore) (*Man prover, err := ffiwrapper.New(&readonlyProvider{stor: lstor, index: si}) require.NoError(t, err) - stor := stores.NewRemote(lstor, si, nil, 6000) + stor := stores.NewRemote(lstor, si, nil, 6000, &stores.DefaultPartialFileHandler{}) m := &Manager{ ls: st, diff --git a/extern/sector-storage/mock/mock.go b/extern/sector-storage/mock/mock.go index 52496f83662..40db3999f34 100644 --- a/extern/sector-storage/mock/mock.go +++ b/extern/sector-storage/mock/mock.go @@ -6,6 +6,7 @@ import ( "crypto/sha256" "fmt" "io" + "io/ioutil" "math/rand" "sync" @@ -34,7 +35,9 @@ type SectorMgr struct { lk sync.Mutex } -type mockVerifProver struct{} +type mockVerifProver struct { + aggregates map[string]proof5.AggregateSealVerifyProofAndInfos // used for logging bad verifies +} func NewMockSectorMgr(genesisSectors []abi.SectorID) *SectorMgr { sectors := make(map[abi.SectorID]*sectorState) @@ -116,6 +119,10 @@ func (mgr *SectorMgr) AcquireSectorNumber() (abi.SectorNumber, error) { return id, nil } +func (mgr *SectorMgr) IsUnsealed(ctx context.Context, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (bool, error) { + return false, nil +} + func (mgr *SectorMgr) ForceState(sid storage.SectorRef, st int) error { mgr.lk.Lock() ss, ok := mgr.sectors[sid.ID] @@ -373,13 +380,12 @@ func generateFakePoSt(sectorInfo []proof5.SectorInfo, rpt func(abi.RegisteredSea } } -func (mgr *SectorMgr) ReadPiece(ctx context.Context, w io.Writer, sectorID storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, randomness abi.SealRandomness, c cid.Cid) error { +func (mgr *SectorMgr) ReadPiece(ctx context.Context, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, ticket abi.SealRandomness, unsealed cid.Cid) (io.ReadCloser, bool, error) { if offset != 0 { panic("implme") } - _, err := io.CopyN(w, bytes.NewReader(mgr.pieces[mgr.sectors[sectorID.ID].pieces[0]]), int64(size)) - return err + return ioutil.NopCloser(bytes.NewReader(mgr.pieces[mgr.sectors[sector.ID].pieces[0]][:size])), false, nil } func (mgr *SectorMgr) StageFakeData(mid abi.ActorID, spt abi.RegisteredSealProof) (storage.SectorRef, []abi.PieceInfo, error) { @@ -490,6 +496,10 @@ func (mgr *SectorMgr) ReturnFetch(ctx context.Context, callID storiface.CallID, panic("not supported") } +func (mgr *SectorMgr) SectorsUnsealPiece(ctx context.Context, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, randomness abi.SealRandomness, commd *cid.Cid) error { + return nil +} + func (m mockVerifProver) VerifySeal(svi proof5.SealVerifyInfo) (bool, error) { plen, err := svi.SealProof.ProofSize() if err != nil { @@ -522,7 +532,19 @@ func (m mockVerifProver) VerifyAggregateSeals(aggregate proof5.AggregateSealVeri } } - return bytes.Equal(aggregate.Proof, out), nil + ok := bytes.Equal(aggregate.Proof, out) + if !ok { + genInfo, found := m.aggregates[string(aggregate.Proof)] + if !found { + log.Errorf("BAD AGGREGATE: saved generate inputs not found; agg.Proof: %x; expected: %x", aggregate.Proof, out) + } else { + log.Errorf("BAD AGGREGATE (1): agg.Proof: %x; expected: %x", aggregate.Proof, out) + log.Errorf("BAD AGGREGATE (2): Verify Infos: %+v", aggregate.Infos) + log.Errorf("BAD AGGREGATE (3): Generate Infos: %+v", genInfo.Infos) + } + } + + return ok, nil } func (m mockVerifProver) AggregateSealProofs(aggregateInfo proof5.AggregateSealVerifyProofAndInfos, proofs [][]byte) ([]byte, error) { @@ -533,6 +555,8 @@ func (m mockVerifProver) AggregateSealProofs(aggregateInfo proof5.AggregateSealV } } + m.aggregates[string(out)] = aggregateInfo + return out, nil } @@ -592,8 +616,11 @@ func (m mockVerifProver) GenerateWinningPoStSectorChallenge(ctx context.Context, return []uint64{0}, nil } -var MockVerifier = mockVerifProver{} -var MockProver = mockVerifProver{} +var MockVerifier = mockVerifProver{ + aggregates: map[string]proof5.AggregateSealVerifyProofAndInfos{}, +} + +var MockProver = MockVerifier var _ storage.Sealer = &SectorMgr{} var _ ffiwrapper.Verifier = MockVerifier diff --git a/extern/sector-storage/ffiwrapper/partialfile.go b/extern/sector-storage/partialfile/partialfile.go similarity index 85% rename from extern/sector-storage/ffiwrapper/partialfile.go rename to extern/sector-storage/partialfile/partialfile.go index e19930ac1ca..2ef68de738c 100644 --- a/extern/sector-storage/ffiwrapper/partialfile.go +++ b/extern/sector-storage/partialfile/partialfile.go @@ -1,4 +1,4 @@ -package ffiwrapper +package partialfile import ( "encoding/binary" @@ -7,6 +7,7 @@ import ( "syscall" "github.com/detailyang/go-fallocate" + logging "github.com/ipfs/go-log/v2" "golang.org/x/xerrors" rlepluslazy "github.com/filecoin-project/go-bitfield/rle" @@ -16,6 +17,8 @@ import ( "github.com/filecoin-project/lotus/extern/sector-storage/storiface" ) +var log = logging.Logger("partialfile") + const veryLargeRle = 1 << 20 // Sectors can be partially unsealed. We support this by appending a small @@ -25,7 +28,7 @@ const veryLargeRle = 1 << 20 // unsealed sector files internally have this structure // [unpadded (raw) data][rle+][4B LE length fo the rle+ field] -type partialFile struct { +type PartialFile struct { maxPiece abi.PaddedPieceSize path string @@ -57,7 +60,7 @@ func writeTrailer(maxPieceSize int64, w *os.File, r rlepluslazy.RunIterator) err return w.Truncate(maxPieceSize + int64(rb) + 4) } -func createPartialFile(maxPieceSize abi.PaddedPieceSize, path string) (*partialFile, error) { +func CreatePartialFile(maxPieceSize abi.PaddedPieceSize, path string) (*PartialFile, error) { f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0644) // nolint if err != nil { return nil, xerrors.Errorf("openning partial file '%s': %w", path, err) @@ -89,10 +92,10 @@ func createPartialFile(maxPieceSize abi.PaddedPieceSize, path string) (*partialF return nil, xerrors.Errorf("close empty partial file: %w", err) } - return openPartialFile(maxPieceSize, path) + return OpenPartialFile(maxPieceSize, path) } -func openPartialFile(maxPieceSize abi.PaddedPieceSize, path string) (*partialFile, error) { +func OpenPartialFile(maxPieceSize abi.PaddedPieceSize, path string) (*PartialFile, error) { f, err := os.OpenFile(path, os.O_RDWR, 0644) // nolint if err != nil { return nil, xerrors.Errorf("openning partial file '%s': %w", path, err) @@ -165,7 +168,7 @@ func openPartialFile(maxPieceSize abi.PaddedPieceSize, path string) (*partialFil return nil, err } - return &partialFile{ + return &PartialFile{ maxPiece: maxPieceSize, path: path, allocated: rle, @@ -173,11 +176,11 @@ func openPartialFile(maxPieceSize abi.PaddedPieceSize, path string) (*partialFil }, nil } -func (pf *partialFile) Close() error { +func (pf *PartialFile) Close() error { return pf.file.Close() } -func (pf *partialFile) Writer(offset storiface.PaddedByteIndex, size abi.PaddedPieceSize) (io.Writer, error) { +func (pf *PartialFile) Writer(offset storiface.PaddedByteIndex, size abi.PaddedPieceSize) (io.Writer, error) { if _, err := pf.file.Seek(int64(offset), io.SeekStart); err != nil { return nil, xerrors.Errorf("seek piece start: %w", err) } @@ -188,7 +191,7 @@ func (pf *partialFile) Writer(offset storiface.PaddedByteIndex, size abi.PaddedP return nil, err } - and, err := rlepluslazy.And(have, pieceRun(offset, size)) + and, err := rlepluslazy.And(have, PieceRun(offset, size)) if err != nil { return nil, err } @@ -206,13 +209,13 @@ func (pf *partialFile) Writer(offset storiface.PaddedByteIndex, size abi.PaddedP return pf.file, nil } -func (pf *partialFile) MarkAllocated(offset storiface.PaddedByteIndex, size abi.PaddedPieceSize) error { +func (pf *PartialFile) MarkAllocated(offset storiface.PaddedByteIndex, size abi.PaddedPieceSize) error { have, err := pf.allocated.RunIterator() if err != nil { return err } - ored, err := rlepluslazy.Or(have, pieceRun(offset, size)) + ored, err := rlepluslazy.Or(have, PieceRun(offset, size)) if err != nil { return err } @@ -224,7 +227,7 @@ func (pf *partialFile) MarkAllocated(offset storiface.PaddedByteIndex, size abi. return nil } -func (pf *partialFile) Free(offset storiface.PaddedByteIndex, size abi.PaddedPieceSize) error { +func (pf *PartialFile) Free(offset storiface.PaddedByteIndex, size abi.PaddedPieceSize) error { have, err := pf.allocated.RunIterator() if err != nil { return err @@ -234,7 +237,7 @@ func (pf *partialFile) Free(offset storiface.PaddedByteIndex, size abi.PaddedPie return xerrors.Errorf("deallocating: %w", err) } - s, err := rlepluslazy.Subtract(have, pieceRun(offset, size)) + s, err := rlepluslazy.Subtract(have, PieceRun(offset, size)) if err != nil { return err } @@ -246,7 +249,7 @@ func (pf *partialFile) Free(offset storiface.PaddedByteIndex, size abi.PaddedPie return nil } -func (pf *partialFile) Reader(offset storiface.PaddedByteIndex, size abi.PaddedPieceSize) (*os.File, error) { +func (pf *PartialFile) Reader(offset storiface.PaddedByteIndex, size abi.PaddedPieceSize) (*os.File, error) { if _, err := pf.file.Seek(int64(offset), io.SeekStart); err != nil { return nil, xerrors.Errorf("seek piece start: %w", err) } @@ -257,7 +260,7 @@ func (pf *partialFile) Reader(offset storiface.PaddedByteIndex, size abi.PaddedP return nil, err } - and, err := rlepluslazy.And(have, pieceRun(offset, size)) + and, err := rlepluslazy.And(have, PieceRun(offset, size)) if err != nil { return nil, err } @@ -275,17 +278,17 @@ func (pf *partialFile) Reader(offset storiface.PaddedByteIndex, size abi.PaddedP return pf.file, nil } -func (pf *partialFile) Allocated() (rlepluslazy.RunIterator, error) { +func (pf *PartialFile) Allocated() (rlepluslazy.RunIterator, error) { return pf.allocated.RunIterator() } -func (pf *partialFile) HasAllocated(offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (bool, error) { +func (pf *PartialFile) HasAllocated(offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (bool, error) { have, err := pf.Allocated() if err != nil { return false, err } - u, err := rlepluslazy.And(have, pieceRun(offset.Padded(), size.Padded())) + u, err := rlepluslazy.And(have, PieceRun(offset.Padded(), size.Padded())) if err != nil { return false, err } @@ -298,7 +301,7 @@ func (pf *partialFile) HasAllocated(offset storiface.UnpaddedByteIndex, size abi return abi.PaddedPieceSize(uc) == size.Padded(), nil } -func pieceRun(offset storiface.PaddedByteIndex, size abi.PaddedPieceSize) rlepluslazy.RunIterator { +func PieceRun(offset storiface.PaddedByteIndex, size abi.PaddedPieceSize) rlepluslazy.RunIterator { var runs []rlepluslazy.Run if offset > 0 { runs = append(runs, rlepluslazy.Run{ diff --git a/extern/sector-storage/piece_provider.go b/extern/sector-storage/piece_provider.go new file mode 100644 index 00000000000..ad3a2543ee3 --- /dev/null +++ b/extern/sector-storage/piece_provider.go @@ -0,0 +1,176 @@ +package sectorstorage + +import ( + "bufio" + "context" + "io" + + "github.com/ipfs/go-cid" + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/specs-storage/storage" + + "github.com/filecoin-project/lotus/extern/sector-storage/fr32" + "github.com/filecoin-project/lotus/extern/sector-storage/stores" + "github.com/filecoin-project/lotus/extern/sector-storage/storiface" +) + +type Unsealer interface { + // SectorsUnsealPiece will Unseal a Sealed sector file for the given sector. + SectorsUnsealPiece(ctx context.Context, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, randomness abi.SealRandomness, commd *cid.Cid) error +} + +type PieceProvider interface { + // ReadPiece is used to read an Unsealed piece at the given offset and of the given size from a Sector + ReadPiece(ctx context.Context, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, ticket abi.SealRandomness, unsealed cid.Cid) (io.ReadCloser, bool, error) + IsUnsealed(ctx context.Context, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (bool, error) +} + +var _ PieceProvider = &pieceProvider{} + +type pieceProvider struct { + storage *stores.Remote + index stores.SectorIndex + uns Unsealer +} + +func NewPieceProvider(storage *stores.Remote, index stores.SectorIndex, uns Unsealer) PieceProvider { + return &pieceProvider{ + storage: storage, + index: index, + uns: uns, + } +} + +// IsUnsealed checks if we have the unsealed piece at the given offset in an already +// existing unsealed file either locally or on any of the workers. +func (p *pieceProvider) IsUnsealed(ctx context.Context, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (bool, error) { + if err := offset.Valid(); err != nil { + return false, xerrors.Errorf("offset is not valid: %w", err) + } + if err := size.Validate(); err != nil { + return false, xerrors.Errorf("size is not a valid piece size: %w", err) + } + + ctxLock, cancel := context.WithCancel(ctx) + defer cancel() + + if err := p.index.StorageLock(ctxLock, sector.ID, storiface.FTUnsealed, storiface.FTNone); err != nil { + return false, xerrors.Errorf("acquiring read sector lock: %w", err) + } + + return p.storage.CheckIsUnsealed(ctxLock, sector, abi.PaddedPieceSize(offset.Padded()), size.Padded()) +} + +// tryReadUnsealedPiece will try to read the unsealed piece from an existing unsealed sector file for the given sector from any worker that has it. +// It will NOT try to schedule an Unseal of a sealed sector file for the read. +// +// Returns a nil reader if the piece does NOT exist in any unsealed file or there is no unsealed file for the given sector on any of the workers. +func (p *pieceProvider) tryReadUnsealedPiece(ctx context.Context, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (io.ReadCloser, context.CancelFunc, error) { + // acquire a lock purely for reading unsealed sectors + ctx, cancel := context.WithCancel(ctx) + if err := p.index.StorageLock(ctx, sector.ID, storiface.FTUnsealed, storiface.FTNone); err != nil { + cancel() + return nil, nil, xerrors.Errorf("acquiring read sector lock: %w", err) + } + + // Reader returns a reader for an unsealed piece at the given offset in the given sector. + // The returned reader will be nil if none of the workers has an unsealed sector file containing + // the unsealed piece. + r, err := p.storage.Reader(ctx, sector, abi.PaddedPieceSize(offset.Padded()), size.Padded()) + if err != nil { + log.Debugf("did not get storage reader;sector=%+v, err:%s", sector.ID, err) + cancel() + return nil, nil, err + } + if r == nil { + cancel() + } + + return r, cancel, nil +} + +// ReadPiece is used to read an Unsealed piece at the given offset and of the given size from a Sector +// If an Unsealed sector file exists with the Piece Unsealed in it, we'll use that for the read. +// Otherwise, we will Unseal a Sealed sector file for the given sector and read the Unsealed piece from it. +// If we do NOT have an existing unsealed file containing the given piece thus causing us to schedule an Unseal, +// the returned boolean parameter will be set to true. +// If we have an existing unsealed file containing the given piece, the returned boolean will be set to false. +func (p *pieceProvider) ReadPiece(ctx context.Context, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, ticket abi.SealRandomness, unsealed cid.Cid) (io.ReadCloser, bool, error) { + if err := offset.Valid(); err != nil { + return nil, false, xerrors.Errorf("offset is not valid: %w", err) + } + if err := size.Validate(); err != nil { + return nil, false, xerrors.Errorf("size is not a valid piece size: %w", err) + } + + r, unlock, err := p.tryReadUnsealedPiece(ctx, sector, offset, size) + + log.Debugf("result of first tryReadUnsealedPiece: r=%+v, err=%s", r, err) + + if xerrors.Is(err, storiface.ErrSectorNotFound) { + log.Debugf("no unsealed sector file with unsealed piece, sector=%+v, offset=%d, size=%d", sector, offset, size) + err = nil + } + if err != nil { + log.Errorf("returning error from ReadPiece:%s", err) + return nil, false, err + } + + var uns bool + + if r == nil { + // a nil reader means that none of the workers has an unsealed sector file + // containing the unsealed piece. + // we now need to unseal a sealed sector file for the given sector to read the unsealed piece from it. + uns = true + commd := &unsealed + if unsealed == cid.Undef { + commd = nil + } + if err := p.uns.SectorsUnsealPiece(ctx, sector, offset, size, ticket, commd); err != nil { + log.Errorf("failed to SectorsUnsealPiece: %s", err) + return nil, false, xerrors.Errorf("unsealing piece: %w", err) + } + + log.Debugf("unsealed a sector file to read the piece, sector=%+v, offset=%d, size=%d", sector, offset, size) + + r, unlock, err = p.tryReadUnsealedPiece(ctx, sector, offset, size) + if err != nil { + log.Errorf("failed to tryReadUnsealedPiece after SectorsUnsealPiece: %s", err) + return nil, true, xerrors.Errorf("read after unsealing: %w", err) + } + if r == nil { + log.Errorf("got no reader after unsealing piece") + return nil, true, xerrors.Errorf("got no reader after unsealing piece") + } + log.Debugf("got a reader to read unsealed piece, sector=%+v, offset=%d, size=%d", sector, offset, size) + } else { + log.Debugf("unsealed piece already exists, no need to unseal, sector=%+v, offset=%d, size=%d", sector, offset, size) + } + + upr, err := fr32.NewUnpadReader(r, size.Padded()) + if err != nil { + unlock() + return nil, uns, xerrors.Errorf("creating unpadded reader: %w", err) + } + + log.Debugf("returning reader to read unsealed piece, sector=%+v, offset=%d, size=%d", sector, offset, size) + + return &funcCloser{ + Reader: bufio.NewReaderSize(upr, 127), + close: func() error { + err = r.Close() + unlock() + return err + }, + }, uns, nil +} + +type funcCloser struct { + io.Reader + close func() error +} + +func (fc *funcCloser) Close() error { return fc.close() } diff --git a/extern/sector-storage/piece_provider_test.go b/extern/sector-storage/piece_provider_test.go new file mode 100644 index 00000000000..d6fa14574f7 --- /dev/null +++ b/extern/sector-storage/piece_provider_test.go @@ -0,0 +1,361 @@ +package sectorstorage + +import ( + "bytes" + "context" + "io/ioutil" + "math/rand" + "net" + "net/http" + "testing" + + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-statestore" + "github.com/filecoin-project/lotus/extern/sector-storage/sealtasks" + specstorage "github.com/filecoin-project/specs-storage/storage" + "github.com/gorilla/mux" + "github.com/ipfs/go-cid" + "github.com/ipfs/go-datastore" + "github.com/ipfs/go-datastore/namespace" + ds_sync "github.com/ipfs/go-datastore/sync" + logging "github.com/ipfs/go-log/v2" + "github.com/stretchr/testify/require" + + "github.com/filecoin-project/lotus/extern/sector-storage/stores" + "github.com/filecoin-project/lotus/extern/sector-storage/storiface" +) + +// TestPieceProviderReadPiece verifies that the ReadPiece method works correctly +// only uses miner and does NOT use any remote worker. +func TestPieceProviderSimpleNoRemoteWorker(t *testing.T) { + // Set up sector storage manager + sealerCfg := SealerConfig{ + ParallelFetchLimit: 10, + AllowAddPiece: true, + AllowPreCommit1: true, + AllowPreCommit2: true, + AllowCommit: true, + AllowUnseal: true, + } + + ppt := newPieceProviderTestHarness(t, sealerCfg, abi.RegisteredSealProof_StackedDrg8MiBV1) + defer ppt.shutdown(t) + + // Create some padded data that aligns with the piece boundaries. + pieceData := generatePieceData(8 * 127 * 1024 * 8) + size := abi.UnpaddedPieceSize(len(pieceData)) + ppt.addPiece(t, pieceData) + + // read piece + ppt.readPiece(t, storiface.UnpaddedByteIndex(0), size, + false, pieceData) + + // pre-commit 1 + preCommit1 := ppt.preCommit1(t) + + // check if IsUnsealed -> true + require.True(t, ppt.isUnsealed(t, storiface.UnpaddedByteIndex(0), size)) + // read piece + ppt.readPiece(t, storiface.UnpaddedByteIndex(0), size, + false, pieceData) + + // pre-commit 2 + ppt.preCommit2(t, preCommit1) + + // check if IsUnsealed -> true + require.True(t, ppt.isUnsealed(t, storiface.UnpaddedByteIndex(0), size)) + // read piece + ppt.readPiece(t, storiface.UnpaddedByteIndex(0), size, + false, pieceData) + + // finalize -> nil here will remove unsealed file + ppt.finalizeSector(t, nil) + + // check if IsUnsealed -> false + require.False(t, ppt.isUnsealed(t, storiface.UnpaddedByteIndex(0), size)) + // Read the piece -> will have to unseal + ppt.readPiece(t, storiface.UnpaddedByteIndex(0), size, + true, pieceData) + + // check if IsUnsealed -> true + require.True(t, ppt.isUnsealed(t, storiface.UnpaddedByteIndex(0), size)) + // read the piece -> will not have to unseal + ppt.readPiece(t, storiface.UnpaddedByteIndex(0), size, + false, pieceData) + +} +func TestReadPieceRemoteWorkers(t *testing.T) { + logging.SetAllLoggers(logging.LevelDebug) + + // miner's worker can only add pieces to an unsealed sector. + sealerCfg := SealerConfig{ + ParallelFetchLimit: 10, + AllowAddPiece: true, + AllowPreCommit1: false, + AllowPreCommit2: false, + AllowCommit: false, + AllowUnseal: false, + } + + // test harness for an 8M sector. + ppt := newPieceProviderTestHarness(t, sealerCfg, abi.RegisteredSealProof_StackedDrg8MiBV1) + defer ppt.shutdown(t) + + // worker 2 will ONLY help with the sealing by first fetching + // the unsealed file from the miner. + ppt.addRemoteWorker(t, []sealtasks.TaskType{ + sealtasks.TTPreCommit1, sealtasks.TTPreCommit2, sealtasks.TTCommit1, + sealtasks.TTFetch, sealtasks.TTFinalize, + }) + + // create a worker that can ONLY unseal and fetch + ppt.addRemoteWorker(t, []sealtasks.TaskType{ + sealtasks.TTUnseal, sealtasks.TTFetch, + }) + + // run the test + + // add one piece that aligns with the padding/piece boundaries. + pd1 := generatePieceData(8 * 127 * 4 * 1024) + pi1 := ppt.addPiece(t, pd1) + pd1size := pi1.Size.Unpadded() + + pd2 := generatePieceData(8 * 127 * 4 * 1024) + pi2 := ppt.addPiece(t, pd2) + pd2size := pi2.Size.Unpadded() + + // pre-commit 1 + pC1 := ppt.preCommit1(t) + + // check if IsUnsealed -> true + require.True(t, ppt.isUnsealed(t, storiface.UnpaddedByteIndex(0), pd1size)) + // Read the piece -> no need to unseal + ppt.readPiece(t, storiface.UnpaddedByteIndex(0), pd1size, + false, pd1) + + // pre-commit 2 + ppt.preCommit2(t, pC1) + + // check if IsUnsealed -> true + require.True(t, ppt.isUnsealed(t, storiface.UnpaddedByteIndex(0), pd1size)) + // Read the piece -> no need to unseal + ppt.readPiece(t, storiface.UnpaddedByteIndex(0), pd1size, + false, pd1) + + // finalize the sector so we declare to the index we have the sealed file + // so the unsealing worker can later look it up and fetch it if needed + // sending nil here will remove all unsealed files after sector is finalized. + ppt.finalizeSector(t, nil) + + // check if IsUnsealed -> false + require.False(t, ppt.isUnsealed(t, storiface.UnpaddedByteIndex(0), pd1size)) + // Read the piece -> have to unseal since we removed the file. + ppt.readPiece(t, storiface.UnpaddedByteIndex(0), pd1size, + true, pd1) + + // Read the same piece again -> will NOT have to unseal. + ppt.readPiece(t, storiface.UnpaddedByteIndex(0), pd1size, false, pd1) + + // remove the unsealed file and read again -> will have to unseal. + ppt.removeAllUnsealedSectorFiles(t) + // check if IsUnsealed -> false + require.False(t, ppt.isUnsealed(t, storiface.UnpaddedByteIndex(0), pd1size)) + ppt.readPiece(t, storiface.UnpaddedByteIndex(0), pd1size, + true, pd1) + + // check if IsUnsealed -> true + require.True(t, ppt.isUnsealed(t, storiface.UnpaddedByteIndex(pd1size), pd2size)) + // Read Piece 2 -> no unsealing as it got unsealed above. + ppt.readPiece(t, storiface.UnpaddedByteIndex(pd1size), pd2size, false, pd2) + + // remove all unseal files -> Read Piece 2 -> will have to Unseal. + ppt.removeAllUnsealedSectorFiles(t) + + // check if IsUnsealed -> false + require.False(t, ppt.isUnsealed(t, storiface.UnpaddedByteIndex(pd1size), pd2size)) + ppt.readPiece(t, storiface.UnpaddedByteIndex(pd1size), pd2size, true, pd2) +} + +type pieceProviderTestHarness struct { + ctx context.Context + index *stores.Index + pp PieceProvider + sector specstorage.SectorRef + mgr *Manager + ticket abi.SealRandomness + commD cid.Cid + localStores []*stores.Local + + servers []*http.Server + + addedPieces []abi.PieceInfo +} + +func generatePieceData(size uint64) []byte { + bz := make([]byte, size) + rand.Read(bz) + return bz +} + +func newPieceProviderTestHarness(t *testing.T, mgrConfig SealerConfig, sectorProofType abi.RegisteredSealProof) *pieceProviderTestHarness { + ctx := context.Background() + // listen on tcp socket to create an http server later + address := "0.0.0.0:0" + nl, err := net.Listen("tcp", address) + require.NoError(t, err) + + // create index, storage, local store & remote store. + index := stores.NewIndex() + storage := newTestStorage(t) + localStore, err := stores.NewLocal(ctx, storage, index, []string{"http://" + nl.Addr().String() + "/remote"}) + require.NoError(t, err) + remoteStore := stores.NewRemote(localStore, index, nil, 6000, &stores.DefaultPartialFileHandler{}) + + // data stores for state tracking. + dstore := ds_sync.MutexWrap(datastore.NewMapDatastore()) + wsts := statestore.New(namespace.Wrap(dstore, datastore.NewKey("/worker/calls"))) + smsts := statestore.New(namespace.Wrap(dstore, datastore.NewKey("/stmgr/calls"))) + + mgr, err := New(ctx, localStore, remoteStore, storage, index, mgrConfig, wsts, smsts) + require.NoError(t, err) + + // start a http server on the manager to serve sector file requests. + svc := &http.Server{ + Addr: nl.Addr().String(), + Handler: mgr, + } + go func() { + _ = svc.Serve(nl) + }() + + pp := NewPieceProvider(remoteStore, index, mgr) + + sector := specstorage.SectorRef{ + ID: abi.SectorID{ + Miner: 100, + Number: 10, + }, + ProofType: sectorProofType, + } + + ticket := abi.SealRandomness{9, 9, 9, 9, 9, 9, 9, 9} + + ppt := &pieceProviderTestHarness{ + ctx: ctx, + index: index, + pp: pp, + sector: sector, + mgr: mgr, + ticket: ticket, + } + ppt.servers = append(ppt.servers, svc) + ppt.localStores = append(ppt.localStores, localStore) + return ppt +} + +func (p *pieceProviderTestHarness) addRemoteWorker(t *testing.T, tasks []sealtasks.TaskType) { + // start an http Server + address := "0.0.0.0:0" + nl, err := net.Listen("tcp", address) + require.NoError(t, err) + + localStore, err := stores.NewLocal(p.ctx, newTestStorage(t), p.index, []string{"http://" + nl.Addr().String() + "/remote"}) + require.NoError(t, err) + + fh := &stores.FetchHandler{ + Local: localStore, + PfHandler: &stores.DefaultPartialFileHandler{}, + } + + mux := mux.NewRouter() + mux.PathPrefix("/remote").HandlerFunc(fh.ServeHTTP) + svc := &http.Server{ + Addr: nl.Addr().String(), + Handler: mux, + } + + go func() { + _ = svc.Serve(nl) + }() + + remote := stores.NewRemote(localStore, p.index, nil, 1000, + &stores.DefaultPartialFileHandler{}) + + dstore := ds_sync.MutexWrap(datastore.NewMapDatastore()) + csts := statestore.New(namespace.Wrap(dstore, datastore.NewKey("/stmgr/calls"))) + + worker := newLocalWorker(nil, WorkerConfig{ + TaskTypes: tasks, + }, remote, localStore, p.index, p.mgr, csts) + + p.servers = append(p.servers, svc) + p.localStores = append(p.localStores, localStore) + + // register self with manager + require.NoError(t, p.mgr.AddWorker(p.ctx, worker)) +} + +func (p *pieceProviderTestHarness) removeAllUnsealedSectorFiles(t *testing.T) { + for i := range p.localStores { + ls := p.localStores[i] + require.NoError(t, ls.Remove(p.ctx, p.sector.ID, storiface.FTUnsealed, false)) + } +} + +func (p *pieceProviderTestHarness) addPiece(t *testing.T, pieceData []byte) abi.PieceInfo { + var existing []abi.UnpaddedPieceSize + for _, pi := range p.addedPieces { + existing = append(existing, pi.Size.Unpadded()) + } + + size := abi.UnpaddedPieceSize(len(pieceData)) + pieceInfo, err := p.mgr.AddPiece(p.ctx, p.sector, existing, size, bytes.NewReader(pieceData)) + require.NoError(t, err) + + p.addedPieces = append(p.addedPieces, pieceInfo) + return pieceInfo +} + +func (p *pieceProviderTestHarness) preCommit1(t *testing.T) specstorage.PreCommit1Out { + preCommit1, err := p.mgr.SealPreCommit1(p.ctx, p.sector, p.ticket, p.addedPieces) + require.NoError(t, err) + return preCommit1 +} + +func (p *pieceProviderTestHarness) preCommit2(t *testing.T, pc1 specstorage.PreCommit1Out) { + sectorCids, err := p.mgr.SealPreCommit2(p.ctx, p.sector, pc1) + require.NoError(t, err) + commD := sectorCids.Unsealed + p.commD = commD +} + +func (p *pieceProviderTestHarness) isUnsealed(t *testing.T, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) bool { + b, err := p.pp.IsUnsealed(p.ctx, p.sector, offset, size) + require.NoError(t, err) + return b +} + +func (p *pieceProviderTestHarness) readPiece(t *testing.T, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, + expectedHadToUnseal bool, expectedBytes []byte) { + rd, isUnsealed, err := p.pp.ReadPiece(p.ctx, p.sector, offset, size, p.ticket, p.commD) + require.NoError(t, err) + require.NotNil(t, rd) + require.Equal(t, expectedHadToUnseal, isUnsealed) + defer func() { _ = rd.Close() }() + + // Make sure the input matches the output + readData, err := ioutil.ReadAll(rd) + require.NoError(t, err) + require.Equal(t, expectedBytes, readData) +} + +func (p *pieceProviderTestHarness) finalizeSector(t *testing.T, keepUnseal []specstorage.Range) { + require.NoError(t, p.mgr.FinalizeSector(p.ctx, p.sector, keepUnseal)) +} + +func (p *pieceProviderTestHarness) shutdown(t *testing.T) { + for _, svc := range p.servers { + s := svc + require.NoError(t, s.Shutdown(p.ctx)) + } +} diff --git a/extern/sector-storage/resources.go b/extern/sector-storage/resources.go index 7da3e96a6a7..2e989fdf45d 100644 --- a/extern/sector-storage/resources.go +++ b/extern/sector-storage/resources.go @@ -313,7 +313,6 @@ var ResourceTable = map[sealtasks.TaskType]map[abi.RegisteredSealProof]Resources func init() { ResourceTable[sealtasks.TTUnseal] = ResourceTable[sealtasks.TTPreCommit1] // TODO: measure accurately - ResourceTable[sealtasks.TTReadUnsealed] = ResourceTable[sealtasks.TTFetch] // V1_1 is the same as V1 for _, m := range ResourceTable { diff --git a/extern/sector-storage/sched.go b/extern/sector-storage/sched.go index 61411081afe..aabf6f0cef2 100644 --- a/extern/sector-storage/sched.go +++ b/extern/sector-storage/sched.go @@ -349,24 +349,24 @@ func (sh *scheduler) trySched() { defer sh.workersLk.RUnlock() windowsLen := len(sh.openWindows) - queuneLen := sh.schedQueue.Len() + queueLen := sh.schedQueue.Len() - log.Debugf("SCHED %d queued; %d open windows", queuneLen, windowsLen) + log.Debugf("SCHED %d queued; %d open windows", queueLen, windowsLen) - if windowsLen == 0 || queuneLen == 0 { + if windowsLen == 0 || queueLen == 0 { // nothing to schedule on return } windows := make([]schedWindow, windowsLen) - acceptableWindows := make([][]int, queuneLen) + acceptableWindows := make([][]int, queueLen) // Step 1 throttle := make(chan struct{}, windowsLen) var wg sync.WaitGroup - wg.Add(queuneLen) - for i := 0; i < queuneLen; i++ { + wg.Add(queueLen) + for i := 0; i < queueLen; i++ { throttle <- struct{}{} go func(sqi int) { @@ -393,7 +393,7 @@ func (sh *scheduler) trySched() { } // TODO: allow bigger windows - if !windows[wnd].allocated.canHandleRequest(needRes, windowRequest.worker, "schedAcceptable", worker.info.Resources) { + if !windows[wnd].allocated.canHandleRequest(needRes, windowRequest.worker, "schedAcceptable", worker.info) { continue } @@ -451,27 +451,27 @@ func (sh *scheduler) trySched() { // Step 2 scheduled := 0 - rmQueue := make([]int, 0, queuneLen) + rmQueue := make([]int, 0, queueLen) - for sqi := 0; sqi < queuneLen; sqi++ { + for sqi := 0; sqi < queueLen; sqi++ { task := (*sh.schedQueue)[sqi] needRes := ResourceTable[task.taskType][task.sector.ProofType] selectedWindow := -1 for _, wnd := range acceptableWindows[task.indexHeap] { wid := sh.openWindows[wnd].worker - wr := sh.workers[wid].info.Resources + info := sh.workers[wid].info log.Debugf("SCHED try assign sqi:%d sector %d to window %d", sqi, task.sector.ID.Number, wnd) // TODO: allow bigger windows - if !windows[wnd].allocated.canHandleRequest(needRes, wid, "schedAssign", wr) { + if !windows[wnd].allocated.canHandleRequest(needRes, wid, "schedAssign", info) { continue } log.Debugf("SCHED ASSIGNED sqi:%d sector %d task %s to window %d", sqi, task.sector.ID.Number, task.taskType, wnd) - windows[wnd].allocated.add(wr, needRes) + windows[wnd].allocated.add(info.Resources, needRes) // TODO: We probably want to re-sort acceptableWindows here based on new // workerHandle.utilization + windows[wnd].allocated.utilization (workerHandle.utilization is used in all // task selectors, but not in the same way, so need to figure out how to do that in a non-O(n^2 way), and diff --git a/extern/sector-storage/sched_resources.go b/extern/sector-storage/sched_resources.go index 3e359c1219b..96a1fa8638d 100644 --- a/extern/sector-storage/sched_resources.go +++ b/extern/sector-storage/sched_resources.go @@ -6,7 +6,7 @@ import ( "github.com/filecoin-project/lotus/extern/sector-storage/storiface" ) -func (a *activeResources) withResources(id WorkerID, wr storiface.WorkerResources, r Resources, locker sync.Locker, cb func() error) error { +func (a *activeResources) withResources(id WorkerID, wr storiface.WorkerInfo, r Resources, locker sync.Locker, cb func() error) error { for !a.canHandleRequest(r, id, "withResources", wr) { if a.cond == nil { a.cond = sync.NewCond(locker) @@ -14,11 +14,11 @@ func (a *activeResources) withResources(id WorkerID, wr storiface.WorkerResource a.cond.Wait() } - a.add(wr, r) + a.add(wr.Resources, r) err := cb() - a.free(wr, r) + a.free(wr.Resources, r) if a.cond != nil { a.cond.Broadcast() } @@ -44,8 +44,15 @@ func (a *activeResources) free(wr storiface.WorkerResources, r Resources) { a.memUsedMax -= r.MaxMemory } -func (a *activeResources) canHandleRequest(needRes Resources, wid WorkerID, caller string, res storiface.WorkerResources) bool { +// canHandleRequest evaluates if the worker has enough available resources to +// handle the request. +func (a *activeResources) canHandleRequest(needRes Resources, wid WorkerID, caller string, info storiface.WorkerInfo) bool { + if info.IgnoreResources { + // shortcircuit; if this worker is ignoring resources, it can always handle the request. + return true + } + res := info.Resources // TODO: dedupe needRes.BaseMinMemory per task type (don't add if that task is already running) minNeedMem := res.MemReserved + a.memUsedMin + needRes.MinMemory + needRes.BaseMinMemory if minNeedMem > res.MemPhysical { diff --git a/extern/sector-storage/sched_test.go b/extern/sector-storage/sched_test.go index 63f3de64d00..fbc4d83ee07 100644 --- a/extern/sector-storage/sched_test.go +++ b/extern/sector-storage/sched_test.go @@ -38,6 +38,20 @@ func TestWithPriority(t *testing.T) { require.Equal(t, 2222, getPriority(ctx)) } +var decentWorkerResources = storiface.WorkerResources{ + MemPhysical: 128 << 30, + MemSwap: 200 << 30, + MemReserved: 2 << 30, + CPUs: 32, + GPUs: []string{"a GPU"}, +} + +var constrainedWorkerResources = storiface.WorkerResources{ + MemPhysical: 1 << 30, + MemReserved: 2 << 30, + CPUs: 1, +} + type schedTestWorker struct { name string taskTypes map[sealtasks.TaskType]struct{} @@ -45,6 +59,9 @@ type schedTestWorker struct { closed bool session uuid.UUID + + resources storiface.WorkerResources + ignoreResources bool } func (s *schedTestWorker) SealPreCommit1(ctx context.Context, sector storage.SectorRef, ticket abi.SealRandomness, pieces []abi.PieceInfo) (storiface.CallID, error) { @@ -107,18 +124,11 @@ func (s *schedTestWorker) Paths(ctx context.Context) ([]stores.StoragePath, erro return s.paths, nil } -var decentWorkerResources = storiface.WorkerResources{ - MemPhysical: 128 << 30, - MemSwap: 200 << 30, - MemReserved: 2 << 30, - CPUs: 32, - GPUs: []string{"a GPU"}, -} - func (s *schedTestWorker) Info(ctx context.Context) (storiface.WorkerInfo, error) { return storiface.WorkerInfo{ - Hostname: s.name, - Resources: decentWorkerResources, + Hostname: s.name, + IgnoreResources: s.ignoreResources, + Resources: s.resources, }, nil } @@ -137,13 +147,16 @@ func (s *schedTestWorker) Close() error { var _ Worker = &schedTestWorker{} -func addTestWorker(t *testing.T, sched *scheduler, index *stores.Index, name string, taskTypes map[sealtasks.TaskType]struct{}) { +func addTestWorker(t *testing.T, sched *scheduler, index *stores.Index, name string, taskTypes map[sealtasks.TaskType]struct{}, resources storiface.WorkerResources, ignoreResources bool) { w := &schedTestWorker{ name: name, taskTypes: taskTypes, paths: []stores.StoragePath{{ID: "bb-8", Weight: 2, LocalPath: "food", CanSeal: true, CanStore: true}}, session: uuid.New(), + + resources: resources, + ignoreResources: ignoreResources, } for _, path := range w.paths { @@ -169,7 +182,7 @@ func TestSchedStartStop(t *testing.T) { sched := newScheduler() go sched.runSched() - addTestWorker(t, sched, stores.NewIndex(), "fred", nil) + addTestWorker(t, sched, stores.NewIndex(), "fred", nil, decentWorkerResources, false) require.NoError(t, sched.Close(context.TODO())) } @@ -183,6 +196,9 @@ func TestSched(t *testing.T) { type workerSpec struct { name string taskTypes map[sealtasks.TaskType]struct{} + + resources storiface.WorkerResources + ignoreResources bool } noopAction := func(ctx context.Context, w Worker) error { @@ -295,7 +311,7 @@ func TestSched(t *testing.T) { go sched.runSched() for _, worker := range workers { - addTestWorker(t, sched, index, worker.name, worker.taskTypes) + addTestWorker(t, sched, index, worker.name, worker.taskTypes, worker.resources, worker.ignoreResources) } rm := runMeta{ @@ -322,31 +338,42 @@ func TestSched(t *testing.T) { } } + // checks behaviour with workers with constrained resources + // the first one is not ignoring resource constraints, so we assign to the second worker, who is + t.Run("constrained-resources", testFunc([]workerSpec{ + {name: "fred1", resources: constrainedWorkerResources, taskTypes: map[sealtasks.TaskType]struct{}{sealtasks.TTPreCommit1: {}}}, + {name: "fred2", resources: constrainedWorkerResources, ignoreResources: true, taskTypes: map[sealtasks.TaskType]struct{}{sealtasks.TTPreCommit1: {}}}, + }, []task{ + sched("pc1-1", "fred2", 8, sealtasks.TTPreCommit1), + taskStarted("pc1-1"), + taskDone("pc1-1"), + })) + t.Run("one-pc1", testFunc([]workerSpec{ - {name: "fred", taskTypes: map[sealtasks.TaskType]struct{}{sealtasks.TTPreCommit1: {}}}, + {name: "fred", resources: decentWorkerResources, taskTypes: map[sealtasks.TaskType]struct{}{sealtasks.TTPreCommit1: {}}}, }, []task{ sched("pc1-1", "fred", 8, sealtasks.TTPreCommit1), taskDone("pc1-1"), })) t.Run("pc1-2workers-1", testFunc([]workerSpec{ - {name: "fred2", taskTypes: map[sealtasks.TaskType]struct{}{sealtasks.TTPreCommit2: {}}}, - {name: "fred1", taskTypes: map[sealtasks.TaskType]struct{}{sealtasks.TTPreCommit1: {}}}, + {name: "fred2", resources: decentWorkerResources, taskTypes: map[sealtasks.TaskType]struct{}{sealtasks.TTPreCommit2: {}}}, + {name: "fred1", resources: decentWorkerResources, taskTypes: map[sealtasks.TaskType]struct{}{sealtasks.TTPreCommit1: {}}}, }, []task{ sched("pc1-1", "fred1", 8, sealtasks.TTPreCommit1), taskDone("pc1-1"), })) t.Run("pc1-2workers-2", testFunc([]workerSpec{ - {name: "fred1", taskTypes: map[sealtasks.TaskType]struct{}{sealtasks.TTPreCommit1: {}}}, - {name: "fred2", taskTypes: map[sealtasks.TaskType]struct{}{sealtasks.TTPreCommit2: {}}}, + {name: "fred1", resources: decentWorkerResources, taskTypes: map[sealtasks.TaskType]struct{}{sealtasks.TTPreCommit1: {}}}, + {name: "fred2", resources: decentWorkerResources, taskTypes: map[sealtasks.TaskType]struct{}{sealtasks.TTPreCommit2: {}}}, }, []task{ sched("pc1-1", "fred1", 8, sealtasks.TTPreCommit1), taskDone("pc1-1"), })) t.Run("pc1-block-pc2", testFunc([]workerSpec{ - {name: "fred", taskTypes: map[sealtasks.TaskType]struct{}{sealtasks.TTPreCommit1: {}, sealtasks.TTPreCommit2: {}}}, + {name: "fred", resources: decentWorkerResources, taskTypes: map[sealtasks.TaskType]struct{}{sealtasks.TTPreCommit1: {}, sealtasks.TTPreCommit2: {}}}, }, []task{ sched("pc1", "fred", 8, sealtasks.TTPreCommit1), taskStarted("pc1"), @@ -359,7 +386,7 @@ func TestSched(t *testing.T) { })) t.Run("pc2-block-pc1", testFunc([]workerSpec{ - {name: "fred", taskTypes: map[sealtasks.TaskType]struct{}{sealtasks.TTPreCommit1: {}, sealtasks.TTPreCommit2: {}}}, + {name: "fred", resources: decentWorkerResources, taskTypes: map[sealtasks.TaskType]struct{}{sealtasks.TTPreCommit1: {}, sealtasks.TTPreCommit2: {}}}, }, []task{ sched("pc2", "fred", 8, sealtasks.TTPreCommit2), taskStarted("pc2"), @@ -372,7 +399,7 @@ func TestSched(t *testing.T) { })) t.Run("pc1-batching", testFunc([]workerSpec{ - {name: "fred", taskTypes: map[sealtasks.TaskType]struct{}{sealtasks.TTPreCommit1: {}}}, + {name: "fred", resources: decentWorkerResources, taskTypes: map[sealtasks.TaskType]struct{}{sealtasks.TTPreCommit1: {}}}, }, []task{ sched("t1", "fred", 8, sealtasks.TTPreCommit1), taskStarted("t1"), @@ -459,7 +486,7 @@ func TestSched(t *testing.T) { // run this one a bunch of times, it had a very annoying tendency to fail randomly for i := 0; i < 40; i++ { t.Run("pc1-pc2-prio", testFunc([]workerSpec{ - {name: "fred", taskTypes: map[sealtasks.TaskType]struct{}{sealtasks.TTPreCommit1: {}, sealtasks.TTPreCommit2: {}}}, + {name: "fred", resources: decentWorkerResources, taskTypes: map[sealtasks.TaskType]struct{}{sealtasks.TTPreCommit1: {}, sealtasks.TTPreCommit2: {}}}, }, []task{ // fill queues twoPC1("w0", 0, taskStarted), diff --git a/extern/sector-storage/sched_worker.go b/extern/sector-storage/sched_worker.go index 4e18e5c6f2b..7bc1affc3b6 100644 --- a/extern/sector-storage/sched_worker.go +++ b/extern/sector-storage/sched_worker.go @@ -296,7 +296,7 @@ func (sw *schedWorker) workerCompactWindows() { for ti, todo := range window.todo { needRes := ResourceTable[todo.taskType][todo.sector.ProofType] - if !lower.allocated.canHandleRequest(needRes, sw.wid, "compactWindows", worker.info.Resources) { + if !lower.allocated.canHandleRequest(needRes, sw.wid, "compactWindows", worker.info) { continue } @@ -352,7 +352,7 @@ assignLoop: worker.lk.Lock() for t, todo := range firstWindow.todo { needRes := ResourceTable[todo.taskType][todo.sector.ProofType] - if worker.preparing.canHandleRequest(needRes, sw.wid, "startPreparing", worker.info.Resources) { + if worker.preparing.canHandleRequest(needRes, sw.wid, "startPreparing", worker.info) { tidx = t break } @@ -424,7 +424,7 @@ func (sw *schedWorker) startProcessingTask(taskDone chan struct{}, req *workerRe } // wait (if needed) for resources in the 'active' window - err = w.active.withResources(sw.wid, w.info.Resources, needRes, &sh.workersLk, func() error { + err = w.active.withResources(sw.wid, w.info, needRes, &sh.workersLk, func() error { w.lk.Lock() w.preparing.free(w.info.Resources, needRes) w.lk.Unlock() diff --git a/extern/sector-storage/sealtasks/task.go b/extern/sector-storage/sealtasks/task.go index 8dd14ca34c2..6d341a4b315 100644 --- a/extern/sector-storage/sealtasks/task.go +++ b/extern/sector-storage/sealtasks/task.go @@ -11,21 +11,19 @@ const ( TTFinalize TaskType = "seal/v0/finalize" - TTFetch TaskType = "seal/v0/fetch" - TTUnseal TaskType = "seal/v0/unseal" - TTReadUnsealed TaskType = "seal/v0/unsealread" + TTFetch TaskType = "seal/v0/fetch" + TTUnseal TaskType = "seal/v0/unseal" ) var order = map[TaskType]int{ - TTAddPiece: 6, // least priority - TTPreCommit1: 5, - TTPreCommit2: 4, - TTCommit2: 3, - TTCommit1: 2, - TTUnseal: 1, - TTFetch: -1, - TTReadUnsealed: -1, - TTFinalize: -2, // most priority + TTAddPiece: 6, // least priority + TTPreCommit1: 5, + TTPreCommit2: 4, + TTCommit2: 3, + TTCommit1: 2, + TTUnseal: 1, + TTFetch: -1, + TTFinalize: -2, // most priority } var shortNames = map[TaskType]string{ @@ -38,9 +36,8 @@ var shortNames = map[TaskType]string{ TTFinalize: "FIN", - TTFetch: "GET", - TTUnseal: "UNS", - TTReadUnsealed: "RD", + TTFetch: "GET", + TTUnseal: "UNS", } func (a TaskType) MuchLess(b TaskType) (bool, bool) { diff --git a/extern/sector-storage/stores/http_handler.go b/extern/sector-storage/stores/http_handler.go index 3e34684709c..dc7797157ae 100644 --- a/extern/sector-storage/stores/http_handler.go +++ b/extern/sector-storage/stores/http_handler.go @@ -5,7 +5,10 @@ import ( "io" "net/http" "os" + "strconv" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/extern/sector-storage/partialfile" "github.com/gorilla/mux" logging "github.com/ipfs/go-log/v2" "golang.org/x/xerrors" @@ -18,8 +21,32 @@ import ( var log = logging.Logger("stores") +var _ partialFileHandler = &DefaultPartialFileHandler{} + +// DefaultPartialFileHandler is the default implementation of the partialFileHandler interface. +// This is probably the only implementation we'll ever use because the purpose of the +// interface to is to mock out partial file related functionality during testing. +type DefaultPartialFileHandler struct{} + +func (d *DefaultPartialFileHandler) OpenPartialFile(maxPieceSize abi.PaddedPieceSize, path string) (*partialfile.PartialFile, error) { + return partialfile.OpenPartialFile(maxPieceSize, path) +} +func (d *DefaultPartialFileHandler) HasAllocated(pf *partialfile.PartialFile, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (bool, error) { + return pf.HasAllocated(offset, size) +} + +func (d *DefaultPartialFileHandler) Reader(pf *partialfile.PartialFile, offset storiface.PaddedByteIndex, size abi.PaddedPieceSize) (*os.File, error) { + return pf.Reader(offset, size) +} + +// Close closes the partial file +func (d *DefaultPartialFileHandler) Close(pf *partialfile.PartialFile) error { + return pf.Close() +} + type FetchHandler struct { - *Local + Local Store + PfHandler partialFileHandler } func (handler *FetchHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // /remote/ @@ -29,6 +56,8 @@ func (handler *FetchHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/remote/{type}/{id}", handler.remoteGetSector).Methods("GET") mux.HandleFunc("/remote/{type}/{id}", handler.remoteDeleteSector).Methods("DELETE") + mux.HandleFunc("/remote/{type}/{id}/{spt}/allocated/{offset}/{size}", handler.remoteGetAllocated).Methods("GET") + mux.ServeHTTP(w, r) } @@ -54,6 +83,8 @@ func (handler *FetchHandler) remoteStatFs(w http.ResponseWriter, r *http.Request } } +// remoteGetSector returns the sector file/tared directory byte stream for the sectorID and sector file type sent in the request. +// returns an error if it does NOT have the required sector file/dir. func (handler *FetchHandler) remoteGetSector(w http.ResponseWriter, r *http.Request) { log.Infof("SERVE GET %s", r.URL) vars := mux.Vars(r) @@ -73,7 +104,6 @@ func (handler *FetchHandler) remoteGetSector(w http.ResponseWriter, r *http.Requ } // The caller has a lock on this sector already, no need to get one here - // passing 0 spt because we don't allocate anything si := storage.SectorRef{ ID: id, @@ -82,7 +112,7 @@ func (handler *FetchHandler) remoteGetSector(w http.ResponseWriter, r *http.Requ paths, _, err := handler.Local.AcquireSector(r.Context(), si, ft, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove) if err != nil { - log.Errorf("%+v", err) + log.Errorf("AcquireSector: %+v", err) w.WriteHeader(500) return } @@ -98,62 +128,170 @@ func (handler *FetchHandler) remoteGetSector(w http.ResponseWriter, r *http.Requ stat, err := os.Stat(path) if err != nil { - log.Errorf("%+v", err) + log.Errorf("os.Stat: %+v", err) w.WriteHeader(500) return } - var rd io.Reader if stat.IsDir() { - rd, err = tarutil.TarDirectory(path) + if _, has := r.Header["Range"]; has { + log.Error("Range not supported on directories") + w.WriteHeader(500) + return + } + + rd, err := tarutil.TarDirectory(path) + if err != nil { + log.Errorf("%+v", err) + w.WriteHeader(500) + return + } + w.Header().Set("Content-Type", "application/x-tar") + w.WriteHeader(200) + if _, err := io.CopyBuffer(w, rd, make([]byte, CopyBuf)); err != nil { + log.Errorf("%+v", err) + return + } } else { - rd, err = os.OpenFile(path, os.O_RDONLY, 0644) // nolint w.Header().Set("Content-Type", "application/octet-stream") + // will do a ranged read over the file at the given path if the caller has asked for a ranged read in the request headers. + http.ServeFile(w, r, path) } + + log.Debugf("served sector file/dir, sectorID=%+v, fileType=%s, path=%s", id, ft, path) +} + +func (handler *FetchHandler) remoteDeleteSector(w http.ResponseWriter, r *http.Request) { + log.Infof("SERVE DELETE %s", r.URL) + vars := mux.Vars(r) + + id, err := storiface.ParseSectorID(vars["id"]) if err != nil { log.Errorf("%+v", err) w.WriteHeader(500) return } - if !stat.IsDir() { - defer func() { - if err := rd.(*os.File).Close(); err != nil { - log.Errorf("closing source file: %+v", err) - } - }() + + ft, err := ftFromString(vars["type"]) + if err != nil { + log.Errorf("%+v", err) + w.WriteHeader(500) + return } - w.WriteHeader(200) - if _, err := io.CopyBuffer(w, rd, make([]byte, CopyBuf)); err != nil { + if err := handler.Local.Remove(r.Context(), id, ft, false); err != nil { log.Errorf("%+v", err) + w.WriteHeader(500) return } } -func (handler *FetchHandler) remoteDeleteSector(w http.ResponseWriter, r *http.Request) { - log.Infof("SERVE DELETE %s", r.URL) +// remoteGetAllocated returns `http.StatusOK` if the worker already has an Unsealed sector file +// containing the Unsealed piece sent in the request. +// returns `http.StatusRequestedRangeNotSatisfiable` otherwise. +func (handler *FetchHandler) remoteGetAllocated(w http.ResponseWriter, r *http.Request) { + log.Infof("SERVE Alloc check %s", r.URL) vars := mux.Vars(r) id, err := storiface.ParseSectorID(vars["id"]) if err != nil { - log.Errorf("%+v", err) + log.Errorf("parsing sectorID: %+v", err) w.WriteHeader(500) return } ft, err := ftFromString(vars["type"]) if err != nil { - log.Errorf("%+v", err) + log.Errorf("ftFromString: %+v", err) + w.WriteHeader(500) + return + } + if ft != storiface.FTUnsealed { + log.Errorf("/allocated only supports unsealed sector files") w.WriteHeader(500) return } - if err := handler.Remove(r.Context(), id, ft, false); err != nil { - log.Errorf("%+v", err) + spti, err := strconv.ParseInt(vars["spt"], 10, 64) + if err != nil { + log.Errorf("parsing spt: %+v", err) w.WriteHeader(500) return } + spt := abi.RegisteredSealProof(spti) + ssize, err := spt.SectorSize() + if err != nil { + log.Errorf("spt.SectorSize(): %+v", err) + w.WriteHeader(500) + return + } + + offi, err := strconv.ParseInt(vars["offset"], 10, 64) + if err != nil { + log.Errorf("parsing offset: %+v", err) + w.WriteHeader(500) + return + } + szi, err := strconv.ParseInt(vars["size"], 10, 64) + if err != nil { + log.Errorf("parsing size: %+v", err) + w.WriteHeader(500) + return + } + + // The caller has a lock on this sector already, no need to get one here + + // passing 0 spt because we don't allocate anything + si := storage.SectorRef{ + ID: id, + ProofType: 0, + } + + // get the path of the local Unsealed file for the given sector. + // return error if we do NOT have it. + paths, _, err := handler.Local.AcquireSector(r.Context(), si, ft, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove) + if err != nil { + log.Errorf("AcquireSector: %+v", err) + w.WriteHeader(500) + return + } + + path := storiface.PathByType(paths, ft) + if path == "" { + log.Error("acquired path was empty") + w.WriteHeader(500) + return + } + + // open the Unsealed file and check if it has the Unsealed sector for the piece at the given offset and size. + pf, err := handler.PfHandler.OpenPartialFile(abi.PaddedPieceSize(ssize), path) + if err != nil { + log.Error("opening partial file: ", err) + w.WriteHeader(500) + return + } + defer func() { + if err := pf.Close(); err != nil { + log.Error("closing partial file: ", err) + } + }() + + has, err := handler.PfHandler.HasAllocated(pf, storiface.UnpaddedByteIndex(offi), abi.UnpaddedPieceSize(szi)) + if err != nil { + log.Error("has allocated: ", err) + w.WriteHeader(500) + return + } + + if has { + log.Debugf("returning ok: worker has unsealed file with unsealed piece, sector:%+v, offset:%d, size:%d", id, offi, szi) + w.WriteHeader(http.StatusOK) + return + } + + log.Debugf("returning StatusRequestedRangeNotSatisfiable: worker does NOT have unsealed file with unsealed piece, sector:%+v, offset:%d, size:%d", id, offi, szi) + w.WriteHeader(http.StatusRequestedRangeNotSatisfiable) } func ftFromString(t string) (storiface.SectorFileType, error) { diff --git a/extern/sector-storage/stores/http_handler_test.go b/extern/sector-storage/stores/http_handler_test.go new file mode 100644 index 00000000000..1258d8530a9 --- /dev/null +++ b/extern/sector-storage/stores/http_handler_test.go @@ -0,0 +1,457 @@ +package stores_test + +import ( + "fmt" + "io/ioutil" + "net/http" + "net/http/httptest" + "os" + "path/filepath" + "testing" + + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/extern/sector-storage/partialfile" + "github.com/filecoin-project/lotus/extern/sector-storage/stores" + "github.com/filecoin-project/lotus/extern/sector-storage/stores/mocks" + "github.com/filecoin-project/lotus/extern/sector-storage/storiface" + "github.com/filecoin-project/specs-storage/storage" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + "golang.org/x/xerrors" +) + +func TestRemoteGetAllocated(t *testing.T) { + + emptyPartialFile := &partialfile.PartialFile{} + pfPath := "path" + expectedSectorRef := storage.SectorRef{ + ID: abi.SectorID{ + Miner: 123, + Number: 123, + }, + ProofType: 0, + } + + validSectorName := fmt.Sprintf("s-t0%d-%d", 123, 123) + validSectorFileType := storiface.FTUnsealed.String() + validSectorType := "1" + sectorSize := abi.SealProofInfos[1].SectorSize + + validOffset := "100" + validOffsetInt := 100 + + validSize := "1000" + validSizeInt := 1000 + + type pieceInfo struct { + sectorName string + fileType string + sectorType string + + // piece info + offset string + size string + } + validPieceInfo := pieceInfo{ + sectorName: validSectorName, + fileType: validSectorFileType, + sectorType: validSectorType, + offset: validOffset, + size: validSize, + } + + tcs := map[string]struct { + piFnc func(pi *pieceInfo) + storeFnc func(s *mocks.MockStore) + pfFunc func(s *mocks.MockpartialFileHandler) + + // expectation + expectedStatusCode int + }{ + "fails when sector name is invalid": { + piFnc: func(pi *pieceInfo) { + pi.sectorName = "invalid" + }, + expectedStatusCode: http.StatusInternalServerError, + }, + "fails when file type is invalid": { + piFnc: func(pi *pieceInfo) { + pi.fileType = "invalid" + }, + expectedStatusCode: http.StatusInternalServerError, + }, + "fails when sector proof type is invalid": { + piFnc: func(pi *pieceInfo) { + pi.sectorType = "invalid" + }, + expectedStatusCode: http.StatusInternalServerError, + }, + "fails when offset is invalid": { + piFnc: func(pi *pieceInfo) { + pi.offset = "invalid" + }, + expectedStatusCode: http.StatusInternalServerError, + }, + "fails when size is invalid": { + piFnc: func(pi *pieceInfo) { + pi.size = "invalid" + }, + expectedStatusCode: http.StatusInternalServerError, + }, + "fails when errors out during acquiring unsealed sector file": { + expectedStatusCode: http.StatusInternalServerError, + storeFnc: func(l *mocks.MockStore) { + + l.EXPECT().AcquireSector(gomock.Any(), expectedSectorRef, storiface.FTUnsealed, + storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ + Unsealed: "path", + }, + storiface.SectorPaths{}, xerrors.New("some error")).Times(1) + }, + }, + "fails when unsealed sector file is not found locally": { + expectedStatusCode: http.StatusInternalServerError, + storeFnc: func(l *mocks.MockStore) { + + l.EXPECT().AcquireSector(gomock.Any(), expectedSectorRef, storiface.FTUnsealed, + storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{}, + storiface.SectorPaths{}, nil).Times(1) + }, + }, + "fails when error while opening partial file": { + expectedStatusCode: http.StatusInternalServerError, + storeFnc: func(l *mocks.MockStore) { + + l.EXPECT().AcquireSector(gomock.Any(), expectedSectorRef, storiface.FTUnsealed, + storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ + Unsealed: pfPath, + }, + storiface.SectorPaths{}, nil).Times(1) + }, + + pfFunc: func(pf *mocks.MockpartialFileHandler) { + pf.EXPECT().OpenPartialFile(abi.PaddedPieceSize(sectorSize), pfPath).Return(&partialfile.PartialFile{}, + xerrors.New("some error")).Times(1) + }, + }, + + "fails when determining partial file allocation returns an error": { + expectedStatusCode: http.StatusInternalServerError, + storeFnc: func(l *mocks.MockStore) { + + l.EXPECT().AcquireSector(gomock.Any(), expectedSectorRef, storiface.FTUnsealed, + storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ + Unsealed: pfPath, + }, + storiface.SectorPaths{}, nil).Times(1) + }, + + pfFunc: func(pf *mocks.MockpartialFileHandler) { + pf.EXPECT().OpenPartialFile(abi.PaddedPieceSize(sectorSize), pfPath).Return(emptyPartialFile, + nil).Times(1) + + pf.EXPECT().HasAllocated(emptyPartialFile, storiface.UnpaddedByteIndex(validOffsetInt), + abi.UnpaddedPieceSize(validSizeInt)).Return(true, xerrors.New("some error")).Times(1) + }, + }, + "StatusRequestedRangeNotSatisfiable when piece is NOT allocated in partial file": { + expectedStatusCode: http.StatusRequestedRangeNotSatisfiable, + storeFnc: func(l *mocks.MockStore) { + + l.EXPECT().AcquireSector(gomock.Any(), expectedSectorRef, storiface.FTUnsealed, + storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ + Unsealed: pfPath, + }, + storiface.SectorPaths{}, nil).Times(1) + }, + + pfFunc: func(pf *mocks.MockpartialFileHandler) { + pf.EXPECT().OpenPartialFile(abi.PaddedPieceSize(sectorSize), pfPath).Return(emptyPartialFile, + nil).Times(1) + + pf.EXPECT().HasAllocated(emptyPartialFile, storiface.UnpaddedByteIndex(validOffsetInt), + abi.UnpaddedPieceSize(validSizeInt)).Return(false, nil).Times(1) + }, + }, + "OK when piece is allocated in partial file": { + expectedStatusCode: http.StatusOK, + storeFnc: func(l *mocks.MockStore) { + + l.EXPECT().AcquireSector(gomock.Any(), expectedSectorRef, storiface.FTUnsealed, + storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ + Unsealed: pfPath, + }, + storiface.SectorPaths{}, nil).Times(1) + }, + + pfFunc: func(pf *mocks.MockpartialFileHandler) { + pf.EXPECT().OpenPartialFile(abi.PaddedPieceSize(sectorSize), pfPath).Return(emptyPartialFile, + nil).Times(1) + + pf.EXPECT().HasAllocated(emptyPartialFile, storiface.UnpaddedByteIndex(validOffsetInt), + abi.UnpaddedPieceSize(validSizeInt)).Return(true, nil).Times(1) + }, + }, + } + + for name, tc := range tcs { + tc := tc + t.Run(name, func(t *testing.T) { + // create go mock controller here + mockCtrl := gomock.NewController(t) + // when test is done, assert expectations on all mock objects. + defer mockCtrl.Finish() + + lstore := mocks.NewMockStore(mockCtrl) + pfhandler := mocks.NewMockpartialFileHandler(mockCtrl) + + handler := &stores.FetchHandler{ + lstore, + pfhandler, + } + + // run http server + ts := httptest.NewServer(handler) + defer ts.Close() + + pi := validPieceInfo + + if tc.piFnc != nil { + tc.piFnc(&pi) + } + + if tc.storeFnc != nil { + tc.storeFnc(lstore) + } + if tc.pfFunc != nil { + tc.pfFunc(pfhandler) + } + + // call remoteGetAllocated + url := fmt.Sprintf("%s/remote/%s/%s/%s/allocated/%s/%s", + ts.URL, + pi.fileType, + pi.sectorName, + pi.sectorType, + pi.offset, + pi.size) + resp, err := http.Get(url) + require.NoError(t, err) + defer func() { + _ = resp.Body.Close() + }() + + // assert expected status code + require.Equal(t, tc.expectedStatusCode, resp.StatusCode) + }) + } +} + +func TestRemoteGetSector(t *testing.T) { + str := "hello-world" + fileBytes := []byte(str) + + validSectorName := fmt.Sprintf("s-t0%d-%d", 123, 123) + validSectorFileType := storiface.FTUnsealed.String() + expectedSectorRef := storage.SectorRef{ + ID: abi.SectorID{ + Miner: 123, + Number: 123, + }, + ProofType: 0, + } + + type sectorInfo struct { + sectorName string + fileType string + } + validSectorInfo := sectorInfo{ + sectorName: validSectorName, + fileType: validSectorFileType, + } + + tcs := map[string]struct { + siFnc func(pi *sectorInfo) + storeFnc func(s *mocks.MockStore, path string) + + // reading a file or a dir + isDir bool + + // expectation + noResponseBytes bool + expectedContentType string + expectedStatusCode int + expectedResponseBytes []byte + }{ + "fails when sector name is invalid": { + siFnc: func(si *sectorInfo) { + si.sectorName = "invalid" + }, + expectedStatusCode: http.StatusInternalServerError, + noResponseBytes: true, + }, + "fails when file type is invalid": { + siFnc: func(si *sectorInfo) { + si.fileType = "invalid" + }, + expectedStatusCode: http.StatusInternalServerError, + noResponseBytes: true, + }, + "fails when error while acquiring sector file": { + storeFnc: func(l *mocks.MockStore, _ string) { + + l.EXPECT().AcquireSector(gomock.Any(), expectedSectorRef, storiface.FTUnsealed, + storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ + Unsealed: "path", + }, + storiface.SectorPaths{}, xerrors.New("some error")).Times(1) + }, + expectedStatusCode: http.StatusInternalServerError, + noResponseBytes: true, + }, + "fails when acquired sector file path is empty": { + expectedStatusCode: http.StatusInternalServerError, + storeFnc: func(l *mocks.MockStore, _ string) { + + l.EXPECT().AcquireSector(gomock.Any(), expectedSectorRef, storiface.FTUnsealed, + storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{}, + storiface.SectorPaths{}, nil).Times(1) + }, + noResponseBytes: true, + }, + "fails when acquired file does not exist": { + expectedStatusCode: http.StatusInternalServerError, + storeFnc: func(l *mocks.MockStore, _ string) { + + l.EXPECT().AcquireSector(gomock.Any(), expectedSectorRef, storiface.FTUnsealed, + storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ + Unsealed: "path", + }, + storiface.SectorPaths{}, nil) + }, + noResponseBytes: true, + }, + "successfully read a sector file": { + storeFnc: func(l *mocks.MockStore, path string) { + + l.EXPECT().AcquireSector(gomock.Any(), expectedSectorRef, storiface.FTUnsealed, + storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ + Unsealed: path, + }, + storiface.SectorPaths{}, nil) + }, + + noResponseBytes: false, + expectedContentType: "application/octet-stream", + expectedStatusCode: 200, + expectedResponseBytes: fileBytes, + }, + "successfully read a sector dir": { + storeFnc: func(l *mocks.MockStore, path string) { + + l.EXPECT().AcquireSector(gomock.Any(), expectedSectorRef, storiface.FTUnsealed, + storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ + Unsealed: path, + }, + storiface.SectorPaths{}, nil) + }, + + isDir: true, + noResponseBytes: false, + expectedContentType: "application/x-tar", + expectedStatusCode: 200, + expectedResponseBytes: fileBytes, + }, + } + + for name, tc := range tcs { + tc := tc + t.Run(name, func(t *testing.T) { + mockCtrl := gomock.NewController(t) + // when test is done, assert expectations on all mock objects. + defer mockCtrl.Finish() + lstore := mocks.NewMockStore(mockCtrl) + pfhandler := mocks.NewMockpartialFileHandler(mockCtrl) + + var path string + + if !tc.isDir { + // create file + tempFile, err := ioutil.TempFile("", "TestRemoteGetSector-") + require.NoError(t, err) + + defer func() { + _ = os.Remove(tempFile.Name()) + }() + + _, err = tempFile.Write(fileBytes) + require.NoError(t, err) + path = tempFile.Name() + } else { + // create dir with a file + tempFile2, err := ioutil.TempFile("", "TestRemoteGetSector-") + require.NoError(t, err) + defer func() { + _ = os.Remove(tempFile2.Name()) + }() + + stat, err := os.Stat(tempFile2.Name()) + require.NoError(t, err) + tempDir, err := ioutil.TempDir("", "TestRemoteGetSector-") + require.NoError(t, err) + + defer func() { + _ = os.RemoveAll(tempDir) + }() + + require.NoError(t, os.Rename(tempFile2.Name(), filepath.Join(tempDir, stat.Name()))) + + path = tempDir + } + + handler := &stores.FetchHandler{ + lstore, + pfhandler, + } + + // run http server + ts := httptest.NewServer(handler) + defer ts.Close() + + si := validSectorInfo + if tc.siFnc != nil { + tc.siFnc(&si) + } + + if tc.storeFnc != nil { + tc.storeFnc(lstore, path) + } + + // call remoteGetAllocated + url := fmt.Sprintf("%s/remote/%s/%s", + ts.URL, + si.fileType, + si.sectorName, + ) + resp, err := http.Get(url) + require.NoError(t, err) + defer func() { + _ = resp.Body.Close() + }() + + bz, err := ioutil.ReadAll(resp.Body) + require.NoError(t, err) + + // assert expected status code + require.Equal(t, tc.expectedStatusCode, resp.StatusCode) + + if !tc.noResponseBytes { + if !tc.isDir { + require.EqualValues(t, tc.expectedResponseBytes, bz) + } + } + + require.Equal(t, tc.expectedContentType, resp.Header.Get("Content-Type")) + }) + } +} diff --git a/extern/sector-storage/stores/interface.go b/extern/sector-storage/stores/interface.go index a997ad3d270..4986e6c808c 100644 --- a/extern/sector-storage/stores/interface.go +++ b/extern/sector-storage/stores/interface.go @@ -2,8 +2,10 @@ package stores import ( "context" + "os" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/extern/sector-storage/partialfile" "github.com/filecoin-project/specs-storage/storage" @@ -11,6 +13,23 @@ import ( "github.com/filecoin-project/lotus/extern/sector-storage/storiface" ) +// PartialFileHandler helps mock out the partial file functionality during testing. +type partialFileHandler interface { + // OpenPartialFile opens and returns a partial file at the given path and also verifies it has the given + // size + OpenPartialFile(maxPieceSize abi.PaddedPieceSize, path string) (*partialfile.PartialFile, error) + + // HasAllocated returns true if the given partial file has an unsealed piece starting at the given offset with the given size. + // returns false otherwise. + HasAllocated(pf *partialfile.PartialFile, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (bool, error) + + // Reader returns a file from which we can read the unsealed piece in the partial file. + Reader(pf *partialfile.PartialFile, offset storiface.PaddedByteIndex, size abi.PaddedPieceSize) (*os.File, error) + + // Close closes the partial file + Close(pf *partialfile.PartialFile) error +} + type Store interface { AcquireSector(ctx context.Context, s storage.SectorRef, existing storiface.SectorFileType, allocate storiface.SectorFileType, sealing storiface.PathType, op storiface.AcquireMode) (paths storiface.SectorPaths, stores storiface.SectorPaths, err error) Remove(ctx context.Context, s abi.SectorID, types storiface.SectorFileType, force bool) error @@ -23,4 +42,6 @@ type Store interface { MoveStorage(ctx context.Context, s storage.SectorRef, types storiface.SectorFileType) error FsStat(ctx context.Context, id ID) (fsutil.FsStat, error) + + Reserve(ctx context.Context, sid storage.SectorRef, ft storiface.SectorFileType, storageIDs storiface.SectorPaths, overheadTab map[storiface.SectorFileType]int) (func(), error) } diff --git a/extern/sector-storage/stores/mocks/index.go b/extern/sector-storage/stores/mocks/index.go new file mode 100644 index 00000000000..e06fa70cccc --- /dev/null +++ b/extern/sector-storage/stores/mocks/index.go @@ -0,0 +1,169 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: index.go + +// Package mock_stores is a generated GoMock package. +package mocks + +import ( + context "context" + reflect "reflect" + + abi "github.com/filecoin-project/go-state-types/abi" + fsutil "github.com/filecoin-project/lotus/extern/sector-storage/fsutil" + stores "github.com/filecoin-project/lotus/extern/sector-storage/stores" + storiface "github.com/filecoin-project/lotus/extern/sector-storage/storiface" + gomock "github.com/golang/mock/gomock" +) + +// MockSectorIndex is a mock of SectorIndex interface. +type MockSectorIndex struct { + ctrl *gomock.Controller + recorder *MockSectorIndexMockRecorder +} + +// MockSectorIndexMockRecorder is the mock recorder for MockSectorIndex. +type MockSectorIndexMockRecorder struct { + mock *MockSectorIndex +} + +// NewMockSectorIndex creates a new mock instance. +func NewMockSectorIndex(ctrl *gomock.Controller) *MockSectorIndex { + mock := &MockSectorIndex{ctrl: ctrl} + mock.recorder = &MockSectorIndexMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockSectorIndex) EXPECT() *MockSectorIndexMockRecorder { + return m.recorder +} + +// StorageAttach mocks base method. +func (m *MockSectorIndex) StorageAttach(arg0 context.Context, arg1 stores.StorageInfo, arg2 fsutil.FsStat) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StorageAttach", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// StorageAttach indicates an expected call of StorageAttach. +func (mr *MockSectorIndexMockRecorder) StorageAttach(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StorageAttach", reflect.TypeOf((*MockSectorIndex)(nil).StorageAttach), arg0, arg1, arg2) +} + +// StorageBestAlloc mocks base method. +func (m *MockSectorIndex) StorageBestAlloc(ctx context.Context, allocate storiface.SectorFileType, ssize abi.SectorSize, pathType storiface.PathType) ([]stores.StorageInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StorageBestAlloc", ctx, allocate, ssize, pathType) + ret0, _ := ret[0].([]stores.StorageInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StorageBestAlloc indicates an expected call of StorageBestAlloc. +func (mr *MockSectorIndexMockRecorder) StorageBestAlloc(ctx, allocate, ssize, pathType interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StorageBestAlloc", reflect.TypeOf((*MockSectorIndex)(nil).StorageBestAlloc), ctx, allocate, ssize, pathType) +} + +// StorageDeclareSector mocks base method. +func (m *MockSectorIndex) StorageDeclareSector(ctx context.Context, storageID stores.ID, s abi.SectorID, ft storiface.SectorFileType, primary bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StorageDeclareSector", ctx, storageID, s, ft, primary) + ret0, _ := ret[0].(error) + return ret0 +} + +// StorageDeclareSector indicates an expected call of StorageDeclareSector. +func (mr *MockSectorIndexMockRecorder) StorageDeclareSector(ctx, storageID, s, ft, primary interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StorageDeclareSector", reflect.TypeOf((*MockSectorIndex)(nil).StorageDeclareSector), ctx, storageID, s, ft, primary) +} + +// StorageDropSector mocks base method. +func (m *MockSectorIndex) StorageDropSector(ctx context.Context, storageID stores.ID, s abi.SectorID, ft storiface.SectorFileType) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StorageDropSector", ctx, storageID, s, ft) + ret0, _ := ret[0].(error) + return ret0 +} + +// StorageDropSector indicates an expected call of StorageDropSector. +func (mr *MockSectorIndexMockRecorder) StorageDropSector(ctx, storageID, s, ft interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StorageDropSector", reflect.TypeOf((*MockSectorIndex)(nil).StorageDropSector), ctx, storageID, s, ft) +} + +// StorageFindSector mocks base method. +func (m *MockSectorIndex) StorageFindSector(ctx context.Context, sector abi.SectorID, ft storiface.SectorFileType, ssize abi.SectorSize, allowFetch bool) ([]stores.SectorStorageInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StorageFindSector", ctx, sector, ft, ssize, allowFetch) + ret0, _ := ret[0].([]stores.SectorStorageInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StorageFindSector indicates an expected call of StorageFindSector. +func (mr *MockSectorIndexMockRecorder) StorageFindSector(ctx, sector, ft, ssize, allowFetch interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StorageFindSector", reflect.TypeOf((*MockSectorIndex)(nil).StorageFindSector), ctx, sector, ft, ssize, allowFetch) +} + +// StorageInfo mocks base method. +func (m *MockSectorIndex) StorageInfo(arg0 context.Context, arg1 stores.ID) (stores.StorageInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StorageInfo", arg0, arg1) + ret0, _ := ret[0].(stores.StorageInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StorageInfo indicates an expected call of StorageInfo. +func (mr *MockSectorIndexMockRecorder) StorageInfo(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StorageInfo", reflect.TypeOf((*MockSectorIndex)(nil).StorageInfo), arg0, arg1) +} + +// StorageLock mocks base method. +func (m *MockSectorIndex) StorageLock(ctx context.Context, sector abi.SectorID, read, write storiface.SectorFileType) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StorageLock", ctx, sector, read, write) + ret0, _ := ret[0].(error) + return ret0 +} + +// StorageLock indicates an expected call of StorageLock. +func (mr *MockSectorIndexMockRecorder) StorageLock(ctx, sector, read, write interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StorageLock", reflect.TypeOf((*MockSectorIndex)(nil).StorageLock), ctx, sector, read, write) +} + +// StorageReportHealth mocks base method. +func (m *MockSectorIndex) StorageReportHealth(arg0 context.Context, arg1 stores.ID, arg2 stores.HealthReport) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StorageReportHealth", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// StorageReportHealth indicates an expected call of StorageReportHealth. +func (mr *MockSectorIndexMockRecorder) StorageReportHealth(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StorageReportHealth", reflect.TypeOf((*MockSectorIndex)(nil).StorageReportHealth), arg0, arg1, arg2) +} + +// StorageTryLock mocks base method. +func (m *MockSectorIndex) StorageTryLock(ctx context.Context, sector abi.SectorID, read, write storiface.SectorFileType) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StorageTryLock", ctx, sector, read, write) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StorageTryLock indicates an expected call of StorageTryLock. +func (mr *MockSectorIndexMockRecorder) StorageTryLock(ctx, sector, read, write interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StorageTryLock", reflect.TypeOf((*MockSectorIndex)(nil).StorageTryLock), ctx, sector, read, write) +} diff --git a/extern/sector-storage/stores/mocks/stores.go b/extern/sector-storage/stores/mocks/stores.go new file mode 100644 index 00000000000..a408419a943 --- /dev/null +++ b/extern/sector-storage/stores/mocks/stores.go @@ -0,0 +1,212 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: interface.go + +// Package mock_stores is a generated GoMock package. +package mocks + +import ( + context "context" + os "os" + reflect "reflect" + + abi "github.com/filecoin-project/go-state-types/abi" + fsutil "github.com/filecoin-project/lotus/extern/sector-storage/fsutil" + partialfile "github.com/filecoin-project/lotus/extern/sector-storage/partialfile" + stores "github.com/filecoin-project/lotus/extern/sector-storage/stores" + storiface "github.com/filecoin-project/lotus/extern/sector-storage/storiface" + storage "github.com/filecoin-project/specs-storage/storage" + gomock "github.com/golang/mock/gomock" +) + +// MockpartialFileHandler is a mock of partialFileHandler interface. +type MockpartialFileHandler struct { + ctrl *gomock.Controller + recorder *MockpartialFileHandlerMockRecorder +} + +// MockpartialFileHandlerMockRecorder is the mock recorder for MockpartialFileHandler. +type MockpartialFileHandlerMockRecorder struct { + mock *MockpartialFileHandler +} + +// NewMockpartialFileHandler creates a new mock instance. +func NewMockpartialFileHandler(ctrl *gomock.Controller) *MockpartialFileHandler { + mock := &MockpartialFileHandler{ctrl: ctrl} + mock.recorder = &MockpartialFileHandlerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockpartialFileHandler) EXPECT() *MockpartialFileHandlerMockRecorder { + return m.recorder +} + +// Close mocks base method. +func (m *MockpartialFileHandler) Close(pf *partialfile.PartialFile) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Close", pf) + ret0, _ := ret[0].(error) + return ret0 +} + +// Close indicates an expected call of Close. +func (mr *MockpartialFileHandlerMockRecorder) Close(pf interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockpartialFileHandler)(nil).Close), pf) +} + +// HasAllocated mocks base method. +func (m *MockpartialFileHandler) HasAllocated(pf *partialfile.PartialFile, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HasAllocated", pf, offset, size) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// HasAllocated indicates an expected call of HasAllocated. +func (mr *MockpartialFileHandlerMockRecorder) HasAllocated(pf, offset, size interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasAllocated", reflect.TypeOf((*MockpartialFileHandler)(nil).HasAllocated), pf, offset, size) +} + +// OpenPartialFile mocks base method. +func (m *MockpartialFileHandler) OpenPartialFile(maxPieceSize abi.PaddedPieceSize, path string) (*partialfile.PartialFile, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "OpenPartialFile", maxPieceSize, path) + ret0, _ := ret[0].(*partialfile.PartialFile) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// OpenPartialFile indicates an expected call of OpenPartialFile. +func (mr *MockpartialFileHandlerMockRecorder) OpenPartialFile(maxPieceSize, path interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenPartialFile", reflect.TypeOf((*MockpartialFileHandler)(nil).OpenPartialFile), maxPieceSize, path) +} + +// Reader mocks base method. +func (m *MockpartialFileHandler) Reader(pf *partialfile.PartialFile, offset storiface.PaddedByteIndex, size abi.PaddedPieceSize) (*os.File, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Reader", pf, offset, size) + ret0, _ := ret[0].(*os.File) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Reader indicates an expected call of Reader. +func (mr *MockpartialFileHandlerMockRecorder) Reader(pf, offset, size interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Reader", reflect.TypeOf((*MockpartialFileHandler)(nil).Reader), pf, offset, size) +} + +// MockStore is a mock of Store interface. +type MockStore struct { + ctrl *gomock.Controller + recorder *MockStoreMockRecorder +} + +// MockStoreMockRecorder is the mock recorder for MockStore. +type MockStoreMockRecorder struct { + mock *MockStore +} + +// NewMockStore creates a new mock instance. +func NewMockStore(ctrl *gomock.Controller) *MockStore { + mock := &MockStore{ctrl: ctrl} + mock.recorder = &MockStoreMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockStore) EXPECT() *MockStoreMockRecorder { + return m.recorder +} + +// AcquireSector mocks base method. +func (m *MockStore) AcquireSector(ctx context.Context, s storage.SectorRef, existing, allocate storiface.SectorFileType, sealing storiface.PathType, op storiface.AcquireMode) (storiface.SectorPaths, storiface.SectorPaths, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AcquireSector", ctx, s, existing, allocate, sealing, op) + ret0, _ := ret[0].(storiface.SectorPaths) + ret1, _ := ret[1].(storiface.SectorPaths) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// AcquireSector indicates an expected call of AcquireSector. +func (mr *MockStoreMockRecorder) AcquireSector(ctx, s, existing, allocate, sealing, op interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcquireSector", reflect.TypeOf((*MockStore)(nil).AcquireSector), ctx, s, existing, allocate, sealing, op) +} + +// FsStat mocks base method. +func (m *MockStore) FsStat(ctx context.Context, id stores.ID) (fsutil.FsStat, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FsStat", ctx, id) + ret0, _ := ret[0].(fsutil.FsStat) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// FsStat indicates an expected call of FsStat. +func (mr *MockStoreMockRecorder) FsStat(ctx, id interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FsStat", reflect.TypeOf((*MockStore)(nil).FsStat), ctx, id) +} + +// MoveStorage mocks base method. +func (m *MockStore) MoveStorage(ctx context.Context, s storage.SectorRef, types storiface.SectorFileType) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MoveStorage", ctx, s, types) + ret0, _ := ret[0].(error) + return ret0 +} + +// MoveStorage indicates an expected call of MoveStorage. +func (mr *MockStoreMockRecorder) MoveStorage(ctx, s, types interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MoveStorage", reflect.TypeOf((*MockStore)(nil).MoveStorage), ctx, s, types) +} + +// Remove mocks base method. +func (m *MockStore) Remove(ctx context.Context, s abi.SectorID, types storiface.SectorFileType, force bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Remove", ctx, s, types, force) + ret0, _ := ret[0].(error) + return ret0 +} + +// Remove indicates an expected call of Remove. +func (mr *MockStoreMockRecorder) Remove(ctx, s, types, force interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Remove", reflect.TypeOf((*MockStore)(nil).Remove), ctx, s, types, force) +} + +// RemoveCopies mocks base method. +func (m *MockStore) RemoveCopies(ctx context.Context, s abi.SectorID, types storiface.SectorFileType) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RemoveCopies", ctx, s, types) + ret0, _ := ret[0].(error) + return ret0 +} + +// RemoveCopies indicates an expected call of RemoveCopies. +func (mr *MockStoreMockRecorder) RemoveCopies(ctx, s, types interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveCopies", reflect.TypeOf((*MockStore)(nil).RemoveCopies), ctx, s, types) +} + +// Reserve mocks base method. +func (m *MockStore) Reserve(ctx context.Context, sid storage.SectorRef, ft storiface.SectorFileType, storageIDs storiface.SectorPaths, overheadTab map[storiface.SectorFileType]int) (func(), error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Reserve", ctx, sid, ft, storageIDs, overheadTab) + ret0, _ := ret[0].(func()) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Reserve indicates an expected call of Reserve. +func (mr *MockStoreMockRecorder) Reserve(ctx, sid, ft, storageIDs, overheadTab interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Reserve", reflect.TypeOf((*MockStore)(nil).Reserve), ctx, sid, ft, storageIDs, overheadTab) +} diff --git a/extern/sector-storage/stores/remote.go b/extern/sector-storage/stores/remote.go index 4388a2ffbee..1e1a54d47ba 100644 --- a/extern/sector-storage/stores/remote.go +++ b/extern/sector-storage/stores/remote.go @@ -3,6 +3,7 @@ package stores import ( "context" "encoding/json" + "fmt" "io" "io/ioutil" "math/bits" @@ -31,7 +32,7 @@ var FetchTempSubdir = "fetching" var CopyBuf = 1 << 20 type Remote struct { - local *Local + local Store index SectorIndex auth http.Header @@ -39,6 +40,8 @@ type Remote struct { fetchLk sync.Mutex fetching map[abi.SectorID]chan struct{} + + pfHandler partialFileHandler } func (r *Remote) RemoveCopies(ctx context.Context, s abi.SectorID, types storiface.SectorFileType) error { @@ -49,7 +52,7 @@ func (r *Remote) RemoveCopies(ctx context.Context, s abi.SectorID, types storifa return r.local.RemoveCopies(ctx, s, types) } -func NewRemote(local *Local, index SectorIndex, auth http.Header, fetchLimit int) *Remote { +func NewRemote(local Store, index SectorIndex, auth http.Header, fetchLimit int, pfHandler partialFileHandler) *Remote { return &Remote{ local: local, index: index, @@ -57,7 +60,8 @@ func NewRemote(local *Local, index SectorIndex, auth http.Header, fetchLimit int limit: make(chan struct{}, fetchLimit), - fetching: map[abi.SectorID]chan struct{}{}, + fetching: map[abi.SectorID]chan struct{}{}, + pfHandler: pfHandler, } } @@ -415,4 +419,265 @@ func (r *Remote) FsStat(ctx context.Context, id ID) (fsutil.FsStat, error) { return out, nil } +func (r *Remote) checkAllocated(ctx context.Context, url string, spt abi.RegisteredSealProof, offset, size abi.PaddedPieceSize) (bool, error) { + url = fmt.Sprintf("%s/%d/allocated/%d/%d", url, spt, offset.Unpadded(), size.Unpadded()) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return false, xerrors.Errorf("request: %w", err) + } + req.Header = r.auth.Clone() + req = req.WithContext(ctx) + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return false, xerrors.Errorf("do request: %w", err) + } + defer resp.Body.Close() // nolint + + switch resp.StatusCode { + case http.StatusOK: + return true, nil + case http.StatusRequestedRangeNotSatisfiable: + return false, nil + default: + return false, xerrors.Errorf("unexpected http response: %d", resp.StatusCode) + } +} + +func (r *Remote) readRemote(ctx context.Context, url string, offset, size abi.PaddedPieceSize) (io.ReadCloser, error) { + if len(r.limit) >= cap(r.limit) { + log.Infof("Throttling remote read, %d already running", len(r.limit)) + } + + // TODO: Smarter throttling + // * Priority (just going sequentially is still pretty good) + // * Per interface + // * Aware of remote load + select { + case r.limit <- struct{}{}: + defer func() { <-r.limit }() + case <-ctx.Done(): + return nil, xerrors.Errorf("context error while waiting for fetch limiter: %w", ctx.Err()) + } + + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return nil, xerrors.Errorf("request: %w", err) + } + + if r.auth != nil { + req.Header = r.auth.Clone() + } + req.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", offset, offset+size-1)) + req = req.WithContext(ctx) + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, xerrors.Errorf("do request: %w", err) + } + + if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusPartialContent { + resp.Body.Close() // nolint + return nil, xerrors.Errorf("non-200 code: %d", resp.StatusCode) + } + + return resp.Body, nil +} + +// CheckIsUnsealed checks if we have an unsealed piece at the given offset in an already unsealed sector file for the given piece +// either locally or on any of the workers. +// Returns true if we have the unsealed piece, false otherwise. +func (r *Remote) CheckIsUnsealed(ctx context.Context, s storage.SectorRef, offset, size abi.PaddedPieceSize) (bool, error) { + ft := storiface.FTUnsealed + + paths, _, err := r.local.AcquireSector(ctx, s, ft, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove) + if err != nil { + return false, xerrors.Errorf("acquire local: %w", err) + } + + path := storiface.PathByType(paths, ft) + if path != "" { + // if we have the unsealed file locally, check if it has the unsealed piece. + log.Infof("Read local %s (+%d,%d)", path, offset, size) + ssize, err := s.ProofType.SectorSize() + if err != nil { + return false, err + } + + // open the unsealed sector file for the given sector size located at the given path. + pf, err := r.pfHandler.OpenPartialFile(abi.PaddedPieceSize(ssize), path) + if err != nil { + return false, xerrors.Errorf("opening partial file: %w", err) + } + log.Debugf("local partial file opened %s (+%d,%d)", path, offset, size) + + // even though we have an unsealed file for the given sector, we still need to determine if we have the unsealed piece + // in the unsealed sector file. That is what `HasAllocated` checks for. + has, err := r.pfHandler.HasAllocated(pf, storiface.UnpaddedByteIndex(offset.Unpadded()), size.Unpadded()) + if err != nil { + return false, xerrors.Errorf("has allocated: %w", err) + } + + // close the local unsealed file. + if err := r.pfHandler.Close(pf); err != nil { + return false, xerrors.Errorf("failed to close partial file: %s", err) + } + log.Debugf("checked if local partial file has the piece %s (+%d,%d), returning answer=%t", path, offset, size, has) + + // Sector files can technically not have a piece unsealed locally, but have it unsealed in remote storage, so we probably + // want to return only if has is true + if has { + return has, nil + } + } + + // --- We don't have the unsealed piece in an unsealed sector file locally + // Check if we have it in a remote cluster. + + si, err := r.index.StorageFindSector(ctx, s.ID, ft, 0, false) + if err != nil { + return false, xerrors.Errorf("StorageFindSector: %s", err) + } + + if len(si) == 0 { + return false, nil + } + + sort.Slice(si, func(i, j int) bool { + return si[i].Weight < si[j].Weight + }) + + for _, info := range si { + for _, url := range info.URLs { + ok, err := r.checkAllocated(ctx, url, s.ProofType, offset, size) + if err != nil { + log.Warnw("check if remote has piece", "url", url, "error", err) + continue + } + if !ok { + continue + } + + return true, nil + } + } + + return false, nil +} + +// Reader returns a reader for an unsealed piece at the given offset in the given sector. +// If the Miner has the unsealed piece locally, it will return a reader that reads from the local copy. +// If the Miner does NOT have the unsealed piece locally, it will query all workers that have the unsealed sector file +// to know if they have the unsealed piece and will then read the unsealed piece data from a worker that has it. +// +// Returns a nil reader if : +// 1. no worker(local worker included) has an unsealed file for the given sector OR +// 2. no worker(local worker included) has the unsealed piece in their unsealed sector file. +// Will return a nil reader and a nil error in such a case. +func (r *Remote) Reader(ctx context.Context, s storage.SectorRef, offset, size abi.PaddedPieceSize) (io.ReadCloser, error) { + ft := storiface.FTUnsealed + + // check if we have the unsealed sector file locally + paths, _, err := r.local.AcquireSector(ctx, s, ft, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove) + if err != nil { + return nil, xerrors.Errorf("acquire local: %w", err) + } + + path := storiface.PathByType(paths, ft) + + if path != "" { + // if we have the unsealed file locally, return a reader that can be used to read the contents of the + // unsealed piece. + log.Debugf("Check local %s (+%d,%d)", path, offset, size) + ssize, err := s.ProofType.SectorSize() + if err != nil { + return nil, err + } + log.Debugf("fetched sector size %s (+%d,%d)", path, offset, size) + + // open the unsealed sector file for the given sector size located at the given path. + pf, err := r.pfHandler.OpenPartialFile(abi.PaddedPieceSize(ssize), path) + if err != nil { + return nil, xerrors.Errorf("opening partial file: %w", err) + } + log.Debugf("local partial file opened %s (+%d,%d)", path, offset, size) + + // even though we have an unsealed file for the given sector, we still need to determine if we have the unsealed piece + // in the unsealed sector file. That is what `HasAllocated` checks for. + has, err := r.pfHandler.HasAllocated(pf, storiface.UnpaddedByteIndex(offset.Unpadded()), size.Unpadded()) + if err != nil { + return nil, xerrors.Errorf("has allocated: %w", err) + } + log.Debugf("check if partial file is allocated %s (+%d,%d)", path, offset, size) + + if has { + log.Infof("returning piece reader for local unsealed piece sector=%+v, (offset=%d, size=%d)", s.ID, offset, size) + return r.pfHandler.Reader(pf, storiface.PaddedByteIndex(offset), size) + } + + log.Debugf("miner has unsealed file but not unseal piece, %s (+%d,%d)", path, offset, size) + if err := r.pfHandler.Close(pf); err != nil { + return nil, xerrors.Errorf("close partial file: %w", err) + } + } + + // --- We don't have the unsealed piece in an unsealed sector file locally + + // if we don't have the unsealed sector file locally, we'll first lookup the Miner Sector Store Index + // to determine which workers have the unsealed file and then query those workers to know + // if they have the unsealed piece in the unsealed sector file. + si, err := r.index.StorageFindSector(ctx, s.ID, ft, 0, false) + if err != nil { + log.Debugf("Reader, did not find unsealed file on any of the workers %s (+%d,%d)", path, offset, size) + return nil, err + } + + if len(si) == 0 { + return nil, xerrors.Errorf("failed to read sector %v from remote(%d): %w", s, ft, storiface.ErrSectorNotFound) + } + + sort.Slice(si, func(i, j int) bool { + return si[i].Weight > si[j].Weight + }) + + var lastErr error + for _, info := range si { + for _, url := range info.URLs { + // checkAllocated makes a JSON RPC query to a remote worker to determine if it has + // unsealed piece in their unsealed sector file. + ok, err := r.checkAllocated(ctx, url, s.ProofType, offset, size) + if err != nil { + log.Warnw("check if remote has piece", "url", url, "error", err) + lastErr = err + continue + } + if !ok { + continue + } + + // readRemote fetches a reader that we can use to read the unsealed piece from the remote worker. + // It uses a ranged HTTP query to ensure we ONLY read the unsealed piece and not the entire unsealed file. + rd, err := r.readRemote(ctx, url, offset, size) + if err != nil { + log.Warnw("reading from remote", "url", url, "error", err) + lastErr = err + continue + } + log.Infof("Read remote %s (+%d,%d)", url, offset, size) + return rd, nil + } + } + + // we couldn't find a unsealed file with the unsealed piece, will return a nil reader. + log.Debugf("returning nil reader, did not find unsealed piece for %+v (+%d,%d), last error=%s", s, offset, size, lastErr) + return nil, nil +} + +func (r *Remote) Reserve(ctx context.Context, sid storage.SectorRef, ft storiface.SectorFileType, storageIDs storiface.SectorPaths, overheadTab map[storiface.SectorFileType]int) (func(), error) { + log.Warnf("reserve called on remote store, sectorID: %v", sid.ID) + return func() { + + }, nil +} + var _ Store = &Remote{} diff --git a/extern/sector-storage/stores/remote_test.go b/extern/sector-storage/stores/remote_test.go new file mode 100644 index 00000000000..b708bb68f6d --- /dev/null +++ b/extern/sector-storage/stores/remote_test.go @@ -0,0 +1,741 @@ +package stores_test + +import ( + "context" + "fmt" + "io/ioutil" + "net/http" + "net/http/httptest" + "os" + "testing" + + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/extern/sector-storage/partialfile" + "github.com/filecoin-project/lotus/extern/sector-storage/stores" + "github.com/filecoin-project/lotus/extern/sector-storage/stores/mocks" + "github.com/filecoin-project/lotus/extern/sector-storage/storiface" + "github.com/filecoin-project/specs-storage/storage" + "github.com/golang/mock/gomock" + "github.com/gorilla/mux" + logging "github.com/ipfs/go-log/v2" + "github.com/stretchr/testify/require" + "golang.org/x/xerrors" +) + +func TestReader(t *testing.T) { + logging.SetAllLoggers(logging.LevelDebug) + bz := []byte("Hello World") + + pfPath := "path" + emptyPartialFile := &partialfile.PartialFile{} + sectorSize := abi.SealProofInfos[1].SectorSize + + ft := storiface.FTUnsealed + + sectorRef := storage.SectorRef{ + ID: abi.SectorID{ + Miner: 123, + Number: 123, + }, + ProofType: 1, + } + + offset := abi.PaddedPieceSize(100) + size := abi.PaddedPieceSize(1000) + ctx := context.Background() + + tcs := map[string]struct { + storeFnc func(s *mocks.MockStore) + pfFunc func(s *mocks.MockpartialFileHandler) + indexFnc func(s *mocks.MockSectorIndex, serverURL string) + + needHttpServer bool + + getAllocatedReturnCode int + getSectorReturnCode int + + serverUrl string + + // expectation + errStr string + expectedNonNilReader bool + expectedSectorBytes []byte + }{ + + // -------- have the unsealed file locally + "fails when error while acquiring unsealed file": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, pfPath, xerrors.New("acquire error")) + }, + + errStr: "acquire error", + }, + + "fails when error while opening local partial (unsealed) file": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, pfPath, nil) + }, + + pfFunc: func(pf *mocks.MockpartialFileHandler) { + mockPartialFileOpen(pf, sectorSize, pfPath, xerrors.New("pf open error")) + }, + errStr: "pf open error", + }, + + "fails when error while checking if local unsealed file has piece": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, pfPath, nil) + }, + + pfFunc: func(pf *mocks.MockpartialFileHandler) { + mockPartialFileOpen(pf, sectorSize, pfPath, nil) + mockCheckAllocation(pf, offset, size, emptyPartialFile, + true, xerrors.New("piece check error")) + }, + + errStr: "piece check error", + }, + + "fails when error while closing local unsealed file that does not have the piece": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, pfPath, nil) + }, + + pfFunc: func(pf *mocks.MockpartialFileHandler) { + mockPartialFileOpen(pf, sectorSize, pfPath, nil) + mockCheckAllocation(pf, offset, size, emptyPartialFile, + false, nil) + pf.EXPECT().Close(emptyPartialFile).Return(xerrors.New("close error")).Times(1) + }, + errStr: "close error", + }, + + "fails when error while fetching reader for the local unsealed file that has the unsealed piece": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, pfPath, nil) + }, + + pfFunc: func(pf *mocks.MockpartialFileHandler) { + mockPartialFileOpen(pf, sectorSize, pfPath, nil) + mockCheckAllocation(pf, offset, size, emptyPartialFile, + true, nil) + mockPfReader(pf, emptyPartialFile, offset, size, nil, xerrors.New("reader error")) + + }, + errStr: "reader error", + }, + + // ------------------- don't have the unsealed file locally + + "fails when error while finding sector": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, "", nil) + }, + + indexFnc: func(in *mocks.MockSectorIndex, _ string) { + in.EXPECT().StorageFindSector(gomock.Any(), sectorRef.ID, storiface.FTUnsealed, gomock.Any(), + false).Return(nil, xerrors.New("find sector error")) + }, + errStr: "find sector error", + }, + + "fails when no worker has unsealed file": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, "", nil) + }, + + indexFnc: func(in *mocks.MockSectorIndex, _ string) { + in.EXPECT().StorageFindSector(gomock.Any(), sectorRef.ID, storiface.FTUnsealed, gomock.Any(), + false).Return(nil, nil) + }, + errStr: storiface.ErrSectorNotFound.Error(), + }, + + // --- nil reader when local unsealed file does NOT have unsealed piece + "nil reader when local unsealed file does not have the unsealed piece and remote sector also dosen't have the unsealed piece": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, pfPath, nil) + }, + + pfFunc: func(pf *mocks.MockpartialFileHandler) { + mockPartialFileOpen(pf, sectorSize, pfPath, nil) + mockCheckAllocation(pf, offset, size, emptyPartialFile, + false, nil) + + pf.EXPECT().Close(emptyPartialFile).Return(nil).Times(1) + + }, + + indexFnc: func(in *mocks.MockSectorIndex, url string) { + si := stores.SectorStorageInfo{ + URLs: []string{url}, + } + + in.EXPECT().StorageFindSector(gomock.Any(), sectorRef.ID, storiface.FTUnsealed, gomock.Any(), + false).Return([]stores.SectorStorageInfo{si}, nil).Times(1) + }, + + needHttpServer: true, + getAllocatedReturnCode: 500, + }, + + // ---- nil reader when none of the remote unsealed file has unsealed piece + "nil reader when none of the worker has the unsealed piece": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, "", nil) + }, + + indexFnc: func(in *mocks.MockSectorIndex, url string) { + si := stores.SectorStorageInfo{ + URLs: []string{url}, + } + + in.EXPECT().StorageFindSector(gomock.Any(), sectorRef.ID, storiface.FTUnsealed, gomock.Any(), + false).Return([]stores.SectorStorageInfo{si}, nil).Times(1) + }, + + needHttpServer: true, + getAllocatedReturnCode: 500, + }, + + "nil reader when none of the worker is able to serve the unsealed piece even though they have it": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, "", nil) + }, + + indexFnc: func(in *mocks.MockSectorIndex, url string) { + si := stores.SectorStorageInfo{ + URLs: []string{url}, + } + + in.EXPECT().StorageFindSector(gomock.Any(), sectorRef.ID, storiface.FTUnsealed, gomock.Any(), + false).Return([]stores.SectorStorageInfo{si}, nil).Times(1) + }, + + needHttpServer: true, + getSectorReturnCode: 500, + getAllocatedReturnCode: 200, + }, + + // ---- Success for local unsealed file + "successfully fetches reader for piece from local unsealed file": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, pfPath, nil) + }, + + pfFunc: func(pf *mocks.MockpartialFileHandler) { + mockPartialFileOpen(pf, sectorSize, pfPath, nil) + mockCheckAllocation(pf, offset, size, emptyPartialFile, + true, nil) + + f, err := ioutil.TempFile("", "TestReader-") + require.NoError(t, err) + _, err = f.Write(bz) + require.NoError(t, err) + require.NoError(t, f.Close()) + f, err = os.Open(f.Name()) + require.NoError(t, err) + + mockPfReader(pf, emptyPartialFile, offset, size, f, nil) + + }, + + expectedNonNilReader: true, + expectedSectorBytes: bz, + }, + + // --- Success for remote unsealed file + // --- Success for remote unsealed file + "successfully fetches reader from remote unsealed piece when local unsealed file does NOT have the unsealed Piece": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, pfPath, nil) + }, + + pfFunc: func(pf *mocks.MockpartialFileHandler) { + mockPartialFileOpen(pf, sectorSize, pfPath, nil) + mockCheckAllocation(pf, offset, size, emptyPartialFile, + false, nil) + + pf.EXPECT().Close(emptyPartialFile).Return(nil).Times(1) + + }, + + indexFnc: func(in *mocks.MockSectorIndex, url string) { + si := stores.SectorStorageInfo{ + URLs: []string{url}, + } + + in.EXPECT().StorageFindSector(gomock.Any(), sectorRef.ID, storiface.FTUnsealed, gomock.Any(), + false).Return([]stores.SectorStorageInfo{si}, nil).Times(1) + }, + + needHttpServer: true, + getSectorReturnCode: 200, + getAllocatedReturnCode: 200, + expectedSectorBytes: bz, + expectedNonNilReader: true, + }, + + "successfully fetches reader for piece from remote unsealed piece": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, "", nil) + }, + + indexFnc: func(in *mocks.MockSectorIndex, url string) { + si := stores.SectorStorageInfo{ + URLs: []string{url}, + } + + in.EXPECT().StorageFindSector(gomock.Any(), sectorRef.ID, storiface.FTUnsealed, gomock.Any(), + false).Return([]stores.SectorStorageInfo{si}, nil).Times(1) + }, + + needHttpServer: true, + getSectorReturnCode: 200, + getAllocatedReturnCode: 200, + expectedSectorBytes: bz, + expectedNonNilReader: true, + }, + } + + for name, tc := range tcs { + tc := tc + t.Run(name, func(t *testing.T) { + // create go mock controller here + mockCtrl := gomock.NewController(t) + // when test is done, assert expectations on all mock objects. + defer mockCtrl.Finish() + + // create them mocks + lstore := mocks.NewMockStore(mockCtrl) + pfhandler := mocks.NewMockpartialFileHandler(mockCtrl) + index := mocks.NewMockSectorIndex(mockCtrl) + + if tc.storeFnc != nil { + tc.storeFnc(lstore) + } + if tc.pfFunc != nil { + tc.pfFunc(pfhandler) + } + + if tc.needHttpServer { + // run http server + ts := httptest.NewServer(&mockHttpServer{ + expectedSectorName: storiface.SectorName(sectorRef.ID), + expectedFileType: ft.String(), + expectedOffset: fmt.Sprintf("%d", offset.Unpadded()), + expectedSize: fmt.Sprintf("%d", size.Unpadded()), + expectedSectorType: fmt.Sprintf("%d", sectorRef.ProofType), + + getAllocatedReturnCode: tc.getAllocatedReturnCode, + getSectorReturnCode: tc.getSectorReturnCode, + getSectorBytes: tc.expectedSectorBytes, + }) + defer ts.Close() + tc.serverUrl = fmt.Sprintf("%s/remote/%s/%s", ts.URL, ft.String(), storiface.SectorName(sectorRef.ID)) + } + if tc.indexFnc != nil { + tc.indexFnc(index, tc.serverUrl) + } + + remoteStore := stores.NewRemote(lstore, index, nil, 6000, pfhandler) + + rd, err := remoteStore.Reader(ctx, sectorRef, offset, size) + + if tc.errStr != "" { + require.Error(t, err) + require.Nil(t, rd) + require.Contains(t, err.Error(), tc.errStr) + } else { + require.NoError(t, err) + } + + if !tc.expectedNonNilReader { + require.Nil(t, rd) + } else { + require.NotNil(t, rd) + defer func() { + require.NoError(t, rd.Close()) + }() + + if f, ok := rd.(*os.File); ok { + require.NoError(t, os.Remove(f.Name())) + } + + bz, err := ioutil.ReadAll(rd) + require.NoError(t, err) + require.Equal(t, tc.expectedSectorBytes, bz) + } + + }) + } +} + +func TestCheckIsUnsealed(t *testing.T) { + logging.SetAllLoggers(logging.LevelDebug) + + pfPath := "path" + ft := storiface.FTUnsealed + emptyPartialFile := &partialfile.PartialFile{} + + sectorRef := storage.SectorRef{ + ID: abi.SectorID{ + Miner: 123, + Number: 123, + }, + ProofType: 1, + } + sectorSize := abi.SealProofInfos[1].SectorSize + + offset := abi.PaddedPieceSize(100) + size := abi.PaddedPieceSize(1000) + ctx := context.Background() + + tcs := map[string]struct { + storeFnc func(s *mocks.MockStore) + pfFunc func(s *mocks.MockpartialFileHandler) + indexFnc func(s *mocks.MockSectorIndex, serverURL string) + + needHttpServer bool + + getAllocatedReturnCode int + + serverUrl string + + // expectation + errStr string + expectedIsUnealed bool + }{ + + // -------- have the unsealed file locally + "fails when error while acquiring unsealed file": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, pfPath, xerrors.New("acquire error")) + }, + + errStr: "acquire error", + }, + + "fails when error while opening local partial (unsealed) file": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, pfPath, nil) + }, + + pfFunc: func(pf *mocks.MockpartialFileHandler) { + mockPartialFileOpen(pf, sectorSize, pfPath, xerrors.New("pf open error")) + }, + errStr: "pf open error", + }, + + "fails when error while checking if local unsealed file has piece": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, pfPath, nil) + }, + + pfFunc: func(pf *mocks.MockpartialFileHandler) { + mockPartialFileOpen(pf, sectorSize, pfPath, nil) + mockCheckAllocation(pf, offset, size, emptyPartialFile, + true, xerrors.New("piece check error")) + }, + + errStr: "piece check error", + }, + + "fails when error while closing local unsealed file": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, pfPath, nil) + }, + + pfFunc: func(pf *mocks.MockpartialFileHandler) { + mockPartialFileOpen(pf, sectorSize, pfPath, nil) + + mockCheckAllocation(pf, offset, size, emptyPartialFile, + false, nil) + + pf.EXPECT().Close(emptyPartialFile).Return(xerrors.New("close error")).Times(1) + }, + errStr: "close error", + }, + + // ------------------- don't have the unsealed file locally + + "fails when error while finding sector": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, "", nil) + }, + + indexFnc: func(in *mocks.MockSectorIndex, _ string) { + in.EXPECT().StorageFindSector(gomock.Any(), sectorRef.ID, storiface.FTUnsealed, gomock.Any(), + false).Return(nil, xerrors.New("find sector error")) + }, + errStr: "find sector error", + }, + + "false when no worker has unsealed file": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, "", nil) + }, + + indexFnc: func(in *mocks.MockSectorIndex, _ string) { + in.EXPECT().StorageFindSector(gomock.Any(), sectorRef.ID, storiface.FTUnsealed, gomock.Any(), + false).Return(nil, nil) + }, + }, + + // false when local unsealed file does NOT have unsealed piece + "false when local unsealed file does not have the piece and remote sector too dosen't have the piece": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, pfPath, nil) + }, + + pfFunc: func(pf *mocks.MockpartialFileHandler) { + mockPartialFileOpen(pf, sectorSize, pfPath, nil) + mockCheckAllocation(pf, offset, size, emptyPartialFile, + false, nil) + + pf.EXPECT().Close(emptyPartialFile).Return(nil).Times(1) + }, + + indexFnc: func(in *mocks.MockSectorIndex, url string) { + si := stores.SectorStorageInfo{ + URLs: []string{url}, + } + + in.EXPECT().StorageFindSector(gomock.Any(), sectorRef.ID, storiface.FTUnsealed, gomock.Any(), + false).Return([]stores.SectorStorageInfo{si}, nil).Times(1) + }, + + needHttpServer: true, + getAllocatedReturnCode: 500, + }, + + "false when none of the worker has the unsealed piece": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, "", nil) + }, + + indexFnc: func(in *mocks.MockSectorIndex, url string) { + si := stores.SectorStorageInfo{ + URLs: []string{url}, + } + + in.EXPECT().StorageFindSector(gomock.Any(), sectorRef.ID, storiface.FTUnsealed, gomock.Any(), + false).Return([]stores.SectorStorageInfo{si}, nil).Times(1) + }, + + needHttpServer: true, + getAllocatedReturnCode: 500, + }, + + // ---- Success for local unsealed file + "true when local unsealed file has the piece": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, pfPath, nil) + }, + + pfFunc: func(pf *mocks.MockpartialFileHandler) { + mockPartialFileOpen(pf, sectorSize, pfPath, nil) + mockCheckAllocation(pf, offset, size, emptyPartialFile, + true, nil) + pf.EXPECT().Close(emptyPartialFile).Return(nil).Times(1) + + }, + + expectedIsUnealed: true, + }, + + // --- Success for remote unsealed file + "true if we have a remote unsealed piece": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, "", nil) + }, + + indexFnc: func(in *mocks.MockSectorIndex, url string) { + si := stores.SectorStorageInfo{ + URLs: []string{url}, + } + + in.EXPECT().StorageFindSector(gomock.Any(), sectorRef.ID, storiface.FTUnsealed, gomock.Any(), + false).Return([]stores.SectorStorageInfo{si}, nil).Times(1) + }, + + needHttpServer: true, + getAllocatedReturnCode: 200, + expectedIsUnealed: true, + }, + + "true when local unsealed file does NOT have the unsealed Piece but remote sector has the unsealed piece": { + storeFnc: func(l *mocks.MockStore) { + mockSectorAcquire(l, sectorRef, pfPath, nil) + }, + + pfFunc: func(pf *mocks.MockpartialFileHandler) { + mockPartialFileOpen(pf, sectorSize, pfPath, nil) + mockCheckAllocation(pf, offset, size, emptyPartialFile, + false, nil) + + pf.EXPECT().Close(emptyPartialFile).Return(nil).Times(1) + }, + + indexFnc: func(in *mocks.MockSectorIndex, url string) { + si := stores.SectorStorageInfo{ + URLs: []string{url}, + } + + in.EXPECT().StorageFindSector(gomock.Any(), sectorRef.ID, storiface.FTUnsealed, gomock.Any(), + false).Return([]stores.SectorStorageInfo{si}, nil).Times(1) + }, + + needHttpServer: true, + getAllocatedReturnCode: 200, + expectedIsUnealed: true, + }, + } + + for name, tc := range tcs { + tc := tc + t.Run(name, func(t *testing.T) { + // create go mock controller here + mockCtrl := gomock.NewController(t) + // when test is done, assert expectations on all mock objects. + defer mockCtrl.Finish() + + // create them mocks + lstore := mocks.NewMockStore(mockCtrl) + pfhandler := mocks.NewMockpartialFileHandler(mockCtrl) + index := mocks.NewMockSectorIndex(mockCtrl) + + if tc.storeFnc != nil { + tc.storeFnc(lstore) + } + if tc.pfFunc != nil { + tc.pfFunc(pfhandler) + } + + if tc.needHttpServer { + // run http server + ts := httptest.NewServer(&mockHttpServer{ + expectedSectorName: storiface.SectorName(sectorRef.ID), + expectedFileType: ft.String(), + expectedOffset: fmt.Sprintf("%d", offset.Unpadded()), + expectedSize: fmt.Sprintf("%d", size.Unpadded()), + expectedSectorType: fmt.Sprintf("%d", sectorRef.ProofType), + + getAllocatedReturnCode: tc.getAllocatedReturnCode, + }) + defer ts.Close() + tc.serverUrl = fmt.Sprintf("%s/remote/%s/%s", ts.URL, ft.String(), storiface.SectorName(sectorRef.ID)) + } + if tc.indexFnc != nil { + tc.indexFnc(index, tc.serverUrl) + } + + remoteStore := stores.NewRemote(lstore, index, nil, 6000, pfhandler) + + isUnsealed, err := remoteStore.CheckIsUnsealed(ctx, sectorRef, offset, size) + + if tc.errStr != "" { + require.Error(t, err) + require.False(t, isUnsealed) + require.Contains(t, err.Error(), tc.errStr) + } else { + require.NoError(t, err) + } + + require.Equal(t, tc.expectedIsUnealed, isUnsealed) + + }) + } +} + +func mockSectorAcquire(l *mocks.MockStore, sectorRef storage.SectorRef, pfPath string, err error) { + l.EXPECT().AcquireSector(gomock.Any(), sectorRef, storiface.FTUnsealed, + storiface.FTNone, storiface.PathStorage, storiface.AcquireMove).Return(storiface.SectorPaths{ + Unsealed: pfPath, + }, + storiface.SectorPaths{}, err).Times(1) +} + +func mockPartialFileOpen(pf *mocks.MockpartialFileHandler, sectorSize abi.SectorSize, pfPath string, err error) { + pf.EXPECT().OpenPartialFile(abi.PaddedPieceSize(sectorSize), pfPath).Return(&partialfile.PartialFile{}, + err).Times(1) +} + +func mockCheckAllocation(pf *mocks.MockpartialFileHandler, offset, size abi.PaddedPieceSize, file *partialfile.PartialFile, + out bool, err error) { + pf.EXPECT().HasAllocated(file, storiface.UnpaddedByteIndex(offset.Unpadded()), + size.Unpadded()).Return(out, err).Times(1) +} + +func mockPfReader(pf *mocks.MockpartialFileHandler, file *partialfile.PartialFile, offset, size abi.PaddedPieceSize, + outFile *os.File, err error) { + pf.EXPECT().Reader(file, storiface.PaddedByteIndex(offset), size).Return(outFile, err) +} + +type mockHttpServer struct { + expectedSectorName string + expectedFileType string + expectedOffset string + expectedSize string + expectedSectorType string + + getAllocatedReturnCode int + + getSectorReturnCode int + getSectorBytes []byte +} + +func (m *mockHttpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { + mux := mux.NewRouter() + mux.HandleFunc("/remote/{type}/{id}", m.getSector).Methods("GET") + mux.HandleFunc("/remote/{type}/{id}/{spt}/allocated/{offset}/{size}", m.getAllocated).Methods("GET") + mux.ServeHTTP(w, r) +} + +func (m *mockHttpServer) getAllocated(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + + if vars["id"] != m.expectedSectorName { + w.WriteHeader(http.StatusBadRequest) + return + } + + if vars["type"] != m.expectedFileType { + w.WriteHeader(http.StatusBadRequest) + return + } + + if vars["spt"] != m.expectedSectorType { + w.WriteHeader(http.StatusBadRequest) + return + } + + if vars["offset"] != m.expectedOffset { + w.WriteHeader(http.StatusBadRequest) + return + } + + if vars["size"] != m.expectedSize { + w.WriteHeader(http.StatusBadRequest) + return + } + + w.WriteHeader(m.getAllocatedReturnCode) +} + +func (m *mockHttpServer) getSector(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + + if vars["id"] != m.expectedSectorName { + w.WriteHeader(http.StatusBadRequest) + return + } + + if vars["type"] != m.expectedFileType { + w.WriteHeader(http.StatusBadRequest) + return + } + + w.WriteHeader(m.getSectorReturnCode) + _, _ = w.Write(m.getSectorBytes) +} diff --git a/extern/sector-storage/stores/util_unix.go b/extern/sector-storage/stores/util_unix.go index 2b057468d95..943681b498c 100644 --- a/extern/sector-storage/stores/util_unix.go +++ b/extern/sector-storage/stores/util_unix.go @@ -2,8 +2,10 @@ package stores import ( "bytes" + "os" "os/exec" "path/filepath" + "runtime" "strings" "github.com/mitchellh/go-homedir" @@ -33,7 +35,18 @@ func move(from, to string) error { // can do better var errOut bytes.Buffer - cmd := exec.Command("/usr/bin/env", "mv", "-t", toDir, from) // nolint + + var cmd *exec.Cmd + if runtime.GOOS == "darwin" { + if err := os.MkdirAll(toDir, 0777); err != nil { + return xerrors.Errorf("failed exec MkdirAll: %s", err) + } + + cmd = exec.Command("/usr/bin/env", "mv", from, toDir) // nolint + } else { + cmd = exec.Command("/usr/bin/env", "mv", "-t", toDir, from) // nolint + } + cmd.Stderr = &errOut if err := cmd.Run(); err != nil { return xerrors.Errorf("exec mv (stderr: %s): %w", strings.TrimSpace(errOut.String()), err) diff --git a/extern/sector-storage/storiface/ffi.go b/extern/sector-storage/storiface/ffi.go index f6b2cbdd31d..2b6df667a68 100644 --- a/extern/sector-storage/storiface/ffi.go +++ b/extern/sector-storage/storiface/ffi.go @@ -5,6 +5,7 @@ import ( "errors" "github.com/ipfs/go-cid" + "golang.org/x/xerrors" "github.com/filecoin-project/go-state-types/abi" ) @@ -17,6 +18,14 @@ func (i UnpaddedByteIndex) Padded() PaddedByteIndex { return PaddedByteIndex(abi.UnpaddedPieceSize(i).Padded()) } +func (i UnpaddedByteIndex) Valid() error { + if i%127 != 0 { + return xerrors.Errorf("unpadded byte index must be a multiple of 127") + } + + return nil +} + type PaddedByteIndex uint64 type RGetter func(ctx context.Context, id abi.SectorID) (cid.Cid, error) diff --git a/extern/sector-storage/storiface/worker.go b/extern/sector-storage/storiface/worker.go index 49d1de357cf..d1373f4c541 100644 --- a/extern/sector-storage/storiface/worker.go +++ b/extern/sector-storage/storiface/worker.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "io" "time" "github.com/google/uuid" @@ -19,7 +18,12 @@ import ( type WorkerInfo struct { Hostname string - Resources WorkerResources + // IgnoreResources indicates whether the worker's available resources should + // be used ignored (true) or used (false) for the purposes of scheduling and + // task assignment. Only supported on local workers. Used for testing. + // Default should be false (zero value, i.e. resources taken into account). + IgnoreResources bool + Resources WorkerResources } type WorkerResources struct { @@ -87,7 +91,6 @@ type WorkerCalls interface { ReleaseUnsealed(ctx context.Context, sector storage.SectorRef, safeToFree []storage.Range) (CallID, error) MoveStorage(ctx context.Context, sector storage.SectorRef, types SectorFileType) (CallID, error) UnsealPiece(context.Context, storage.SectorRef, UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) (CallID, error) - ReadPiece(context.Context, io.Writer, storage.SectorRef, UnpaddedByteIndex, abi.UnpaddedPieceSize) (CallID, error) Fetch(context.Context, storage.SectorRef, SectorFileType, PathType, AcquireMode) (CallID, error) } diff --git a/extern/sector-storage/worker_local.go b/extern/sector-storage/worker_local.go index abbad4d9c14..3e63f8659fc 100644 --- a/extern/sector-storage/worker_local.go +++ b/extern/sector-storage/worker_local.go @@ -20,7 +20,7 @@ import ( ffi "github.com/filecoin-project/filecoin-ffi" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-statestore" - storage "github.com/filecoin-project/specs-storage/storage" + "github.com/filecoin-project/specs-storage/storage" "github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper" "github.com/filecoin-project/lotus/extern/sector-storage/sealtasks" @@ -33,6 +33,11 @@ var pathTypes = []storiface.SectorFileType{storiface.FTUnsealed, storiface.FTSea type WorkerConfig struct { TaskTypes []sealtasks.TaskType NoSwap bool + + // IgnoreResourceFiltering enables task distribution to happen on this + // worker regardless of its currently available resources. Used in testing + // with the local worker. + IgnoreResourceFiltering bool } // used do provide custom proofs impl (mostly used in testing) @@ -46,6 +51,9 @@ type LocalWorker struct { executor ExecutorFunc noSwap bool + // see equivalent field on WorkerConfig. + ignoreResources bool + ct *workerCallTracker acceptTasks map[sealtasks.TaskType]struct{} running sync.WaitGroup @@ -71,12 +79,12 @@ func newLocalWorker(executor ExecutorFunc, wcfg WorkerConfig, store stores.Store ct: &workerCallTracker{ st: cst, }, - acceptTasks: acceptTasks, - executor: executor, - noSwap: wcfg.NoSwap, - - session: uuid.New(), - closing: make(chan struct{}), + acceptTasks: acceptTasks, + executor: executor, + noSwap: wcfg.NoSwap, + ignoreResources: wcfg.IgnoreResourceFiltering, + session: uuid.New(), + closing: make(chan struct{}), } if w.executor == nil { @@ -161,7 +169,6 @@ const ( ReleaseUnsealed ReturnType = "ReleaseUnsealed" MoveStorage ReturnType = "MoveStorage" UnsealPiece ReturnType = "UnsealPiece" - ReadPiece ReturnType = "ReadPiece" Fetch ReturnType = "Fetch" ) @@ -209,7 +216,6 @@ var returnFunc = map[ReturnType]func(context.Context, storiface.CallID, storifac ReleaseUnsealed: rfunc(storiface.WorkerReturn.ReturnReleaseUnsealed), MoveStorage: rfunc(storiface.WorkerReturn.ReturnMoveStorage), UnsealPiece: rfunc(storiface.WorkerReturn.ReturnUnsealPiece), - ReadPiece: rfunc(storiface.WorkerReturn.ReturnReadPiece), Fetch: rfunc(storiface.WorkerReturn.ReturnFetch), } @@ -430,6 +436,7 @@ func (l *LocalWorker) UnsealPiece(ctx context.Context, sector storage.SectorRef, } return l.asyncCall(ctx, sector, UnsealPiece, func(ctx context.Context, ci storiface.CallID) (interface{}, error) { + log.Debugf("worker will unseal piece now, sector=%+v", sector.ID) if err = sb.UnsealPiece(ctx, sector, index, size, randomness, cid); err != nil { return nil, xerrors.Errorf("unsealing sector: %w", err) } @@ -442,18 +449,9 @@ func (l *LocalWorker) UnsealPiece(ctx context.Context, sector storage.SectorRef, return nil, xerrors.Errorf("removing source data: %w", err) } - return nil, nil - }) -} - -func (l *LocalWorker) ReadPiece(ctx context.Context, writer io.Writer, sector storage.SectorRef, index storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (storiface.CallID, error) { - sb, err := l.executor() - if err != nil { - return storiface.UndefCall, err - } + log.Debugf("worker has unsealed piece, sector=%+v", sector.ID) - return l.asyncCall(ctx, sector, ReadPiece, func(ctx context.Context, ci storiface.CallID) (interface{}, error) { - return sb.ReadPiece(ctx, writer, sector, index, size) + return nil, nil }) } @@ -511,7 +509,8 @@ func (l *LocalWorker) Info(context.Context) (storiface.WorkerInfo, error) { } return storiface.WorkerInfo{ - Hostname: hostname, + Hostname: hostname, + IgnoreResources: l.ignoreResources, Resources: storiface.WorkerResources{ MemPhysical: mem.Total, MemSwap: memSwap, diff --git a/extern/sector-storage/worker_tracked.go b/extern/sector-storage/worker_tracked.go index aeb3eea748a..2160dd8e6a8 100644 --- a/extern/sector-storage/worker_tracked.go +++ b/extern/sector-storage/worker_tracked.go @@ -2,7 +2,6 @@ package sectorstorage import ( "context" - "io" "sync" "time" @@ -156,8 +155,4 @@ func (t *trackedWorker) UnsealPiece(ctx context.Context, id storage.SectorRef, i return t.tracker.track(ctx, t.wid, t.workerInfo, id, sealtasks.TTUnseal)(t.Worker.UnsealPiece(ctx, id, index, size, randomness, cid)) } -func (t *trackedWorker) ReadPiece(ctx context.Context, writer io.Writer, id storage.SectorRef, index storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (storiface.CallID, error) { - return t.tracker.track(ctx, t.wid, t.workerInfo, id, sealtasks.TTReadUnsealed)(t.Worker.ReadPiece(ctx, writer, id, index, size)) -} - var _ Worker = &trackedWorker{} diff --git a/extern/storage-sealing/commit_batch.go b/extern/storage-sealing/commit_batch.go index 7d128fe76b7..097d55a1ad9 100644 --- a/extern/storage-sealing/commit_batch.go +++ b/extern/storage-sealing/commit_batch.go @@ -7,6 +7,10 @@ import ( "sync" "time" + "github.com/filecoin-project/go-state-types/network" + + "github.com/filecoin-project/lotus/chain/actors" + "github.com/ipfs/go-cid" "golang.org/x/xerrors" @@ -23,23 +27,28 @@ import ( "github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper" "github.com/filecoin-project/lotus/extern/storage-sealing/sealiface" + "github.com/filecoin-project/lotus/node/config" ) const arp = abi.RegisteredAggregationProof_SnarkPackV1 +//go:generate go run github.com/golang/mock/mockgen -destination=mocks/mock_commit_batcher.go -package=mocks . CommitBatcherApi + type CommitBatcherApi interface { SendMsg(ctx context.Context, from, to address.Address, method abi.MethodNum, value, maxFee abi.TokenAmount, params []byte) (cid.Cid, error) StateMinerInfo(context.Context, address.Address, TipSetToken) (miner.MinerInfo, error) ChainHead(ctx context.Context) (TipSetToken, abi.ChainEpoch, error) + ChainBaseFee(context.Context, TipSetToken) (abi.TokenAmount, error) StateSectorPreCommitInfo(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok TipSetToken) (*miner.SectorPreCommitOnChainInfo, error) StateMinerInitialPledgeCollateral(context.Context, address.Address, miner.SectorPreCommitInfo, TipSetToken) (big.Int, error) + StateNetworkVersion(ctx context.Context, tok TipSetToken) (network.Version, error) } type AggregateInput struct { - spt abi.RegisteredSealProof - info proof5.AggregateSealVerifyInfo - proof []byte + Spt abi.RegisteredSealProof + Info proof5.AggregateSealVerifyInfo + Proof []byte } type CommitBatcher struct { @@ -47,20 +56,20 @@ type CommitBatcher struct { maddr address.Address mctx context.Context addrSel AddrSel - feeCfg FeeConfig + feeCfg config.MinerFeeConfig getConfig GetSealingConfigFunc prover ffiwrapper.Prover - deadlines map[abi.SectorNumber]time.Time - todo map[abi.SectorNumber]AggregateInput - waiting map[abi.SectorNumber][]chan sealiface.CommitBatchRes + cutoffs map[abi.SectorNumber]time.Time + todo map[abi.SectorNumber]AggregateInput + waiting map[abi.SectorNumber][]chan sealiface.CommitBatchRes notify, stop, stopped chan struct{} force chan chan []sealiface.CommitBatchRes lk sync.Mutex } -func NewCommitBatcher(mctx context.Context, maddr address.Address, api CommitBatcherApi, addrSel AddrSel, feeCfg FeeConfig, getConfig GetSealingConfigFunc, prov ffiwrapper.Prover) *CommitBatcher { +func NewCommitBatcher(mctx context.Context, maddr address.Address, api CommitBatcherApi, addrSel AddrSel, feeCfg config.MinerFeeConfig, getConfig GetSealingConfigFunc, prov ffiwrapper.Prover) *CommitBatcher { b := &CommitBatcher{ api: api, maddr: maddr, @@ -70,9 +79,9 @@ func NewCommitBatcher(mctx context.Context, maddr address.Address, api CommitBat getConfig: getConfig, prover: prov, - deadlines: map[abi.SectorNumber]time.Time{}, - todo: map[abi.SectorNumber]AggregateInput{}, - waiting: map[abi.SectorNumber][]chan sealiface.CommitBatchRes{}, + cutoffs: map[abi.SectorNumber]time.Time{}, + todo: map[abi.SectorNumber]AggregateInput{}, + waiting: map[abi.SectorNumber][]chan sealiface.CommitBatchRes{}, notify: make(chan struct{}, 1), force: make(chan chan []sealiface.CommitBatchRes), @@ -101,7 +110,8 @@ func (b *CommitBatcher) run() { } lastMsg = nil - var sendAboveMax, sendAboveMin bool + // indicates whether we should only start a batch if we have reached or exceeded cfg.MaxCommitBatch + var sendAboveMax bool select { case <-b.stop: close(b.stopped) @@ -109,13 +119,13 @@ func (b *CommitBatcher) run() { case <-b.notify: sendAboveMax = true case <-b.batchWait(cfg.CommitBatchWait, cfg.CommitBatchSlack): - sendAboveMin = true + // do nothing case fr := <-b.force: // user triggered forceRes = fr } var err error - lastMsg, err = b.maybeStartBatch(sendAboveMax, sendAboveMin) + lastMsg, err = b.maybeStartBatch(sendAboveMax) if err != nil { log.Warnw("CommitBatcher processBatch error", "error", err) } @@ -132,30 +142,30 @@ func (b *CommitBatcher) batchWait(maxWait, slack time.Duration) <-chan time.Time return nil } - var deadline time.Time + var cutoff time.Time for sn := range b.todo { - sectorDeadline := b.deadlines[sn] - if deadline.IsZero() || (!sectorDeadline.IsZero() && sectorDeadline.Before(deadline)) { - deadline = sectorDeadline + sectorCutoff := b.cutoffs[sn] + if cutoff.IsZero() || (!sectorCutoff.IsZero() && sectorCutoff.Before(cutoff)) { + cutoff = sectorCutoff } } for sn := range b.waiting { - sectorDeadline := b.deadlines[sn] - if deadline.IsZero() || (!sectorDeadline.IsZero() && sectorDeadline.Before(deadline)) { - deadline = sectorDeadline + sectorCutoff := b.cutoffs[sn] + if cutoff.IsZero() || (!sectorCutoff.IsZero() && sectorCutoff.Before(cutoff)) { + cutoff = sectorCutoff } } - if deadline.IsZero() { + if cutoff.IsZero() { return time.After(maxWait) } - deadline = deadline.Add(-slack) - if deadline.Before(now) { + cutoff = cutoff.Add(-slack) + if cutoff.Before(now) { return time.After(time.Nanosecond) // can't return 0 } - wait := deadline.Sub(now) + wait := cutoff.Sub(now) if wait > maxWait { wait = maxWait } @@ -163,7 +173,7 @@ func (b *CommitBatcher) batchWait(maxWait, slack time.Duration) <-chan time.Time return time.After(wait) } -func (b *CommitBatcher) maybeStartBatch(notif, after bool) ([]sealiface.CommitBatchRes, error) { +func (b *CommitBatcher) maybeStartBatch(notif bool) ([]sealiface.CommitBatchRes, error) { b.lk.Lock() defer b.lk.Unlock() @@ -181,10 +191,6 @@ func (b *CommitBatcher) maybeStartBatch(notif, after bool) ([]sealiface.CommitBa return nil, nil } - if after && total < cfg.MinCommitBatch { - return nil, nil - } - var res []sealiface.CommitBatchRes if total < cfg.MinCommitBatch || total < miner5.MinAggregatedSectors { @@ -208,7 +214,7 @@ func (b *CommitBatcher) maybeStartBatch(notif, after bool) ([]sealiface.CommitBa delete(b.waiting, sn) delete(b.todo, sn) - delete(b.deadlines, sn) + delete(b.cutoffs, sn) } } @@ -239,6 +245,8 @@ func (b *CommitBatcher) processBatch(cfg sealiface.Config) ([]sealiface.CommitBa break } + res.Sectors = append(res.Sectors, id) + sc, err := b.getSectorCollateral(id, tok) if err != nil { res.FailedSectors[id] = err.Error() @@ -247,9 +255,8 @@ func (b *CommitBatcher) processBatch(cfg sealiface.Config) ([]sealiface.CommitBa collateral = big.Add(collateral, sc) - res.Sectors = append(res.Sectors, id) params.SectorNumbers.Set(uint64(id)) - infos = append(infos, p.info) + infos = append(infos, p.Info) } sort.Slice(infos, func(i, j int) bool { @@ -257,7 +264,7 @@ func (b *CommitBatcher) processBatch(cfg sealiface.Config) ([]sealiface.CommitBa }) for _, info := range infos { - proofs = append(proofs, b.todo[info.Number].proof) + proofs = append(proofs, b.todo[info.Number].Proof) } mid, err := address.IDFromAddress(b.maddr) @@ -267,7 +274,7 @@ func (b *CommitBatcher) processBatch(cfg sealiface.Config) ([]sealiface.CommitBa params.AggregateProof, err = b.prover.AggregateSealProofs(proof5.AggregateSealVerifyProofAndInfos{ Miner: abi.ActorID(mid), - SealProof: b.todo[infos[0].Number].spt, + SealProof: b.todo[infos[0].Number].Spt, AggregateProof: arp, Infos: infos, }, proofs) @@ -285,14 +292,29 @@ func (b *CommitBatcher) processBatch(cfg sealiface.Config) ([]sealiface.CommitBa return []sealiface.CommitBatchRes{res}, xerrors.Errorf("couldn't get miner info: %w", err) } - goodFunds := big.Add(b.feeCfg.MaxCommitGasFee, collateral) + maxFee := b.feeCfg.MaxCommitBatchGasFee.FeeForSectors(len(infos)) + + bf, err := b.api.ChainBaseFee(b.mctx, tok) + if err != nil { + return []sealiface.CommitBatchRes{res}, xerrors.Errorf("couldn't get base fee: %w", err) + } + + nv, err := b.api.StateNetworkVersion(b.mctx, tok) + if err != nil { + log.Errorf("getting network version: %s", err) + return []sealiface.CommitBatchRes{res}, xerrors.Errorf("getting network version: %s", err) + } + + aggFee := policy.AggregateNetworkFee(nv, len(infos), bf) + + goodFunds := big.Add(maxFee, big.Add(collateral, aggFee)) from, _, err := b.addrSel(b.mctx, mi, api.CommitAddr, goodFunds, collateral) if err != nil { return []sealiface.CommitBatchRes{res}, xerrors.Errorf("no good address found: %w", err) } - mcid, err := b.api.SendMsg(b.mctx, from, b.maddr, miner.Methods.ProveCommitAggregate, collateral, b.feeCfg.MaxCommitGasFee, enc.Bytes()) + mcid, err := b.api.SendMsg(b.mctx, from, b.maddr, miner.Methods.ProveCommitAggregate, collateral, maxFee, enc.Bytes()) if err != nil { return []sealiface.CommitBatchRes{res}, xerrors.Errorf("sending message failed: %w", err) } @@ -340,7 +362,7 @@ func (b *CommitBatcher) processSingle(mi miner.MinerInfo, sn abi.SectorNumber, i enc := new(bytes.Buffer) params := &miner.ProveCommitSectorParams{ SectorNumber: sn, - Proof: info.proof, + Proof: info.Proof, } if err := params.MarshalCBOR(enc); err != nil { @@ -352,14 +374,14 @@ func (b *CommitBatcher) processSingle(mi miner.MinerInfo, sn abi.SectorNumber, i return cid.Undef, err } - goodFunds := big.Add(collateral, b.feeCfg.MaxCommitGasFee) + goodFunds := big.Add(collateral, big.Int(b.feeCfg.MaxCommitGasFee)) from, _, err := b.addrSel(b.mctx, mi, api.CommitAddr, goodFunds, collateral) if err != nil { return cid.Undef, xerrors.Errorf("no good address to send commit message from: %w", err) } - mcid, err := b.api.SendMsg(b.mctx, from, b.maddr, miner.Methods.ProveCommitSector, collateral, b.feeCfg.MaxCommitGasFee, enc.Bytes()) + mcid, err := b.api.SendMsg(b.mctx, from, b.maddr, miner.Methods.ProveCommitSector, collateral, big.Int(b.feeCfg.MaxCommitGasFee), enc.Bytes()) if err != nil { return cid.Undef, xerrors.Errorf("pushing message to mpool: %w", err) } @@ -369,16 +391,15 @@ func (b *CommitBatcher) processSingle(mi miner.MinerInfo, sn abi.SectorNumber, i // register commit, wait for batch message, return message CID func (b *CommitBatcher) AddCommit(ctx context.Context, s SectorInfo, in AggregateInput) (res sealiface.CommitBatchRes, err error) { - _, curEpoch, err := b.api.ChainHead(b.mctx) + sn := s.SectorNumber + + cu, err := b.getCommitCutoff(s) if err != nil { - log.Errorf("getting chain head: %s", err) - return sealiface.CommitBatchRes{}, nil + return sealiface.CommitBatchRes{}, err } - sn := s.SectorNumber - b.lk.Lock() - b.deadlines[sn] = getSectorDeadline(curEpoch, s) + b.cutoffs[sn] = cu b.todo[sn] = in sent := make(chan sealiface.CommitBatchRes, 1) @@ -426,7 +447,7 @@ func (b *CommitBatcher) Pending(ctx context.Context) ([]abi.SectorID, error) { for _, s := range b.todo { res = append(res, abi.SectorID{ Miner: abi.ActorID(mid), - Number: s.info.Number, + Number: s.Info.Number, }) } @@ -452,24 +473,43 @@ func (b *CommitBatcher) Stop(ctx context.Context) error { } } -func getSectorDeadline(curEpoch abi.ChainEpoch, si SectorInfo) time.Time { - deadlineEpoch := si.TicketEpoch + policy.MaxPreCommitRandomnessLookback +// TODO: If this returned epochs, it would make testing much easier +func (b *CommitBatcher) getCommitCutoff(si SectorInfo) (time.Time, error) { + tok, curEpoch, err := b.api.ChainHead(b.mctx) + if err != nil { + return time.Now(), xerrors.Errorf("getting chain head: %s", err) + } + + nv, err := b.api.StateNetworkVersion(b.mctx, tok) + if err != nil { + log.Errorf("getting network version: %s", err) + return time.Now(), xerrors.Errorf("getting network version: %s", err) + } + + pci, err := b.api.StateSectorPreCommitInfo(b.mctx, b.maddr, si.SectorNumber, tok) + if err != nil { + log.Errorf("getting precommit info: %s", err) + return time.Now(), err + } + + cutoffEpoch := pci.PreCommitEpoch + policy.GetMaxProveCommitDuration(actors.VersionForNetwork(nv), si.SectorType) + for _, p := range si.Pieces { if p.DealInfo == nil { continue } startEpoch := p.DealInfo.DealSchedule.StartEpoch - if startEpoch < deadlineEpoch { - deadlineEpoch = startEpoch + if startEpoch < cutoffEpoch { + cutoffEpoch = startEpoch } } - if deadlineEpoch <= curEpoch { - return time.Now() + if cutoffEpoch <= curEpoch { + return time.Now(), nil } - return time.Now().Add(time.Duration(deadlineEpoch-curEpoch) * time.Duration(build.BlockDelaySecs) * time.Second) + return time.Now().Add(time.Duration(cutoffEpoch-curEpoch) * time.Duration(build.BlockDelaySecs) * time.Second), nil } func (b *CommitBatcher) getSectorCollateral(sn abi.SectorNumber, tok TipSetToken) (abi.TokenAmount, error) { diff --git a/extern/storage-sealing/commit_batch_test.go b/extern/storage-sealing/commit_batch_test.go new file mode 100644 index 00000000000..ad2bc8f6f70 --- /dev/null +++ b/extern/storage-sealing/commit_batch_test.go @@ -0,0 +1,298 @@ +package sealing_test + +import ( + "bytes" + "context" + "sort" + "sync" + "testing" + "time" + + "github.com/golang/mock/gomock" + "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" + miner5 "github.com/filecoin-project/specs-actors/v5/actors/builtin/miner" + proof5 "github.com/filecoin-project/specs-actors/v5/actors/runtime/proof" + + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + "github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper" + sealing "github.com/filecoin-project/lotus/extern/storage-sealing" + "github.com/filecoin-project/lotus/extern/storage-sealing/mocks" + "github.com/filecoin-project/lotus/extern/storage-sealing/sealiface" +) + +func TestCommitBatcher(t *testing.T) { + t0123, err := address.NewFromString("t0123") + require.NoError(t, err) + + ctx := context.Background() + + as := func(ctx context.Context, mi miner.MinerInfo, use api.AddrUse, goodFunds, minFunds abi.TokenAmount) (address.Address, abi.TokenAmount, error) { + return t0123, big.Zero(), nil + } + + maxBatch := miner5.MaxAggregatedSectors + minBatch := miner5.MinAggregatedSectors + + cfg := func() (sealiface.Config, error) { + return sealiface.Config{ + MaxWaitDealsSectors: 2, + MaxSealingSectors: 0, + MaxSealingSectorsForDeals: 0, + WaitDealsDelay: time.Hour * 6, + AlwaysKeepUnsealedCopy: true, + + BatchPreCommits: true, + MaxPreCommitBatch: miner5.PreCommitSectorBatchMaxSize, + PreCommitBatchWait: 24 * time.Hour, + PreCommitBatchSlack: 3 * time.Hour, + + AggregateCommits: true, + MinCommitBatch: minBatch, + MaxCommitBatch: maxBatch, + CommitBatchWait: 24 * time.Hour, + CommitBatchSlack: 1 * time.Hour, + + TerminateBatchMin: 1, + TerminateBatchMax: 100, + TerminateBatchWait: 5 * time.Minute, + }, nil + } + + type promise func(t *testing.T) + type action func(t *testing.T, s *mocks.MockCommitBatcherApi, pcb *sealing.CommitBatcher) promise + + actions := func(as ...action) action { + return func(t *testing.T, s *mocks.MockCommitBatcherApi, pcb *sealing.CommitBatcher) promise { + var ps []promise + for _, a := range as { + p := a(t, s, pcb) + if p != nil { + ps = append(ps, p) + } + } + + if len(ps) > 0 { + return func(t *testing.T) { + for _, p := range ps { + p(t) + } + } + } + return nil + } + } + + addSector := func(sn abi.SectorNumber) action { + return func(t *testing.T, s *mocks.MockCommitBatcherApi, pcb *sealing.CommitBatcher) promise { + var pcres sealiface.CommitBatchRes + var pcerr error + done := sync.Mutex{} + done.Lock() + + si := sealing.SectorInfo{ + SectorNumber: sn, + } + + s.EXPECT().ChainHead(gomock.Any()).Return(nil, abi.ChainEpoch(1), nil) + s.EXPECT().StateNetworkVersion(gomock.Any(), gomock.Any()).Return(network.Version13, nil) + s.EXPECT().StateSectorPreCommitInfo(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(&miner.SectorPreCommitOnChainInfo{ + PreCommitDeposit: big.Zero(), + }, nil) + + go func() { + defer done.Unlock() + pcres, pcerr = pcb.AddCommit(ctx, si, sealing.AggregateInput{ + Info: proof5.AggregateSealVerifyInfo{ + Number: sn, + }, + }) + }() + + return func(t *testing.T) { + done.Lock() + require.NoError(t, pcerr) + require.Empty(t, pcres.Error) + require.Contains(t, pcres.Sectors, si.SectorNumber) + } + } + } + + addSectors := func(sectors []abi.SectorNumber) action { + as := make([]action, len(sectors)) + for i, sector := range sectors { + as[i] = addSector(sector) + } + return actions(as...) + } + + waitPending := func(n int) action { + return func(t *testing.T, s *mocks.MockCommitBatcherApi, pcb *sealing.CommitBatcher) promise { + require.Eventually(t, func() bool { + p, err := pcb.Pending(ctx) + require.NoError(t, err) + return len(p) == n + }, time.Second*5, 10*time.Millisecond) + + return nil + } + } + + expectSend := func(expect []abi.SectorNumber) action { + return func(t *testing.T, s *mocks.MockCommitBatcherApi, pcb *sealing.CommitBatcher) promise { + s.EXPECT().StateMinerInfo(gomock.Any(), gomock.Any(), gomock.Any()).Return(miner.MinerInfo{Owner: t0123, Worker: t0123}, nil) + + ti := len(expect) + batch := false + if ti >= minBatch { + batch = true + ti = 1 + } + s.EXPECT().ChainHead(gomock.Any()).Return(nil, abi.ChainEpoch(1), nil) + s.EXPECT().StateSectorPreCommitInfo(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(&miner.SectorPreCommitOnChainInfo{ + PreCommitDeposit: big.Zero(), + }, nil).Times(len(expect)) + s.EXPECT().StateMinerInitialPledgeCollateral(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(big.Zero(), nil).Times(len(expect)) + if batch { + s.EXPECT().StateNetworkVersion(gomock.Any(), gomock.Any()).Return(network.Version13, nil) + s.EXPECT().ChainBaseFee(gomock.Any(), gomock.Any()).Return(big.NewInt(2000), nil) + } + + s.EXPECT().SendMsg(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), funMatcher(func(i interface{}) bool { + b := i.([]byte) + if batch { + var params miner5.ProveCommitAggregateParams + require.NoError(t, params.UnmarshalCBOR(bytes.NewReader(b))) + for _, number := range expect { + set, err := params.SectorNumbers.IsSet(uint64(number)) + require.NoError(t, err) + require.True(t, set) + } + } else { + var params miner5.ProveCommitSectorParams + require.NoError(t, params.UnmarshalCBOR(bytes.NewReader(b))) + } + return true + })).Times(ti) + return nil + } + } + + flush := func(expect []abi.SectorNumber) action { + return func(t *testing.T, s *mocks.MockCommitBatcherApi, pcb *sealing.CommitBatcher) promise { + _ = expectSend(expect)(t, s, pcb) + + batch := len(expect) >= minBatch + + r, err := pcb.Flush(ctx) + require.NoError(t, err) + if batch { + require.Len(t, r, 1) + require.Empty(t, r[0].Error) + sort.Slice(r[0].Sectors, func(i, j int) bool { + return r[0].Sectors[i] < r[0].Sectors[j] + }) + require.Equal(t, expect, r[0].Sectors) + } else { + require.Len(t, r, len(expect)) + for _, res := range r { + require.Len(t, res.Sectors, 1) + require.Empty(t, res.Error) + } + sort.Slice(r, func(i, j int) bool { + return r[i].Sectors[0] < r[j].Sectors[0] + }) + for i, res := range r { + require.Equal(t, abi.SectorNumber(i), res.Sectors[0]) + } + } + + return nil + } + } + + getSectors := func(n int) []abi.SectorNumber { + out := make([]abi.SectorNumber, n) + for i := range out { + out[i] = abi.SectorNumber(i) + } + return out + } + + tcs := map[string]struct { + actions []action + }{ + "addSingle": { + actions: []action{ + addSector(0), + waitPending(1), + flush([]abi.SectorNumber{0}), + }, + }, + "addTwo": { + actions: []action{ + addSectors(getSectors(2)), + waitPending(2), + flush(getSectors(2)), + }, + }, + "addAte": { + actions: []action{ + addSectors(getSectors(8)), + waitPending(8), + flush(getSectors(8)), + }, + }, + "addMax": { + actions: []action{ + expectSend(getSectors(maxBatch)), + addSectors(getSectors(maxBatch)), + }, + }, + } + + for name, tc := range tcs { + tc := tc + + t.Run(name, func(t *testing.T) { + // create go mock controller here + mockCtrl := gomock.NewController(t) + // when test is done, assert expectations on all mock objects. + defer mockCtrl.Finish() + + // create them mocks + pcapi := mocks.NewMockCommitBatcherApi(mockCtrl) + + pcb := sealing.NewCommitBatcher(ctx, t0123, pcapi, as, fc, cfg, &fakeProver{}) + + var promises []promise + + for _, a := range tc.actions { + p := a(t, pcapi, pcb) + if p != nil { + promises = append(promises, p) + } + } + + for _, p := range promises { + p(t) + } + + err := pcb.Stop(ctx) + require.NoError(t, err) + }) + } +} + +type fakeProver struct{} + +func (f fakeProver) AggregateSealProofs(aggregateInfo proof5.AggregateSealVerifyProofAndInfos, proofs [][]byte) ([]byte, error) { + return []byte("Trust me, I'm a proof"), nil +} + +var _ ffiwrapper.Prover = &fakeProver{} diff --git a/extern/storage-sealing/fsm.go b/extern/storage-sealing/fsm.go index 640aaf19aaf..d3e1e9d5283 100644 --- a/extern/storage-sealing/fsm.go +++ b/extern/storage-sealing/fsm.go @@ -103,6 +103,10 @@ var fsmPlanners = map[SectorState]func(events []statemachine.Event, state *Secto on(SectorChainPreCommitFailed{}, PreCommitFailed), ), Committing: planCommitting, + CommitFinalize: planOne( + on(SectorFinalized{}, SubmitCommit), + on(SectorFinalizeFailed{}, CommitFinalizeFailed), + ), SubmitCommit: planOne( on(SectorCommitSubmitted{}, CommitWait), on(SectorSubmitCommitAggregate{}, SubmitCommitAggregate), @@ -151,6 +155,9 @@ var fsmPlanners = map[SectorState]func(events []statemachine.Event, state *Secto on(SectorRetryComputeProof{}, Committing), on(SectorSealPreCommit1Failed{}, SealPreCommit1Failed), ), + CommitFinalizeFailed: planOne( + on(SectorRetryFinalize{}, CommitFinalize), + ), CommitFailed: planOne( on(SectorSealPreCommit1Failed{}, SealPreCommit1Failed), on(SectorRetryWaitSeed{}, WaitSeed), @@ -379,6 +386,8 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta fallthrough case CommitWait: return m.handleCommitWait, processed, nil + case CommitFinalize: + fallthrough case FinalizeSector: return m.handleFinalizeSector, processed, nil @@ -393,6 +402,8 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta return m.handleComputeProofFailed, processed, nil case CommitFailed: return m.handleCommitFailed, processed, nil + case CommitFinalizeFailed: + fallthrough case FinalizeFailed: return m.handleFinalizeFailed, processed, nil case PackingFailed: // DEPRECATED: remove this for the next reset @@ -482,6 +493,9 @@ func planCommitting(events []statemachine.Event, state *SectorInfo) (uint64, err case SectorCommitted: // the normal case e.apply(state) state.State = SubmitCommit + case SectorProofReady: // early finalize + e.apply(state) + state.State = CommitFinalize case SectorSeedReady: // seed changed :/ if e.SeedEpoch == state.SeedEpoch && bytes.Equal(e.SeedValue, state.SeedValue) { log.Warnf("planCommitting: got SectorSeedReady, but the seed didn't change") @@ -508,6 +522,8 @@ func planCommitting(events []statemachine.Event, state *SectorInfo) (uint64, err } func (m *Sealing) restartSectors(ctx context.Context) error { + defer m.startupWait.Done() + trackedSectors, err := m.ListSectors() if err != nil { log.Errorf("loading sector list: %+v", err) @@ -525,6 +541,7 @@ func (m *Sealing) restartSectors(ctx context.Context) error { } func (m *Sealing) ForceSectorState(ctx context.Context, id abi.SectorNumber, state SectorState) error { + m.startupWait.Wait() return m.sectors.Send(id, SectorForceState{state}) } diff --git a/extern/storage-sealing/fsm_events.go b/extern/storage-sealing/fsm_events.go index 7ec8f3dfce2..3dab6d40356 100644 --- a/extern/storage-sealing/fsm_events.go +++ b/extern/storage-sealing/fsm_events.go @@ -245,6 +245,15 @@ func (evt SectorCommitted) apply(state *SectorInfo) { state.Proof = evt.Proof } +// like SectorCommitted, but finalizes before sending the proof to the chain +type SectorProofReady struct { + Proof []byte +} + +func (evt SectorProofReady) apply(state *SectorInfo) { + state.Proof = evt.Proof +} + type SectorSubmitCommitAggregate struct{} func (evt SectorSubmitCommitAggregate) apply(*SectorInfo) {} diff --git a/extern/storage-sealing/fsm_test.go b/extern/storage-sealing/fsm_test.go index f3d6d87d1d2..1d2df27846e 100644 --- a/extern/storage-sealing/fsm_test.go +++ b/extern/storage-sealing/fsm_test.go @@ -87,6 +87,112 @@ func TestHappyPath(t *testing.T) { } } +func TestHappyPathFinalizeEarly(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: Packing}, + } + + m.planSingle(SectorPacked{}) + require.Equal(m.t, m.state.State, GetTicket) + + m.planSingle(SectorTicket{}) + require.Equal(m.t, m.state.State, PreCommit1) + + m.planSingle(SectorPreCommit1{}) + require.Equal(m.t, m.state.State, PreCommit2) + + m.planSingle(SectorPreCommit2{}) + require.Equal(m.t, m.state.State, PreCommitting) + + m.planSingle(SectorPreCommitted{}) + require.Equal(m.t, m.state.State, PreCommitWait) + + m.planSingle(SectorPreCommitLanded{}) + require.Equal(m.t, m.state.State, WaitSeed) + + m.planSingle(SectorSeedReady{}) + require.Equal(m.t, m.state.State, Committing) + + m.planSingle(SectorProofReady{}) + require.Equal(m.t, m.state.State, CommitFinalize) + + m.planSingle(SectorFinalized{}) + require.Equal(m.t, m.state.State, SubmitCommit) + + m.planSingle(SectorSubmitCommitAggregate{}) + require.Equal(m.t, m.state.State, SubmitCommitAggregate) + + m.planSingle(SectorCommitAggregateSent{}) + require.Equal(m.t, m.state.State, CommitWait) + + m.planSingle(SectorProving{}) + require.Equal(m.t, m.state.State, FinalizeSector) + + m.planSingle(SectorFinalized{}) + require.Equal(m.t, m.state.State, Proving) + + expected := []SectorState{Packing, GetTicket, PreCommit1, PreCommit2, PreCommitting, PreCommitWait, WaitSeed, Committing, CommitFinalize, SubmitCommit, SubmitCommitAggregate, CommitWait, FinalizeSector, Proving} + 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) + } + } +} + +func TestCommitFinalizeFailed(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: Committing}, + } + + m.planSingle(SectorProofReady{}) + require.Equal(m.t, m.state.State, CommitFinalize) + + m.planSingle(SectorFinalizeFailed{}) + require.Equal(m.t, m.state.State, CommitFinalizeFailed) + + m.planSingle(SectorRetryFinalize{}) + require.Equal(m.t, m.state.State, CommitFinalize) + + m.planSingle(SectorFinalized{}) + require.Equal(m.t, m.state.State, SubmitCommit) + + expected := []SectorState{Committing, CommitFinalize, CommitFinalizeFailed, CommitFinalize, SubmitCommit} + 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) + } + } +} func TestSeedRevert(t *testing.T) { ma, _ := address.NewIDAddress(55151) m := test{ diff --git a/extern/storage-sealing/garbage.go b/extern/storage-sealing/garbage.go index c8ec21a84d8..d429b5b438d 100644 --- a/extern/storage-sealing/garbage.go +++ b/extern/storage-sealing/garbage.go @@ -9,6 +9,8 @@ import ( ) func (m *Sealing) PledgeSector(ctx context.Context) (storage.SectorRef, error) { + m.startupWait.Wait() + m.inputLk.Lock() defer m.inputLk.Unlock() diff --git a/extern/storage-sealing/input.go b/extern/storage-sealing/input.go index bf66382d370..85a5c429f4d 100644 --- a/extern/storage-sealing/input.go +++ b/extern/storage-sealing/input.go @@ -394,6 +394,8 @@ func (m *Sealing) updateInput(ctx context.Context, sp abi.RegisteredSealProof) e } func (m *Sealing) tryCreateDealSector(ctx context.Context, sp abi.RegisteredSealProof) error { + m.startupWait.Wait() + if m.creating != nil { return nil // new sector is being created right now } @@ -446,6 +448,8 @@ func (m *Sealing) createSector(ctx context.Context, cfg sealiface.Config, sp abi } func (m *Sealing) StartPacking(sid abi.SectorNumber) error { + m.startupWait.Wait() + log.Infow("starting to seal deal sector", "sector", sid, "trigger", "user") return m.sectors.Send(uint64(sid), SectorStartPacking{}) } diff --git a/extern/storage-sealing/mocks/mock_commit_batcher.go b/extern/storage-sealing/mocks/mock_commit_batcher.go new file mode 100644 index 00000000000..c4746e0ebf7 --- /dev/null +++ b/extern/storage-sealing/mocks/mock_commit_batcher.go @@ -0,0 +1,149 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/filecoin-project/lotus/extern/storage-sealing (interfaces: CommitBatcherApi) + +// Package mocks is a generated GoMock package. +package mocks + +import ( + context "context" + reflect "reflect" + + 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" + network "github.com/filecoin-project/go-state-types/network" + miner "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + sealing "github.com/filecoin-project/lotus/extern/storage-sealing" + miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" + gomock "github.com/golang/mock/gomock" + cid "github.com/ipfs/go-cid" +) + +// MockCommitBatcherApi is a mock of CommitBatcherApi interface. +type MockCommitBatcherApi struct { + ctrl *gomock.Controller + recorder *MockCommitBatcherApiMockRecorder +} + +// MockCommitBatcherApiMockRecorder is the mock recorder for MockCommitBatcherApi. +type MockCommitBatcherApiMockRecorder struct { + mock *MockCommitBatcherApi +} + +// NewMockCommitBatcherApi creates a new mock instance. +func NewMockCommitBatcherApi(ctrl *gomock.Controller) *MockCommitBatcherApi { + mock := &MockCommitBatcherApi{ctrl: ctrl} + mock.recorder = &MockCommitBatcherApiMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockCommitBatcherApi) EXPECT() *MockCommitBatcherApiMockRecorder { + return m.recorder +} + +// ChainBaseFee mocks base method. +func (m *MockCommitBatcherApi) ChainBaseFee(arg0 context.Context, arg1 sealing.TipSetToken) (big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainBaseFee", arg0, arg1) + ret0, _ := ret[0].(big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainBaseFee indicates an expected call of ChainBaseFee. +func (mr *MockCommitBatcherApiMockRecorder) ChainBaseFee(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainBaseFee", reflect.TypeOf((*MockCommitBatcherApi)(nil).ChainBaseFee), arg0, arg1) +} + +// ChainHead mocks base method. +func (m *MockCommitBatcherApi) ChainHead(arg0 context.Context) (sealing.TipSetToken, abi.ChainEpoch, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainHead", arg0) + ret0, _ := ret[0].(sealing.TipSetToken) + ret1, _ := ret[1].(abi.ChainEpoch) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// ChainHead indicates an expected call of ChainHead. +func (mr *MockCommitBatcherApiMockRecorder) ChainHead(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainHead", reflect.TypeOf((*MockCommitBatcherApi)(nil).ChainHead), arg0) +} + +// SendMsg mocks base method. +func (m *MockCommitBatcherApi) SendMsg(arg0 context.Context, arg1, arg2 address.Address, arg3 abi.MethodNum, arg4, arg5 big.Int, arg6 []byte) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SendMsg", arg0, arg1, arg2, arg3, arg4, arg5, arg6) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SendMsg indicates an expected call of SendMsg. +func (mr *MockCommitBatcherApiMockRecorder) SendMsg(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMsg", reflect.TypeOf((*MockCommitBatcherApi)(nil).SendMsg), arg0, arg1, arg2, arg3, arg4, arg5, arg6) +} + +// StateMinerInfo mocks base method. +func (m *MockCommitBatcherApi) StateMinerInfo(arg0 context.Context, arg1 address.Address, arg2 sealing.TipSetToken) (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 *MockCommitBatcherApiMockRecorder) StateMinerInfo(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerInfo", reflect.TypeOf((*MockCommitBatcherApi)(nil).StateMinerInfo), arg0, arg1, arg2) +} + +// StateMinerInitialPledgeCollateral mocks base method. +func (m *MockCommitBatcherApi) StateMinerInitialPledgeCollateral(arg0 context.Context, arg1 address.Address, arg2 miner0.SectorPreCommitInfo, arg3 sealing.TipSetToken) (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 *MockCommitBatcherApiMockRecorder) StateMinerInitialPledgeCollateral(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerInitialPledgeCollateral", reflect.TypeOf((*MockCommitBatcherApi)(nil).StateMinerInitialPledgeCollateral), arg0, arg1, arg2, arg3) +} + +// StateNetworkVersion mocks base method. +func (m *MockCommitBatcherApi) StateNetworkVersion(arg0 context.Context, arg1 sealing.TipSetToken) (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 *MockCommitBatcherApiMockRecorder) StateNetworkVersion(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateNetworkVersion", reflect.TypeOf((*MockCommitBatcherApi)(nil).StateNetworkVersion), arg0, arg1) +} + +// StateSectorPreCommitInfo mocks base method. +func (m *MockCommitBatcherApi) StateSectorPreCommitInfo(arg0 context.Context, arg1 address.Address, arg2 abi.SectorNumber, arg3 sealing.TipSetToken) (*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 *MockCommitBatcherApiMockRecorder) StateSectorPreCommitInfo(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSectorPreCommitInfo", reflect.TypeOf((*MockCommitBatcherApi)(nil).StateSectorPreCommitInfo), arg0, arg1, arg2, arg3) +} diff --git a/extern/storage-sealing/mocks/mock_precommit_batcher.go b/extern/storage-sealing/mocks/mock_precommit_batcher.go new file mode 100644 index 00000000000..4a50740271c --- /dev/null +++ b/extern/storage-sealing/mocks/mock_precommit_batcher.go @@ -0,0 +1,87 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/filecoin-project/lotus/extern/storage-sealing (interfaces: PreCommitBatcherApi) + +// Package mocks is a generated GoMock package. +package mocks + +import ( + context "context" + reflect "reflect" + + 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" + miner "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + sealing "github.com/filecoin-project/lotus/extern/storage-sealing" + gomock "github.com/golang/mock/gomock" + cid "github.com/ipfs/go-cid" +) + +// MockPreCommitBatcherApi is a mock of PreCommitBatcherApi interface. +type MockPreCommitBatcherApi struct { + ctrl *gomock.Controller + recorder *MockPreCommitBatcherApiMockRecorder +} + +// MockPreCommitBatcherApiMockRecorder is the mock recorder for MockPreCommitBatcherApi. +type MockPreCommitBatcherApiMockRecorder struct { + mock *MockPreCommitBatcherApi +} + +// NewMockPreCommitBatcherApi creates a new mock instance. +func NewMockPreCommitBatcherApi(ctrl *gomock.Controller) *MockPreCommitBatcherApi { + mock := &MockPreCommitBatcherApi{ctrl: ctrl} + mock.recorder = &MockPreCommitBatcherApiMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockPreCommitBatcherApi) EXPECT() *MockPreCommitBatcherApiMockRecorder { + return m.recorder +} + +// ChainHead mocks base method. +func (m *MockPreCommitBatcherApi) ChainHead(arg0 context.Context) (sealing.TipSetToken, abi.ChainEpoch, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainHead", arg0) + ret0, _ := ret[0].(sealing.TipSetToken) + ret1, _ := ret[1].(abi.ChainEpoch) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// ChainHead indicates an expected call of ChainHead. +func (mr *MockPreCommitBatcherApiMockRecorder) ChainHead(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainHead", reflect.TypeOf((*MockPreCommitBatcherApi)(nil).ChainHead), arg0) +} + +// SendMsg mocks base method. +func (m *MockPreCommitBatcherApi) SendMsg(arg0 context.Context, arg1, arg2 address.Address, arg3 abi.MethodNum, arg4, arg5 big.Int, arg6 []byte) (cid.Cid, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SendMsg", arg0, arg1, arg2, arg3, arg4, arg5, arg6) + ret0, _ := ret[0].(cid.Cid) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SendMsg indicates an expected call of SendMsg. +func (mr *MockPreCommitBatcherApiMockRecorder) SendMsg(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMsg", reflect.TypeOf((*MockPreCommitBatcherApi)(nil).SendMsg), arg0, arg1, arg2, arg3, arg4, arg5, arg6) +} + +// StateMinerInfo mocks base method. +func (m *MockPreCommitBatcherApi) StateMinerInfo(arg0 context.Context, arg1 address.Address, arg2 sealing.TipSetToken) (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 *MockPreCommitBatcherApiMockRecorder) StateMinerInfo(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateMinerInfo", reflect.TypeOf((*MockPreCommitBatcherApi)(nil).StateMinerInfo), arg0, arg1, arg2) +} diff --git a/extern/storage-sealing/precommit_batch.go b/extern/storage-sealing/precommit_batch.go index dd674d331b2..3dc3510c282 100644 --- a/extern/storage-sealing/precommit_batch.go +++ b/extern/storage-sealing/precommit_batch.go @@ -7,6 +7,9 @@ import ( "sync" "time" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/actors/policy" + "github.com/ipfs/go-cid" "golang.org/x/xerrors" @@ -19,8 +22,11 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" "github.com/filecoin-project/lotus/extern/storage-sealing/sealiface" + "github.com/filecoin-project/lotus/node/config" ) +//go:generate go run github.com/golang/mock/mockgen -destination=mocks/mock_precommit_batcher.go -package=mocks . PreCommitBatcherApi + type PreCommitBatcherApi interface { SendMsg(ctx context.Context, from, to address.Address, method abi.MethodNum, value, maxFee abi.TokenAmount, params []byte) (cid.Cid, error) StateMinerInfo(context.Context, address.Address, TipSetToken) (miner.MinerInfo, error) @@ -37,19 +43,19 @@ type PreCommitBatcher struct { maddr address.Address mctx context.Context addrSel AddrSel - feeCfg FeeConfig + feeCfg config.MinerFeeConfig getConfig GetSealingConfigFunc - deadlines map[abi.SectorNumber]time.Time - todo map[abi.SectorNumber]*preCommitEntry - waiting map[abi.SectorNumber][]chan sealiface.PreCommitBatchRes + cutoffs map[abi.SectorNumber]time.Time + todo map[abi.SectorNumber]*preCommitEntry + waiting map[abi.SectorNumber][]chan sealiface.PreCommitBatchRes notify, stop, stopped chan struct{} force chan chan []sealiface.PreCommitBatchRes lk sync.Mutex } -func NewPreCommitBatcher(mctx context.Context, maddr address.Address, api PreCommitBatcherApi, addrSel AddrSel, feeCfg FeeConfig, getConfig GetSealingConfigFunc) *PreCommitBatcher { +func NewPreCommitBatcher(mctx context.Context, maddr address.Address, api PreCommitBatcherApi, addrSel AddrSel, feeCfg config.MinerFeeConfig, getConfig GetSealingConfigFunc) *PreCommitBatcher { b := &PreCommitBatcher{ api: api, maddr: maddr, @@ -58,9 +64,9 @@ func NewPreCommitBatcher(mctx context.Context, maddr address.Address, api PreCom feeCfg: feeCfg, getConfig: getConfig, - deadlines: map[abi.SectorNumber]time.Time{}, - todo: map[abi.SectorNumber]*preCommitEntry{}, - waiting: map[abi.SectorNumber][]chan sealiface.PreCommitBatchRes{}, + cutoffs: map[abi.SectorNumber]time.Time{}, + todo: map[abi.SectorNumber]*preCommitEntry{}, + waiting: map[abi.SectorNumber][]chan sealiface.PreCommitBatchRes{}, notify: make(chan struct{}, 1), force: make(chan chan []sealiface.PreCommitBatchRes), @@ -89,7 +95,7 @@ func (b *PreCommitBatcher) run() { } lastRes = nil - var sendAboveMax, sendAboveMin bool + var sendAboveMax bool select { case <-b.stop: close(b.stopped) @@ -97,13 +103,13 @@ func (b *PreCommitBatcher) run() { case <-b.notify: sendAboveMax = true case <-b.batchWait(cfg.PreCommitBatchWait, cfg.PreCommitBatchSlack): - sendAboveMin = true + // do nothing case fr := <-b.force: // user triggered forceRes = fr } var err error - lastRes, err = b.maybeStartBatch(sendAboveMax, sendAboveMin) + lastRes, err = b.maybeStartBatch(sendAboveMax) if err != nil { log.Warnw("PreCommitBatcher processBatch error", "error", err) } @@ -120,30 +126,30 @@ func (b *PreCommitBatcher) batchWait(maxWait, slack time.Duration) <-chan time.T return nil } - var deadline time.Time + var cutoff time.Time for sn := range b.todo { - sectorDeadline := b.deadlines[sn] - if deadline.IsZero() || (!sectorDeadline.IsZero() && sectorDeadline.Before(deadline)) { - deadline = sectorDeadline + sectorCutoff := b.cutoffs[sn] + if cutoff.IsZero() || (!sectorCutoff.IsZero() && sectorCutoff.Before(cutoff)) { + cutoff = sectorCutoff } } for sn := range b.waiting { - sectorDeadline := b.deadlines[sn] - if deadline.IsZero() || (!sectorDeadline.IsZero() && sectorDeadline.Before(deadline)) { - deadline = sectorDeadline + sectorCutoff := b.cutoffs[sn] + if cutoff.IsZero() || (!sectorCutoff.IsZero() && sectorCutoff.Before(cutoff)) { + cutoff = sectorCutoff } } - if deadline.IsZero() { + if cutoff.IsZero() { return time.After(maxWait) } - deadline = deadline.Add(-slack) - if deadline.Before(now) { + cutoff = cutoff.Add(-slack) + if cutoff.Before(now) { return time.After(time.Nanosecond) // can't return 0 } - wait := deadline.Sub(now) + wait := cutoff.Sub(now) if wait > maxWait { wait = maxWait } @@ -151,7 +157,7 @@ func (b *PreCommitBatcher) batchWait(maxWait, slack time.Duration) <-chan time.T return time.After(wait) } -func (b *PreCommitBatcher) maybeStartBatch(notif, after bool) ([]sealiface.PreCommitBatchRes, error) { +func (b *PreCommitBatcher) maybeStartBatch(notif bool) ([]sealiface.PreCommitBatchRes, error) { b.lk.Lock() defer b.lk.Unlock() @@ -169,10 +175,6 @@ func (b *PreCommitBatcher) maybeStartBatch(notif, after bool) ([]sealiface.PreCo return nil, nil } - if after && total < cfg.MinPreCommitBatch { - return nil, nil - } - // todo support multiple batches res, err := b.processBatch(cfg) if err != nil && len(res) == 0 { @@ -191,7 +193,7 @@ func (b *PreCommitBatcher) maybeStartBatch(notif, after bool) ([]sealiface.PreCo delete(b.waiting, sn) delete(b.todo, sn) - delete(b.deadlines, sn) + delete(b.cutoffs, sn) } } @@ -224,21 +226,22 @@ func (b *PreCommitBatcher) processBatch(cfg sealiface.Config) ([]sealiface.PreCo return []sealiface.PreCommitBatchRes{res}, xerrors.Errorf("couldn't get miner info: %w", err) } - goodFunds := big.Add(deposit, b.feeCfg.MaxPreCommitGasFee) + maxFee := b.feeCfg.MaxPreCommitBatchGasFee.FeeForSectors(len(params.Sectors)) + goodFunds := big.Add(deposit, maxFee) from, _, err := b.addrSel(b.mctx, mi, api.PreCommitAddr, goodFunds, deposit) if err != nil { return []sealiface.PreCommitBatchRes{res}, xerrors.Errorf("no good address found: %w", err) } - mcid, err := b.api.SendMsg(b.mctx, from, b.maddr, miner.Methods.PreCommitSectorBatch, deposit, b.feeCfg.MaxPreCommitGasFee, enc.Bytes()) + mcid, err := b.api.SendMsg(b.mctx, from, b.maddr, miner.Methods.PreCommitSectorBatch, deposit, maxFee, enc.Bytes()) if err != nil { return []sealiface.PreCommitBatchRes{res}, xerrors.Errorf("sending message failed: %w", err) } res.Msg = &mcid - log.Infow("Sent ProveCommitAggregate message", "cid", mcid, "from", from, "sectors", len(b.todo)) + log.Infow("Sent PreCommitSectorBatch message", "cid", mcid, "from", from, "sectors", len(b.todo)) return []sealiface.PreCommitBatchRes{res}, nil } @@ -254,7 +257,7 @@ func (b *PreCommitBatcher) AddPreCommit(ctx context.Context, s SectorInfo, depos sn := s.SectorNumber b.lk.Lock() - b.deadlines[sn] = getSectorDeadline(curEpoch, s) + b.cutoffs[sn] = getPreCommitCutoff(curEpoch, s) b.todo[sn] = &preCommitEntry{ deposit: deposit, pci: in, @@ -330,3 +333,24 @@ func (b *PreCommitBatcher) Stop(ctx context.Context) error { return ctx.Err() } } + +// TODO: If this returned epochs, it would make testing much easier +func getPreCommitCutoff(curEpoch abi.ChainEpoch, si SectorInfo) time.Time { + cutoffEpoch := si.TicketEpoch + policy.MaxPreCommitRandomnessLookback + for _, p := range si.Pieces { + if p.DealInfo == nil { + continue + } + + startEpoch := p.DealInfo.DealSchedule.StartEpoch + if startEpoch < cutoffEpoch { + cutoffEpoch = startEpoch + } + } + + if cutoffEpoch <= curEpoch { + return time.Now() + } + + return time.Now().Add(time.Duration(cutoffEpoch-curEpoch) * time.Duration(build.BlockDelaySecs) * time.Second) +} diff --git a/extern/storage-sealing/precommit_batch_test.go b/extern/storage-sealing/precommit_batch_test.go new file mode 100644 index 00000000000..b6c35362e02 --- /dev/null +++ b/extern/storage-sealing/precommit_batch_test.go @@ -0,0 +1,257 @@ +package sealing_test + +import ( + "bytes" + "context" + "sort" + "sync" + "testing" + "time" + + "github.com/golang/mock/gomock" + "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" + miner5 "github.com/filecoin-project/specs-actors/v5/actors/builtin/miner" + + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + "github.com/filecoin-project/lotus/chain/types" + sealing "github.com/filecoin-project/lotus/extern/storage-sealing" + "github.com/filecoin-project/lotus/extern/storage-sealing/mocks" + "github.com/filecoin-project/lotus/extern/storage-sealing/sealiface" + "github.com/filecoin-project/lotus/node/config" + miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" +) + +var fc = config.MinerFeeConfig{ + MaxPreCommitGasFee: types.FIL(types.FromFil(1)), + MaxCommitGasFee: types.FIL(types.FromFil(1)), + MaxTerminateGasFee: types.FIL(types.FromFil(1)), + MaxPreCommitBatchGasFee: config.BatchFeeConfig{Base: types.FIL(types.FromFil(3)), PerSector: types.FIL(types.FromFil(1))}, + MaxCommitBatchGasFee: config.BatchFeeConfig{Base: types.FIL(types.FromFil(3)), PerSector: types.FIL(types.FromFil(1))}, +} + +func TestPrecommitBatcher(t *testing.T) { + t0123, err := address.NewFromString("t0123") + require.NoError(t, err) + + ctx := context.Background() + + as := func(ctx context.Context, mi miner.MinerInfo, use api.AddrUse, goodFunds, minFunds abi.TokenAmount) (address.Address, abi.TokenAmount, error) { + return t0123, big.Zero(), nil + } + + maxBatch := miner5.PreCommitSectorBatchMaxSize + + cfg := func() (sealiface.Config, error) { + return sealiface.Config{ + MaxWaitDealsSectors: 2, + MaxSealingSectors: 0, + MaxSealingSectorsForDeals: 0, + WaitDealsDelay: time.Hour * 6, + AlwaysKeepUnsealedCopy: true, + + BatchPreCommits: true, + MaxPreCommitBatch: maxBatch, + PreCommitBatchWait: 24 * time.Hour, + PreCommitBatchSlack: 3 * time.Hour, + + AggregateCommits: true, + MinCommitBatch: miner5.MinAggregatedSectors, + MaxCommitBatch: miner5.MaxAggregatedSectors, + CommitBatchWait: 24 * time.Hour, + CommitBatchSlack: 1 * time.Hour, + + TerminateBatchMin: 1, + TerminateBatchMax: 100, + TerminateBatchWait: 5 * time.Minute, + }, nil + } + + type promise func(t *testing.T) + type action func(t *testing.T, s *mocks.MockPreCommitBatcherApi, pcb *sealing.PreCommitBatcher) promise + + actions := func(as ...action) action { + return func(t *testing.T, s *mocks.MockPreCommitBatcherApi, pcb *sealing.PreCommitBatcher) promise { + var ps []promise + for _, a := range as { + p := a(t, s, pcb) + if p != nil { + ps = append(ps, p) + } + } + + if len(ps) > 0 { + return func(t *testing.T) { + for _, p := range ps { + p(t) + } + } + } + return nil + } + } + + addSector := func(sn abi.SectorNumber) action { + return func(t *testing.T, s *mocks.MockPreCommitBatcherApi, pcb *sealing.PreCommitBatcher) promise { + var pcres sealiface.PreCommitBatchRes + var pcerr error + done := sync.Mutex{} + done.Lock() + + si := sealing.SectorInfo{ + SectorNumber: sn, + } + + s.EXPECT().ChainHead(gomock.Any()).Return(nil, abi.ChainEpoch(1), nil) + + go func() { + defer done.Unlock() + pcres, pcerr = pcb.AddPreCommit(ctx, si, big.Zero(), &miner0.SectorPreCommitInfo{ + SectorNumber: si.SectorNumber, + SealedCID: fakePieceCid(t), + DealIDs: nil, + Expiration: 0, + }) + }() + + return func(t *testing.T) { + done.Lock() + require.NoError(t, pcerr) + require.Empty(t, pcres.Error) + require.Contains(t, pcres.Sectors, si.SectorNumber) + } + } + } + + addSectors := func(sectors []abi.SectorNumber) action { + as := make([]action, len(sectors)) + for i, sector := range sectors { + as[i] = addSector(sector) + } + return actions(as...) + } + + waitPending := func(n int) action { + return func(t *testing.T, s *mocks.MockPreCommitBatcherApi, pcb *sealing.PreCommitBatcher) promise { + require.Eventually(t, func() bool { + p, err := pcb.Pending(ctx) + require.NoError(t, err) + return len(p) == n + }, time.Second*5, 10*time.Millisecond) + + return nil + } + } + + expectSend := func(expect []abi.SectorNumber) action { + return func(t *testing.T, s *mocks.MockPreCommitBatcherApi, pcb *sealing.PreCommitBatcher) promise { + s.EXPECT().StateMinerInfo(gomock.Any(), gomock.Any(), gomock.Any()).Return(miner.MinerInfo{Owner: t0123, Worker: t0123}, nil) + s.EXPECT().SendMsg(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), funMatcher(func(i interface{}) bool { + b := i.([]byte) + var params miner5.PreCommitSectorBatchParams + require.NoError(t, params.UnmarshalCBOR(bytes.NewReader(b))) + for s, number := range expect { + require.Equal(t, number, params.Sectors[s].SectorNumber) + } + return true + })) + return nil + } + } + + flush := func(expect []abi.SectorNumber) action { + return func(t *testing.T, s *mocks.MockPreCommitBatcherApi, pcb *sealing.PreCommitBatcher) promise { + _ = expectSend(expect)(t, s, pcb) + + r, err := pcb.Flush(ctx) + require.NoError(t, err) + require.Len(t, r, 1) + require.Empty(t, r[0].Error) + sort.Slice(r[0].Sectors, func(i, j int) bool { + return r[0].Sectors[i] < r[0].Sectors[j] + }) + require.Equal(t, expect, r[0].Sectors) + + return nil + } + } + + getSectors := func(n int) []abi.SectorNumber { + out := make([]abi.SectorNumber, n) + for i := range out { + out[i] = abi.SectorNumber(i) + } + return out + } + + tcs := map[string]struct { + actions []action + }{ + "addSingle": { + actions: []action{ + addSector(0), + waitPending(1), + flush([]abi.SectorNumber{0}), + }, + }, + "addTwo": { + actions: []action{ + addSectors(getSectors(2)), + waitPending(2), + flush(getSectors(2)), + }, + }, + "addMax": { + actions: []action{ + expectSend(getSectors(maxBatch)), + addSectors(getSectors(maxBatch)), + }, + }, + } + + for name, tc := range tcs { + tc := tc + + t.Run(name, func(t *testing.T) { + // create go mock controller here + mockCtrl := gomock.NewController(t) + // when test is done, assert expectations on all mock objects. + defer mockCtrl.Finish() + + // create them mocks + pcapi := mocks.NewMockPreCommitBatcherApi(mockCtrl) + + pcb := sealing.NewPreCommitBatcher(ctx, t0123, pcapi, as, fc, cfg) + + var promises []promise + + for _, a := range tc.actions { + p := a(t, pcapi, pcb) + if p != nil { + promises = append(promises, p) + } + } + + for _, p := range promises { + p(t) + } + + err := pcb.Stop(ctx) + require.NoError(t, err) + }) + } +} + +type funMatcher func(interface{}) bool + +func (funMatcher) Matches(interface{}) bool { + return true +} + +func (funMatcher) String() string { + return "fun" +} diff --git a/extern/storage-sealing/sealiface/config.go b/extern/storage-sealing/sealiface/config.go index 54ba2ef5884..b237072d304 100644 --- a/extern/storage-sealing/sealiface/config.go +++ b/extern/storage-sealing/sealiface/config.go @@ -18,9 +18,10 @@ type Config struct { AlwaysKeepUnsealedCopy bool + FinalizeEarly bool + BatchPreCommits bool MaxPreCommitBatch int - MinPreCommitBatch int PreCommitBatchWait time.Duration PreCommitBatchSlack time.Duration diff --git a/extern/storage-sealing/sealing.go b/extern/storage-sealing/sealing.go index 69746268f19..8a70704c416 100644 --- a/extern/storage-sealing/sealing.go +++ b/extern/storage-sealing/sealing.go @@ -28,6 +28,7 @@ import ( sectorstorage "github.com/filecoin-project/lotus/extern/sector-storage" "github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper" "github.com/filecoin-project/lotus/extern/storage-sealing/sealiface" + "github.com/filecoin-project/lotus/node/config" ) const SectorStorePrefix = "/sectors" @@ -66,6 +67,7 @@ type SealingAPI interface { StateMinerPartitions(ctx context.Context, m address.Address, dlIdx uint64, tok TipSetToken) ([]api.Partition, error) SendMsg(ctx context.Context, from, to address.Address, method abi.MethodNum, value, maxFee abi.TokenAmount, params []byte) (cid.Cid, error) ChainHead(ctx context.Context) (TipSetToken, abi.ChainEpoch, error) + ChainBaseFee(context.Context, TipSetToken) (abi.TokenAmount, error) ChainGetMessage(ctx context.Context, mc cid.Cid) (*types.Message, error) ChainGetRandomnessFromBeacon(ctx context.Context, tok TipSetToken, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) ChainGetRandomnessFromTickets(ctx context.Context, tok TipSetToken, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) @@ -78,9 +80,11 @@ type AddrSel func(ctx context.Context, mi miner.MinerInfo, use api.AddrUse, good type Sealing struct { api SealingAPI - feeCfg FeeConfig + feeCfg config.MinerFeeConfig events Events + startupWait sync.WaitGroup + maddr address.Address sealer sectorstorage.SectorManager @@ -112,12 +116,6 @@ type Sealing struct { dealInfo *CurrentDealInfoManager } -type FeeConfig struct { - MaxPreCommitGasFee abi.TokenAmount - MaxCommitGasFee abi.TokenAmount - MaxTerminateGasFee abi.TokenAmount -} - type openSector struct { used abi.UnpaddedPieceSize // change to bitfield/rle when AddPiece gains offset support to better fill sectors @@ -134,7 +132,7 @@ type pendingPiece struct { accepted func(abi.SectorNumber, abi.UnpaddedPieceSize, error) } -func New(api SealingAPI, fc FeeConfig, events Events, maddr address.Address, ds datastore.Batching, sealer sectorstorage.SectorManager, sc SectorIDCounter, verif ffiwrapper.Verifier, prov ffiwrapper.Prover, pcp PreCommitPolicy, gc GetSealingConfigFunc, notifee SectorStateNotifee, as AddrSel) *Sealing { +func New(mctx context.Context, api SealingAPI, fc config.MinerFeeConfig, events Events, maddr address.Address, ds datastore.Batching, sealer sectorstorage.SectorManager, sc SectorIDCounter, verif ffiwrapper.Verifier, prov ffiwrapper.Prover, pcp PreCommitPolicy, gc GetSealingConfigFunc, notifee SectorStateNotifee, as AddrSel) *Sealing { s := &Sealing{ api: api, feeCfg: fc, @@ -155,9 +153,9 @@ func New(api SealingAPI, fc FeeConfig, events Events, maddr address.Address, ds notifee: notifee, addrSel: as, - terminator: NewTerminationBatcher(context.TODO(), maddr, api, as, fc, gc), - precommiter: NewPreCommitBatcher(context.TODO(), maddr, api, as, fc, gc), - commiter: NewCommitBatcher(context.TODO(), maddr, api, as, fc, gc, prov), + terminator: NewTerminationBatcher(mctx, maddr, api, as, fc, gc), + precommiter: NewPreCommitBatcher(mctx, maddr, api, as, fc, gc), + commiter: NewCommitBatcher(mctx, maddr, api, as, fc, gc, prov), getConfig: gc, dealInfo: &CurrentDealInfoManager{api}, @@ -166,6 +164,7 @@ func New(api SealingAPI, fc FeeConfig, events Events, maddr address.Address, ds bySector: map[abi.SectorID]statSectorState{}, }, } + s.startupWait.Add(1) s.sectors = statemachine.New(namespace.Wrap(ds, datastore.NewKey(SectorStorePrefix)), s, SectorInfo{}) @@ -193,10 +192,14 @@ func (m *Sealing) Stop(ctx context.Context) error { } func (m *Sealing) Remove(ctx context.Context, sid abi.SectorNumber) error { + m.startupWait.Wait() + return m.sectors.Send(uint64(sid), SectorRemove{}) } func (m *Sealing) Terminate(ctx context.Context, sid abi.SectorNumber) error { + m.startupWait.Wait() + return m.sectors.Send(uint64(sid), SectorTerminate{}) } diff --git a/extern/storage-sealing/sector_state.go b/extern/storage-sealing/sector_state.go index 23c7695e7ad..deb5e9f28e6 100644 --- a/extern/storage-sealing/sector_state.go +++ b/extern/storage-sealing/sector_state.go @@ -17,6 +17,8 @@ var ExistSectorStateList = map[SectorState]struct{}{ PreCommitBatchWait: {}, WaitSeed: {}, Committing: {}, + CommitFinalize: {}, + CommitFinalizeFailed: {}, SubmitCommit: {}, CommitWait: {}, SubmitCommitAggregate: {}, @@ -63,8 +65,10 @@ const ( SubmitPreCommitBatch SectorState = "SubmitPreCommitBatch" PreCommitBatchWait SectorState = "PreCommitBatchWait" - WaitSeed SectorState = "WaitSeed" // waiting for seed - Committing SectorState = "Committing" // compute PoRep + WaitSeed SectorState = "WaitSeed" // waiting for seed + Committing SectorState = "Committing" // compute PoRep + CommitFinalize SectorState = "CommitFinalize" // cleanup sector metadata before submitting the proof (early finalize) + CommitFinalizeFailed SectorState = "CommitFinalizeFailed" // single commit SubmitCommit SectorState = "SubmitCommit" // send commit message to the chain @@ -106,7 +110,7 @@ func toStatState(st SectorState) statSectorState { switch st { case UndefinedSectorState, Empty, WaitDeals, AddPiece: return sstStaging - case Packing, GetTicket, PreCommit1, PreCommit2, PreCommitting, PreCommitWait, SubmitPreCommitBatch, PreCommitBatchWait, WaitSeed, Committing, SubmitCommit, CommitWait, SubmitCommitAggregate, CommitAggregateWait, FinalizeSector: + case Packing, GetTicket, PreCommit1, PreCommit2, PreCommitting, PreCommitWait, SubmitPreCommitBatch, PreCommitBatchWait, WaitSeed, Committing, CommitFinalize, SubmitCommit, CommitWait, SubmitCommitAggregate, CommitAggregateWait, FinalizeSector: return sstSealing case Proving, Removed, Removing, Terminating, TerminateWait, TerminateFinality, TerminateFailed: return sstProving diff --git a/extern/storage-sealing/states_sealing.go b/extern/storage-sealing/states_sealing.go index 5e8f5269be7..360eeafa632 100644 --- a/extern/storage-sealing/states_sealing.go +++ b/extern/storage-sealing/states_sealing.go @@ -274,7 +274,7 @@ func (m *Sealing) preCommitParams(ctx statemachine.Context, sector SectorInfo) ( msd := policy.GetMaxProveCommitDuration(actors.VersionForNetwork(nv), sector.SectorType) - if minExpiration := height + msd + miner.MinSectorExpiration + 10; expiration < minExpiration { + if minExpiration := sector.TicketEpoch + policy.MaxPreCommitRandomnessLookback + msd + miner.MinSectorExpiration; expiration < minExpiration { expiration = minExpiration } // TODO: enforce a reasonable _maximum_ sector lifetime? @@ -334,7 +334,7 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf return nil } - goodFunds := big.Add(deposit, m.feeCfg.MaxPreCommitGasFee) + goodFunds := big.Add(deposit, big.Int(m.feeCfg.MaxPreCommitGasFee)) from, _, err := m.addrSel(ctx.Context(), mi, api.PreCommitAddr, goodFunds, deposit) if err != nil { @@ -342,7 +342,7 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf } log.Infof("submitting precommit for sector %d (deposit: %s): ", sector.SectorNumber, deposit) - mcid, err := m.api.SendMsg(ctx.Context(), from, m.maddr, miner.Methods.PreCommitSector, deposit, m.feeCfg.MaxPreCommitGasFee, enc.Bytes()) + mcid, err := m.api.SendMsg(ctx.Context(), from, m.maddr, miner.Methods.PreCommitSector, deposit, big.Int(m.feeCfg.MaxPreCommitGasFee), enc.Bytes()) if err != nil { if params.ReplaceCapacity { m.remarkForUpgrade(params.ReplaceSectorNumber) @@ -478,6 +478,11 @@ func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) } } + cfg, err := m.getConfig() + if err != nil { + return xerrors.Errorf("getting config: %w", err) + } + log.Info("scheduling seal proof computation...") log.Infof("KOMIT %d %x(%d); %x(%d); %v; r:%x; d:%x", sector.SectorNumber, sector.TicketValue, sector.TicketEpoch, sector.SeedValue, sector.SeedEpoch, sector.pieceInfos(), sector.CommR, sector.CommD) @@ -500,6 +505,24 @@ func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) return ctx.Send(SectorComputeProofFailed{xerrors.Errorf("computing seal proof failed(2): %w", err)}) } + { + tok, _, err := m.api.ChainHead(ctx.Context()) + if err != nil { + log.Errorf("handleCommitting: api error, not proceeding: %+v", err) + return nil + } + + if err := m.checkCommit(ctx.Context(), sector, proof, tok); err != nil { + return ctx.Send(SectorComputeProofFailed{xerrors.Errorf("commit check error: %w", err)}) + } + } + + if cfg.FinalizeEarly { + return ctx.Send(SectorProofReady{ + Proof: proof, + }) + } + return ctx.Send(SectorCommitted{ Proof: proof, }) @@ -524,7 +547,7 @@ func (m *Sealing) handleSubmitCommit(ctx statemachine.Context, sector SectorInfo tok, _, err := m.api.ChainHead(ctx.Context()) if err != nil { - log.Errorf("handleCommitting: api error, not proceeding: %+v", err) + log.Errorf("handleSubmitCommit: api error, not proceeding: %+v", err) return nil } @@ -566,7 +589,7 @@ func (m *Sealing) handleSubmitCommit(ctx statemachine.Context, sector SectorInfo collateral = big.Zero() } - goodFunds := big.Add(collateral, m.feeCfg.MaxCommitGasFee) + goodFunds := big.Add(collateral, big.Int(m.feeCfg.MaxCommitGasFee)) from, _, err := m.addrSel(ctx.Context(), mi, api.CommitAddr, goodFunds, collateral) if err != nil { @@ -574,7 +597,7 @@ func (m *Sealing) handleSubmitCommit(ctx statemachine.Context, sector SectorInfo } // TODO: check seed / ticket / deals are up to date - mcid, err := m.api.SendMsg(ctx.Context(), from, m.maddr, miner.Methods.ProveCommitSector, collateral, m.feeCfg.MaxCommitGasFee, enc.Bytes()) + mcid, err := m.api.SendMsg(ctx.Context(), from, m.maddr, miner.Methods.ProveCommitSector, collateral, big.Int(m.feeCfg.MaxCommitGasFee), enc.Bytes()) if err != nil { return ctx.Send(SectorCommitFailed{xerrors.Errorf("pushing message to mpool: %w", err)}) } @@ -590,15 +613,15 @@ func (m *Sealing) handleSubmitCommitAggregate(ctx statemachine.Context, sector S } res, err := m.commiter.AddCommit(ctx.Context(), sector, AggregateInput{ - info: proof.AggregateSealVerifyInfo{ + Info: proof.AggregateSealVerifyInfo{ Number: sector.SectorNumber, Randomness: sector.TicketValue, InteractiveRandomness: sector.SeedValue, SealedCID: *sector.CommR, UnsealedCID: *sector.CommD, }, - proof: sector.Proof, // todo: this correct?? - spt: sector.SectorType, + Proof: sector.Proof, // todo: this correct?? + Spt: sector.SectorType, }) if err != nil { return ctx.Send(SectorCommitFailed{xerrors.Errorf("queuing commit for aggregation failed: %w", err)}) diff --git a/extern/storage-sealing/terminate_batch.go b/extern/storage-sealing/terminate_batch.go index d545f443f38..13fa281c3ee 100644 --- a/extern/storage-sealing/terminate_batch.go +++ b/extern/storage-sealing/terminate_batch.go @@ -19,6 +19,7 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + "github.com/filecoin-project/lotus/node/config" ) type TerminateBatcherApi interface { @@ -34,7 +35,7 @@ type TerminateBatcher struct { maddr address.Address mctx context.Context addrSel AddrSel - feeCfg FeeConfig + feeCfg config.MinerFeeConfig getConfig GetSealingConfigFunc todo map[SectorLocation]*bitfield.BitField // MinerSectorLocation -> BitField @@ -46,7 +47,7 @@ type TerminateBatcher struct { lk sync.Mutex } -func NewTerminationBatcher(mctx context.Context, maddr address.Address, api TerminateBatcherApi, addrSel AddrSel, feeCfg FeeConfig, getConfig GetSealingConfigFunc) *TerminateBatcher { +func NewTerminationBatcher(mctx context.Context, maddr address.Address, api TerminateBatcherApi, addrSel AddrSel, feeCfg config.MinerFeeConfig, getConfig GetSealingConfigFunc) *TerminateBatcher { b := &TerminateBatcher{ api: api, maddr: maddr, @@ -214,12 +215,12 @@ func (b *TerminateBatcher) processBatch(notif, after bool) (*cid.Cid, error) { return nil, xerrors.Errorf("couldn't get miner info: %w", err) } - from, _, err := b.addrSel(b.mctx, mi, api.TerminateSectorsAddr, b.feeCfg.MaxTerminateGasFee, b.feeCfg.MaxTerminateGasFee) + from, _, err := b.addrSel(b.mctx, mi, api.TerminateSectorsAddr, big.Int(b.feeCfg.MaxTerminateGasFee), big.Int(b.feeCfg.MaxTerminateGasFee)) if err != nil { return nil, xerrors.Errorf("no good address found: %w", err) } - mcid, err := b.api.SendMsg(b.mctx, from, b.maddr, miner.Methods.TerminateSectors, big.Zero(), b.feeCfg.MaxTerminateGasFee, enc.Bytes()) + mcid, err := b.api.SendMsg(b.mctx, from, b.maddr, miner.Methods.TerminateSectors, big.Zero(), big.Int(b.feeCfg.MaxTerminateGasFee), enc.Bytes()) if err != nil { return nil, xerrors.Errorf("sending message failed: %w", err) } diff --git a/gateway/handler.go b/gateway/handler.go new file mode 100644 index 00000000000..3273c66db8b --- /dev/null +++ b/gateway/handler.go @@ -0,0 +1,48 @@ +package gateway + +import ( + "net/http" + + "contrib.go.opencensus.io/exporter/prometheus" + "github.com/filecoin-project/go-jsonrpc" + "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/metrics" + "github.com/gorilla/mux" + promclient "github.com/prometheus/client_golang/prometheus" +) + +// Handler returns a gateway http.Handler, to be mounted as-is on the server. +func Handler(a api.Gateway, opts ...jsonrpc.ServerOption) (http.Handler, error) { + m := mux.NewRouter() + + serveRpc := func(path string, hnd interface{}) { + rpcServer := jsonrpc.NewServer(opts...) + rpcServer.Register("Filecoin", hnd) + m.Handle(path, rpcServer) + } + + ma := metrics.MetricedGatewayAPI(a) + + serveRpc("/rpc/v1", ma) + serveRpc("/rpc/v0", api.Wrap(new(v1api.FullNodeStruct), new(v0api.WrapperV1Full), ma)) + + registry := promclient.DefaultRegisterer.(*promclient.Registry) + exporter, err := prometheus.NewExporter(prometheus.Options{ + Registry: registry, + Namespace: "lotus_gw", + }) + if err != nil { + return nil, err + } + m.Handle("/debug/metrics", exporter) + m.PathPrefix("/").Handler(http.DefaultServeMux) + + /*ah := &auth.Handler{ + Verify: nodeApi.AuthVerify, + Next: mux.ServeHTTP, + }*/ + + return m, nil +} diff --git a/go.mod b/go.mod index bdd60283f39..56d52a3d40a 100644 --- a/go.mod +++ b/go.mod @@ -35,11 +35,11 @@ require ( github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 github.com/filecoin-project/go-data-transfer v1.6.1-0.20210601213510-73edd813d563 github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a - github.com/filecoin-project/go-fil-markets v1.2.6-0.20210601213658-4449fd6940d8 + github.com/filecoin-project/go-fil-markets v1.5.1-0.20210630085438-c79fd6bcae82 github.com/filecoin-project/go-jsonrpc v0.1.4-0.20210217175800-45ea43ac2bec github.com/filecoin-project/go-multistore v0.0.4-0.20210601185713-428a2691a567 github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20 - github.com/filecoin-project/go-paramfetch v0.0.2-0.20210330140417-936748d3f5ec + github.com/filecoin-project/go-paramfetch v0.0.2-0.20210614165157-25a6c7769498 github.com/filecoin-project/go-state-types v0.1.1-0.20210506134452-99b279731c48 github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe github.com/filecoin-project/go-statestore v0.1.1 @@ -48,14 +48,14 @@ require ( github.com/filecoin-project/specs-actors/v2 v2.3.5 github.com/filecoin-project/specs-actors/v3 v3.1.1 github.com/filecoin-project/specs-actors/v4 v4.0.1 - github.com/filecoin-project/specs-actors/v5 v5.0.0-20210602024058-0c296bb386bf + github.com/filecoin-project/specs-actors/v5 v5.0.1 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 + github.com/golang/mock v1.5.0 github.com/google/uuid v1.1.2 github.com/gorilla/mux v1.7.4 github.com/gorilla/websocket v1.4.2 @@ -89,7 +89,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/v2 v2.1.2 + github.com/ipfs/go-log/v2 v2.1.3 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 @@ -104,21 +104,21 @@ require ( github.com/lib/pq v1.7.0 github.com/libp2p/go-buffer-pool v0.0.2 github.com/libp2p/go-eventbus v0.2.1 - github.com/libp2p/go-libp2p v0.13.0 + github.com/libp2p/go-libp2p v0.14.2 github.com/libp2p/go-libp2p-connmgr v0.2.4 github.com/libp2p/go-libp2p-core v0.8.5 github.com/libp2p/go-libp2p-discovery v0.5.0 github.com/libp2p/go-libp2p-kad-dht v0.11.0 github.com/libp2p/go-libp2p-mplex v0.4.1 - github.com/libp2p/go-libp2p-noise v0.1.2 - github.com/libp2p/go-libp2p-peerstore v0.2.6 + github.com/libp2p/go-libp2p-noise v0.2.0 + github.com/libp2p/go-libp2p-peerstore v0.2.7 github.com/libp2p/go-libp2p-pubsub v0.4.2-0.20210212194758-6c1addf493eb github.com/libp2p/go-libp2p-quic-transport v0.10.0 github.com/libp2p/go-libp2p-record v0.1.3 github.com/libp2p/go-libp2p-routing-helpers v0.2.3 - github.com/libp2p/go-libp2p-swarm v0.4.0 + github.com/libp2p/go-libp2p-swarm v0.5.0 github.com/libp2p/go-libp2p-tls v0.1.3 - github.com/libp2p/go-libp2p-yamux v0.5.1 + github.com/libp2p/go-libp2p-yamux v0.5.4 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 @@ -126,10 +126,9 @@ require ( github.com/mitchellh/go-homedir v1.1.0 github.com/multiformats/go-base32 v0.0.3 github.com/multiformats/go-multiaddr v0.3.1 - github.com/multiformats/go-multiaddr-dns v0.2.0 + github.com/multiformats/go-multiaddr-dns v0.3.1 github.com/multiformats/go-multibase v0.0.3 github.com/multiformats/go-multihash v0.0.15 - github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect github.com/open-rpc/meta-schema v0.0.0-20201029221707-1b72ef2ea333 github.com/opentracing/opentracing-go v1.2.0 github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e @@ -147,18 +146,17 @@ require ( github.com/whyrusleeping/pubsub v0.0.0-20190708150250-92bcb0691325 github.com/xorcare/golden v0.6.1-0.20191112154924-b87f686d7542 go.etcd.io/bbolt v1.3.4 - go.opencensus.io v0.22.5 + go.opencensus.io v0.23.0 go.uber.org/dig v1.10.0 // indirect go.uber.org/fx v1.9.0 go.uber.org/multierr v1.6.0 go.uber.org/zap v1.16.0 - golang.org/x/net v0.0.0-20201022231255-08b38378de70 - golang.org/x/sync v0.0.0-20201207232520-09787c993a3a - golang.org/x/sys v0.0.0-20210309074719-68d13333faf2 + golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6 + golang.org/x/sync v0.0.0-20210220032951-036812b2e83c + golang.org/x/sys v0.0.0-20210426080607-c94f62235c83 golang.org/x/time v0.0.0-20191024005414-555d28b269f0 golang.org/x/tools v0.1.1-0.20210225150353-54dc8c5edb56 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 gotest.tools v2.2.0+incompatible honnef.co/go/tools v0.0.1-2020.1.3 // indirect diff --git a/go.sum b/go.sum index b7531009bdc..6296fd39165 100644 --- a/go.sum +++ b/go.sum @@ -108,14 +108,18 @@ github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dm github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.0.0-20190605094302-a0d1e3e36d50/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= -github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= +github.com/btcsuite/btcd v0.21.0-beta h1:At9hIZdJW0s9E/fAz28nrz6AmcNlSVucCH796ZteX1M= +github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/buger/goterm v0.0.0-20200322175922-2f3e71b85129 h1:gfAMKE626QEuKG3si0pdTRcr/YEbBoxY+3GOH3gWvl4= @@ -187,8 +191,10 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davidlazar/go-crypto v0.0.0-20170701192655-dcfb0a7ac018/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4= -github.com/davidlazar/go-crypto v0.0.0-20190912175916-7055855a373f h1:BOaYiTvg8p9vBUXpklC22XSK/mifLF7lG9jtmYYi3Tc= github.com/davidlazar/go-crypto v0.0.0-20190912175916-7055855a373f/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4= +github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= +github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= +github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/detailyang/go-fallocate v0.0.0-20180908115635-432fa640bd2e h1:lj77EKYUpYXTd8CD/+QMIf8b6OIOTsfEBSXiAzuEHTU= github.com/detailyang/go-fallocate v0.0.0-20180908115635-432fa640bd2e/go.mod h1:3ZQK6DMPSz/QZ73jlWxBtUhNA8xZx7LzUFSq/OfP8vk= github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= @@ -279,8 +285,8 @@ github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f/go 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.2.6-0.20210601213658-4449fd6940d8 h1:/DYiVrJKucvX8qijRywIyLakTkGD+7yRNlndgI3BC+s= -github.com/filecoin-project/go-fil-markets v1.2.6-0.20210601213658-4449fd6940d8/go.mod h1:nwpBX12xsl6Oj3+kvEOCSTS1HVzYRtV9XBQmqq4LPdA= +github.com/filecoin-project/go-fil-markets v1.5.1-0.20210630085438-c79fd6bcae82 h1:fWkSmAZqxLtfr60Rn/J70hq/OUWFkiTqVILJ2wPj0V4= +github.com/filecoin-project/go-fil-markets v1.5.1-0.20210630085438-c79fd6bcae82/go.mod h1:nwpBX12xsl6Oj3+kvEOCSTS1HVzYRtV9XBQmqq4LPdA= 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= @@ -295,8 +301,8 @@ github.com/filecoin-project/go-multistore v0.0.4-0.20210601185713-428a2691a567 h github.com/filecoin-project/go-multistore v0.0.4-0.20210601185713-428a2691a567/go.mod h1:ya2COxasTn5LTaQ3Na++smn6FxMjW+oNtXsLI+tsqVk= github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20 h1:+/4aUeUoKr6AKfPE3mBhXA5spIV6UcKdTYDPNU2Tdmg= github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20/go.mod h1:mPn+LRRd5gEKNAtc+r3ScpW2JRU/pj4NBKdADYWHiak= -github.com/filecoin-project/go-paramfetch v0.0.2-0.20210330140417-936748d3f5ec h1:gExwWUiT1TcARkxGneS4nvp9C+wBsKU0bFdg7qFpNco= -github.com/filecoin-project/go-paramfetch v0.0.2-0.20210330140417-936748d3f5ec/go.mod h1:fZzmf4tftbwf9S37XRifoJlz7nCjRdIrMGLR07dKLCc= +github.com/filecoin-project/go-paramfetch v0.0.2-0.20210614165157-25a6c7769498 h1:G10ezOvpH1CLXQ19EA9VWNwyL0mg536ujSayjV0yg0k= +github.com/filecoin-project/go-paramfetch v0.0.2-0.20210614165157-25a6c7769498/go.mod h1:1FH85P8U+DUEmWk1Jkw3Bw7FrwTVUNHk/95PSPG+dts= github.com/filecoin-project/go-state-types v0.0.0-20200903145444-247639ffa6ad/go.mod h1:IQ0MBPnonv35CJHtWSN3YY1Hz2gkPru1Q9qoaYLxx9I= github.com/filecoin-project/go-state-types v0.0.0-20200904021452-1883f36ca2f4/go.mod h1:IQ0MBPnonv35CJHtWSN3YY1Hz2gkPru1Q9qoaYLxx9I= github.com/filecoin-project/go-state-types v0.0.0-20200928172055-2df22083d8ab/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= @@ -328,15 +334,16 @@ github.com/filecoin-project/specs-actors/v4 v4.0.0/go.mod h1:TkHXf/l7Wyw4ZejyXIP github.com/filecoin-project/specs-actors/v4 v4.0.1 h1:AiWrtvJZ63MHGe6rn7tPu4nSUY8bA1KDNszqJaD5+Fg= github.com/filecoin-project/specs-actors/v4 v4.0.1/go.mod h1:TkHXf/l7Wyw4ZejyXIPS2rK8bBO0rdwhTZyQQgaglng= github.com/filecoin-project/specs-actors/v5 v5.0.0-20210512015452-4fe3889fff57/go.mod h1:283yBMMUSDB2abcjP/hhrwTkhb9h3sfM6KGrep/ZlBI= -github.com/filecoin-project/specs-actors/v5 v5.0.0-20210602024058-0c296bb386bf h1:xt9A1omyhSDbQvpVk7Na1J15a/n8y0y4GQDLeiWLpFs= -github.com/filecoin-project/specs-actors/v5 v5.0.0-20210602024058-0c296bb386bf/go.mod h1:b/btpRl84Q9SeDKlyIoORBQwe2OTmq14POrYrVvBWCM= +github.com/filecoin-project/specs-actors/v5 v5.0.1 h1:PrYm5AKdMlJ/55eRW5laWcnaX66gyyDYBWvH38kNAMo= +github.com/filecoin-project/specs-actors/v5 v5.0.1/go.mod h1:74euMDIXorusOBs/QL/LNkYsXZdDpLJwojWw6T03pdE= 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= github.com/filecoin-project/test-vectors/schema v0.0.5/go.mod h1:iQ9QXLpYWL3m7warwvK1JC/pTri8mnfEmKygNDqqY6E= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6 h1:u/UEqS66A5ckRmS4yNpjmVH56sVtS/RfclBAYocb4as= github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6/go.mod h1:1i71OnUq3iUe1ma7Lr6yG6/rjvM3emb6yoL7xLFzcVQ= +github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= +github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= @@ -422,8 +429,9 @@ github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -435,8 +443,9 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.2-0.20190904063534-ff6b7dc882cf h1:gFVkHXmVAhEbxZVDln5V9GKrLaluNoFHDbrZwAWZgws= @@ -449,14 +458,16 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= -github.com/google/gopacket v1.1.18 h1:lum7VRA9kdlvBi7/v2p7/zcbkduHaCH/SVVyurs7OpY= github.com/google/gopacket v1.1.18/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= +github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= +github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -698,11 +709,13 @@ github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscw 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/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-log/v2 v2.1.3 h1:1iS3IU7aXRlbgUpN8yTTpJ53NXYjAe37vcI5+5nYrzk= +github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= 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= +github.com/ipfs/go-merkledag v0.2.4/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB3ClKnBAlk= github.com/ipfs/go-merkledag v0.3.1/go.mod h1:fvkZNNZixVW6cKSZ/JfLlON5OlgTXNdRLz0p6QG/I2M= github.com/ipfs/go-merkledag v0.3.2 h1:MRqj40QkrWkvPswXs4EfSslhZ4RVPRbxwX11js0t1xY= github.com/ipfs/go-merkledag v0.3.2/go.mod h1:fvkZNNZixVW6cKSZ/JfLlON5OlgTXNdRLz0p6QG/I2M= @@ -721,6 +734,7 @@ github.com/ipfs/go-peertaskqueue v0.2.0/go.mod h1:5/eNrBEbtSKWCG+kQK8K8fGNixoYUn github.com/ipfs/go-todocounter v0.0.1/go.mod h1:l5aErvQc8qKE2r7NDMjmq5UNAvuZy0rC8BHOplkWvZ4= github.com/ipfs/go-unixfs v0.0.4/go.mod h1:eIo/p9ADu/MFOuyxzwU+Th8D6xoxU//r590vUpWyfz8= github.com/ipfs/go-unixfs v0.2.1/go.mod h1:IwAAgul1UQIcNZzKPYZWOCijryFBeCV79cNubPzol+k= +github.com/ipfs/go-unixfs v0.2.2-0.20190827150610-868af2e9e5cb/go.mod h1:IwAAgul1UQIcNZzKPYZWOCijryFBeCV79cNubPzol+k= github.com/ipfs/go-unixfs v0.2.4 h1:6NwppOXefWIyysZ4LR/qUBPvXd5//8J3jiMdvpbw6Lo= github.com/ipfs/go-unixfs v0.2.4/go.mod h1:SUdisfUjNoSDzzhGVxvCL9QO/nKdwXdr+gbMUdqcbYw= github.com/ipfs/go-verifcid v0.0.1 h1:m2HI7zIuR5TFyQ1b79Da5N9dnnCP1vcu2QqawmWlK2E= @@ -731,12 +745,14 @@ github.com/ipfs/iptb v1.4.0 h1:YFYTrCkLMRwk/35IMyC6+yjoQSHTEcNcefBStLJzgvo= github.com/ipfs/iptb v1.4.0/go.mod h1:1rzHpCYtNp87/+hTxG5TfCVn/yMY3dKnLn8tBiMfdmg= github.com/ipfs/iptb-plugins v0.2.1 h1:au4HWn9/pRPbkxA08pDx2oRAs4cnbgQWgV0teYXuuGA= github.com/ipfs/iptb-plugins v0.2.1/go.mod h1:QXMbtIWZ+jRsW8a4h13qAKU7jcM7qaittO8wOsTP0Rs= +github.com/ipld/go-car v0.1.0/go.mod h1:RCWzaUh2i4mOEkB3W45Vc+9jnS/M6Qay5ooytiBHl3g= github.com/ipld/go-car v0.1.1-0.20200923150018-8cdef32e2da4/go.mod h1:xrMEcuSq+D1vEwl+YAXsg/JfA98XGpXDwnkIL4Aimqw= github.com/ipld/go-car v0.1.1-0.20201119040415-11b6074b6d4d/go.mod h1:2Gys8L8MJ6zkh1gktTSXreY63t4UbyvNp5JaudTyxHQ= github.com/ipld/go-car v0.3.1-0.20210601190600-f512dac51e8e h1:iTAJWTWEMe0Lx8JwRaIYrYgDuI9bVzkgogGz43Yv9Eo= github.com/ipld/go-car v0.3.1-0.20210601190600-f512dac51e8e/go.mod h1:wUxBdwOLA9/0HZBi3fnTBzla0MuwlqgJLyrhOg1XaKI= github.com/ipld/go-codec-dagpb v1.2.0 h1:2umV7ud8HBMkRuJgd8gXw95cLhwmcYrihS3cQEy9zpI= github.com/ipld/go-codec-dagpb v1.2.0/go.mod h1:6nBN7X7h8EOsEejZGqC7tej5drsdBAXbMHyBT+Fne5s= +github.com/ipld/go-ipld-prime v0.0.2-0.20191108012745-28a82f04c785/go.mod h1:bDDSvVz7vaK12FNvMeRYnpRFkSUPNQOiCYQezMD/P3w= github.com/ipld/go-ipld-prime v0.0.2-0.20200428162820-8b59dc292b8e/go.mod h1:uVIwe/u0H4VdKv3kaN1ck7uCb6yD9cFLS9/ELyXbsw8= github.com/ipld/go-ipld-prime v0.5.1-0.20200828233916-988837377a7f/go.mod h1:0xEgdD6MKbZ1vF0GC+YcR/C4SQCAlRuOjIJ2i0HxqzM= github.com/ipld/go-ipld-prime v0.5.1-0.20201021195245-109253e8a018/go.mod h1:0xEgdD6MKbZ1vF0GC+YcR/C4SQCAlRuOjIJ2i0HxqzM= @@ -744,6 +760,7 @@ github.com/ipld/go-ipld-prime v0.9.0/go.mod h1:KvBLMr4PX1gWptgkzRjVZCrLmSGcZCb/j github.com/ipld/go-ipld-prime v0.9.1-0.20210324083106-dc342a9917db/go.mod h1:KvBLMr4PX1gWptgkzRjVZCrLmSGcZCb/jioOQwCqZN8= github.com/ipld/go-ipld-prime v0.10.0 h1:ZCd52SDUqvA3YUJEx9v2uIm1qWv6FAxBt2mhiFpoZ6s= github.com/ipld/go-ipld-prime v0.10.0/go.mod h1:KvBLMr4PX1gWptgkzRjVZCrLmSGcZCb/jioOQwCqZN8= +github.com/ipld/go-ipld-prime-proto v0.0.0-20191113031812-e32bd156a1e5/go.mod h1:gcvzoEDBjwycpXt3LBE061wT9f46szXGHAmj9uoP6fU= github.com/ipld/go-ipld-prime-proto v0.0.0-20200428191222-c1ffdadc01e1/go.mod h1:OAV6xBmuTLsPZ+epzKkPB1e25FHk/vCtyatkdHcArLs= github.com/ipld/go-ipld-prime-proto v0.0.0-20200922192210-9a2bfd4440a6/go.mod h1:3pHYooM9Ea65jewRwrb2u5uHZCNkNTe9ABsVB+SrkH0= github.com/ipld/go-ipld-prime-proto v0.1.0/go.mod h1:11zp8f3sHVgIqtb/c9Kr5ZGqpnCLF1IVTNOez9TopzE= @@ -840,8 +857,9 @@ github.com/libp2p/go-conn-security v0.0.1/go.mod h1:bGmu51N0KU9IEjX7kl2PQjgZa40J github.com/libp2p/go-conn-security-multistream v0.0.1/go.mod h1:nc9vud7inQ+d6SO0I/6dSWrdMnHnzZNHeyUQqrAJulE= github.com/libp2p/go-conn-security-multistream v0.0.2/go.mod h1:nc9vud7inQ+d6SO0I/6dSWrdMnHnzZNHeyUQqrAJulE= github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= -github.com/libp2p/go-conn-security-multistream v0.2.0 h1:uNiDjS58vrvJTg9jO6bySd1rMKejieG7v45ekqHbZ1M= github.com/libp2p/go-conn-security-multistream v0.2.0/go.mod h1:hZN4MjlNetKD3Rq5Jb/P5ohUnFLNzEAR4DLSzpn2QLU= +github.com/libp2p/go-conn-security-multistream v0.2.1 h1:ft6/POSK7F+vl/2qzegnHDaXFU0iWB4yVTYrioC6Zy0= +github.com/libp2p/go-conn-security-multistream v0.2.1/go.mod h1:cR1d8gA0Hr59Fj6NhaTpFhJZrjSYuNmhpT2r25zYR70= github.com/libp2p/go-eventbus v0.0.2/go.mod h1:Hr/yGlwxA/stuLnpMiu82lpNKpvRy3EaJxPu40XYOwk= github.com/libp2p/go-eventbus v0.1.0/go.mod h1:vROgu5cs5T7cv7POWlWxBaVLxfSegC5UGQf8A2eEmx4= github.com/libp2p/go-eventbus v0.2.1 h1:VanAdErQnpTioN2TowqNcOijf6YwhuODe4pPKSDpxGc= @@ -865,8 +883,9 @@ github.com/libp2p/go-libp2p v0.8.3/go.mod h1:EsH1A+8yoWK+L4iKcbPYu6MPluZ+CHWI9El github.com/libp2p/go-libp2p v0.9.2/go.mod h1:cunHNLDVus66Ct9iXXcjKRLdmHdFdHVe1TAnbubJQqQ= github.com/libp2p/go-libp2p v0.10.0/go.mod h1:yBJNpb+mGJdgrwbKAKrhPU0u3ogyNFTfjJ6bdM+Q/G8= github.com/libp2p/go-libp2p v0.12.0/go.mod h1:FpHZrfC1q7nA8jitvdjKBDF31hguaC676g/nT9PgQM0= -github.com/libp2p/go-libp2p v0.13.0 h1:tDdrXARSghmusdm0nf1U/4M8aj8Rr0V2IzQOXmbzQ3s= github.com/libp2p/go-libp2p v0.13.0/go.mod h1:pM0beYdACRfHO1WcJlp65WXyG2A6NqYM+t2DTVAJxMo= +github.com/libp2p/go-libp2p v0.14.2 h1:qs0ABtjjNjS+RIXT1uM7sMJEvIc0pq2nKR0VQxFXhHI= +github.com/libp2p/go-libp2p v0.14.2/go.mod h1:0PQMADQEjCM2l8cSMYDpTgsb8gr6Zq7i4LUgq1mlW2E= github.com/libp2p/go-libp2p-asn-util v0.0.0-20200825225859-85005c6cf052 h1:BM7aaOF7RpmNn9+9g6uTjGJ0cTzWr5j9i9IKeun2M8U= github.com/libp2p/go-libp2p-asn-util v0.0.0-20200825225859-85005c6cf052/go.mod h1:nRMRTab+kZuk0LnKZpxhOVH/ndsdr2Nr//Zltc/vwgo= github.com/libp2p/go-libp2p-autonat v0.0.2/go.mod h1:fs71q5Xk+pdnKU014o2iq1RhMs9/PMaG5zXRFNnIIT4= @@ -877,8 +896,9 @@ github.com/libp2p/go-libp2p-autonat v0.2.0/go.mod h1:DX+9teU4pEEoZUqR1PiMlqliONQ github.com/libp2p/go-libp2p-autonat v0.2.1/go.mod h1:MWtAhV5Ko1l6QBsHQNSuM6b1sRkXrpk0/LqCr+vCVxI= github.com/libp2p/go-libp2p-autonat v0.2.2/go.mod h1:HsM62HkqZmHR2k1xgX34WuWDzk/nBwNHoeyyT4IWV6A= github.com/libp2p/go-libp2p-autonat v0.2.3/go.mod h1:2U6bNWCNsAG9LEbwccBDQbjzQ8Krdjge1jLTE9rdoMM= -github.com/libp2p/go-libp2p-autonat v0.4.0 h1:3y8XQbpr+ssX8QfZUHekjHCYK64sj6/4hnf/awD4+Ug= github.com/libp2p/go-libp2p-autonat v0.4.0/go.mod h1:YxaJlpr81FhdOv3W3BTconZPfhaYivRdf53g+S2wobk= +github.com/libp2p/go-libp2p-autonat v0.4.2 h1:YMp7StMi2dof+baaxkbxaizXjY1RPvU71CXfxExzcUU= +github.com/libp2p/go-libp2p-autonat v0.4.2/go.mod h1:YxaJlpr81FhdOv3W3BTconZPfhaYivRdf53g+S2wobk= github.com/libp2p/go-libp2p-autonat-svc v0.1.0/go.mod h1:fqi8Obl/z3R4PFVLm8xFtZ6PBL9MlV/xumymRFkKq5A= github.com/libp2p/go-libp2p-blankhost v0.0.1/go.mod h1:Ibpbw/7cPPYwFb7PACIWdvxxv0t0XCCI10t7czjAjTc= github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro= @@ -927,6 +947,8 @@ github.com/libp2p/go-libp2p-core v0.6.0/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX github.com/libp2p/go-libp2p-core v0.6.1/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= github.com/libp2p/go-libp2p-core v0.7.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= github.com/libp2p/go-libp2p-core v0.8.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.1/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.2/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= github.com/libp2p/go-libp2p-core v0.8.5 h1:aEgbIcPGsKy6zYcC+5AJivYFedhYa4sW7mIpWpUaLKw= github.com/libp2p/go-libp2p-core v0.8.5/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= github.com/libp2p/go-libp2p-crypto v0.0.1/go.mod h1:yJkNyDmO341d5wwXxDUGO0LykUVT72ImHNUqh5D/dBE= @@ -977,8 +999,8 @@ github.com/libp2p/go-libp2p-netutil v0.0.1/go.mod h1:GdusFvujWZI9Vt0X5BKqwWWmZFx github.com/libp2p/go-libp2p-netutil v0.1.0 h1:zscYDNVEcGxyUpMd0JReUZTrpMfia8PmLKcKF72EAMQ= github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU= github.com/libp2p/go-libp2p-noise v0.1.1/go.mod h1:QDFLdKX7nluB7DEnlVPbz7xlLHdwHFA9HiohJRr3vwM= -github.com/libp2p/go-libp2p-noise v0.1.2 h1:IH9GRihQJTx56obm+GnpdPX4KeVIlvpXrP6xnJ0wxWk= -github.com/libp2p/go-libp2p-noise v0.1.2/go.mod h1:9B10b7ueo7TIxZHHcjcDCo5Hd6kfKT2m77by82SFRfE= +github.com/libp2p/go-libp2p-noise v0.2.0 h1:wmk5nhB9a2w2RxMOyvsoKjizgJOEaJdfAakr0jN8gds= +github.com/libp2p/go-libp2p-noise v0.2.0/go.mod h1:IEbYhBBzGyvdLBoxxULL/SGbJARhUeqlO8lVSREYu2Q= github.com/libp2p/go-libp2p-peer v0.0.1/go.mod h1:nXQvOBbwVqoP+T5Y5nCjeH4sP9IX/J0AMzcDUVruVoo= github.com/libp2p/go-libp2p-peer v0.1.1/go.mod h1:jkF12jGB4Gk/IOo+yomm+7oLWxF278F7UnrYUQ1Q8es= github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= @@ -992,8 +1014,9 @@ github.com/libp2p/go-libp2p-peerstore v0.2.1/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRj github.com/libp2p/go-libp2p-peerstore v0.2.2/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRjwRLBr4TYKfNgrUkOPA= github.com/libp2p/go-libp2p-peerstore v0.2.3/go.mod h1:K8ljLdFn590GMttg/luh4caB/3g0vKuY01psze0upRw= github.com/libp2p/go-libp2p-peerstore v0.2.4/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= -github.com/libp2p/go-libp2p-peerstore v0.2.6 h1:2ACefBX23iMdJU9Ke+dcXt3w86MIryes9v7In4+Qq3U= github.com/libp2p/go-libp2p-peerstore v0.2.6/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= +github.com/libp2p/go-libp2p-peerstore v0.2.7 h1:83JoLxyR9OYTnNfB5vvFqvMUv/xDNa6NoPHnENhBsGw= +github.com/libp2p/go-libp2p-peerstore v0.2.7/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= github.com/libp2p/go-libp2p-pnet v0.2.0 h1:J6htxttBipJujEjz1y0a5+eYoiPcFHhSYHH6na5f0/k= github.com/libp2p/go-libp2p-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYcO0BW4wssv21LA= github.com/libp2p/go-libp2p-protocol v0.0.1/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1VZNHYcK8cLgFJLZ4s= @@ -1033,8 +1056,9 @@ github.com/libp2p/go-libp2p-swarm v0.2.7/go.mod h1:ZSJ0Q+oq/B1JgfPHJAT2HTall+xYR github.com/libp2p/go-libp2p-swarm v0.2.8/go.mod h1:JQKMGSth4SMqonruY0a8yjlPVIkb0mdNSwckW7OYziM= github.com/libp2p/go-libp2p-swarm v0.3.0/go.mod h1:hdv95GWCTmzkgeJpP+GK/9D9puJegb7H57B5hWQR5Kk= github.com/libp2p/go-libp2p-swarm v0.3.1/go.mod h1:hdv95GWCTmzkgeJpP+GK/9D9puJegb7H57B5hWQR5Kk= -github.com/libp2p/go-libp2p-swarm v0.4.0 h1:hahq/ijRoeH6dgROOM8x7SeaKK5VgjjIr96vdrT+NUA= github.com/libp2p/go-libp2p-swarm v0.4.0/go.mod h1:XVFcO52VoLoo0eitSxNQWYq4D6sydGOweTOAjJNraCw= +github.com/libp2p/go-libp2p-swarm v0.5.0 h1:HIK0z3Eqoo8ugmN8YqWAhD2RORgR+3iNXYG4U2PFd1E= +github.com/libp2p/go-libp2p-swarm v0.5.0/go.mod h1:sU9i6BoHE0Ve5SKz3y9WfKrh8dUat6JknzUehFx8xW4= github.com/libp2p/go-libp2p-testing v0.0.1/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= @@ -1055,8 +1079,9 @@ github.com/libp2p/go-libp2p-transport-upgrader v0.0.4/go.mod h1:RGq+tupk+oj7PzL2 github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= github.com/libp2p/go-libp2p-transport-upgrader v0.2.0/go.mod h1:mQcrHj4asu6ArfSoMuyojOdjx73Q47cYD7s5+gZOlns= github.com/libp2p/go-libp2p-transport-upgrader v0.3.0/go.mod h1:i+SKzbRnvXdVbU3D1dwydnTmKRPXiAR/fyvi1dXuL4o= -github.com/libp2p/go-libp2p-transport-upgrader v0.4.0 h1:xwj4h3hJdBrxqMOyMUjwscjoVst0AASTsKtZiTChoHI= github.com/libp2p/go-libp2p-transport-upgrader v0.4.0/go.mod h1:J4ko0ObtZSmgn5BX5AmegP+dK3CSnU2lMCKsSq/EY0s= +github.com/libp2p/go-libp2p-transport-upgrader v0.4.2 h1:4JsnbfJzgZeRS9AWN7B9dPqn/LY/HoQTlO9gtdJTIYM= +github.com/libp2p/go-libp2p-transport-upgrader v0.4.2/go.mod h1:NR8ne1VwfreD5VIWIU62Agt/J18ekORFU/j1i2y8zvk= github.com/libp2p/go-libp2p-yamux v0.1.2/go.mod h1:xUoV/RmYkg6BW/qGxA9XJyg+HzXFYkeXbnhjmnYzKp8= github.com/libp2p/go-libp2p-yamux v0.1.3/go.mod h1:VGSQVrqkh6y4nm0189qqxMtvyBft44MOYYPpYKXiVt4= github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= @@ -1067,8 +1092,9 @@ github.com/libp2p/go-libp2p-yamux v0.2.7/go.mod h1:X28ENrBMU/nm4I3Nx4sZ4dgjZ6VhL github.com/libp2p/go-libp2p-yamux v0.2.8/go.mod h1:/t6tDqeuZf0INZMTgd0WxIRbtK2EzI2h7HbFm9eAKI4= github.com/libp2p/go-libp2p-yamux v0.4.0/go.mod h1:+DWDjtFMzoAwYLVkNZftoucn7PelNoy5nm3tZ3/Zw30= github.com/libp2p/go-libp2p-yamux v0.5.0/go.mod h1:AyR8k5EzyM2QN9Bbdg6X1SkVVuqLwTGf0L4DFq9g6po= -github.com/libp2p/go-libp2p-yamux v0.5.1 h1:sX4WQPHMhRxJE5UZTfjEuBvlQWXB5Bo3A2JK9ZJ9EM0= github.com/libp2p/go-libp2p-yamux v0.5.1/go.mod h1:dowuvDu8CRWmr0iqySMiSxK+W0iL5cMVO9S94Y6gkv4= +github.com/libp2p/go-libp2p-yamux v0.5.4 h1:/UOPtT/6DHPtr3TtKXBHa6g0Le0szYuI33Xc/Xpd7fQ= +github.com/libp2p/go-libp2p-yamux v0.5.4/go.mod h1:tfrXbyaTqqSU654GTvK3ocnSZL3BuHoeTSqhcel1wsE= github.com/libp2p/go-maddr-filter v0.0.1/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= github.com/libp2p/go-maddr-filter v0.0.5/go.mod h1:Jk+36PMfIqCJhAnaASRH83bdAvfDRp/w6ENFaC9bG+M= @@ -1094,8 +1120,9 @@ github.com/libp2p/go-nat v0.0.4/go.mod h1:Nmw50VAvKuk38jUBcmNh6p9lUJLoODbJRvYAa/ github.com/libp2p/go-nat v0.0.5 h1:qxnwkco8RLKqVh1NmjQ+tJ8p8khNLFxuElYG/TwqW4Q= github.com/libp2p/go-nat v0.0.5/go.mod h1:B7NxsVNPZmRLvMOwiEO1scOSyjA56zxYAGv1yQgRkEU= github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= -github.com/libp2p/go-netroute v0.1.3 h1:1ngWRx61us/EpaKkdqkMjKk/ufr/JlIFYQAxV2XX8Ig= github.com/libp2p/go-netroute v0.1.3/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= +github.com/libp2p/go-netroute v0.1.6 h1:ruPJStbYyXVYGQ81uzEDzuvbYRLKRrLvTYd33yomC38= +github.com/libp2p/go-netroute v0.1.6/go.mod h1:AqhkMh0VuWmfgtxKPp3Oc1LdU5QSWS7wl0QLhSZqXxQ= github.com/libp2p/go-openssl v0.0.2/go.mod h1:v8Zw2ijCSWBQi8Pq5GAixw6DbFfa9u6VIYDXnvOXkc0= github.com/libp2p/go-openssl v0.0.3/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= github.com/libp2p/go-openssl v0.0.4/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= @@ -1111,8 +1138,9 @@ github.com/libp2p/go-reuseport-transport v0.0.3/go.mod h1:Spv+MPft1exxARzP2Sruj2 github.com/libp2p/go-reuseport-transport v0.0.4 h1:OZGz0RB620QDGpv300n1zaOcKGGAoGVf8h9txtt/1uM= github.com/libp2p/go-reuseport-transport v0.0.4/go.mod h1:trPa7r/7TJK/d+0hdBLOCGvpQQVOU74OXbNCIMkufGw= github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= -github.com/libp2p/go-sockaddr v0.1.0 h1:Y4s3/jNoryVRKEBrkJ576F17CPOaMIzUeCsg7dlTDj0= github.com/libp2p/go-sockaddr v0.1.0/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= +github.com/libp2p/go-sockaddr v0.1.1 h1:yD80l2ZOdGksnOyHrhxDdTDFrf7Oy+v3FMVArIRgZxQ= +github.com/libp2p/go-sockaddr v0.1.1/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= github.com/libp2p/go-stream-muxer v0.1.0/go.mod h1:8JAVsjeRBCWwPoZeH0W1imLOcriqXJyFvB0mR4A04sQ= github.com/libp2p/go-stream-muxer-multistream v0.1.1/go.mod h1:zmGdfkQ1AzOECIAcccoL8L//laqawOsO03zX8Sa+eGw= @@ -1148,8 +1176,9 @@ github.com/libp2p/go-yamux v1.3.7/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/h github.com/libp2p/go-yamux v1.4.0/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= github.com/libp2p/go-yamux v1.4.1 h1:P1Fe9vF4th5JOxxgQvfbOHkrGqIZniTLf+ddhZp8YTI= github.com/libp2p/go-yamux v1.4.1/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= -github.com/libp2p/go-yamux/v2 v2.0.0 h1:vSGhAy5u6iHBq11ZDcyHH4Blcf9xlBhT4WQDoOE90LU= github.com/libp2p/go-yamux/v2 v2.0.0/go.mod h1:NVWira5+sVUIU6tu1JWvaRn1dRnG+cawOJiflsAM+7U= +github.com/libp2p/go-yamux/v2 v2.2.0 h1:RwtpYZ2/wVviZ5+3pjC8qdQ4TKnrak0/E01N1UWoAFU= +github.com/libp2p/go-yamux/v2 v2.2.0/go.mod h1:3So6P6TV6r75R9jiBpiIKgU/66lOarCZjqROGxzPpPQ= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/lucas-clemente/quic-go v0.11.2/go.mod h1:PpMmPfPKO9nKJ/psF49ESTAGQSdfXxlg1otPbEB2nOw= @@ -1210,6 +1239,8 @@ github.com/miekg/dns v1.1.4/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nr github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.28/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= +github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY= +github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= @@ -1257,8 +1288,9 @@ github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/94 github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= github.com/multiformats/go-multiaddr-dns v0.0.3/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= github.com/multiformats/go-multiaddr-dns v0.1.0/go.mod h1:01k2RAqtoXIuPa3DCavAE9/6jc6nM0H3EgZyfUhN2oY= -github.com/multiformats/go-multiaddr-dns v0.2.0 h1:YWJoIDwLePniH7OU5hBnDZV6SWuvJqJ0YtN6pLeH9zA= github.com/multiformats/go-multiaddr-dns v0.2.0/go.mod h1:TJ5pr5bBO7Y1B18djPuRsVkduhQH2YqYSbxWJzYGdK0= +github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= +github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= @@ -1289,8 +1321,10 @@ github.com/multiformats/go-multistream v0.0.1/go.mod h1:fJTiDfXJVmItycydCnNx4+wS github.com/multiformats/go-multistream v0.0.4/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= github.com/multiformats/go-multistream v0.1.1/go.mod h1:KmHZ40hzVxiaiwlj3MEbYgK9JFk2/9UktWZAF54Du38= -github.com/multiformats/go-multistream v0.2.0 h1:6AuNmQVKUkRnddw2YiDjt5Elit40SFxMJkVnhmETXtU= github.com/multiformats/go-multistream v0.2.0/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= +github.com/multiformats/go-multistream v0.2.1/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= +github.com/multiformats/go-multistream v0.2.2 h1:TCYu1BHTDr1F/Qm75qwYISQdzGcRdC21nFgQW7l7GBo= +github.com/multiformats/go-multistream v0.2.2/go.mod h1:UIcnm7Zuo8HKG+HkWgfQsGL+/MIEhyTqbODbIUwSXKs= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.2/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= @@ -1307,8 +1341,6 @@ github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OS github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/ngdinhtoan/glide-cleanup v0.2.0/go.mod h1:UQzsmiDOb8YV3nOsCxK/c9zPpCZVNoHScRE3EO9pVMM= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nikkolasg/hexjson v0.0.0-20181101101858-78e39397e00c h1:5bFTChQxSKNwy8ALwOebjekYExl9HTT9urdawqC95tA= github.com/nikkolasg/hexjson v0.0.0-20181101101858-78e39397e00c/go.mod h1:7qN3Y0BvzRUf4LofcoJplQL10lsFDb4PYlePTVwrP28= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229 h1:E2B8qYyeSgv5MXpmzZXRNp8IAQ4vjxIjhpAf5hv/tAg= @@ -1326,6 +1358,7 @@ github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0 github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= @@ -1639,8 +1672,8 @@ go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -1693,17 +1726,20 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/exp v0.0.0-20181106170214-d68db9428509/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1726,8 +1762,9 @@ golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367 h1:0IiAsCRByjO2QjX7ZPkw5oU9x+n1YqRL802rjC0c3Aw= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -1739,6 +1776,7 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1 h1:Kvvh58BN8Y9/lBi7hTekvtMpm07eUZ0ck5pRHpsMWrY= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180524181706-dfa909b99c79/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1782,8 +1820,11 @@ golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201022231255-08b38378de70 h1:Z6x4N9mAi4oF0TbHweCsH618MO6OI6UFgV0FP5n0wBY= golang.org/x/net v0.0.0-20201022231255-08b38378de70/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6 h1:0PC75Fz/kyMGhL0e1QnypqK2kQMqKt9csD1GnMJR+Zk= +golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1801,8 +1842,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180202135801-37707fdb30a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1871,17 +1912,22 @@ 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/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210309074719-68d13333faf2 h1:46ULzRKLh1CwgRq2dC5SlBzEqqNCi8rreOZnNrbqcIY= +golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210426080607-c94f62235c83 h1:kHSDPqCtsHZOg0nVylfTo20DDhE9gG4Y0jn7hKQ0QAM= +golang.org/x/sys v0.0.0-20210426080607-c94f62235c83/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf h1:MZ2shdL+ZM/XzY3ZGOnh4Nlpnxz5GSOhOmtHo3iPU6M= 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= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1999,8 +2045,9 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.31.1 h1:SfXqXS5hkufcdZ/mHtYCh53P2b+92WQq/DZcKLgsFRs= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -2016,8 +2063,8 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/cheggaaa/pb.v1 v1.0.28 h1:n1tBJnnK2r7g9OW2btFH91V92STTUevLXYFb8gy9EMk= gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= diff --git a/itests/api_test.go b/itests/api_test.go new file mode 100644 index 00000000000..ee70a337b35 --- /dev/null +++ b/itests/api_test.go @@ -0,0 +1,267 @@ +package itests + +import ( + "context" + "strings" + "testing" + "time" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/big" + lapi "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/itests/kit" + "github.com/filecoin-project/lotus/node/impl" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestAPI(t *testing.T) { + t.Run("direct", func(t *testing.T) { + runAPITest(t, kit.Builder) + }) + t.Run("rpc", func(t *testing.T) { + runAPITest(t, kit.RPCBuilder) + }) +} + +type apiSuite struct { + makeNodes kit.APIBuilder +} + +// runAPITest is the entry point to API test suite +func runAPITest(t *testing.T, b kit.APIBuilder) { + ts := apiSuite{ + makeNodes: b, + } + + t.Run("version", ts.testVersion) + t.Run("id", ts.testID) + t.Run("testConnectTwo", ts.testConnectTwo) + t.Run("testMining", ts.testMining) + t.Run("testMiningReal", ts.testMiningReal) + t.Run("testSearchMsg", ts.testSearchMsg) + t.Run("testNonGenesisMiner", ts.testNonGenesisMiner) +} + +func (ts *apiSuite) testVersion(t *testing.T) { + lapi.RunningNodeType = lapi.NodeFull + t.Cleanup(func() { + lapi.RunningNodeType = lapi.NodeUnknown + }) + + ctx := context.Background() + apis, _ := ts.makeNodes(t, kit.OneFull, kit.OneMiner) + napi := apis[0] + + v, err := napi.Version(ctx) + if err != nil { + t.Fatal(err) + } + versions := strings.Split(v.Version, "+") + if len(versions) <= 0 { + t.Fatal("empty version") + } + require.Equal(t, versions[0], build.BuildVersion) +} + +func (ts *apiSuite) testSearchMsg(t *testing.T) { + apis, miners := ts.makeNodes(t, kit.OneFull, kit.OneMiner) + + api := apis[0] + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + senderAddr, err := api.WalletDefaultAddress(ctx) + if err != nil { + t.Fatal(err) + } + + msg := &types.Message{ + From: senderAddr, + To: senderAddr, + Value: big.Zero(), + } + bm := kit.NewBlockMiner(t, miners[0]) + bm.MineBlocks(ctx, 100*time.Millisecond) + defer bm.Stop() + + sm, err := api.MpoolPushMessage(ctx, msg, nil) + if err != nil { + t.Fatal(err) + } + res, err := api.StateWaitMsg(ctx, sm.Cid(), 1, lapi.LookbackNoLimit, true) + if err != nil { + t.Fatal(err) + } + if res.Receipt.ExitCode != 0 { + t.Fatal("did not successfully send message") + } + + searchRes, err := api.StateSearchMsg(ctx, types.EmptyTSK, sm.Cid(), lapi.LookbackNoLimit, true) + if err != nil { + t.Fatal(err) + } + + if searchRes.TipSet != res.TipSet { + t.Fatalf("search ts: %s, different from wait ts: %s", searchRes.TipSet, res.TipSet) + } + +} + +func (ts *apiSuite) testID(t *testing.T) { + ctx := context.Background() + apis, _ := ts.makeNodes(t, kit.OneFull, kit.OneMiner) + api := apis[0] + + id, err := api.ID(ctx) + if err != nil { + t.Fatal(err) + } + assert.Regexp(t, "^12", id.Pretty()) +} + +func (ts *apiSuite) testConnectTwo(t *testing.T) { + ctx := context.Background() + apis, _ := ts.makeNodes(t, kit.TwoFull, kit.OneMiner) + + p, err := apis[0].NetPeers(ctx) + if err != nil { + t.Fatal(err) + } + if len(p) != 0 { + t.Error("Node 0 has a peer") + } + + p, err = apis[1].NetPeers(ctx) + if err != nil { + t.Fatal(err) + } + if len(p) != 0 { + t.Error("Node 1 has a peer") + } + + addrs, err := apis[1].NetAddrsListen(ctx) + if err != nil { + t.Fatal(err) + } + + if err := apis[0].NetConnect(ctx, addrs); err != nil { + t.Fatal(err) + } + + p, err = apis[0].NetPeers(ctx) + if err != nil { + t.Fatal(err) + } + if len(p) != 1 { + t.Error("Node 0 doesn't have 1 peer") + } + + p, err = apis[1].NetPeers(ctx) + if err != nil { + t.Fatal(err) + } + if len(p) != 1 { + t.Error("Node 0 doesn't have 1 peer") + } +} + +func (ts *apiSuite) testMining(t *testing.T) { + ctx := context.Background() + fulls, miners := ts.makeNodes(t, kit.OneFull, kit.OneMiner) + api := fulls[0] + + newHeads, err := api.ChainNotify(ctx) + require.NoError(t, err) + initHead := (<-newHeads)[0] + baseHeight := initHead.Val.Height() + + h1, err := api.ChainHead(ctx) + require.NoError(t, err) + require.Equal(t, int64(h1.Height()), int64(baseHeight)) + + bm := kit.NewBlockMiner(t, miners[0]) + bm.MineUntilBlock(ctx, fulls[0], nil) + require.NoError(t, err) + + <-newHeads + + h2, err := api.ChainHead(ctx) + require.NoError(t, err) + require.Greater(t, int64(h2.Height()), int64(h1.Height())) +} + +func (ts *apiSuite) testMiningReal(t *testing.T) { + build.InsecurePoStValidation = false + defer func() { + build.InsecurePoStValidation = true + }() + + ctx := context.Background() + fulls, miners := ts.makeNodes(t, kit.OneFull, kit.OneMiner) + api := fulls[0] + + newHeads, err := api.ChainNotify(ctx) + require.NoError(t, err) + at := (<-newHeads)[0].Val.Height() + + h1, err := api.ChainHead(ctx) + require.NoError(t, err) + require.Equal(t, int64(at), int64(h1.Height())) + + bm := kit.NewBlockMiner(t, miners[0]) + + bm.MineUntilBlock(ctx, fulls[0], nil) + require.NoError(t, err) + + <-newHeads + + h2, err := api.ChainHead(ctx) + require.NoError(t, err) + require.Greater(t, int64(h2.Height()), int64(h1.Height())) + + bm.MineUntilBlock(ctx, fulls[0], nil) + require.NoError(t, err) + + <-newHeads + + h3, err := api.ChainHead(ctx) + require.NoError(t, err) + require.Greater(t, int64(h3.Height()), int64(h2.Height())) +} + +func (ts *apiSuite) testNonGenesisMiner(t *testing.T) { + ctx := context.Background() + n, sn := ts.makeNodes(t, + []kit.FullNodeOpts{kit.FullNodeWithLatestActorsAt(-1)}, + []kit.StorageMiner{{Full: 0, Preseal: kit.PresealGenesis}}, + ) + + full, ok := n[0].FullNode.(*impl.FullNodeAPI) + if !ok { + t.Skip("not testing with a full node") + return + } + genesisMiner := sn[0] + + bm := kit.NewBlockMiner(t, genesisMiner) + bm.MineBlocks(ctx, 4*time.Millisecond) + 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, kit.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/itests/batch_deal_test.go b/itests/batch_deal_test.go new file mode 100644 index 00000000000..9676dffcce3 --- /dev/null +++ b/itests/batch_deal_test.go @@ -0,0 +1,140 @@ +package itests + +import ( + "context" + "fmt" + "sort" + "testing" + "time" + + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/lotus/extern/storage-sealing/sealiface" + "github.com/filecoin-project/lotus/itests/kit" + "github.com/filecoin-project/lotus/markets/storageadapter" + "github.com/filecoin-project/lotus/node" + "github.com/filecoin-project/lotus/node/impl" + "github.com/filecoin-project/lotus/node/modules/dtypes" + "github.com/stretchr/testify/require" +) + +func TestBatchDealInput(t *testing.T) { + kit.QuietMiningLogs() + + var ( + 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) + ) + + run := func(piece, deals, expectSectors int) func(t *testing.T) { + return func(t *testing.T) { + publishPeriod := 10 * time.Second + maxDealsPerMsg := uint64(deals) + + // Set max deals per publish deals message to maxDealsPerMsg + minerDef := []kit.StorageMiner{{ + Full: 0, + Opts: node.Options( + node.Override( + new(*storageadapter.DealPublisher), + storageadapter.NewDealPublisher(nil, storageadapter.PublishMsgConfig{ + Period: publishPeriod, + MaxDealsPerMsg: maxDealsPerMsg, + })), + node.Override(new(dtypes.GetSealingConfigFunc), func() (dtypes.GetSealingConfigFunc, error) { + return func() (sealiface.Config, error) { + return sealiface.Config{ + MaxWaitDealsSectors: 2, + MaxSealingSectors: 1, + MaxSealingSectorsForDeals: 3, + AlwaysKeepUnsealedCopy: true, + WaitDealsDelay: time.Hour, + }, nil + }, nil + }), + ), + Preseal: kit.PresealGenesis, + }} + + // Create a connect client and miner node + n, sn := kit.MockMinerBuilder(t, kit.OneFull, minerDef) + client := n[0].FullNode.(*impl.FullNodeAPI) + miner := sn[0] + + blockMiner := kit.ConnectAndStartMining(t, blockTime, miner, client) + t.Cleanup(blockMiner.Stop) + + dh := kit.NewDealHarness(t, client, miner) + ctx := context.Background() + + err := miner.MarketSetAsk(ctx, big.Zero(), big.Zero(), 200, 128, 32<<30) + require.NoError(t, err) + + checkNoPadding := func() { + sl, err := sn[0].SectorsList(ctx) + require.NoError(t, err) + + sort.Slice(sl, func(i, j int) bool { + return sl[i] < sl[j] + }) + + for _, snum := range sl { + si, err := sn[0].SectorsStatus(ctx, snum, false) + require.NoError(t, err) + + // fmt.Printf("S %d: %+v %s\n", snum, si.Deals, si.State) + + for _, deal := range si.Deals { + if deal == 0 { + fmt.Printf("sector %d had a padding piece!\n", snum) + } + } + } + } + + // Starts a deal and waits until it's published + runDealTillSeal := func(rseed int) { + res, _, _, err := kit.CreateImportFile(ctx, client, rseed, piece) + require.NoError(t, err) + + deal := dh.StartDeal(ctx, res.Root, false, dealStartEpoch) + dh.WaitDealSealed(ctx, deal, false, true, checkNoPadding) + } + + // Run maxDealsPerMsg deals in parallel + done := make(chan struct{}, maxDealsPerMsg) + for rseed := 0; rseed < int(maxDealsPerMsg); rseed++ { + rseed := rseed + go func() { + runDealTillSeal(rseed) + done <- struct{}{} + }() + } + + // Wait for maxDealsPerMsg of the deals to be published + for i := 0; i < int(maxDealsPerMsg); i++ { + <-done + } + + checkNoPadding() + + sl, err := sn[0].SectorsList(ctx) + require.NoError(t, err) + require.Equal(t, len(sl), expectSectors) + } + } + + t.Run("4-p1600B", run(1600, 4, 4)) + t.Run("4-p513B", run(513, 4, 2)) + if !testing.Short() { + t.Run("32-p257B", run(257, 32, 8)) + t.Run("32-p10B", run(10, 32, 2)) + + // fixme: this appears to break data-transfer / markets in some really creative ways + // t.Run("128-p10B", run(10, 128, 8)) + } +} diff --git a/api/test/ccupgrade.go b/itests/ccupgrade_test.go similarity index 74% rename from api/test/ccupgrade.go rename to itests/ccupgrade_test.go index 283c8f610c4..196cf710619 100644 --- a/api/test/ccupgrade.go +++ b/itests/ccupgrade_test.go @@ -1,4 +1,4 @@ -package test +package itests import ( "context" @@ -7,6 +7,7 @@ import ( "testing" "time" + "github.com/filecoin-project/lotus/itests/kit" "github.com/stretchr/testify/require" "github.com/filecoin-project/go-state-types/abi" @@ -15,7 +16,9 @@ import ( "github.com/filecoin-project/lotus/node/impl" ) -func TestCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration) { +func TestCCUpgrade(t *testing.T) { + kit.QuietMiningLogs() + for _, height := range []abi.ChainEpoch{ -1, // before 162, // while sealing @@ -24,14 +27,14 @@ func TestCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration) { } { height := height // make linters happy by copying t.Run(fmt.Sprintf("upgrade-%d", height), func(t *testing.T) { - testCCUpgrade(t, b, blocktime, height) + runTestCCUpgrade(t, kit.MockMinerBuilder, 5*time.Millisecond, height) }) } } -func testCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration, upgradeHeight abi.ChainEpoch) { +func runTestCCUpgrade(t *testing.T, b kit.APIBuilder, blocktime time.Duration, upgradeHeight abi.ChainEpoch) { ctx := context.Background() - n, sn := b(t, []FullNodeOpts{FullNodeWithLatestActorsAt(upgradeHeight)}, OneMiner) + n, sn := b(t, []kit.FullNodeOpts{kit.FullNodeWithLatestActorsAt(upgradeHeight)}, kit.OneMiner) client := n[0].FullNode.(*impl.FullNodeAPI) miner := sn[0] @@ -51,7 +54,7 @@ func testCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration, upgradeH defer close(done) for atomic.LoadInt64(&mine) == 1 { time.Sleep(blocktime) - if err := sn[0].MineOne(ctx, MineNext); err != nil { + if err := sn[0].MineOne(ctx, kit.MineNext); err != nil { t.Error(err) } } @@ -62,10 +65,10 @@ func testCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration, upgradeH t.Fatal(err) } - CC := abi.SectorNumber(GenesisPreseals + 1) + CC := abi.SectorNumber(kit.GenesisPreseals + 1) Upgraded := CC + 1 - pledgeSectors(t, ctx, miner, 1, 0, nil) + kit.PledgeSectors(t, ctx, miner, 1, 0, nil) sl, err := miner.SectorsList(ctx) if err != nil { @@ -89,7 +92,16 @@ func testCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration, upgradeH t.Fatal(err) } - MakeDeal(t, ctx, 6, client, miner, false, false, 0) + dh := kit.NewDealHarness(t, client, miner) + + _, _, _ = dh.MakeFullDeal(kit.MakeFullDealParams{ + Ctx: context.Background(), + Rseed: 6, + CarExport: false, + FastRet: false, + StartEpoch: 0, + DoRetrieval: true, + }) // Validate upgrade diff --git a/itests/cli_test.go b/itests/cli_test.go new file mode 100644 index 00000000000..10e2af15c8d --- /dev/null +++ b/itests/cli_test.go @@ -0,0 +1,22 @@ +package itests + +import ( + "context" + "os" + "testing" + "time" + + "github.com/filecoin-project/lotus/cli" + "github.com/filecoin-project/lotus/itests/kit" +) + +// TestClient does a basic test to exercise the client CLI commands. +func TestClient(t *testing.T) { + _ = os.Setenv("BELLMAN_NO_GPU", "1") + kit.QuietMiningLogs() + + blocktime := 5 * time.Millisecond + ctx := context.Background() + clientNode, _ := kit.StartOneNodeOneMiner(ctx, t, blocktime) + kit.RunClientTest(t, cli.Commands, clientNode) +} diff --git a/api/test/deadlines.go b/itests/deadlines_test.go similarity index 72% rename from api/test/deadlines.go rename to itests/deadlines_test.go index 987bfb3aebe..193cdf40bdb 100644 --- a/api/test/deadlines.go +++ b/itests/deadlines_test.go @@ -1,4 +1,4 @@ -package test +package itests import ( "bytes" @@ -7,20 +7,13 @@ import ( "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/api" "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors" @@ -28,7 +21,13 @@ import ( "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/itests/kit" "github.com/filecoin-project/lotus/node/impl" + miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" + "github.com/ipfs/go-cid" + cbor "github.com/ipfs/go-ipld-cbor" + logging "github.com/ipfs/go-log/v2" + "github.com/stretchr/testify/require" ) // TestDeadlineToggling: @@ -54,16 +53,27 @@ import ( // * 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 +func TestDeadlineToggling(t *testing.T) { + kit.Expensive(t) + + _ = logging.SetLogLevel("miner", "ERROR") + _ = logging.SetLogLevel("chainstore", "ERROR") + _ = logging.SetLogLevel("chain", "ERROR") + _ = logging.SetLogLevel("sub", "ERROR") + _ = logging.SetLogLevel("storageminer", "FATAL") - const sectorsC, sectorsD, sectersB = 10, 9, 8 + const sectorsC, sectorsD, sectorsB = 10, 9, 8 + + var ( + upgradeH abi.ChainEpoch = 4000 + provingPeriod abi.ChainEpoch = 2880 + blocktime = 2 * time.Millisecond + ) ctx, cancel := context.WithCancel(context.Background()) defer cancel() - n, sn := b(t, []FullNodeOpts{FullNodeWithNetworkUpgradeAt(network.Version12, upgradeH)}, OneMiner) + n, sn := kit.MockMinerBuilder(t, []kit.FullNodeOpts{kit.FullNodeWithNetworkUpgradeAt(network.Version12, upgradeH)}, kit.OneMiner) client := n[0].FullNode.(*impl.FullNodeAPI) minerA := sn[0] @@ -92,7 +102,7 @@ func TestDeadlineToggling(t *testing.T, b APIBuilder, blocktime time.Duration) { defer close(done) for ctx.Err() == nil { build.Clock.Sleep(blocktime) - if err := minerA.MineOne(ctx, MineNext); err != nil { + if err := minerA.MineOne(ctx, kit.MineNext); err != nil { if ctx.Err() != nil { // context was canceled, ignore the error. return @@ -106,8 +116,8 @@ func TestDeadlineToggling(t *testing.T, b APIBuilder, blocktime time.Duration) { <-done }() - minerB := n[0].Stb(ctx, t, TestSpt, defaultFrom) - minerC := n[0].Stb(ctx, t, TestSpt, defaultFrom) + minerB := n[0].Stb(ctx, t, kit.TestSpt, defaultFrom) + minerC := n[0].Stb(ctx, t, kit.TestSpt, defaultFrom) maddrB, err := minerB.ActorAddress(ctx) require.NoError(t, err) @@ -119,7 +129,7 @@ func TestDeadlineToggling(t *testing.T, b APIBuilder, blocktime time.Duration) { // pledge sectors on C, go through a PP, check for power { - pledgeSectors(t, ctx, minerC, sectorsC, 0, nil) + kit.PledgeSectors(t, ctx, minerC, sectorsC, 0, nil) di, err := client.StateMinerProvingDeadline(ctx, maddrC, types.EmptyTSK) require.NoError(t, err) @@ -159,7 +169,7 @@ func TestDeadlineToggling(t *testing.T, b APIBuilder, blocktime time.Duration) { build.Clock.Sleep(blocktime) } - checkMiner := func(ma address.Address, power abi.StoragePower, active bool, tsk types.TipSetKey) { + checkMiner := func(ma address.Address, power abi.StoragePower, active, activeIfCron bool, tsk types.TipSetKey) { p, err := client.StateMinerPower(ctx, ma, tsk) require.NoError(t, err) @@ -174,6 +184,22 @@ func TestDeadlineToggling(t *testing.T, b APIBuilder, blocktime time.Duration) { act, err := mst.DeadlineCronActive() require.NoError(t, err) + + if tsk != types.EmptyTSK { + ts, err := client.ChainGetTipSet(ctx, tsk) + require.NoError(t, err) + di, err := mst.DeadlineInfo(ts.Height()) + require.NoError(t, err) + + // cron happened on the same epoch some other condition would have happened + if di.Open == ts.Height() { + act, err := mst.DeadlineCronActive() + require.NoError(t, err) + require.Equal(t, activeIfCron, act) + return + } + } + require.Equal(t, active, act) } @@ -181,15 +207,15 @@ func TestDeadlineToggling(t *testing.T, b APIBuilder, blocktime time.Duration) { { uts, err := client.ChainGetTipSetByHeight(ctx, upgradeH+2, types.EmptyTSK) require.NoError(t, err) - checkMiner(maddrB, types.NewInt(0), true, uts.Key()) + checkMiner(maddrB, types.NewInt(0), true, 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) + minerD := n[0].Stb(ctx, t, kit.TestSpt, defaultFrom) + minerE := n[0].Stb(ctx, t, kit.TestSpt, defaultFrom) maddrD, err := minerD.ActorAddress(ctx) require.NoError(t, err) @@ -197,19 +223,19 @@ func TestDeadlineToggling(t *testing.T, b APIBuilder, blocktime time.Duration) { 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(maddrA, types.NewInt(uint64(ssz)*kit.GenesisPreseals), true, true, types.EmptyTSK) + checkMiner(maddrC, types.NewInt(uint64(ssz)*sectorsC), true, 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) + checkMiner(maddrB, types.NewInt(0), false, false, types.EmptyTSK) + checkMiner(maddrD, types.NewInt(0), false, false, types.EmptyTSK) + checkMiner(maddrE, types.NewInt(0), false, 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) + kit.PledgeSectors(t, ctx, minerB, sectorsB, 0, nil) + checkMiner(maddrB, types.NewInt(0), true, true, types.EmptyTSK) - pledgeSectors(t, ctx, minerD, sectorsD, 0, nil) - checkMiner(maddrD, types.NewInt(0), true, types.EmptyTSK) + kit.PledgeSectors(t, ctx, minerD, sectorsD, 0, nil) + checkMiner(maddrD, types.NewInt(0), true, true, types.EmptyTSK) minerC.StorageMiner.(*impl.StorageMinerAPI).IStorageMgr.(*mock.SectorMgr).Fail() @@ -224,7 +250,7 @@ func TestDeadlineToggling(t *testing.T, b APIBuilder, blocktime time.Duration) { params := &miner.SectorPreCommitInfo{ Expiration: 2880 * 300, SectorNumber: 22, - SealProof: TestSpt, + SealProof: kit.TestSpt, SealedCID: cr, SealRandEpoch: head.Height() - 200, @@ -259,7 +285,7 @@ func TestDeadlineToggling(t *testing.T, b APIBuilder, blocktime time.Duration) { build.Clock.Sleep(blocktime) } - checkMiner(maddrE, types.NewInt(0), true, types.EmptyTSK) + checkMiner(maddrE, types.NewInt(0), true, true, types.EmptyTSK) // go through rest of the PP for { @@ -274,11 +300,11 @@ func TestDeadlineToggling(t *testing.T, b APIBuilder, blocktime time.Duration) { } // 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) + checkMiner(maddrA, types.NewInt(uint64(ssz)*kit.GenesisPreseals), true, true, types.EmptyTSK) + checkMiner(maddrC, types.NewInt(0), true, true, types.EmptyTSK) + checkMiner(maddrB, types.NewInt(uint64(ssz)*sectorsB), true, true, types.EmptyTSK) + checkMiner(maddrD, types.NewInt(uint64(ssz)*sectorsD), true, true, types.EmptyTSK) + checkMiner(maddrE, types.NewInt(0), false, false, types.EmptyTSK) // disable post on minerB minerB.StorageMiner.(*impl.StorageMinerAPI).IStorageMgr.(*mock.SectorMgr).Fail() @@ -329,7 +355,8 @@ func TestDeadlineToggling(t *testing.T, b APIBuilder, blocktime time.Duration) { require.NoError(t, err) require.Equal(t, exitcode.Ok, r.Receipt.ExitCode) - checkMiner(maddrD, types.NewInt(0), true, r.TipSet) + // assert inactive if the message landed in the tipset we run cron in + checkMiner(maddrD, types.NewInt(0), true, false, r.TipSet) } // go through another PP @@ -344,9 +371,8 @@ func TestDeadlineToggling(t *testing.T, b APIBuilder, blocktime time.Duration) { 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) + checkMiner(maddrA, types.NewInt(uint64(ssz)*kit.GenesisPreseals), true, true, types.EmptyTSK) + checkMiner(maddrC, types.NewInt(0), true, true, types.EmptyTSK) + checkMiner(maddrB, types.NewInt(0), true, true, types.EmptyTSK) + checkMiner(maddrD, types.NewInt(0), false, false, types.EmptyTSK) } diff --git a/itests/deals_test.go b/itests/deals_test.go new file mode 100644 index 00000000000..e5909cb80f5 --- /dev/null +++ b/itests/deals_test.go @@ -0,0 +1,633 @@ +package itests + +import ( + "bytes" + "context" + "fmt" + "io/ioutil" + "math/rand" + "os" + "path/filepath" + "sync/atomic" + "testing" + "time" + + "github.com/filecoin-project/go-fil-markets/storagemarket" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/actors/builtin/market" + "github.com/filecoin-project/lotus/chain/actors/policy" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/extern/sector-storage/storiface" + "github.com/filecoin-project/lotus/itests/kit" + "github.com/filecoin-project/lotus/markets/storageadapter" + "github.com/filecoin-project/lotus/miner" + "github.com/filecoin-project/lotus/node" + "github.com/filecoin-project/lotus/node/impl" + market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market" + "github.com/stretchr/testify/require" +) + +func TestDealCycle(t *testing.T) { + kit.QuietMiningLogs() + + 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) + + t.Run("TestFullDealCycle_Single", func(t *testing.T) { + runFullDealCycles(t, 1, kit.MockMinerBuilder, blockTime, false, false, dealStartEpoch) + }) + t.Run("TestFullDealCycle_Two", func(t *testing.T) { + runFullDealCycles(t, 2, kit.MockMinerBuilder, blockTime, false, false, dealStartEpoch) + }) + t.Run("WithExportedCAR", func(t *testing.T) { + runFullDealCycles(t, 1, kit.MockMinerBuilder, blockTime, true, false, dealStartEpoch) + }) + t.Run("TestFastRetrievalDealCycle", func(t *testing.T) { + runFastRetrievalDealFlowT(t, kit.MockMinerBuilder, blockTime, dealStartEpoch) + }) + t.Run("TestZeroPricePerByteRetrievalDealFlow", func(t *testing.T) { + runZeroPricePerByteRetrievalDealFlow(t, kit.MockMinerBuilder, blockTime, dealStartEpoch) + }) +} + +func TestAPIDealFlowReal(t *testing.T) { + if testing.Short() { + t.Skip("skipping test in short mode") + } + + kit.QuietMiningLogs() + + // TODO: just set this globally? + oldDelay := policy.GetPreCommitChallengeDelay() + policy.SetPreCommitChallengeDelay(5) + t.Cleanup(func() { + policy.SetPreCommitChallengeDelay(oldDelay) + }) + + t.Run("basic", func(t *testing.T) { + runFullDealCycles(t, 1, kit.Builder, time.Second, false, false, 0) + }) + + t.Run("fast-retrieval", func(t *testing.T) { + runFullDealCycles(t, 1, kit.Builder, time.Second, false, true, 0) + }) + + t.Run("retrieval-second", func(t *testing.T) { + runSecondDealRetrievalTest(t, kit.Builder, time.Second) + }) + + t.Run("quote-price-for-non-unsealed-retrieval", func(t *testing.T) { + runQuotePriceForUnsealedRetrieval(t, kit.Builder, time.Second, 0) + }) +} + +func runQuotePriceForUnsealedRetrieval(t *testing.T, b kit.APIBuilder, blocktime time.Duration, startEpoch abi.ChainEpoch) { + ctx := context.Background() + fulls, miners := b(t, kit.OneFull, kit.OneMiner) + client, miner := fulls[0].FullNode.(*impl.FullNodeAPI), miners[0] + kit.ConnectAndStartMining(t, blocktime, miner, client) + + ppb := int64(1) + unsealPrice := int64(77) + + // Set unsealed price to non-zero + ask, err := miner.MarketGetRetrievalAsk(ctx) + require.NoError(t, err) + ask.PricePerByte = abi.NewTokenAmount(ppb) + ask.UnsealPrice = abi.NewTokenAmount(unsealPrice) + err = miner.MarketSetRetrievalAsk(ctx, ask) + require.NoError(t, err) + + dh := kit.NewDealHarness(t, client, miner) + + _, info, fcid := dh.MakeFullDeal(kit.MakeFullDealParams{ + Ctx: ctx, + Rseed: 6, + CarExport: false, + FastRet: false, + StartEpoch: startEpoch, + DoRetrieval: false, + }) + + // one more storage deal for the same data + _, _, fcid2 := dh.MakeFullDeal(kit.MakeFullDealParams{ + Ctx: ctx, + Rseed: 6, + CarExport: false, + FastRet: false, + StartEpoch: startEpoch, + DoRetrieval: false, + }) + require.Equal(t, fcid, fcid2) + + // fetch quote -> zero for unsealed price since unsealed file already exists. + offers, err := client.ClientFindData(ctx, fcid, &info.PieceCID) + require.NoError(t, err) + require.Len(t, offers, 2) + require.Equal(t, offers[0], offers[1]) + require.Equal(t, uint64(0), offers[0].UnsealPrice.Uint64()) + require.Equal(t, info.Size*uint64(ppb), offers[0].MinPrice.Uint64()) + + // remove ONLY one unsealed file + ss, err := miner.StorageList(context.Background()) + require.NoError(t, err) + _, err = miner.SectorsList(ctx) + require.NoError(t, err) + +iLoop: + for storeID, sd := range ss { + for _, sector := range sd { + require.NoError(t, miner.StorageDropSector(ctx, storeID, sector.SectorID, storiface.FTUnsealed)) + // remove ONLY one + break iLoop + } + } + + // get retrieval quote -> zero for unsealed price as unsealed file exists. + offers, err = client.ClientFindData(ctx, fcid, &info.PieceCID) + require.NoError(t, err) + require.Len(t, offers, 2) + require.Equal(t, offers[0], offers[1]) + require.Equal(t, uint64(0), offers[0].UnsealPrice.Uint64()) + require.Equal(t, info.Size*uint64(ppb), offers[0].MinPrice.Uint64()) + + // remove the other unsealed file as well + ss, err = miner.StorageList(context.Background()) + require.NoError(t, err) + _, err = miner.SectorsList(ctx) + require.NoError(t, err) + for storeID, sd := range ss { + for _, sector := range sd { + require.NoError(t, miner.StorageDropSector(ctx, storeID, sector.SectorID, storiface.FTUnsealed)) + } + } + + // fetch quote -> non-zero for unseal price as we no more unsealed files. + offers, err = client.ClientFindData(ctx, fcid, &info.PieceCID) + require.NoError(t, err) + require.Len(t, offers, 2) + require.Equal(t, offers[0], offers[1]) + require.Equal(t, uint64(unsealPrice), offers[0].UnsealPrice.Uint64()) + total := (info.Size * uint64(ppb)) + uint64(unsealPrice) + require.Equal(t, total, offers[0].MinPrice.Uint64()) +} + +func TestPublishDealsBatching(t *testing.T) { + ctx := context.Background() + + kit.QuietMiningLogs() + + b := kit.MockMinerBuilder + blocktime := 10 * time.Millisecond + startEpoch := abi.ChainEpoch(2 << 12) + + publishPeriod := 10 * time.Second + maxDealsPerMsg := uint64(2) + + // Set max deals per publish deals message to 2 + minerDef := []kit.StorageMiner{{ + Full: 0, + Opts: node.Override( + new(*storageadapter.DealPublisher), + storageadapter.NewDealPublisher(nil, storageadapter.PublishMsgConfig{ + Period: publishPeriod, + MaxDealsPerMsg: maxDealsPerMsg, + })), + Preseal: kit.PresealGenesis, + }} + + // Create a connect client and miner node + n, sn := b(t, kit.OneFull, minerDef) + client := n[0].FullNode.(*impl.FullNodeAPI) + miner := sn[0] + + kit.ConnectAndStartMining(t, blocktime, miner, client) + + dh := kit.NewDealHarness(t, client, miner) + + // Starts a deal and waits until it's published + runDealTillPublish := func(rseed int) { + res, _, _, err := kit.CreateImportFile(ctx, client, rseed, 0) + require.NoError(t, err) + + upds, err := client.ClientGetDealUpdates(ctx) + require.NoError(t, err) + + dh.StartDeal(ctx, res.Root, false, startEpoch) + + // TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this + time.Sleep(time.Second) + + done := make(chan struct{}) + go func() { + for upd := range upds { + if upd.DataRef.Root == res.Root && upd.State == storagemarket.StorageDealAwaitingPreCommit { + done <- struct{}{} + } + } + }() + <-done + } + + // Run three deals in parallel + done := make(chan struct{}, maxDealsPerMsg+1) + for rseed := 1; rseed <= 3; rseed++ { + rseed := rseed + go func() { + runDealTillPublish(rseed) + done <- struct{}{} + }() + } + + // Wait for two of the deals to be published + for i := 0; i < int(maxDealsPerMsg); i++ { + <-done + } + + // Expect a single PublishStorageDeals message that includes the first two deals + msgCids, err := client.StateListMessages(ctx, &api.MessageMatch{To: market.Address}, types.EmptyTSK, 1) + require.NoError(t, err) + count := 0 + for _, msgCid := range msgCids { + msg, err := client.ChainGetMessage(ctx, msgCid) + require.NoError(t, err) + + if msg.Method == market.Methods.PublishStorageDeals { + count++ + var pubDealsParams market2.PublishStorageDealsParams + err = pubDealsParams.UnmarshalCBOR(bytes.NewReader(msg.Params)) + require.NoError(t, err) + require.Len(t, pubDealsParams.Deals, int(maxDealsPerMsg)) + } + } + require.Equal(t, 1, count) + + // The third deal should be published once the publish period expires. + // Allow a little padding as it takes a moment for the state change to + // be noticed by the client. + padding := 10 * time.Second + select { + case <-time.After(publishPeriod + padding): + require.Fail(t, "Expected 3rd deal to be published once publish period elapsed") + case <-done: // Success + } +} + +func TestDealMining(t *testing.T) { + // test making a deal with a fresh miner, and see if it starts to mine. + if testing.Short() { + t.Skip("skipping test in short mode") + } + + kit.QuietMiningLogs() + + b := kit.MockMinerBuilder + blocktime := 50 * time.Millisecond + + ctx := context.Background() + fulls, miners := b(t, + kit.OneFull, + []kit.StorageMiner{ + {Full: 0, Preseal: kit.PresealGenesis}, + {Full: 0, Preseal: 0}, // TODO: Add support for miners on non-first full node + }) + client := fulls[0].FullNode.(*impl.FullNodeAPI) + genesisMiner := miners[0] + provider := miners[1] + + addrinfo, err := client.NetAddrsListen(ctx) + if err != nil { + t.Fatal(err) + } + + if err := provider.NetConnect(ctx, addrinfo); err != nil { + t.Fatal(err) + } + + if err := genesisMiner.NetConnect(ctx, addrinfo); err != nil { + t.Fatal(err) + } + + time.Sleep(time.Second) + + data := make([]byte, 600) + rand.New(rand.NewSource(5)).Read(data) + + r := bytes.NewReader(data) + fcid, err := client.ClientImportLocal(ctx, r) + if err != nil { + t.Fatal(err) + } + + fmt.Println("FILE CID: ", fcid) + + var mine int32 = 1 + done := make(chan struct{}) + minedTwo := make(chan struct{}) + + m2addr, err := miners[1].ActorAddress(context.TODO()) + if err != nil { + t.Fatal(err) + } + + go func() { + defer close(done) + + complChan := minedTwo + for atomic.LoadInt32(&mine) != 0 { + wait := make(chan int) + mdone := func(mined bool, _ abi.ChainEpoch, err error) { + n := 0 + if mined { + n = 1 + } + wait <- n + } + + if err := miners[0].MineOne(ctx, miner.MineReq{Done: mdone}); err != nil { + t.Error(err) + } + + if err := miners[1].MineOne(ctx, miner.MineReq{Done: mdone}); err != nil { + t.Error(err) + } + + expect := <-wait + expect += <-wait + + time.Sleep(blocktime) + if expect == 0 { + // null block + continue + } + + var nodeOneMined bool + for _, node := range miners { + mb, err := node.MiningBase(ctx) + if err != nil { + t.Error(err) + return + } + + for _, b := range mb.Blocks() { + if b.Miner == m2addr { + nodeOneMined = true + break + } + } + + } + + if nodeOneMined && complChan != nil { + close(complChan) + complChan = nil + } + + } + }() + + dh := kit.NewDealHarness(t, client, provider) + + deal := dh.StartDeal(ctx, fcid, false, 0) + + // TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this + time.Sleep(time.Second) + + dh.WaitDealSealed(ctx, deal, false, false, nil) + + <-minedTwo + + atomic.StoreInt32(&mine, 0) + fmt.Println("shutting down mining") + <-done +} + +func TestOfflineDealFlow(t *testing.T) { + 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 + startEpoch := abi.ChainEpoch(2 << 12) + + runTest := func(t *testing.T, fastRet bool) { + ctx := context.Background() + fulls, miners := kit.MockMinerBuilder(t, kit.OneFull, kit.OneMiner) + client, miner := fulls[0].FullNode.(*impl.FullNodeAPI), miners[0] + + kit.ConnectAndStartMining(t, blocktime, miner, client) + + dh := kit.NewDealHarness(t, client, miner) + + // Create a random file and import on the client. + res, path, data, err := kit.CreateImportFile(ctx, client, 1, 0) + require.NoError(t, err) + + // Get the piece size and commP + fcid := res.Root + pieceInfo, err := client.ClientDealPieceCID(ctx, fcid) + require.NoError(t, err) + fmt.Println("FILE CID: ", fcid) + + // Create a storage deal with the miner + maddr, err := miner.ActorAddress(ctx) + require.NoError(t, err) + + addr, err := client.WalletDefaultAddress(ctx) + require.NoError(t, err) + + // Manual storage deal (offline deal) + dataRef := &storagemarket.DataRef{ + TransferType: storagemarket.TTManual, + Root: fcid, + PieceCid: &pieceInfo.PieceCID, + PieceSize: pieceInfo.PieceSize.Unpadded(), + } + + proposalCid, err := client.ClientStartDeal(ctx, &api.StartDealParams{ + Data: dataRef, + Wallet: addr, + Miner: maddr, + EpochPrice: types.NewInt(1000000), + DealStartEpoch: startEpoch, + MinBlocksDuration: uint64(build.MinDealDuration), + FastRetrieval: fastRet, + }) + require.NoError(t, err) + + // Wait for the deal to reach StorageDealCheckForAcceptance on the client + cd, err := client.ClientGetDealInfo(ctx, *proposalCid) + require.NoError(t, err) + require.Eventually(t, func() bool { + cd, _ := client.ClientGetDealInfo(ctx, *proposalCid) + return cd.State == storagemarket.StorageDealCheckForAcceptance + }, 30*time.Second, 1*time.Second, "actual deal status is %s", storagemarket.DealStates[cd.State]) + + // Create a CAR file from the raw file + carFileDir, err := ioutil.TempDir(os.TempDir(), "test-make-deal-car") + require.NoError(t, err) + carFilePath := filepath.Join(carFileDir, "out.car") + err = client.ClientGenCar(ctx, api.FileRef{Path: path}, carFilePath) + require.NoError(t, err) + + // Import the CAR file on the miner - this is the equivalent to + // transferring the file across the wire in a normal (non-offline) deal + err = miner.DealsImportData(ctx, *proposalCid, carFilePath) + require.NoError(t, err) + + // Wait for the deal to be published + dh.WaitDealPublished(ctx, proposalCid) + + t.Logf("deal published, retrieving") + + // Retrieve the deal + dh.TestRetrieval(ctx, fcid, &pieceInfo.PieceCID, false, data) + } + + t.Run("NormalRetrieval", func(t *testing.T) { + runTest(t, false) + }) + t.Run("FastRetrieval", func(t *testing.T) { + runTest(t, true) + }) + +} + +func runFullDealCycles(t *testing.T, n int, b kit.APIBuilder, blocktime time.Duration, carExport, fastRet bool, startEpoch abi.ChainEpoch) { + fulls, miners := b(t, kit.OneFull, kit.OneMiner) + client, miner := fulls[0].FullNode.(*impl.FullNodeAPI), miners[0] + + kit.ConnectAndStartMining(t, blocktime, miner, client) + + dh := kit.NewDealHarness(t, client, miner) + + baseseed := 6 + for i := 0; i < n; i++ { + _, _, _ = dh.MakeFullDeal(kit.MakeFullDealParams{ + Ctx: context.Background(), + Rseed: baseseed + i, + CarExport: carExport, + FastRet: fastRet, + StartEpoch: startEpoch, + DoRetrieval: true, + }) + } +} + +func runFastRetrievalDealFlowT(t *testing.T, b kit.APIBuilder, blocktime time.Duration, startEpoch abi.ChainEpoch) { + ctx := context.Background() + + fulls, miners := b(t, kit.OneFull, kit.OneMiner) + client, miner := fulls[0].FullNode.(*impl.FullNodeAPI), miners[0] + + kit.ConnectAndStartMining(t, blocktime, miner, client) + + dh := kit.NewDealHarness(t, client, miner) + + data := make([]byte, 1600) + rand.New(rand.NewSource(int64(8))).Read(data) + + r := bytes.NewReader(data) + fcid, err := client.ClientImportLocal(ctx, r) + if err != nil { + t.Fatal(err) + } + + fmt.Println("FILE CID: ", fcid) + + deal := dh.StartDeal(ctx, fcid, true, startEpoch) + dh.WaitDealPublished(ctx, deal) + + fmt.Println("deal published, retrieving") + + // Retrieval + info, err := client.ClientGetDealInfo(ctx, *deal) + require.NoError(t, err) + + dh.TestRetrieval(ctx, fcid, &info.PieceCID, false, data) +} + +func runSecondDealRetrievalTest(t *testing.T, b kit.APIBuilder, blocktime time.Duration) { + ctx := context.Background() + + fulls, miners := b(t, kit.OneFull, kit.OneMiner) + client, miner := fulls[0].FullNode.(*impl.FullNodeAPI), miners[0] + + kit.ConnectAndStartMining(t, blocktime, miner, client) + + dh := kit.NewDealHarness(t, client, miner) + + { + data1 := make([]byte, 800) + rand.New(rand.NewSource(int64(3))).Read(data1) + r := bytes.NewReader(data1) + + fcid1, err := client.ClientImportLocal(ctx, r) + if err != nil { + t.Fatal(err) + } + + data2 := make([]byte, 800) + rand.New(rand.NewSource(int64(9))).Read(data2) + r2 := bytes.NewReader(data2) + + fcid2, err := client.ClientImportLocal(ctx, r2) + if err != nil { + t.Fatal(err) + } + + deal1 := dh.StartDeal(ctx, fcid1, true, 0) + + // TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this + time.Sleep(time.Second) + dh.WaitDealSealed(ctx, deal1, true, false, nil) + + deal2 := dh.StartDeal(ctx, fcid2, true, 0) + + time.Sleep(time.Second) + dh.WaitDealSealed(ctx, deal2, false, false, nil) + + // Retrieval + info, err := client.ClientGetDealInfo(ctx, *deal2) + require.NoError(t, err) + + rf, _ := miner.SectorsRefs(ctx) + fmt.Printf("refs: %+v\n", rf) + + dh.TestRetrieval(ctx, fcid2, &info.PieceCID, false, data2) + } +} + +func runZeroPricePerByteRetrievalDealFlow(t *testing.T, b kit.APIBuilder, blocktime time.Duration, startEpoch abi.ChainEpoch) { + ctx := context.Background() + + fulls, miners := b(t, kit.OneFull, kit.OneMiner) + client, miner := fulls[0].FullNode.(*impl.FullNodeAPI), miners[0] + + kit.ConnectAndStartMining(t, blocktime, miner, client) + + dh := kit.NewDealHarness(t, client, miner) + + // Set price-per-byte to zero + ask, err := miner.MarketGetRetrievalAsk(ctx) + require.NoError(t, err) + + ask.PricePerByte = abi.NewTokenAmount(0) + err = miner.MarketSetRetrievalAsk(ctx, ask) + require.NoError(t, err) + + _, _, _ = dh.MakeFullDeal(kit.MakeFullDealParams{ + Ctx: ctx, + Rseed: 6, + CarExport: false, + FastRet: false, + StartEpoch: startEpoch, + DoRetrieval: true, + }) +} diff --git a/itests/doc.go b/itests/doc.go new file mode 100644 index 00000000000..474e5727780 --- /dev/null +++ b/itests/doc.go @@ -0,0 +1,2 @@ +// Package itests contains integration tests for Lotus. +package itests diff --git a/cmd/lotus-gateway/endtoend_test.go b/itests/gateway_test.go similarity index 84% rename from cmd/lotus-gateway/endtoend_test.go rename to itests/gateway_test.go index fc9f3d918f0..c7fe594445d 100644 --- a/cmd/lotus-gateway/endtoend_test.go +++ b/itests/gateway_test.go @@ -1,4 +1,4 @@ -package main +package itests import ( "bytes" @@ -10,30 +10,26 @@ import ( "time" "github.com/filecoin-project/lotus/chain/stmgr" - "github.com/filecoin-project/lotus/cli" - clitest "github.com/filecoin-project/lotus/cli/test" - "github.com/filecoin-project/lotus/gateway" - - init2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/init" - multisig2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig" - + "github.com/filecoin-project/lotus/itests/multisig" "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/ipfs/go-cid" + "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/types" + "github.com/filecoin-project/lotus/cli" + "github.com/filecoin-project/lotus/gateway" + "github.com/filecoin-project/lotus/itests/kit" "github.com/filecoin-project/lotus/node" - builder "github.com/filecoin-project/lotus/node/test" + + init2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/init" + multisig2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig" ) const ( @@ -47,11 +43,11 @@ func init() { policy.SetMinVerifiedDealSize(abi.NewStoragePower(256)) } -// TestWalletMsig tests that API calls to wallet and msig can be made on a lite +// TestGatewayWalletMsig tests that API calls to wallet and msig can be made on a lite // node that is connected through a gateway to a full API node -func TestWalletMsig(t *testing.T) { +func TestGatewayWalletMsig(t *testing.T) { _ = os.Setenv("BELLMAN_NO_GPU", "1") - clitest.QuietMiningLogs() + kit.QuietMiningLogs() blocktime := 5 * time.Millisecond ctx := context.Background() @@ -181,11 +177,11 @@ func TestWalletMsig(t *testing.T) { require.True(t, approveReturn.Applied) } -// TestMsigCLI tests that msig CLI calls can be made +// TestGatewayMsigCLI tests that msig CLI calls can be made // on a lite node that is connected through a gateway to a full API node -func TestMsigCLI(t *testing.T) { +func TestGatewayMsigCLI(t *testing.T) { _ = os.Setenv("BELLMAN_NO_GPU", "1") - clitest.QuietMiningLogs() + kit.QuietMiningLogs() blocktime := 5 * time.Millisecond ctx := context.Background() @@ -193,12 +189,12 @@ func TestMsigCLI(t *testing.T) { defer nodes.closer() lite := nodes.lite - clitest.RunMultisigTest(t, cli.Commands, lite) + multisig.RunMultisigTests(t, lite) } -func TestDealFlow(t *testing.T) { +func TestGatewayDealFlow(t *testing.T) { _ = os.Setenv("BELLMAN_NO_GPU", "1") - clitest.QuietMiningLogs() + kit.QuietMiningLogs() blocktime := 5 * time.Millisecond ctx := context.Background() @@ -209,25 +205,34 @@ func TestDealFlow(t *testing.T) { // 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.MakeDeal(t, ctx, 6, nodes.lite, nodes.miner, false, false, dealStartEpoch) + + dh := kit.NewDealHarness(t, nodes.lite, nodes.miner) + dh.MakeFullDeal(kit.MakeFullDealParams{ + Ctx: ctx, + Rseed: 6, + CarExport: false, + FastRet: false, + StartEpoch: dealStartEpoch, + DoRetrieval: true, + }) } -func TestCLIDealFlow(t *testing.T) { +func TestGatewayCLIDealFlow(t *testing.T) { _ = os.Setenv("BELLMAN_NO_GPU", "1") - clitest.QuietMiningLogs() + kit.QuietMiningLogs() blocktime := 5 * time.Millisecond ctx := context.Background() nodes := startNodesWithFunds(ctx, t, blocktime, maxLookbackCap, maxStateWaitLookbackLimit) defer nodes.closer() - clitest.RunClientTest(t, cli.Commands, nodes.lite) + kit.RunClientTest(t, cli.Commands, nodes.lite) } type testNodes struct { - lite test.TestNode - full test.TestNode - miner test.TestStorageNode + lite kit.TestFullNode + full kit.TestFullNode + miner kit.TestMiner closer jsonrpc.ClientCloser } @@ -270,24 +275,23 @@ func startNodes( // - Connect lite node -> gateway server -> full node opts := append( // Full node - test.OneFull, + kit.OneFull, // Lite node - test.FullNodeOpts{ + kit.FullNodeOpts{ Lite: true, - Opts: func(nodes []test.TestNode) node.Option { + Opts: func(nodes []kit.TestFullNode) node.Option { fullNode := nodes[0] // Create a gateway server in front of the full node - gapiImpl := gateway.NewNode(fullNode, lookbackCap, stateWaitLookbackLimit) - _, addr, err := builder.CreateRPCServer(t, map[string]interface{}{ - "/rpc/v1": gapiImpl, - "/rpc/v0": api.Wrap(new(v1api.FullNodeStruct), new(v0api.WrapperV1Full), gapiImpl), - }) + gwapi := gateway.NewNode(fullNode, lookbackCap, stateWaitLookbackLimit) + handler, err := gateway.Handler(gwapi) require.NoError(t, err) + srv, _ := kit.CreateRPCServer(t, handler) + // Create a gateway client API that connects to the gateway server var gapi api.Gateway - gapi, closer, err = client.NewGatewayRPCV1(ctx, addr+"/rpc/v1", nil) + gapi, closer, err = client.NewGatewayRPCV1(ctx, "ws://"+srv.Listener.Addr().String()+"/rpc/v1", nil) require.NoError(t, err) // Provide the gateway API to dependency injection @@ -295,7 +299,7 @@ func startNodes( }, }, ) - n, sn := builder.RPCMockSbBuilder(t, opts, test.OneMiner) + n, sn := kit.RPCMockMinerBuilder(t, opts, kit.OneMiner) full := n[0] lite := n[1] @@ -317,14 +321,14 @@ func startNodes( require.NoError(t, err) // Start mining blocks - bm := test.NewBlockMiner(ctx, t, miner, blocktime) - bm.MineBlocks() + bm := kit.NewBlockMiner(t, miner) + bm.MineBlocks(ctx, blocktime) t.Cleanup(bm.Stop) return &testNodes{lite: lite, full: full, miner: miner, closer: closer} } -func sendFunds(ctx context.Context, fromNode test.TestNode, fromAddr address.Address, toAddr address.Address, amt types.BigInt) error { +func sendFunds(ctx context.Context, fromNode kit.TestFullNode, fromAddr address.Address, toAddr address.Address, amt types.BigInt) error { msg := &types.Message{ From: fromAddr, To: toAddr, diff --git a/itests/kit/blockminer.go b/itests/kit/blockminer.go new file mode 100644 index 00000000000..3b1f1fedfa7 --- /dev/null +++ b/itests/kit/blockminer.go @@ -0,0 +1,124 @@ +package kit + +import ( + "context" + "sync" + "sync/atomic" + "testing" + "time" + + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/miner" + "github.com/stretchr/testify/require" +) + +// BlockMiner is a utility that makes a test miner Mine blocks on a timer. +type BlockMiner struct { + t *testing.T + miner TestMiner + + nextNulls int64 + wg sync.WaitGroup + cancel context.CancelFunc +} + +func NewBlockMiner(t *testing.T, miner TestMiner) *BlockMiner { + return &BlockMiner{ + t: t, + miner: miner, + cancel: func() {}, + } +} + +func (bm *BlockMiner) MineBlocks(ctx context.Context, blocktime time.Duration) { + time.Sleep(time.Second) + + // wrap context in a cancellable context. + ctx, bm.cancel = context.WithCancel(ctx) + + bm.wg.Add(1) + go func() { + defer bm.wg.Done() + + for { + select { + case <-time.After(blocktime): + case <-ctx.Done(): + return + } + + nulls := atomic.SwapInt64(&bm.nextNulls, 0) + err := bm.miner.MineOne(ctx, miner.MineReq{ + InjectNulls: abi.ChainEpoch(nulls), + Done: func(bool, abi.ChainEpoch, error) {}, + }) + switch { + case err == nil: // wrap around + case ctx.Err() != nil: // context fired. + return + default: // log error + bm.t.Error(err) + } + } + }() +} + +// InjectNulls injects the specified amount of null rounds in the next +// mining rounds. +func (bm *BlockMiner) InjectNulls(rounds abi.ChainEpoch) { + atomic.AddInt64(&bm.nextNulls, int64(rounds)) +} + +func (bm *BlockMiner) MineUntilBlock(ctx context.Context, fn TestFullNode, cb func(abi.ChainEpoch)) { + for i := 0; i < 1000; i++ { + var ( + success bool + err error + epoch abi.ChainEpoch + wait = make(chan struct{}) + ) + + doneFn := func(win bool, ep abi.ChainEpoch, e error) { + success = win + err = e + epoch = ep + wait <- struct{}{} + } + + mineErr := bm.miner.MineOne(ctx, miner.MineReq{Done: doneFn}) + require.NoError(bm.t, mineErr) + <-wait + + require.NoError(bm.t, err) + + if success { + // Wait until it shows up on the given full nodes ChainHead + nloops := 50 + for i := 0; i < nloops; i++ { + ts, err := fn.ChainHead(ctx) + require.NoError(bm.t, err) + + if ts.Height() == epoch { + break + } + + require.NotEqual(bm.t, i, nloops-1, "block never managed to sync to node") + time.Sleep(time.Millisecond * 10) + } + + if cb != nil { + cb(epoch) + } + return + } + bm.t.Log("did not Mine block, trying again", i) + } + bm.t.Fatal("failed to Mine 1000 times in a row...") +} + +// Stop stops the block miner. +func (bm *BlockMiner) Stop() { + bm.t.Log("shutting down mining") + bm.cancel() + bm.wg.Wait() +} diff --git a/cli/test/client.go b/itests/kit/client.go similarity index 65% rename from cli/test/client.go rename to itests/kit/client.go index 2a48b7b6443..fd0968e5146 100644 --- a/cli/test/client.go +++ b/itests/kit/client.go @@ -1,9 +1,10 @@ -package test +package kit import ( "context" "fmt" "io/ioutil" + "math/rand" "os" "path/filepath" "regexp" @@ -11,9 +12,7 @@ import ( "testing" "time" - "golang.org/x/xerrors" - - "github.com/filecoin-project/lotus/api/test" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/specs-actors/v2/actors/builtin" @@ -21,8 +20,8 @@ import ( lcli "github.com/urfave/cli/v2" ) -// RunClientTest exercises some of the client CLI commands -func RunClientTest(t *testing.T, cmds []*lcli.Command, clientNode test.TestNode) { +// RunClientTest exercises some of the Client CLI commands +func RunClientTest(t *testing.T, cmds []*lcli.Command, clientNode TestFullNode) { ctx, cancel := context.WithTimeout(context.Background(), time.Minute) defer cancel() @@ -30,7 +29,7 @@ func RunClientTest(t *testing.T, cmds []*lcli.Command, clientNode test.TestNode) mockCLI := NewMockCLI(ctx, t, cmds) clientCLI := mockCLI.Client(clientNode.ListenAddr) - // Get the miner address + // Get the Miner address addrs, err := clientNode.StateListMiners(ctx, types.EmptyTSK) require.NoError(t, err) require.Len(t, addrs, 1) @@ -38,13 +37,14 @@ func RunClientTest(t *testing.T, cmds []*lcli.Command, clientNode test.TestNode) minerAddr := addrs[0] fmt.Println("Miner:", minerAddr) - // client query-ask + // client query-ask out := clientCLI.RunCmd("client", "query-ask", minerAddr.String()) require.Regexp(t, regexp.MustCompile("Ask:"), out) // Create a deal (non-interactive) // client deal --start-epoch= 1000000attofil - res, _, err := test.CreateClientFile(ctx, clientNode, 1, 0) + res, _, _, err := CreateImportFile(ctx, clientNode, 1, 0) + require.NoError(t, err) startEpoch := fmt.Sprintf("--start-epoch=%d", 2<<12) dataCid := res.Root @@ -58,9 +58,9 @@ func RunClientTest(t *testing.T, cmds []*lcli.Command, clientNode test.TestNode) // // (in days) // - // "no" (verified client) + // "no" (verified Client) // "yes" (confirm deal) - res, _, err = test.CreateClientFile(ctx, clientNode, 2, 0) + res, _, _, err = CreateImportFile(ctx, clientNode, 2, 0) require.NoError(t, err) dataCid2 := res.Root duration = fmt.Sprintf("%d", build.MinDealDuration/builtin.EpochsInDay) @@ -91,16 +91,19 @@ func RunClientTest(t *testing.T, cmds []*lcli.Command, clientNode test.TestNode) } dealStatus = parts[3] fmt.Println(" Deal status:", dealStatus) - if dealComplete(t, dealStatus) { + + st := CategorizeDealState(dealStatus) + require.NotEqual(t, TestDealStateFailed, st) + if st == TestDealStateComplete { break } time.Sleep(time.Second) } - // Retrieve the first file from the miner + // Retrieve the first file from the Miner // client retrieve - tmpdir, err := ioutil.TempDir(os.TempDir(), "test-cli-client") + tmpdir, err := ioutil.TempDir(os.TempDir(), "test-cli-Client") require.NoError(t, err) path := filepath.Join(tmpdir, "outfile.dat") out = clientCLI.RunCmd("client", "retrieve", dataCid.String(), path) @@ -108,13 +111,36 @@ func RunClientTest(t *testing.T, cmds []*lcli.Command, clientNode test.TestNode) require.Regexp(t, regexp.MustCompile("Success"), out) } -func dealComplete(t *testing.T, dealStatus string) bool { - switch dealStatus { - case "StorageDealFailing", "StorageDealError": - t.Fatal(xerrors.Errorf("Storage deal failed with status: " + dealStatus)) - case "StorageDealStaged", "StorageDealAwaitingPreCommit", "StorageDealSealing", "StorageDealActive", "StorageDealExpired", "StorageDealSlashed": - return true +func CreateImportFile(ctx context.Context, client api.FullNode, rseed int, size int) (res *api.ImportRes, path string, data []byte, err error) { + data, path, err = createRandomFile(rseed, size) + if err != nil { + return nil, "", nil, err + } + + res, err = client.ClientImport(ctx, api.FileRef{Path: path}) + if err != nil { + return nil, "", nil, err + } + return res, path, data, nil +} + +func createRandomFile(rseed, size int) ([]byte, string, error) { + if size == 0 { + size = 1600 + } + data := make([]byte, size) + rand.New(rand.NewSource(int64(rseed))).Read(data) + + dir, err := ioutil.TempDir(os.TempDir(), "test-make-deal-") + if err != nil { + return nil, "", err + } + + path := filepath.Join(dir, "sourcefile.dat") + err = ioutil.WriteFile(path, data, 0644) + if err != nil { + return nil, "", err } - return false + return data, path, nil } diff --git a/itests/kit/deals.go b/itests/kit/deals.go new file mode 100644 index 00000000000..f85618901fd --- /dev/null +++ b/itests/kit/deals.go @@ -0,0 +1,326 @@ +package kit + +import ( + "bytes" + "context" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "testing" + "time" + + "github.com/ipfs/go-cid" + files "github.com/ipfs/go-ipfs-files" + "github.com/ipld/go-car" + "github.com/stretchr/testify/require" + + "github.com/filecoin-project/go-fil-markets/storagemarket" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/types" + sealing "github.com/filecoin-project/lotus/extern/storage-sealing" + "github.com/filecoin-project/lotus/node/impl" + ipld "github.com/ipfs/go-ipld-format" + dag "github.com/ipfs/go-merkledag" + dstest "github.com/ipfs/go-merkledag/test" + unixfile "github.com/ipfs/go-unixfs/file" +) + +type DealHarness struct { + t *testing.T + client api.FullNode + miner TestMiner +} + +type MakeFullDealParams struct { + Ctx context.Context + Rseed int + CarExport bool + FastRet bool + StartEpoch abi.ChainEpoch + DoRetrieval bool +} + +// NewDealHarness creates a test harness that contains testing utilities for deals. +func NewDealHarness(t *testing.T, client api.FullNode, miner TestMiner) *DealHarness { + return &DealHarness{ + t: t, + client: client, + miner: miner, + } +} + +func (dh *DealHarness) MakeFullDeal(params MakeFullDealParams) ([]byte, + *api.DealInfo, cid.Cid) { + res, _, data, err := CreateImportFile(params.Ctx, dh.client, params.Rseed, 0) + if err != nil { + dh.t.Fatal(err) + } + + fcid := res.Root + fmt.Println("FILE CID: ", fcid) + + deal := dh.StartDeal(params.Ctx, fcid, params.FastRet, params.StartEpoch) + + // TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this + time.Sleep(time.Second) + dh.WaitDealSealed(params.Ctx, deal, false, false, nil) + + // Retrieval + info, err := dh.client.ClientGetDealInfo(params.Ctx, *deal) + require.NoError(dh.t, err) + + if params.DoRetrieval { + dh.TestRetrieval(params.Ctx, fcid, &info.PieceCID, params.CarExport, data) + } + + return data, info, fcid +} + +func (dh *DealHarness) StartDeal(ctx context.Context, fcid cid.Cid, fastRet bool, startEpoch abi.ChainEpoch) *cid.Cid { + maddr, err := dh.miner.ActorAddress(ctx) + if err != nil { + dh.t.Fatal(err) + } + + addr, err := dh.client.WalletDefaultAddress(ctx) + if err != nil { + dh.t.Fatal(err) + } + deal, err := dh.client.ClientStartDeal(ctx, &api.StartDealParams{ + Data: &storagemarket.DataRef{ + TransferType: storagemarket.TTGraphsync, + Root: fcid, + }, + Wallet: addr, + Miner: maddr, + EpochPrice: types.NewInt(1000000), + DealStartEpoch: startEpoch, + MinBlocksDuration: uint64(build.MinDealDuration), + FastRetrieval: fastRet, + }) + if err != nil { + dh.t.Fatalf("%+v", err) + } + return deal +} + +func (dh *DealHarness) WaitDealSealed(ctx context.Context, deal *cid.Cid, noseal, noSealStart bool, cb func()) { +loop: + for { + di, err := dh.client.ClientGetDealInfo(ctx, *deal) + require.NoError(dh.t, err) + + switch di.State { + case storagemarket.StorageDealAwaitingPreCommit, storagemarket.StorageDealSealing: + if noseal { + return + } + if !noSealStart { + dh.StartSealingWaiting(ctx) + } + case storagemarket.StorageDealProposalRejected: + dh.t.Fatal("deal rejected") + case storagemarket.StorageDealFailing: + dh.t.Fatal("deal failed") + case storagemarket.StorageDealError: + dh.t.Fatal("deal errored", di.Message) + case storagemarket.StorageDealActive: + fmt.Println("COMPLETE", di) + break loop + } + + mds, err := dh.miner.MarketListIncompleteDeals(ctx) + require.NoError(dh.t, err) + + var minerState storagemarket.StorageDealStatus + for _, md := range mds { + if md.DealID == di.DealID { + minerState = md.State + break + } + } + + fmt.Printf("Deal %d state: client:%s provider:%s\n", di.DealID, storagemarket.DealStates[di.State], storagemarket.DealStates[minerState]) + time.Sleep(time.Second / 2) + if cb != nil { + cb() + } + } +} + +func (dh *DealHarness) WaitDealPublished(ctx context.Context, deal *cid.Cid) { + subCtx, cancel := context.WithCancel(ctx) + defer cancel() + updates, err := dh.miner.MarketGetDealUpdates(subCtx) + if err != nil { + dh.t.Fatal(err) + } + for { + select { + case <-ctx.Done(): + dh.t.Fatal("context timeout") + case di := <-updates: + if deal.Equals(di.ProposalCid) { + switch di.State { + case storagemarket.StorageDealProposalRejected: + dh.t.Fatal("deal rejected") + case storagemarket.StorageDealFailing: + dh.t.Fatal("deal failed") + case storagemarket.StorageDealError: + dh.t.Fatal("deal errored", di.Message) + case storagemarket.StorageDealFinalizing, storagemarket.StorageDealAwaitingPreCommit, storagemarket.StorageDealSealing, storagemarket.StorageDealActive: + fmt.Println("COMPLETE", di) + return + } + fmt.Println("Deal state: ", storagemarket.DealStates[di.State]) + } + } + } +} + +func (dh *DealHarness) StartSealingWaiting(ctx context.Context) { + snums, err := dh.miner.SectorsList(ctx) + require.NoError(dh.t, err) + + for _, snum := range snums { + si, err := dh.miner.SectorsStatus(ctx, snum, false) + require.NoError(dh.t, err) + + dh.t.Logf("Sector state: %s", si.State) + if si.State == api.SectorState(sealing.WaitDeals) { + require.NoError(dh.t, dh.miner.SectorStartSealing(ctx, snum)) + } + + flushSealingBatches(dh.t, ctx, dh.miner) + } +} + +func (dh *DealHarness) TestRetrieval(ctx context.Context, fcid cid.Cid, piece *cid.Cid, carExport bool, expect []byte) { + offers, err := dh.client.ClientFindData(ctx, fcid, piece) + if err != nil { + dh.t.Fatal(err) + } + + if len(offers) < 1 { + dh.t.Fatal("no offers") + } + + rpath, err := ioutil.TempDir("", "lotus-retrieve-test-") + if err != nil { + dh.t.Fatal(err) + } + defer os.RemoveAll(rpath) //nolint:errcheck + + caddr, err := dh.client.WalletDefaultAddress(ctx) + if err != nil { + dh.t.Fatal(err) + } + + ref := &api.FileRef{ + Path: filepath.Join(rpath, "ret"), + IsCAR: carExport, + } + updates, err := dh.client.ClientRetrieveWithEvents(ctx, offers[0].Order(caddr), ref) + if err != nil { + dh.t.Fatal(err) + } + for update := range updates { + if update.Err != "" { + dh.t.Fatalf("retrieval failed: %s", update.Err) + } + } + + rdata, err := ioutil.ReadFile(filepath.Join(rpath, "ret")) + if err != nil { + dh.t.Fatal(err) + } + + if carExport { + rdata = dh.ExtractCarData(ctx, rdata, rpath) + } + + if !bytes.Equal(rdata, expect) { + dh.t.Fatal("wrong expect retrieved") + } +} + +func (dh *DealHarness) ExtractCarData(ctx context.Context, rdata []byte, rpath string) []byte { + bserv := dstest.Bserv() + ch, err := car.LoadCar(bserv.Blockstore(), bytes.NewReader(rdata)) + if err != nil { + dh.t.Fatal(err) + } + b, err := bserv.GetBlock(ctx, ch.Roots[0]) + if err != nil { + dh.t.Fatal(err) + } + nd, err := ipld.Decode(b) + if err != nil { + dh.t.Fatal(err) + } + dserv := dag.NewDAGService(bserv) + fil, err := unixfile.NewUnixfsFile(ctx, dserv, nd) + if err != nil { + dh.t.Fatal(err) + } + outPath := filepath.Join(rpath, "retLoadedCAR") + if err := files.WriteTo(fil, outPath); err != nil { + dh.t.Fatal(err) + } + rdata, err = ioutil.ReadFile(outPath) + if err != nil { + dh.t.Fatal(err) + } + return rdata +} + +type DealsScaffold struct { + Ctx context.Context + Client *impl.FullNodeAPI + Miner TestMiner + BlockMiner *BlockMiner +} + +func ConnectAndStartMining(t *testing.T, blocktime time.Duration, miner TestMiner, clients ...api.FullNode) *BlockMiner { + ctx := context.Background() + + for _, c := range clients { + addrinfo, err := c.NetAddrsListen(ctx) + if err != nil { + t.Fatal(err) + } + if err := miner.NetConnect(ctx, addrinfo); err != nil { + t.Fatal(err) + } + } + + time.Sleep(time.Second) + + blockMiner := NewBlockMiner(t, miner) + blockMiner.MineBlocks(ctx, blocktime) + t.Cleanup(blockMiner.Stop) + return blockMiner +} + +type TestDealState int + +const ( + TestDealStateFailed = TestDealState(-1) + TestDealStateInProgress = TestDealState(0) + TestDealStateComplete = TestDealState(1) +) + +// CategorizeDealState categorizes deal states into one of three states: +// Complete, InProgress, Failed. +func CategorizeDealState(dealStatus string) TestDealState { + switch dealStatus { + case "StorageDealFailing", "StorageDealError": + return TestDealStateFailed + case "StorageDealStaged", "StorageDealAwaitingPreCommit", "StorageDealSealing", "StorageDealActive", "StorageDealExpired", "StorageDealSlashed": + return TestDealStateComplete + } + return TestDealStateInProgress +} diff --git a/itests/kit/funds.go b/itests/kit/funds.go new file mode 100644 index 00000000000..4c739dc62c2 --- /dev/null +++ b/itests/kit/funds.go @@ -0,0 +1,39 @@ +package kit + +import ( + "context" + "testing" + + "github.com/filecoin-project/go-state-types/abi" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/types" +) + +// SendFunds sends funds from the default wallet of the specified sender node +// to the recipient address. +func SendFunds(ctx context.Context, t *testing.T, sender TestFullNode, recipient address.Address, amount abi.TokenAmount) { + senderAddr, err := sender.WalletDefaultAddress(ctx) + if err != nil { + t.Fatal(err) + } + + msg := &types.Message{ + From: senderAddr, + To: recipient, + Value: amount, + } + + sm, err := sender.MpoolPushMessage(ctx, msg, nil) + if err != nil { + t.Fatal(err) + } + res, err := sender.StateWaitMsg(ctx, sm.Cid(), 3, api.LookbackNoLimit, true) + if err != nil { + t.Fatal(err) + } + if res.Receipt.ExitCode != 0 { + t.Fatal("did not successfully send money") + } +} diff --git a/itests/kit/init.go b/itests/kit/init.go new file mode 100644 index 00000000000..2f40ca0f048 --- /dev/null +++ b/itests/kit/init.go @@ -0,0 +1,32 @@ +package kit + +import ( + "fmt" + "os" + "strings" + + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/actors/policy" + logging "github.com/ipfs/go-log/v2" +) + +func init() { + bin := os.Args[0] + if !strings.HasSuffix(bin, ".test") { + panic("package itests/kit must only be imported from tests") + } + + _ = logging.SetLogLevel("*", "INFO") + + policy.SetConsensusMinerMinPower(abi.NewStoragePower(2048)) + policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1) + policy.SetMinVerifiedDealSize(abi.NewStoragePower(256)) + + err := os.Setenv("BELLMAN_NO_GPU", "1") + if err != nil { + panic(fmt.Sprintf("failed to set BELLMAN_NO_GPU env variable: %s", err)) + } + build.InsecurePoStValidation = true + +} diff --git a/itests/kit/log.go b/itests/kit/log.go new file mode 100644 index 00000000000..638e768d825 --- /dev/null +++ b/itests/kit/log.go @@ -0,0 +1,19 @@ +package kit + +import ( + "github.com/filecoin-project/lotus/lib/lotuslog" + logging "github.com/ipfs/go-log/v2" +) + +func QuietMiningLogs() { + lotuslog.SetupLogLevels() + + _ = logging.SetLogLevel("miner", "ERROR") + _ = logging.SetLogLevel("chainstore", "ERROR") + _ = logging.SetLogLevel("chain", "ERROR") + _ = logging.SetLogLevel("sub", "ERROR") + _ = logging.SetLogLevel("storageminer", "ERROR") + _ = logging.SetLogLevel("pubsub", "ERROR") + _ = logging.SetLogLevel("gen", "ERROR") + _ = logging.SetLogLevel("dht/RtRefreshManager", "ERROR") +} diff --git a/cli/test/mockcli.go b/itests/kit/mockcli.go similarity index 99% rename from cli/test/mockcli.go rename to itests/kit/mockcli.go index aef7808c8c3..c0f21892033 100644 --- a/cli/test/mockcli.go +++ b/itests/kit/mockcli.go @@ -1,4 +1,4 @@ -package test +package kit import ( "bytes" diff --git a/cli/test/net.go b/itests/kit/net.go similarity index 71% rename from cli/test/net.go rename to itests/kit/net.go index 8e45e3aedca..54c72443f43 100644 --- a/cli/test/net.go +++ b/itests/kit/net.go @@ -1,4 +1,4 @@ -package test +package kit import ( "context" @@ -9,12 +9,10 @@ import ( "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/go-address" - "github.com/filecoin-project/lotus/api/test" - test2 "github.com/filecoin-project/lotus/node/test" ) -func StartOneNodeOneMiner(ctx context.Context, t *testing.T, blocktime time.Duration) (test.TestNode, address.Address) { - n, sn := test2.RPCMockSbBuilder(t, test.OneFull, test.OneMiner) +func StartOneNodeOneMiner(ctx context.Context, t *testing.T, blocktime time.Duration) (TestFullNode, address.Address) { + n, sn := RPCMockMinerBuilder(t, OneFull, OneMiner) full := n[0] miner := sn[0] @@ -30,8 +28,8 @@ func StartOneNodeOneMiner(ctx context.Context, t *testing.T, blocktime time.Dura } // Start mining blocks - bm := test.NewBlockMiner(ctx, t, miner, blocktime) - bm.MineBlocks() + bm := NewBlockMiner(t, miner) + bm.MineBlocks(ctx, blocktime) t.Cleanup(bm.Stop) // Get the full node's wallet address @@ -44,8 +42,8 @@ func StartOneNodeOneMiner(ctx context.Context, t *testing.T, blocktime time.Dura return full, fullAddr } -func StartTwoNodesOneMiner(ctx context.Context, t *testing.T, blocktime time.Duration) ([]test.TestNode, []address.Address) { - n, sn := test2.RPCMockSbBuilder(t, test.TwoFull, test.OneMiner) +func StartTwoNodesOneMiner(ctx context.Context, t *testing.T, blocktime time.Duration) ([]TestFullNode, []address.Address) { + n, sn := RPCMockMinerBuilder(t, TwoFull, OneMiner) fullNode1 := n[0] fullNode2 := n[1] @@ -66,8 +64,8 @@ func StartTwoNodesOneMiner(ctx context.Context, t *testing.T, blocktime time.Dur } // Start mining blocks - bm := test.NewBlockMiner(ctx, t, miner, blocktime) - bm.MineBlocks() + bm := NewBlockMiner(t, miner) + bm.MineBlocks(ctx, blocktime) t.Cleanup(bm.Stop) // Send some funds to register the second node @@ -76,7 +74,7 @@ func StartTwoNodesOneMiner(ctx context.Context, t *testing.T, blocktime time.Dur t.Fatal(err) } - test.SendFunds(ctx, t, fullNode1, fullNodeAddr2, abi.NewTokenAmount(1e18)) + SendFunds(ctx, t, fullNode1, fullNodeAddr2, abi.NewTokenAmount(1e18)) // Get the first node's address fullNodeAddr1, err := fullNode1.WalletDefaultAddress(ctx) diff --git a/node/test/builder.go b/itests/kit/node_builder.go similarity index 73% rename from node/test/builder.go rename to itests/kit/node_builder.go index 6b0b9aa9676..3306d427f24 100644 --- a/node/test/builder.go +++ b/itests/kit/node_builder.go @@ -1,32 +1,26 @@ -package test +package kit import ( "bytes" "context" "crypto/rand" "io/ioutil" - "net" + "net/http" "net/http/httptest" - "strings" "sync" "testing" "time" "github.com/filecoin-project/go-state-types/network" - - "github.com/gorilla/mux" - "golang.org/x/xerrors" + "github.com/filecoin-project/lotus/node/config" "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" @@ -57,6 +51,7 @@ import ( "github.com/libp2p/go-libp2p-core/peer" mocknet "github.com/libp2p/go-libp2p/p2p/net/mock" "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr/net" "github.com/stretchr/testify/require" ) @@ -67,7 +62,7 @@ func init() { messagepool.HeadChangeCoalesceMergeInterval = 100 * time.Nanosecond } -func CreateTestStorageNode(ctx context.Context, t *testing.T, waddr address.Address, act address.Address, pk crypto.PrivKey, tnd test.TestNode, mn mocknet.Mocknet, opts node.Option) test.TestStorageNode { +func CreateTestStorageNode(ctx context.Context, t *testing.T, waddr address.Address, act address.Address, pk crypto.PrivKey, tnd TestFullNode, mn mocknet.Mocknet, opts node.Option) TestMiner { r := repo.NewMemory(nil) lr, err := r.Lock(repo.StorageMiner) @@ -91,7 +86,7 @@ func CreateTestStorageNode(ctx context.Context, t *testing.T, waddr address.Addr require.NoError(t, err) nic := storedcounter.New(ds, datastore.NewKey(modules.StorageCounterDSPrefix)) - for i := 0; i < test.GenesisPreseals; i++ { + for i := 0; i < GenesisPreseals; i++ { _, err := nic.Next() require.NoError(t, err) } @@ -133,6 +128,12 @@ func CreateTestStorageNode(ctx context.Context, t *testing.T, waddr address.Addr node.Override(new(v1api.FullNode), tnd), node.Override(new(*lotusminer.Miner), lotusminer.NewTestMiner(mineBlock, act)), + node.Override(new(*sectorstorage.SealerConfig), func() *sectorstorage.SealerConfig { + scfg := config.DefaultStorageMiner() + scfg.Storage.ResourceFiltering = sectorstorage.ResourceFilteringDisabled + return &scfg.Storage + }), + opts, ) if err != nil { @@ -142,10 +143,10 @@ func CreateTestStorageNode(ctx context.Context, t *testing.T, waddr address.Addr t.Cleanup(func() { _ = stop(context.Background()) }) /*// Bootstrap with full node - remoteAddrs, err := tnd.NetAddrsListen(ctx) + remoteAddrs, err := tnd.NetAddrsListen(Ctx) require.NoError(t, err) - err = minerapi.NetConnect(ctx, remoteAddrs) + err = minerapi.NetConnect(Ctx, remoteAddrs) require.NoError(t, err)*/ mineOne := func(ctx context.Context, req lotusminer.MineReq) error { select { @@ -156,11 +157,11 @@ func CreateTestStorageNode(ctx context.Context, t *testing.T, waddr address.Addr } } - return test.TestStorageNode{StorageMiner: minerapi, MineOne: mineOne, Stop: stop} + return TestMiner{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 { +func storageBuilder(parentNode TestFullNode, mn mocknet.Mocknet, opts node.Option) MinerBuilder { + return func(ctx context.Context, t *testing.T, spt abi.RegisteredSealProof, owner address.Address) TestMiner { pk, _, err := crypto.GenerateEd25519Key(rand.Reader) require.NoError(t, err) @@ -202,31 +203,32 @@ func storageBuilder(parentNode test.TestNode, mn mocknet.Mocknet, opts node.Opti } } -func Builder(t *testing.T, fullOpts []test.FullNodeOpts, storage []test.StorageMiner) ([]test.TestNode, []test.TestStorageNode) { +func Builder(t *testing.T, fullOpts []FullNodeOpts, storage []StorageMiner) ([]TestFullNode, []TestMiner) { return mockBuilderOpts(t, fullOpts, storage, false) } -func MockSbBuilder(t *testing.T, fullOpts []test.FullNodeOpts, storage []test.StorageMiner) ([]test.TestNode, []test.TestStorageNode) { - return mockSbBuilderOpts(t, fullOpts, storage, false) +func RPCBuilder(t *testing.T, fullOpts []FullNodeOpts, storage []StorageMiner) ([]TestFullNode, []TestMiner) { + return mockBuilderOpts(t, fullOpts, storage, true) } -func RPCBuilder(t *testing.T, fullOpts []test.FullNodeOpts, storage []test.StorageMiner) ([]test.TestNode, []test.TestStorageNode) { - return mockBuilderOpts(t, fullOpts, storage, true) +func MockMinerBuilder(t *testing.T, fullOpts []FullNodeOpts, storage []StorageMiner) ([]TestFullNode, []TestMiner) { + return mockMinerBuilderOpts(t, fullOpts, storage, false) } -func RPCMockSbBuilder(t *testing.T, fullOpts []test.FullNodeOpts, storage []test.StorageMiner) ([]test.TestNode, []test.TestStorageNode) { - return mockSbBuilderOpts(t, fullOpts, storage, true) +func RPCMockMinerBuilder(t *testing.T, fullOpts []FullNodeOpts, storage []StorageMiner) ([]TestFullNode, []TestMiner) { + return mockMinerBuilderOpts(t, fullOpts, storage, true) } -func mockBuilderOpts(t *testing.T, fullOpts []test.FullNodeOpts, storage []test.StorageMiner, rpc bool) ([]test.TestNode, []test.TestStorageNode) { +func mockBuilderOpts(t *testing.T, fullOpts []FullNodeOpts, storage []StorageMiner, rpc bool) ([]TestFullNode, []TestMiner) { ctx, cancel := context.WithCancel(context.Background()) t.Cleanup(cancel) mn := mocknet.New(ctx) - fulls := make([]test.TestNode, len(fullOpts)) - storers := make([]test.TestStorageNode, len(storage)) + fulls := make([]TestFullNode, len(fullOpts)) + miners := make([]TestMiner, len(storage)) + // ***** pk, _, err := crypto.GenerateEd25519Key(rand.Reader) require.NoError(t, err) @@ -238,13 +240,17 @@ func mockBuilderOpts(t *testing.T, fullOpts []test.FullNodeOpts, storage []test. if len(storage) > 1 { panic("need more peer IDs") } + // ***** + // PRESEAL SECTION, TRY TO REPLACE WITH BETTER IN THE FUTURE // TODO: would be great if there was a better way to fake the preseals - var genms []genesis.Miner - var maddrs []address.Address - var genaccs []genesis.Actor - var keys []*wallet.Key + var ( + genms []genesis.Miner + maddrs []address.Address + genaccs []genesis.Actor + keys []*wallet.Key + ) var presealDirs []string for i := 0; i < len(storage); i++ { @@ -256,7 +262,7 @@ func mockBuilderOpts(t *testing.T, fullOpts []test.FullNodeOpts, storage []test. if err != nil { t.Fatal(err) } - genm, k, err := seed.PreSeal(maddr, abi.RegisteredSealProof_StackedDrg2KiBV1, 0, test.GenesisPreseals, tdir, []byte("make genesis mem random"), nil, true) + genm, k, err := seed.PreSeal(maddr, abi.RegisteredSealProof_StackedDrg2KiBV1, 0, GenesisPreseals, tdir, []byte("make genesis mem random"), nil, true) if err != nil { t.Fatal(err) } @@ -364,17 +370,17 @@ func mockBuilderOpts(t *testing.T, fullOpts []test.FullNodeOpts, storage []test. if opts == nil { opts = node.Options() } - storers[i] = CreateTestStorageNode(ctx, t, wa, genMiner, pk, f, mn, opts) - if err := storers[i].StorageAddLocal(ctx, presealDirs[i]); err != nil { + miners[i] = CreateTestStorageNode(ctx, t, wa, genMiner, pk, f, mn, opts) + if err := miners[i].StorageAddLocal(ctx, presealDirs[i]); err != nil { t.Fatalf("%+v", err) } /* - sma := storers[i].StorageMiner.(*impl.StorageMinerAPI) + sma := miners[i].StorageMiner.(*impl.StorageMinerAPI) psd := presealDirs[i] */ if rpc { - storers[i] = storerRpc(t, storers[i]) + miners[i] = storerRpc(t, miners[i]) } } @@ -382,44 +388,49 @@ func mockBuilderOpts(t *testing.T, fullOpts []test.FullNodeOpts, storage []test. t.Fatal(err) } - if len(storers) > 0 { + if len(miners) > 0 { // Mine 2 blocks to setup some CE stuff in some actors var wait sync.Mutex wait.Lock() - test.MineUntilBlock(ctx, t, fulls[0], storers[0], func(epoch abi.ChainEpoch) { + bm := NewBlockMiner(t, miners[0]) + t.Cleanup(bm.Stop) + + bm.MineUntilBlock(ctx, fulls[0], func(epoch abi.ChainEpoch) { wait.Unlock() }) wait.Lock() - test.MineUntilBlock(ctx, t, fulls[0], storers[0], func(epoch abi.ChainEpoch) { + bm.MineUntilBlock(ctx, fulls[0], func(epoch abi.ChainEpoch) { wait.Unlock() }) wait.Lock() } - return fulls, storers + return fulls, miners } -func mockSbBuilderOpts(t *testing.T, fullOpts []test.FullNodeOpts, storage []test.StorageMiner, rpc bool) ([]test.TestNode, []test.TestStorageNode) { +func mockMinerBuilderOpts(t *testing.T, fullOpts []FullNodeOpts, storage []StorageMiner, rpc bool) ([]TestFullNode, []TestMiner) { ctx, cancel := context.WithCancel(context.Background()) t.Cleanup(cancel) mn := mocknet.New(ctx) - fulls := make([]test.TestNode, len(fullOpts)) - storers := make([]test.TestStorageNode, len(storage)) + fulls := make([]TestFullNode, len(fullOpts)) + miners := make([]TestMiner, len(storage)) var genbuf bytes.Buffer // PRESEAL SECTION, TRY TO REPLACE WITH BETTER IN THE FUTURE // TODO: would be great if there was a better way to fake the preseals - var genms []genesis.Miner - var genaccs []genesis.Actor - var maddrs []address.Address - var keys []*wallet.Key - var pidKeys []crypto.PrivKey + var ( + genms []genesis.Miner + genaccs []genesis.Actor + maddrs []address.Address + keys []*wallet.Key + pidKeys []crypto.PrivKey + ) for i := 0; i < len(storage); i++ { maddr, err := address.NewIDAddress(genesis2.MinerStart + uint64(i)) if err != nil { @@ -427,8 +438,8 @@ func mockSbBuilderOpts(t *testing.T, fullOpts []test.FullNodeOpts, storage []tes } preseals := storage[i].Preseal - if preseals == test.PresealGenesis { - preseals = test.GenesisPreseals + if preseals == PresealGenesis { + preseals = GenesisPreseals } genm, k, err := mockstorage.PreSeal(abi.RegisteredSealProof_StackedDrg2KiBV1, maddr, preseals) @@ -521,9 +532,19 @@ func mockSbBuilderOpts(t *testing.T, fullOpts []test.FullNodeOpts, storage []tes } fulls[i].Stb = storageBuilder(fulls[i], mn, node.Options( - node.Override(new(sectorstorage.SectorManager), func() (sectorstorage.SectorManager, error) { + node.Override(new(*mock.SectorMgr), func() (*mock.SectorMgr, error) { return mock.NewMockSectorMgr(nil), nil }), + + node.Override(new(sectorstorage.SectorManager), node.From(new(*mock.SectorMgr))), + node.Override(new(sectorstorage.Unsealer), node.From(new(*mock.SectorMgr))), + node.Override(new(sectorstorage.PieceProvider), node.From(new(*mock.SectorMgr))), + node.Override(new(*sectorstorage.SealerConfig), func() *sectorstorage.SealerConfig { + scfg := config.DefaultStorageMiner() + scfg.Storage.ResourceFiltering = sectorstorage.ResourceFilteringDisabled + return &scfg.Storage + }), + node.Override(new(ffiwrapper.Verifier), mock.MockVerifier), node.Override(new(ffiwrapper.Prover), mock.MockProver), node.Unset(new(*sectorstorage.Manager)), @@ -563,10 +584,15 @@ func mockSbBuilderOpts(t *testing.T, fullOpts []test.FullNodeOpts, storage []tes if opts == nil { opts = node.Options() } - storers[i] = CreateTestStorageNode(ctx, t, genms[i].Worker, maddrs[i], pidKeys[i], f, mn, node.Options( - node.Override(new(sectorstorage.SectorManager), func() (sectorstorage.SectorManager, error) { + miners[i] = CreateTestStorageNode(ctx, t, genms[i].Worker, maddrs[i], pidKeys[i], f, mn, node.Options( + node.Override(new(*mock.SectorMgr), func() (*mock.SectorMgr, error) { return mock.NewMockSectorMgr(sectors), nil }), + + node.Override(new(sectorstorage.SectorManager), node.From(new(*mock.SectorMgr))), + node.Override(new(sectorstorage.Unsealer), node.From(new(*mock.SectorMgr))), + node.Override(new(sectorstorage.PieceProvider), node.From(new(*mock.SectorMgr))), + node.Override(new(ffiwrapper.Verifier), mock.MockVerifier), node.Override(new(ffiwrapper.Prover), mock.MockProver), node.Unset(new(*sectorstorage.Manager)), @@ -574,7 +600,7 @@ func mockSbBuilderOpts(t *testing.T, fullOpts []test.FullNodeOpts, storage []tes )) if rpc { - storers[i] = storerRpc(t, storers[i]) + miners[i] = storerRpc(t, miners[i]) } } @@ -582,99 +608,63 @@ func mockSbBuilderOpts(t *testing.T, fullOpts []test.FullNodeOpts, storage []tes t.Fatal(err) } - if len(storers) > 0 { + bm := NewBlockMiner(t, miners[0]) + + if len(miners) > 0 { // Mine 2 blocks to setup some CE stuff in some actors var wait sync.Mutex wait.Lock() - test.MineUntilBlock(ctx, t, fulls[0], storers[0], func(abi.ChainEpoch) { + bm.MineUntilBlock(ctx, fulls[0], func(abi.ChainEpoch) { wait.Unlock() }) wait.Lock() - test.MineUntilBlock(ctx, t, fulls[0], storers[0], func(abi.ChainEpoch) { + bm.MineUntilBlock(ctx, fulls[0], func(abi.ChainEpoch) { wait.Unlock() }) wait.Lock() } - return fulls, storers + return fulls, miners } -func fullRpc(t *testing.T, nd test.TestNode) test.TestNode { - ma, listenAddr, err := CreateRPCServer(t, map[string]interface{}{ - "/rpc/v1": nd, - "/rpc/v0": &v0api.WrapperV1Full{FullNode: nd}, - }) - require.NoError(t, err) +func CreateRPCServer(t *testing.T, handler http.Handler) (*httptest.Server, multiaddr.Multiaddr) { + testServ := httptest.NewServer(handler) + t.Cleanup(testServ.Close) + t.Cleanup(testServ.CloseClientConnections) - var stop func() - var full test.TestNode - full.FullNode, stop, err = client.NewFullNodeRPCV1(context.Background(), listenAddr+"/rpc/v1", nil) + addr := testServ.Listener.Addr() + maddr, err := manet.FromNetAddr(addr) require.NoError(t, err) - t.Cleanup(stop) - - full.ListenAddr = ma - return full + return testServ, maddr } -func storerRpc(t *testing.T, nd test.TestStorageNode) test.TestStorageNode { - ma, listenAddr, err := CreateRPCServer(t, map[string]interface{}{ - "/rpc/v0": nd, - }) +func fullRpc(t *testing.T, nd TestFullNode) TestFullNode { + handler, err := node.FullNodeHandler(nd.FullNode, false) require.NoError(t, err) - var stop func() - var storer test.TestStorageNode - storer.StorageMiner, stop, err = client.NewStorageMinerRPCV0(context.Background(), listenAddr+"/rpc/v0", nil) + srv, maddr := CreateRPCServer(t, handler) + + var ret TestFullNode + cl, stop, err := client.NewFullNodeRPCV1(context.Background(), "ws://"+srv.Listener.Addr().String()+"/rpc/v1", nil) require.NoError(t, err) t.Cleanup(stop) + ret.ListenAddr, ret.FullNode = maddr, cl - storer.ListenAddr = ma - storer.MineOne = nd.MineOne - return storer -} - -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) - - addr := testServ.Listener.Addr() - listenAddr := "ws://" + addr.String() - ma, err := parseWSMultiAddr(addr) - if err != nil { - return nil, "", err - } - return ma, listenAddr, err + return ret } -func parseWSMultiAddr(addr net.Addr) (multiaddr.Multiaddr, error) { - host, port, err := net.SplitHostPort(addr.String()) - if err != nil { - return nil, err - } - ma, err := multiaddr.NewMultiaddr("/ip4/" + host + "/" + addr.Network() + "/" + port + "/ws") - if err != nil { - return nil, err - } - return ma, nil -} +func storerRpc(t *testing.T, nd TestMiner) TestMiner { + handler, err := node.MinerHandler(nd.StorageMiner, false) + require.NoError(t, err) -func WSMultiAddrToString(addr multiaddr.Multiaddr) (string, error) { - parts := strings.Split(addr.String(), "/") - if len(parts) != 6 || parts[0] != "" { - return "", xerrors.Errorf("Malformed ws multiaddr %s", addr) - } + srv, maddr := CreateRPCServer(t, handler) - host := parts[2] - port := parts[4] - proto := parts[5] + var ret TestMiner + cl, stop, err := client.NewStorageMinerRPCV0(context.Background(), "ws://"+srv.Listener.Addr().String()+"/rpc/v0", nil) + require.NoError(t, err) + t.Cleanup(stop) - return proto + "://" + host + ":" + port + "/rpc/v0", nil + ret.ListenAddr, ret.StorageMiner, ret.MineOne = maddr, cl, nd.MineOne + return ret } diff --git a/itests/kit/nodes.go b/itests/kit/nodes.go new file mode 100644 index 00000000000..d9b04166a50 --- /dev/null +++ b/itests/kit/nodes.go @@ -0,0 +1,153 @@ +package kit + +import ( + "context" + "testing" + + "github.com/multiformats/go-multiaddr" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/network" + + lapi "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v1api" + "github.com/filecoin-project/lotus/chain/stmgr" + "github.com/filecoin-project/lotus/miner" + "github.com/filecoin-project/lotus/node" +) + +type MinerBuilder func(context.Context, *testing.T, abi.RegisteredSealProof, address.Address) TestMiner + +type TestFullNode struct { + 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 MinerBuilder +} + +type TestMiner struct { + 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 + + MineOne func(context.Context, miner.MineReq) error + Stop func(context.Context) error +} + +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 + Opts node.Option + Preseal int +} + +type OptionGenerator func([]TestFullNode) node.Option + +// Options for setting up a mock full node +type FullNodeOpts struct { + Lite bool // run node in "lite" mode + Opts OptionGenerator // generate dependency injection options +} + +// APIBuilder is a function which is invoked in test suite to provide +// test nodes and networks +// +// fullOpts array defines options for each full node +// storage array defines storage nodes, numbers in the array specify full node +// index the storage node 'belongs' to +type APIBuilder func(t *testing.T, full []FullNodeOpts, storage []StorageMiner) ([]TestFullNode, []TestMiner) + +func DefaultFullOpts(nFull int) []FullNodeOpts { + full := make([]FullNodeOpts, nFull) + for i := range full { + full[i] = FullNodeOpts{ + Opts: func(nodes []TestFullNode) node.Option { + return node.Options() + }, + } + } + return full +} + +var OneMiner = []StorageMiner{{Full: 0, Preseal: PresealGenesis}} +var OneFull = DefaultFullOpts(1) +var TwoFull = DefaultFullOpts(2) + +var FullNodeWithLatestActorsAt = func(upgradeHeight abi.ChainEpoch) FullNodeOpts { + // Attention: Update this when introducing new actor versions or your tests will be sad + return FullNodeWithNetworkUpgradeAt(network.Version13, upgradeHeight) +} + +var FullNodeWithNetworkUpgradeAt = func(version network.Version, upgradeHeight abi.ChainEpoch) FullNodeOpts { + fullSchedule := stmgr.UpgradeSchedule{{ + // prepare for upgrade. + Network: network.Version9, + Height: 1, + Migration: stmgr.UpgradeActorsV2, + }, { + Network: network.Version10, + Height: 2, + Migration: stmgr.UpgradeActorsV3, + }, { + Network: network.Version12, + Height: 3, + Migration: stmgr.UpgradeActorsV4, + }, { + Network: network.Version13, + Height: 4, + Migration: stmgr.UpgradeActorsV5, + }} + + schedule := stmgr.UpgradeSchedule{} + for _, upgrade := range fullSchedule { + if upgrade.Network > version { + break + } + + schedule = append(schedule, upgrade) + } + + if upgradeHeight > 0 { + schedule[len(schedule)-1].Height = upgradeHeight + } + + return FullNodeOpts{ + Opts: func(nodes []TestFullNode) node.Option { + return node.Override(new(stmgr.UpgradeSchedule), schedule) + }, + } +} + +var FullNodeWithSDRAt = func(calico, persian abi.ChainEpoch) FullNodeOpts { + return FullNodeOpts{ + Opts: func(nodes []TestFullNode) node.Option { + return node.Override(new(stmgr.UpgradeSchedule), stmgr.UpgradeSchedule{{ + Network: network.Version6, + Height: 1, + Migration: stmgr.UpgradeActorsV2, + }, { + Network: network.Version7, + Height: calico, + Migration: stmgr.UpgradeCalico, + }, { + Network: network.Version8, + Height: persian, + }}) + }, + } +} + +var MineNext = miner.MineReq{ + InjectNulls: 0, + Done: func(bool, abi.ChainEpoch, error) {}, +} diff --git a/itests/kit/pledge.go b/itests/kit/pledge.go new file mode 100644 index 00000000000..254f87bac58 --- /dev/null +++ b/itests/kit/pledge.go @@ -0,0 +1,88 @@ +package kit + +import ( + "context" + "fmt" + "strings" + "testing" + "time" + + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/build" + sealing "github.com/filecoin-project/lotus/extern/storage-sealing" + "github.com/stretchr/testify/require" +) + +func PledgeSectors(t *testing.T, ctx context.Context, miner TestMiner, n, existing int, blockNotif <-chan struct{}) { //nolint:golint + toCheck := StartPledge(t, ctx, miner, n, existing, blockNotif) + + for len(toCheck) > 0 { + flushSealingBatches(t, ctx, miner) + + states := map[api.SectorState]int{} + for n := range toCheck { + st, err := miner.SectorsStatus(ctx, n, false) + require.NoError(t, err) + states[st.State]++ + if st.State == api.SectorState(sealing.Proving) { + delete(toCheck, n) + } + if strings.Contains(string(st.State), "Fail") { + t.Fatal("sector in a failed state", st.State) + } + } + + build.Clock.Sleep(100 * time.Millisecond) + fmt.Printf("WaitSeal: %d %+v\n", len(toCheck), states) + } +} + +func flushSealingBatches(t *testing.T, ctx context.Context, miner TestMiner) { //nolint:golint + pcb, err := miner.SectorPreCommitFlush(ctx) + require.NoError(t, err) + if pcb != nil { + fmt.Printf("PRECOMMIT BATCH: %+v\n", pcb) + } + + cb, err := miner.SectorCommitFlush(ctx) + require.NoError(t, err) + if cb != nil { + fmt.Printf("COMMIT BATCH: %+v\n", cb) + } +} + +func StartPledge(t *testing.T, ctx context.Context, miner TestMiner, n, existing int, blockNotif <-chan struct{}) map[abi.SectorNumber]struct{} { //nolint:golint + for i := 0; i < n; i++ { + if i%3 == 0 && blockNotif != nil { + <-blockNotif + t.Log("WAIT") + } + t.Logf("PLEDGING %d", i) + _, err := miner.PledgeSector(ctx) + require.NoError(t, err) + } + + for { + s, err := miner.SectorsList(ctx) // Note - the test builder doesn't import genesis sectors into FSM + require.NoError(t, err) + fmt.Printf("Sectors: %d\n", len(s)) + if len(s) >= n+existing { + break + } + + build.Clock.Sleep(100 * time.Millisecond) + } + + fmt.Printf("All sectors is fsm\n") + + s, err := miner.SectorsList(ctx) + require.NoError(t, err) + + toCheck := map[abi.SectorNumber]struct{}{} + for _, number := range s { + toCheck[number] = struct{}{} + } + + return toCheck +} diff --git a/itests/kit/run.go b/itests/kit/run.go new file mode 100644 index 00000000000..713efa3b831 --- /dev/null +++ b/itests/kit/run.go @@ -0,0 +1,20 @@ +package kit + +import ( + "os" + "testing" +) + +// EnvRunExpensiveTests is the environment variable that needs to be present +// and set to value "1" to enable running expensive tests outside of CI. +const EnvRunExpensiveTests = "LOTUS_RUN_EXPENSIVE_TESTS" + +// Expensive marks a test as expensive, skipping it immediately if not running an +func Expensive(t *testing.T) { + switch { + case os.Getenv("CI") == "true": + return + case os.Getenv(EnvRunExpensiveTests) != "1": + t.Skipf("skipping expensive test outside of CI; enable by setting env var %s=1", EnvRunExpensiveTests) + } +} diff --git a/cli/test/multisig.go b/itests/multisig/suite.go similarity index 89% rename from cli/test/multisig.go rename to itests/multisig/suite.go index 5a60894e650..31113cb1002 100644 --- a/cli/test/multisig.go +++ b/itests/multisig/suite.go @@ -1,4 +1,4 @@ -package test +package multisig import ( "context" @@ -8,17 +8,16 @@ import ( "testing" "github.com/filecoin-project/go-address" - "github.com/filecoin-project/lotus/api/test" "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/cli" + "github.com/filecoin-project/lotus/itests/kit" "github.com/stretchr/testify/require" - lcli "github.com/urfave/cli/v2" ) -func RunMultisigTest(t *testing.T, cmds []*lcli.Command, clientNode test.TestNode) { - ctx := context.Background() - +func RunMultisigTests(t *testing.T, clientNode kit.TestFullNode) { // Create mock CLI - mockCLI := NewMockCLI(ctx, t, cmds) + ctx := context.Background() + mockCLI := kit.NewMockCLI(ctx, t, cli.Commands) clientCLI := mockCLI.Client(clientNode.ListenAddr) // Create some wallets on the node to use for testing multisig @@ -29,7 +28,7 @@ func RunMultisigTest(t *testing.T, cmds []*lcli.Command, clientNode test.TestNod walletAddrs = append(walletAddrs, addr) - test.SendFunds(ctx, t, clientNode, addr, types.NewInt(1e15)) + kit.SendFunds(ctx, t, clientNode, addr, types.NewInt(1e15)) } // Create an msig with three of the addresses and threshold of two sigs diff --git a/itests/multisig_test.go b/itests/multisig_test.go new file mode 100644 index 00000000000..f30b26641d8 --- /dev/null +++ b/itests/multisig_test.go @@ -0,0 +1,23 @@ +package itests + +import ( + "context" + "os" + "testing" + "time" + + "github.com/filecoin-project/lotus/itests/kit" + "github.com/filecoin-project/lotus/itests/multisig" +) + +// TestMultisig does a basic test to exercise the multisig CLI commands +func TestMultisig(t *testing.T) { + _ = os.Setenv("BELLMAN_NO_GPU", "1") + kit.QuietMiningLogs() + + blocktime := 5 * time.Millisecond + ctx := context.Background() + clientNode, _ := kit.StartOneNodeOneMiner(ctx, t, blocktime) + + multisig.RunMultisigTests(t, clientNode) +} diff --git a/api/test/paych.go b/itests/paych_api_test.go similarity index 92% rename from api/test/paych.go rename to itests/paych_api_test.go index 93a083c4a8c..23fec855b48 100644 --- a/api/test/paych.go +++ b/itests/paych_api_test.go @@ -1,14 +1,14 @@ -package test +package itests import ( "context" "fmt" - "sync/atomic" "testing" "time" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/lotus/itests/kit" "github.com/ipfs/go-cid" "github.com/filecoin-project/go-address" @@ -26,9 +26,11 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) -func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) { +func TestPaymentChannelsAPI(t *testing.T) { + kit.QuietMiningLogs() + ctx := context.Background() - n, sn := b(t, TwoFull, OneMiner) + n, sn := kit.MockMinerBuilder(t, kit.TwoFull, kit.OneMiner) paymentCreator := n[0] paymentReceiver := n[1] @@ -49,8 +51,9 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) { } // start mining blocks - bm := NewBlockMiner(ctx, t, miner, blocktime) - bm.MineBlocks() + bm := kit.NewBlockMiner(t, miner) + bm.MineBlocks(ctx, 5*time.Millisecond) + t.Cleanup(bm.Stop) // send some funds to register the receiver receiverAddr, err := paymentReceiver.WalletNew(ctx, types.KTSecp256k1) @@ -58,7 +61,7 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) { t.Fatal(err) } - SendFunds(ctx, t, paymentCreator, receiverAddr, abi.NewTokenAmount(1e18)) + kit.SendFunds(ctx, t, paymentCreator, receiverAddr, abi.NewTokenAmount(1e18)) // setup the payment channel createrAddr, err := paymentCreator.WalletDefaultAddress(ctx) @@ -173,7 +176,7 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) { select { case <-finished: - case <-time.After(time.Second): + case <-time.After(10 * time.Second): t.Fatal("Timed out waiting for receiver to submit vouchers") } @@ -265,7 +268,7 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) { bm.Stop() } -func waitForBlocks(ctx context.Context, t *testing.T, bm *BlockMiner, paymentReceiver TestNode, receiverAddr address.Address, count int) { +func waitForBlocks(ctx context.Context, t *testing.T, bm *kit.BlockMiner, paymentReceiver kit.TestFullNode, receiverAddr address.Address, count int) { // We need to add null blocks in batches, if we add too many the chain can't sync batchSize := 60 for i := 0; i < count; i += batchSize { @@ -274,8 +277,8 @@ func waitForBlocks(ctx context.Context, t *testing.T, bm *BlockMiner, paymentRec size = count - i } - // Add a batch of null blocks - atomic.StoreInt64(&bm.nulls, int64(size-1)) + // Add a batch of null blocks to advance the chain quicker through finalities. + bm.InjectNulls(abi.ChainEpoch(size - 1)) // Add a real block m, err := paymentReceiver.MpoolPushMessage(ctx, &types.Message{ @@ -294,7 +297,7 @@ func waitForBlocks(ctx context.Context, t *testing.T, bm *BlockMiner, paymentRec } } -func waitForMessage(ctx context.Context, t *testing.T, paymentCreator TestNode, msgCid cid.Cid, duration time.Duration, desc string) *api.MsgLookup { +func waitForMessage(ctx context.Context, t *testing.T, paymentCreator kit.TestFullNode, msgCid cid.Cid, duration time.Duration, desc string) *api.MsgLookup { ctx, cancel := context.WithTimeout(ctx, duration) defer cancel() diff --git a/cli/paych_test.go b/itests/paych_cli_test.go similarity index 93% rename from cli/paych_test.go rename to itests/paych_cli_test.go index 44d0a41e7a0..373b6f43bfd 100644 --- a/cli/paych_test.go +++ b/itests/paych_cli_test.go @@ -1,4 +1,4 @@ -package cli +package itests import ( "context" @@ -10,7 +10,8 @@ import ( "testing" "time" - clitest "github.com/filecoin-project/lotus/cli/test" + "github.com/filecoin-project/lotus/cli" + "github.com/filecoin-project/lotus/itests/kit" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" @@ -20,7 +21,6 @@ import ( cbor "github.com/ipfs/go-ipld-cbor" "github.com/stretchr/testify/require" - "github.com/filecoin-project/lotus/api/test" "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/events" @@ -35,20 +35,20 @@ func init() { // TestPaymentChannels does a basic test to exercise the payment channel CLI // commands -func TestPaymentChannels(t *testing.T) { +func TestPaymentChannelsBasic(t *testing.T) { _ = os.Setenv("BELLMAN_NO_GPU", "1") - clitest.QuietMiningLogs() + kit.QuietMiningLogs() blocktime := 5 * time.Millisecond ctx := context.Background() - nodes, addrs := clitest.StartTwoNodesOneMiner(ctx, t, blocktime) + nodes, addrs := kit.StartTwoNodesOneMiner(ctx, t, blocktime) paymentCreator := nodes[0] paymentReceiver := nodes[1] creatorAddr := addrs[0] receiverAddr := addrs[1] // Create mock CLI - mockCLI := clitest.NewMockCLI(ctx, t, Commands) + mockCLI := kit.NewMockCLI(ctx, t, cli.Commands) creatorCLI := mockCLI.Client(paymentCreator.ListenAddr) receiverCLI := mockCLI.Client(paymentReceiver.ListenAddr) @@ -89,17 +89,17 @@ type voucherSpec struct { // TestPaymentChannelStatus tests the payment channel status CLI command func TestPaymentChannelStatus(t *testing.T) { _ = os.Setenv("BELLMAN_NO_GPU", "1") - clitest.QuietMiningLogs() + kit.QuietMiningLogs() blocktime := 5 * time.Millisecond ctx := context.Background() - nodes, addrs := clitest.StartTwoNodesOneMiner(ctx, t, blocktime) + nodes, addrs := kit.StartTwoNodesOneMiner(ctx, t, blocktime) paymentCreator := nodes[0] creatorAddr := addrs[0] receiverAddr := addrs[1] // Create mock CLI - mockCLI := clitest.NewMockCLI(ctx, t, Commands) + mockCLI := kit.NewMockCLI(ctx, t, cli.Commands) creatorCLI := mockCLI.Client(paymentCreator.ListenAddr) // creator: paych status-by-from-to @@ -168,18 +168,18 @@ func TestPaymentChannelStatus(t *testing.T) { // channel voucher commands func TestPaymentChannelVouchers(t *testing.T) { _ = os.Setenv("BELLMAN_NO_GPU", "1") - clitest.QuietMiningLogs() + kit.QuietMiningLogs() blocktime := 5 * time.Millisecond ctx := context.Background() - nodes, addrs := clitest.StartTwoNodesOneMiner(ctx, t, blocktime) + nodes, addrs := kit.StartTwoNodesOneMiner(ctx, t, blocktime) paymentCreator := nodes[0] paymentReceiver := nodes[1] creatorAddr := addrs[0] receiverAddr := addrs[1] // Create mock CLI - mockCLI := clitest.NewMockCLI(ctx, t, Commands) + mockCLI := kit.NewMockCLI(ctx, t, cli.Commands) creatorCLI := mockCLI.Client(paymentCreator.ListenAddr) receiverCLI := mockCLI.Client(paymentReceiver.ListenAddr) @@ -300,17 +300,17 @@ func TestPaymentChannelVouchers(t *testing.T) { // is greater than what's left in the channel, voucher create fails func TestPaymentChannelVoucherCreateShortfall(t *testing.T) { _ = os.Setenv("BELLMAN_NO_GPU", "1") - clitest.QuietMiningLogs() + kit.QuietMiningLogs() blocktime := 5 * time.Millisecond ctx := context.Background() - nodes, addrs := clitest.StartTwoNodesOneMiner(ctx, t, blocktime) + nodes, addrs := kit.StartTwoNodesOneMiner(ctx, t, blocktime) paymentCreator := nodes[0] creatorAddr := addrs[0] receiverAddr := addrs[1] // Create mock CLI - mockCLI := clitest.NewMockCLI(ctx, t, Commands) + mockCLI := kit.NewMockCLI(ctx, t, cli.Commands) creatorCLI := mockCLI.Client(paymentCreator.ListenAddr) // creator: paych add-funds @@ -378,7 +378,7 @@ func checkVoucherOutput(t *testing.T, list string, vouchers []voucherSpec) { } // waitForHeight waits for the node to reach the given chain epoch -func waitForHeight(ctx context.Context, t *testing.T, node test.TestNode, height abi.ChainEpoch) { +func waitForHeight(ctx context.Context, t *testing.T, node kit.TestFullNode, height abi.ChainEpoch) { atHeight := make(chan struct{}) chainEvents := events.NewEvents(ctx, node) err := chainEvents.ChainAt(func(ctx context.Context, ts *types.TipSet, curH abi.ChainEpoch) error { @@ -396,7 +396,7 @@ func waitForHeight(ctx context.Context, t *testing.T, node test.TestNode, height } // getPaychState gets the state of the payment channel with the given address -func getPaychState(ctx context.Context, t *testing.T, node test.TestNode, chAddr address.Address) paych.State { +func getPaychState(ctx context.Context, t *testing.T, node kit.TestFullNode, chAddr address.Address) paych.State { act, err := node.StateGetActor(ctx, chAddr, types.EmptyTSK) require.NoError(t, err) diff --git a/itests/sdr_upgrade_test.go b/itests/sdr_upgrade_test.go new file mode 100644 index 00000000000..dfb4284b9f1 --- /dev/null +++ b/itests/sdr_upgrade_test.go @@ -0,0 +1,112 @@ +package itests + +import ( + "context" + "sort" + "sync/atomic" + "testing" + "time" + + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/network" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/itests/kit" + bminer "github.com/filecoin-project/lotus/miner" + "github.com/filecoin-project/lotus/node/impl" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestSDRUpgrade(t *testing.T) { + kit.QuietMiningLogs() + + // oldDelay := policy.GetPreCommitChallengeDelay() + // policy.SetPreCommitChallengeDelay(5) + // t.Cleanup(func() { + // policy.SetPreCommitChallengeDelay(oldDelay) + // }) + + blocktime := 50 * time.Millisecond + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + n, sn := kit.MockMinerBuilder(t, []kit.FullNodeOpts{kit.FullNodeWithSDRAt(500, 1000)}, kit.OneMiner) + client := n[0].FullNode.(*impl.FullNodeAPI) + miner := sn[0] + + addrinfo, err := client.NetAddrsListen(ctx) + if err != nil { + t.Fatal(err) + } + + if err := miner.NetConnect(ctx, addrinfo); err != nil { + t.Fatal(err) + } + build.Clock.Sleep(time.Second) + + pledge := make(chan struct{}) + mine := int64(1) + done := make(chan struct{}) + go func() { + defer close(done) + round := 0 + for atomic.LoadInt64(&mine) != 0 { + build.Clock.Sleep(blocktime) + if err := sn[0].MineOne(ctx, bminer.MineReq{Done: func(bool, abi.ChainEpoch, error) { + + }}); err != nil { + t.Error(err) + } + + // 3 sealing rounds: before, during after. + if round >= 3 { + continue + } + + head, err := client.ChainHead(ctx) + assert.NoError(t, err) + + // rounds happen every 100 blocks, with a 50 block offset. + if head.Height() >= abi.ChainEpoch(round*500+50) { + round++ + pledge <- struct{}{} + + ver, err := client.StateNetworkVersion(ctx, head.Key()) + assert.NoError(t, err) + switch round { + case 1: + assert.Equal(t, network.Version6, ver) + case 2: + assert.Equal(t, network.Version7, ver) + case 3: + assert.Equal(t, network.Version8, ver) + } + } + + } + }() + + // before. + kit.PledgeSectors(t, ctx, miner, 9, 0, pledge) + + s, err := miner.SectorsList(ctx) + require.NoError(t, err) + sort.Slice(s, func(i, j int) bool { + return s[i] < s[j] + }) + + for i, id := range s { + info, err := miner.SectorsStatus(ctx, id, true) + require.NoError(t, err) + expectProof := abi.RegisteredSealProof_StackedDrg2KiBV1 + if i >= 3 { + // after + expectProof = abi.RegisteredSealProof_StackedDrg2KiBV1_1 + } + assert.Equal(t, expectProof, info.SealProof, "sector %d, id %d", i, id) + } + + atomic.StoreInt64(&mine, 0) + <-done +} diff --git a/itests/sector_pledge_test.go b/itests/sector_pledge_test.go new file mode 100644 index 00000000000..e3d2a843cf8 --- /dev/null +++ b/itests/sector_pledge_test.go @@ -0,0 +1,261 @@ +package itests + +import ( + "context" + "fmt" + "strings" + "sync/atomic" + "testing" + "time" + + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/network" + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/stmgr" + sealing "github.com/filecoin-project/lotus/extern/storage-sealing" + "github.com/filecoin-project/lotus/itests/kit" + bminer "github.com/filecoin-project/lotus/miner" + "github.com/filecoin-project/lotus/node" + "github.com/filecoin-project/lotus/node/impl" + "github.com/stretchr/testify/require" +) + +func TestPledgeSectors(t *testing.T) { + kit.QuietMiningLogs() + + runTest := func(t *testing.T, b kit.APIBuilder, blocktime time.Duration, nSectors int) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + n, sn := b(t, kit.OneFull, kit.OneMiner) + client := n[0].FullNode.(*impl.FullNodeAPI) + miner := sn[0] + + addrinfo, err := client.NetAddrsListen(ctx) + if err != nil { + t.Fatal(err) + } + + if err := miner.NetConnect(ctx, addrinfo); err != nil { + t.Fatal(err) + } + build.Clock.Sleep(time.Second) + + mine := int64(1) + done := make(chan struct{}) + go func() { + defer close(done) + for atomic.LoadInt64(&mine) != 0 { + build.Clock.Sleep(blocktime) + if err := sn[0].MineOne(ctx, bminer.MineReq{Done: func(bool, abi.ChainEpoch, error) { + + }}); err != nil { + t.Error(err) + } + } + }() + + kit.PledgeSectors(t, ctx, miner, nSectors, 0, nil) + + atomic.StoreInt64(&mine, 0) + <-done + } + + t.Run("1", func(t *testing.T) { + runTest(t, kit.MockMinerBuilder, 50*time.Millisecond, 1) + }) + + t.Run("100", func(t *testing.T) { + runTest(t, kit.MockMinerBuilder, 50*time.Millisecond, 100) + }) + + t.Run("1000", func(t *testing.T) { + if testing.Short() { // takes ~16s + t.Skip("skipping test in short mode") + } + + runTest(t, kit.MockMinerBuilder, 50*time.Millisecond, 1000) + }) +} + +func TestPledgeBatching(t *testing.T) { + runTest := func(t *testing.T, b kit.APIBuilder, blocktime time.Duration, nSectors int) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + n, sn := b(t, []kit.FullNodeOpts{kit.FullNodeWithLatestActorsAt(-1)}, kit.OneMiner) + client := n[0].FullNode.(*impl.FullNodeAPI) + miner := sn[0] + + addrinfo, err := client.NetAddrsListen(ctx) + if err != nil { + t.Fatal(err) + } + + if err := miner.NetConnect(ctx, addrinfo); err != nil { + t.Fatal(err) + } + build.Clock.Sleep(time.Second) + + mine := int64(1) + done := make(chan struct{}) + go func() { + defer close(done) + for atomic.LoadInt64(&mine) != 0 { + build.Clock.Sleep(blocktime) + if err := sn[0].MineOne(ctx, bminer.MineReq{Done: func(bool, abi.ChainEpoch, error) { + + }}); err != nil { + t.Error(err) + } + } + }() + + for { + h, err := client.ChainHead(ctx) + require.NoError(t, err) + if h.Height() > 10 { + break + } + } + + toCheck := kit.StartPledge(t, ctx, miner, nSectors, 0, nil) + + for len(toCheck) > 0 { + states := map[api.SectorState]int{} + + for n := range toCheck { + st, err := miner.SectorsStatus(ctx, n, false) + require.NoError(t, err) + states[st.State]++ + if st.State == api.SectorState(sealing.Proving) { + delete(toCheck, n) + } + if strings.Contains(string(st.State), "Fail") { + t.Fatal("sector in a failed state", st.State) + } + } + if states[api.SectorState(sealing.SubmitPreCommitBatch)] == nSectors || + (states[api.SectorState(sealing.SubmitPreCommitBatch)] > 0 && states[api.SectorState(sealing.PreCommit1)] == 0 && states[api.SectorState(sealing.PreCommit2)] == 0) { + pcb, err := miner.SectorPreCommitFlush(ctx) + require.NoError(t, err) + if pcb != nil { + fmt.Printf("PRECOMMIT BATCH: %+v\n", pcb) + } + } + + if states[api.SectorState(sealing.SubmitCommitAggregate)] == nSectors || + (states[api.SectorState(sealing.SubmitCommitAggregate)] > 0 && states[api.SectorState(sealing.WaitSeed)] == 0 && states[api.SectorState(sealing.Committing)] == 0) { + cb, err := miner.SectorCommitFlush(ctx) + require.NoError(t, err) + if cb != nil { + fmt.Printf("COMMIT BATCH: %+v\n", cb) + } + } + + build.Clock.Sleep(100 * time.Millisecond) + fmt.Printf("WaitSeal: %d %+v\n", len(toCheck), states) + } + + atomic.StoreInt64(&mine, 0) + <-done + } + + t.Run("100", func(t *testing.T) { + runTest(t, kit.MockMinerBuilder, 50*time.Millisecond, 100) + }) +} + +func TestPledgeBeforeNv13(t *testing.T) { + runTest := func(t *testing.T, b kit.APIBuilder, blocktime time.Duration, nSectors int) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + n, sn := b(t, []kit.FullNodeOpts{ + { + Opts: func(nodes []kit.TestFullNode) node.Option { + return node.Override(new(stmgr.UpgradeSchedule), stmgr.UpgradeSchedule{{ + Network: network.Version9, + Height: 1, + Migration: stmgr.UpgradeActorsV2, + }, { + Network: network.Version10, + Height: 2, + Migration: stmgr.UpgradeActorsV3, + }, { + Network: network.Version12, + Height: 3, + Migration: stmgr.UpgradeActorsV4, + }, { + Network: network.Version13, + Height: 1000000000, + Migration: stmgr.UpgradeActorsV5, + }}) + }, + }, + }, kit.OneMiner) + client := n[0].FullNode.(*impl.FullNodeAPI) + miner := sn[0] + + addrinfo, err := client.NetAddrsListen(ctx) + if err != nil { + t.Fatal(err) + } + + if err := miner.NetConnect(ctx, addrinfo); err != nil { + t.Fatal(err) + } + build.Clock.Sleep(time.Second) + + mine := int64(1) + done := make(chan struct{}) + go func() { + defer close(done) + for atomic.LoadInt64(&mine) != 0 { + build.Clock.Sleep(blocktime) + if err := sn[0].MineOne(ctx, bminer.MineReq{Done: func(bool, abi.ChainEpoch, error) { + + }}); err != nil { + t.Error(err) + } + } + }() + + for { + h, err := client.ChainHead(ctx) + require.NoError(t, err) + if h.Height() > 10 { + break + } + } + + toCheck := kit.StartPledge(t, ctx, miner, nSectors, 0, nil) + + for len(toCheck) > 0 { + states := map[api.SectorState]int{} + + for n := range toCheck { + st, err := miner.SectorsStatus(ctx, n, false) + require.NoError(t, err) + states[st.State]++ + if st.State == api.SectorState(sealing.Proving) { + delete(toCheck, n) + } + if strings.Contains(string(st.State), "Fail") { + t.Fatal("sector in a failed state", st.State) + } + } + + build.Clock.Sleep(100 * time.Millisecond) + fmt.Printf("WaitSeal: %d %+v\n", len(toCheck), states) + } + + atomic.StoreInt64(&mine, 0) + <-done + } + + t.Run("100-before-nv13", func(t *testing.T) { + runTest(t, kit.MockMinerBuilder, 50*time.Millisecond, 100) + }) +} diff --git a/itests/sector_terminate_test.go b/itests/sector_terminate_test.go new file mode 100644 index 00000000000..73b4e443cb0 --- /dev/null +++ b/itests/sector_terminate_test.go @@ -0,0 +1,198 @@ +package itests + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/filecoin-project/go-bitfield" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/types" + sealing "github.com/filecoin-project/lotus/extern/storage-sealing" + "github.com/filecoin-project/lotus/itests/kit" + "github.com/filecoin-project/lotus/node/impl" + "github.com/stretchr/testify/require" +) + +func TestTerminate(t *testing.T) { + kit.Expensive(t) + + kit.QuietMiningLogs() + + const blocktime = 2 * time.Millisecond + + nSectors := uint64(2) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + n, sn := kit.MockMinerBuilder(t, + []kit.FullNodeOpts{kit.FullNodeWithLatestActorsAt(-1)}, + []kit.StorageMiner{{Full: 0, Preseal: int(nSectors)}}, + ) + + client := n[0].FullNode.(*impl.FullNodeAPI) + miner := sn[0] + + addrinfo, err := client.NetAddrsListen(ctx) + if err != nil { + t.Fatal(err) + } + + if err := miner.NetConnect(ctx, addrinfo); err != nil { + t.Fatal(err) + } + build.Clock.Sleep(time.Second) + + done := make(chan struct{}) + go func() { + defer close(done) + for ctx.Err() == nil { + build.Clock.Sleep(blocktime) + if err := sn[0].MineOne(ctx, kit.MineNext); err != nil { + if ctx.Err() != nil { + // context was canceled, ignore the error. + return + } + t.Error(err) + } + } + }() + defer func() { + cancel() + <-done + }() + + maddr, err := miner.ActorAddress(ctx) + require.NoError(t, err) + + ssz, err := miner.ActorSectorSize(ctx, maddr) + require.NoError(t, err) + + p, err := client.StateMinerPower(ctx, maddr, types.EmptyTSK) + require.NoError(t, err) + require.Equal(t, p.MinerPower, p.TotalPower) + require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz)*nSectors)) + + fmt.Printf("Seal a sector\n") + + kit.PledgeSectors(t, ctx, miner, 1, 0, nil) + + fmt.Printf("wait for power\n") + + { + // Wait until proven. + di, err := client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK) + require.NoError(t, err) + + waitUntil := di.PeriodStart + di.WPoStProvingPeriod + 2 + fmt.Printf("End for head.Height > %d\n", waitUntil) + + for { + head, err := client.ChainHead(ctx) + require.NoError(t, err) + + if head.Height() > waitUntil { + fmt.Printf("Now head.Height = %d\n", head.Height()) + break + } + } + } + + nSectors++ + + p, err = client.StateMinerPower(ctx, maddr, types.EmptyTSK) + require.NoError(t, err) + require.Equal(t, p.MinerPower, p.TotalPower) + require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz)*nSectors)) + + fmt.Println("Terminate a sector") + + toTerminate := abi.SectorNumber(3) + + err = miner.SectorTerminate(ctx, toTerminate) + require.NoError(t, err) + + msgTriggerred := false +loop: + for { + si, err := miner.SectorsStatus(ctx, toTerminate, false) + require.NoError(t, err) + + fmt.Println("state: ", si.State, msgTriggerred) + + switch sealing.SectorState(si.State) { + case sealing.Terminating: + if !msgTriggerred { + { + p, err := miner.SectorTerminatePending(ctx) + require.NoError(t, err) + require.Len(t, p, 1) + require.Equal(t, abi.SectorNumber(3), p[0].Number) + } + + c, err := miner.SectorTerminateFlush(ctx) + require.NoError(t, err) + if c != nil { + msgTriggerred = true + fmt.Println("terminate message:", c) + + { + p, err := miner.SectorTerminatePending(ctx) + require.NoError(t, err) + require.Len(t, p, 0) + } + } + } + case sealing.TerminateWait, sealing.TerminateFinality, sealing.Removed: + break loop + } + + time.Sleep(100 * time.Millisecond) + } + + // check power decreased + p, err = client.StateMinerPower(ctx, maddr, types.EmptyTSK) + require.NoError(t, err) + require.Equal(t, p.MinerPower, p.TotalPower) + require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz)*(nSectors-1))) + + // check in terminated set + { + parts, err := client.StateMinerPartitions(ctx, maddr, 1, types.EmptyTSK) + require.NoError(t, err) + require.Greater(t, len(parts), 0) + + bflen := func(b bitfield.BitField) uint64 { + l, err := b.Count() + require.NoError(t, err) + return l + } + + require.Equal(t, uint64(1), bflen(parts[0].AllSectors)) + require.Equal(t, uint64(0), bflen(parts[0].LiveSectors)) + } + + di, err := client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK) + require.NoError(t, err) + for { + head, err := client.ChainHead(ctx) + require.NoError(t, err) + + if head.Height() > di.PeriodStart+di.WPoStProvingPeriod+2 { + fmt.Printf("Now head.Height = %d\n", head.Height()) + break + } + build.Clock.Sleep(blocktime) + } + require.NoError(t, err) + fmt.Printf("End for head.Height > %d\n", di.PeriodStart+di.WPoStProvingPeriod+2) + + p, err = client.StateMinerPower(ctx, maddr, types.EmptyTSK) + require.NoError(t, err) + + require.Equal(t, p.MinerPower, p.TotalPower) + require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz)*(nSectors-1))) +} diff --git a/api/test/tape.go b/itests/tape_test.go similarity index 78% rename from api/test/tape.go rename to itests/tape_test.go index 74206a97a32..5c0cadc3f4e 100644 --- a/api/test/tape.go +++ b/itests/tape_test.go @@ -1,4 +1,4 @@ -package test +package itests import ( "context" @@ -11,18 +11,24 @@ import ( "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/stmgr" sealing "github.com/filecoin-project/lotus/extern/storage-sealing" + "github.com/filecoin-project/lotus/itests/kit" "github.com/filecoin-project/lotus/node" "github.com/filecoin-project/lotus/node/impl" "github.com/stretchr/testify/require" ) -func TestTapeFix(t *testing.T, b APIBuilder, blocktime time.Duration) { +func TestTapeFix(t *testing.T) { + kit.QuietMiningLogs() + + var blocktime = 2 * time.Millisecond + // The "before" case is disabled, because we need the builder to mock 32 GiB sectors to accurately repro this case // TODO: Make the mock sector size configurable and reenable this - //t.Run("before", func(t *testing.T) { testTapeFix(t, b, blocktime, false) }) - t.Run("after", func(t *testing.T) { testTapeFix(t, b, blocktime, true) }) + // t.Run("before", func(t *testing.T) { testTapeFix(t, b, blocktime, false) }) + t.Run("after", func(t *testing.T) { testTapeFix(t, kit.MockMinerBuilder, blocktime, true) }) } -func testTapeFix(t *testing.T, b APIBuilder, blocktime time.Duration, after bool) { + +func testTapeFix(t *testing.T, b kit.APIBuilder, blocktime time.Duration, after bool) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -38,9 +44,9 @@ func testTapeFix(t *testing.T, b APIBuilder, blocktime time.Duration, after bool }) } - n, sn := b(t, []FullNodeOpts{{Opts: func(_ []TestNode) node.Option { + n, sn := b(t, []kit.FullNodeOpts{{Opts: func(_ []kit.TestFullNode) node.Option { return node.Override(new(stmgr.UpgradeSchedule), upgradeSchedule) - }}}, OneMiner) + }}}, kit.OneMiner) client := n[0].FullNode.(*impl.FullNodeAPI) miner := sn[0] @@ -60,7 +66,7 @@ func testTapeFix(t *testing.T, b APIBuilder, blocktime time.Duration, after bool defer close(done) for ctx.Err() == nil { build.Clock.Sleep(blocktime) - if err := sn[0].MineOne(ctx, MineNext); err != nil { + if err := sn[0].MineOne(ctx, kit.MineNext); err != nil { if ctx.Err() != nil { // context was canceled, ignore the error. return @@ -97,5 +103,4 @@ func testTapeFix(t *testing.T, b APIBuilder, blocktime time.Duration, after bool build.Clock.Sleep(100 * time.Millisecond) fmt.Println("WaitSeal") } - } diff --git a/api/test/verifreg.go b/itests/verifreg_test.go similarity index 91% rename from api/test/verifreg.go rename to itests/verifreg_test.go index 3fc1fb75af1..b3555cc0634 100644 --- a/api/test/verifreg.go +++ b/itests/verifreg_test.go @@ -1,10 +1,13 @@ -package test +package itests import ( "context" "strings" + "testing" + "time" "github.com/filecoin-project/go-state-types/network" + "github.com/filecoin-project/lotus/itests/kit" lapi "github.com/filecoin-project/lotus/api" @@ -13,18 +16,14 @@ import ( "github.com/filecoin-project/lotus/node/impl" verifreg4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/verifreg" - "testing" - "time" - "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/lotus/chain/types" ) -func AddVerifiedClient(t *testing.T, b APIBuilder) { +func TestVerifiedClientTopUp(t *testing.T) { test := func(nv network.Version, shouldWork bool) func(*testing.T) { return func(t *testing.T) { - - nodes, miners := b(t, []FullNodeOpts{FullNodeWithNetworkUpgradeAt(nv, -1)}, OneMiner) + nodes, miners := kit.MockMinerBuilder(t, []kit.FullNodeOpts{kit.FullNodeWithNetworkUpgradeAt(nv, -1)}, kit.OneMiner) api := nodes[0].FullNode.(*impl.FullNodeAPI) ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -53,9 +52,9 @@ func AddVerifiedClient(t *testing.T, b APIBuilder) { Value: big.Zero(), } - bm := NewBlockMiner(ctx, t, miners[0], 100*time.Millisecond) - bm.MineBlocks() - defer bm.Stop() + bm := kit.NewBlockMiner(t, miners[0]) + bm.MineBlocks(ctx, 100*time.Millisecond) + t.Cleanup(bm.Stop) sm, err := api.MpoolPushMessage(ctx, msg, nil) if err != nil { diff --git a/itests/wdpost_dispute_test.go b/itests/wdpost_dispute_test.go new file mode 100644 index 00000000000..b665667a33c --- /dev/null +++ b/itests/wdpost_dispute_test.go @@ -0,0 +1,453 @@ +package itests + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-bitfield" + "github.com/filecoin-project/go-state-types/crypto" + "github.com/filecoin-project/go-state-types/dline" + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/actors" + minerActor "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/itests/kit" + "github.com/filecoin-project/lotus/node/impl" + proof3 "github.com/filecoin-project/specs-actors/v3/actors/runtime/proof" + "github.com/stretchr/testify/require" +) + +func TestWindowPostDispute(t *testing.T) { + kit.Expensive(t) + + kit.QuietMiningLogs() + + b := kit.MockMinerBuilder + blocktime := 2 * time.Millisecond + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + // First, we configure two miners. After sealing, we're going to turn off the first miner so + // it doesn't submit proofs. + // + // Then we're going to manually submit bad proofs. + n, sn := b(t, + []kit.FullNodeOpts{kit.FullNodeWithLatestActorsAt(-1)}, + []kit.StorageMiner{ + {Full: 0, Preseal: kit.PresealGenesis}, + {Full: 0}, + }) + + client := n[0].FullNode.(*impl.FullNodeAPI) + chainMiner := sn[0] + evilMiner := sn[1] + + { + addrinfo, err := client.NetAddrsListen(ctx) + if err != nil { + t.Fatal(err) + } + + if err := chainMiner.NetConnect(ctx, addrinfo); err != nil { + t.Fatal(err) + } + + if err := evilMiner.NetConnect(ctx, addrinfo); err != nil { + t.Fatal(err) + } + } + + defaultFrom, err := client.WalletDefaultAddress(ctx) + require.NoError(t, err) + + build.Clock.Sleep(time.Second) + + // Mine with the _second_ node (the good one). + done := make(chan struct{}) + go func() { + defer close(done) + for ctx.Err() == nil { + build.Clock.Sleep(blocktime) + if err := chainMiner.MineOne(ctx, kit.MineNext); err != nil { + if ctx.Err() != nil { + // context was canceled, ignore the error. + return + } + t.Error(err) + } + } + }() + defer func() { + cancel() + <-done + }() + + // Give the chain miner enough sectors to win every block. + kit.PledgeSectors(t, ctx, chainMiner, 10, 0, nil) + // And the evil one 1 sector. No cookie for you. + kit.PledgeSectors(t, ctx, evilMiner, 1, 0, nil) + + // Let the evil miner's sectors gain power. + evilMinerAddr, err := evilMiner.ActorAddress(ctx) + require.NoError(t, err) + + di, err := client.StateMinerProvingDeadline(ctx, evilMinerAddr, types.EmptyTSK) + require.NoError(t, err) + + fmt.Printf("Running one proving period\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+di.WPoStProvingPeriod*2 { + fmt.Printf("Now head.Height = %d\n", head.Height()) + break + } + build.Clock.Sleep(blocktime) + } + + p, err := client.StateMinerPower(ctx, evilMinerAddr, types.EmptyTSK) + require.NoError(t, err) + + ssz, err := evilMiner.ActorSectorSize(ctx, evilMinerAddr) + require.NoError(t, err) + + // make sure it has gained power. + require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz))) + + evilSectors, err := evilMiner.SectorsList(ctx) + require.NoError(t, err) + evilSectorNo := evilSectors[0] // only one. + evilSectorLoc, err := client.StateSectorPartition(ctx, evilMinerAddr, evilSectorNo, types.EmptyTSK) + require.NoError(t, err) + + fmt.Println("evil miner stopping") + + // Now stop the evil miner, and start manually submitting bad proofs. + require.NoError(t, evilMiner.Stop(ctx)) + + fmt.Println("evil miner stopped") + + // Wait until we need to prove our sector. + for { + di, err = client.StateMinerProvingDeadline(ctx, evilMinerAddr, types.EmptyTSK) + require.NoError(t, err) + if di.Index == evilSectorLoc.Deadline && di.CurrentEpoch-di.PeriodStart > 1 { + break + } + build.Clock.Sleep(blocktime) + } + + err = submitBadProof(ctx, client, evilMinerAddr, di, evilSectorLoc.Deadline, evilSectorLoc.Partition) + require.NoError(t, err, "evil proof not accepted") + + // Wait until after the proving period. + for { + di, err = client.StateMinerProvingDeadline(ctx, evilMinerAddr, types.EmptyTSK) + require.NoError(t, err) + if di.Index != evilSectorLoc.Deadline { + break + } + build.Clock.Sleep(blocktime) + } + + fmt.Println("accepted evil proof") + + // Make sure the evil node didn't lose any power. + p, err = client.StateMinerPower(ctx, evilMinerAddr, types.EmptyTSK) + require.NoError(t, err) + require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz))) + + // OBJECTION! The good miner files a DISPUTE!!!! + { + params := &minerActor.DisputeWindowedPoStParams{ + Deadline: evilSectorLoc.Deadline, + PoStIndex: 0, + } + + enc, aerr := actors.SerializeParams(params) + require.NoError(t, aerr) + + msg := &types.Message{ + To: evilMinerAddr, + Method: minerActor.Methods.DisputeWindowedPoSt, + Params: enc, + Value: types.NewInt(0), + From: defaultFrom, + } + sm, err := client.MpoolPushMessage(ctx, msg, nil) + require.NoError(t, err) + + fmt.Println("waiting dispute") + 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()) + } + + // Objection SUSTAINED! + // Make sure the evil node lost power. + p, err = client.StateMinerPower(ctx, evilMinerAddr, types.EmptyTSK) + require.NoError(t, err) + require.True(t, p.MinerPower.RawBytePower.IsZero()) + + // Now we begin the redemption arc. + require.True(t, p.MinerPower.RawBytePower.IsZero()) + + // First, recover the sector. + + { + minerInfo, err := client.StateMinerInfo(ctx, evilMinerAddr, types.EmptyTSK) + require.NoError(t, err) + + params := &minerActor.DeclareFaultsRecoveredParams{ + Recoveries: []minerActor.RecoveryDeclaration{{ + Deadline: evilSectorLoc.Deadline, + Partition: evilSectorLoc.Partition, + Sectors: bitfield.NewFromSet([]uint64{uint64(evilSectorNo)}), + }}, + } + + enc, aerr := actors.SerializeParams(params) + require.NoError(t, aerr) + + msg := &types.Message{ + To: evilMinerAddr, + Method: minerActor.Methods.DeclareFaultsRecovered, + Params: enc, + Value: types.FromFil(30), // repay debt. + From: minerInfo.Owner, + } + sm, err := client.MpoolPushMessage(ctx, msg, nil) + require.NoError(t, err) + + 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()) + } + + // Then wait for the deadline. + for { + di, err = client.StateMinerProvingDeadline(ctx, evilMinerAddr, types.EmptyTSK) + require.NoError(t, err) + if di.Index == evilSectorLoc.Deadline { + break + } + build.Clock.Sleep(blocktime) + } + + // Now try to be evil again + err = submitBadProof(ctx, client, evilMinerAddr, di, evilSectorLoc.Deadline, evilSectorLoc.Partition) + require.Error(t, err) + require.Contains(t, err.Error(), "message execution failed: exit 16, reason: window post failed: invalid PoSt") + + // It didn't work because we're recovering. +} + +func TestWindowPostDisputeFails(t *testing.T) { + kit.Expensive(t) + + kit.QuietMiningLogs() + + b := kit.MockMinerBuilder + blocktime := 2 * time.Millisecond + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + n, sn := b(t, []kit.FullNodeOpts{kit.FullNodeWithLatestActorsAt(-1)}, kit.OneMiner) + + client := n[0].FullNode.(*impl.FullNodeAPI) + miner := sn[0] + + { + addrinfo, err := client.NetAddrsListen(ctx) + if err != nil { + t.Fatal(err) + } + + if err := miner.NetConnect(ctx, addrinfo); err != nil { + t.Fatal(err) + } + } + + defaultFrom, err := client.WalletDefaultAddress(ctx) + require.NoError(t, err) + + maddr, err := miner.ActorAddress(ctx) + require.NoError(t, err) + + build.Clock.Sleep(time.Second) + + // Mine with the _second_ node (the good one). + done := make(chan struct{}) + go func() { + defer close(done) + for ctx.Err() == nil { + build.Clock.Sleep(blocktime) + if err := miner.MineOne(ctx, kit.MineNext); err != nil { + if ctx.Err() != nil { + // context was canceled, ignore the error. + return + } + t.Error(err) + } + } + }() + defer func() { + cancel() + <-done + }() + + kit.PledgeSectors(t, ctx, miner, 10, 0, nil) + + di, err := client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK) + require.NoError(t, err) + + fmt.Printf("Running one proving period\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+di.WPoStProvingPeriod*2 { + fmt.Printf("Now head.Height = %d\n", head.Height()) + break + } + build.Clock.Sleep(blocktime) + } + + ssz, err := miner.ActorSectorSize(ctx, maddr) + require.NoError(t, err) + expectedPower := types.NewInt(uint64(ssz) * (kit.GenesisPreseals + 10)) + + p, err := client.StateMinerPower(ctx, maddr, types.EmptyTSK) + require.NoError(t, err) + + // make sure it has gained power. + require.Equal(t, p.MinerPower.RawBytePower, expectedPower) + + // Wait until a proof has been submitted. + var targetDeadline uint64 +waitForProof: + for { + deadlines, err := client.StateMinerDeadlines(ctx, maddr, types.EmptyTSK) + require.NoError(t, err) + for dlIdx, dl := range deadlines { + nonEmpty, err := dl.PostSubmissions.IsEmpty() + require.NoError(t, err) + if nonEmpty { + targetDeadline = uint64(dlIdx) + break waitForProof + } + } + + build.Clock.Sleep(blocktime) + } + + for { + di, err := client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK) + require.NoError(t, err) + // wait until the deadline finishes. + if di.Index == ((targetDeadline + 1) % di.WPoStPeriodDeadlines) { + break + } + + build.Clock.Sleep(blocktime) + } + + // Try to object to the proof. This should fail. + { + params := &minerActor.DisputeWindowedPoStParams{ + Deadline: targetDeadline, + PoStIndex: 0, + } + + enc, aerr := actors.SerializeParams(params) + require.NoError(t, aerr) + + msg := &types.Message{ + To: maddr, + Method: minerActor.Methods.DisputeWindowedPoSt, + Params: enc, + Value: types.NewInt(0), + From: defaultFrom, + } + _, err := client.MpoolPushMessage(ctx, msg, nil) + require.Error(t, err) + require.Contains(t, err.Error(), "failed to dispute valid post (RetCode=16)") + } +} + +func submitBadProof( + ctx context.Context, + client api.FullNode, maddr address.Address, + di *dline.Info, dlIdx, partIdx uint64, +) error { + head, err := client.ChainHead(ctx) + if err != nil { + return err + } + + from, err := client.WalletDefaultAddress(ctx) + if err != nil { + return err + } + + minerInfo, err := client.StateMinerInfo(ctx, maddr, head.Key()) + if err != nil { + return err + } + + commEpoch := di.Open + commRand, err := client.ChainGetRandomnessFromTickets( + ctx, head.Key(), crypto.DomainSeparationTag_PoStChainCommit, + commEpoch, nil, + ) + if err != nil { + return err + } + params := &minerActor.SubmitWindowedPoStParams{ + ChainCommitEpoch: commEpoch, + ChainCommitRand: commRand, + Deadline: dlIdx, + Partitions: []minerActor.PoStPartition{{Index: partIdx}}, + Proofs: []proof3.PoStProof{{ + PoStProof: minerInfo.WindowPoStProofType, + ProofBytes: []byte("I'm soooo very evil."), + }}, + } + + enc, aerr := actors.SerializeParams(params) + if aerr != nil { + return aerr + } + + msg := &types.Message{ + To: maddr, + Method: minerActor.Methods.SubmitWindowedPoSt, + Params: enc, + Value: types.NewInt(0), + From: from, + } + sm, err := client.MpoolPushMessage(ctx, msg, nil) + if err != nil { + return err + } + + rec, err := client.StateWaitMsg(ctx, sm.Cid(), build.MessageConfidence, api.LookbackNoLimit, true) + if err != nil { + return err + } + if rec.Receipt.ExitCode.IsError() { + return rec.Receipt.ExitCode + } + return nil +} diff --git a/itests/wdpost_test.go b/itests/wdpost_test.go new file mode 100644 index 00000000000..81f93837922 --- /dev/null +++ b/itests/wdpost_test.go @@ -0,0 +1,367 @@ +package itests + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/itests/kit" + "github.com/stretchr/testify/require" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/extern/sector-storage/mock" + "github.com/filecoin-project/specs-storage/storage" + + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/node/impl" +) + +func TestWindowedPost(t *testing.T) { + kit.Expensive(t) + + kit.QuietMiningLogs() + + var ( + blocktime = 2 * time.Millisecond + nSectors = 10 + ) + + for _, height := range []abi.ChainEpoch{ + -1, // before + 162, // while sealing + 5000, // while proving + } { + height := height // copy to satisfy lints + t.Run(fmt.Sprintf("upgrade-%d", height), func(t *testing.T) { + testWindowPostUpgrade(t, kit.MockMinerBuilder, blocktime, nSectors, height) + }) + } +} + +func testWindowPostUpgrade(t *testing.T, b kit.APIBuilder, blocktime time.Duration, nSectors int, upgradeHeight abi.ChainEpoch) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + n, sn := b(t, []kit.FullNodeOpts{kit.FullNodeWithLatestActorsAt(upgradeHeight)}, kit.OneMiner) + + client := n[0].FullNode.(*impl.FullNodeAPI) + miner := sn[0] + + addrinfo, err := client.NetAddrsListen(ctx) + if err != nil { + t.Fatal(err) + } + + if err := miner.NetConnect(ctx, addrinfo); err != nil { + t.Fatal(err) + } + build.Clock.Sleep(time.Second) + + done := make(chan struct{}) + go func() { + defer close(done) + for ctx.Err() == nil { + build.Clock.Sleep(blocktime) + if err := sn[0].MineOne(ctx, kit.MineNext); err != nil { + if ctx.Err() != nil { + // context was canceled, ignore the error. + return + } + t.Error(err) + } + } + }() + defer func() { + cancel() + <-done + }() + + kit.PledgeSectors(t, ctx, miner, nSectors, 0, nil) + + maddr, err := miner.ActorAddress(ctx) + require.NoError(t, err) + + di, err := client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK) + require.NoError(t, err) + + mid, err := address.IDFromAddress(maddr) + require.NoError(t, err) + + fmt.Printf("Running one proving period\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+di.WPoStProvingPeriod+2 { + fmt.Printf("Now head.Height = %d\n", head.Height()) + break + } + build.Clock.Sleep(blocktime) + } + + p, err := client.StateMinerPower(ctx, maddr, types.EmptyTSK) + require.NoError(t, err) + + ssz, err := miner.ActorSectorSize(ctx, maddr) + require.NoError(t, err) + + require.Equal(t, p.MinerPower, p.TotalPower) + require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz)*uint64(nSectors+kit.GenesisPreseals))) + + fmt.Printf("Drop some sectors\n") + + // Drop 2 sectors from deadline 2 partition 0 (full partition / deadline) + { + parts, err := client.StateMinerPartitions(ctx, maddr, 2, types.EmptyTSK) + require.NoError(t, err) + require.Greater(t, len(parts), 0) + + secs := parts[0].AllSectors + n, err := secs.Count() + require.NoError(t, err) + require.Equal(t, uint64(2), n) + + // Drop the partition + err = secs.ForEach(func(sid uint64) error { + return miner.StorageMiner.(*impl.StorageMinerAPI).IStorageMgr.(*mock.SectorMgr).MarkCorrupted(storage.SectorRef{ + ID: abi.SectorID{ + Miner: abi.ActorID(mid), + Number: abi.SectorNumber(sid), + }, + }, true) + }) + require.NoError(t, err) + } + + var s storage.SectorRef + + // Drop 1 sectors from deadline 3 partition 0 + { + parts, err := client.StateMinerPartitions(ctx, maddr, 3, types.EmptyTSK) + require.NoError(t, err) + require.Greater(t, len(parts), 0) + + secs := parts[0].AllSectors + n, err := secs.Count() + require.NoError(t, err) + require.Equal(t, uint64(2), n) + + // Drop the sector + sn, err := secs.First() + require.NoError(t, err) + + all, err := secs.All(2) + require.NoError(t, err) + fmt.Println("the sectors", all) + + s = storage.SectorRef{ + ID: abi.SectorID{ + Miner: abi.ActorID(mid), + Number: abi.SectorNumber(sn), + }, + } + + err = miner.StorageMiner.(*impl.StorageMinerAPI).IStorageMgr.(*mock.SectorMgr).MarkFailed(s, true) + require.NoError(t, err) + } + + di, err = client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK) + require.NoError(t, err) + + fmt.Printf("Go through another PP, wait for sectors to become faulty\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+(di.WPoStProvingPeriod)+2 { + fmt.Printf("Now head.Height = %d\n", head.Height()) + break + } + + build.Clock.Sleep(blocktime) + } + + p, err = client.StateMinerPower(ctx, maddr, types.EmptyTSK) + require.NoError(t, err) + + require.Equal(t, p.MinerPower, p.TotalPower) + + sectors := p.MinerPower.RawBytePower.Uint64() / uint64(ssz) + require.Equal(t, nSectors+kit.GenesisPreseals-3, int(sectors)) // -3 just removed sectors + + fmt.Printf("Recover one sector\n") + + err = miner.StorageMiner.(*impl.StorageMinerAPI).IStorageMgr.(*mock.SectorMgr).MarkFailed(s, false) + require.NoError(t, err) + + di, err = client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK) + require.NoError(t, err) + + 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+di.WPoStProvingPeriod+2 { + fmt.Printf("Now head.Height = %d\n", head.Height()) + break + } + + build.Clock.Sleep(blocktime) + } + + p, err = client.StateMinerPower(ctx, maddr, types.EmptyTSK) + require.NoError(t, err) + + require.Equal(t, p.MinerPower, p.TotalPower) + + sectors = p.MinerPower.RawBytePower.Uint64() / uint64(ssz) + require.Equal(t, nSectors+kit.GenesisPreseals-2, int(sectors)) // -2 not recovered sectors + + // pledge a sector after recovery + + kit.PledgeSectors(t, ctx, miner, 1, nSectors, nil) + + { + // Wait until proven. + di, err = client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK) + require.NoError(t, err) + + waitUntil := di.PeriodStart + di.WPoStProvingPeriod + 2 + fmt.Printf("End for head.Height > %d\n", waitUntil) + + for { + head, err := client.ChainHead(ctx) + require.NoError(t, err) + + if head.Height() > waitUntil { + fmt.Printf("Now head.Height = %d\n", head.Height()) + break + } + } + } + + p, err = client.StateMinerPower(ctx, maddr, types.EmptyTSK) + require.NoError(t, err) + + require.Equal(t, p.MinerPower, p.TotalPower) + + sectors = p.MinerPower.RawBytePower.Uint64() / uint64(ssz) + require.Equal(t, nSectors+kit.GenesisPreseals-2+1, int(sectors)) // -2 not recovered sectors + 1 just pledged +} + +func TestWindowPostBaseFeeNoBurn(t *testing.T) { + kit.Expensive(t) + + kit.QuietMiningLogs() + + var ( + blocktime = 2 * time.Millisecond + nSectors = 10 + ) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + och := build.UpgradeClausHeight + build.UpgradeClausHeight = 10 + + n, sn := kit.MockMinerBuilder(t, kit.DefaultFullOpts(1), kit.OneMiner) + client := n[0].FullNode.(*impl.FullNodeAPI) + miner := sn[0] + bm := kit.ConnectAndStartMining(t, blocktime, miner, client) + t.Cleanup(bm.Stop) + + maddr, err := miner.ActorAddress(ctx) + require.NoError(t, err) + + mi, err := client.StateMinerInfo(ctx, maddr, types.EmptyTSK) + require.NoError(t, err) + + kit.PledgeSectors(t, ctx, miner, nSectors, 0, nil) + wact, err := client.StateGetActor(ctx, mi.Worker, types.EmptyTSK) + require.NoError(t, err) + en := wact.Nonce + + // wait for a new message to be sent from worker address, it will be a PoSt + +waitForProof: + for { + wact, err := client.StateGetActor(ctx, mi.Worker, types.EmptyTSK) + require.NoError(t, err) + if wact.Nonce > en { + break waitForProof + } + + build.Clock.Sleep(blocktime) + } + + slm, err := client.StateListMessages(ctx, &api.MessageMatch{To: maddr}, types.EmptyTSK, 0) + require.NoError(t, err) + + pmr, err := client.StateReplay(ctx, types.EmptyTSK, slm[0]) + require.NoError(t, err) + + require.Equal(t, pmr.GasCost.BaseFeeBurn, big.Zero()) + + build.UpgradeClausHeight = och +} + +func TestWindowPostBaseFeeBurn(t *testing.T) { + kit.Expensive(t) + + kit.QuietMiningLogs() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + blocktime := 2 * time.Millisecond + + n, sn := kit.MockMinerBuilder(t, []kit.FullNodeOpts{kit.FullNodeWithLatestActorsAt(-1)}, kit.OneMiner) + client := n[0].FullNode.(*impl.FullNodeAPI) + miner := sn[0] + bm := kit.ConnectAndStartMining(t, blocktime, miner, client) + t.Cleanup(bm.Stop) + + maddr, err := miner.ActorAddress(ctx) + require.NoError(t, err) + + mi, err := client.StateMinerInfo(ctx, maddr, types.EmptyTSK) + require.NoError(t, err) + + kit.PledgeSectors(t, ctx, miner, 10, 0, nil) + wact, err := client.StateGetActor(ctx, mi.Worker, types.EmptyTSK) + require.NoError(t, err) + en := wact.Nonce + + // wait for a new message to be sent from worker address, it will be a PoSt + +waitForProof: + for { + wact, err := client.StateGetActor(ctx, mi.Worker, types.EmptyTSK) + require.NoError(t, err) + if wact.Nonce > en { + break waitForProof + } + + build.Clock.Sleep(blocktime) + } + + slm, err := client.StateListMessages(ctx, &api.MessageMatch{To: maddr}, types.EmptyTSK, 0) + require.NoError(t, err) + + pmr, err := client.StateReplay(ctx, types.EmptyTSK, slm[0]) + require.NoError(t, err) + + require.NotEqual(t, pmr.GasCost.BaseFeeBurn, big.Zero()) +} diff --git a/markets/pricing/cli.go b/markets/pricing/cli.go new file mode 100644 index 00000000000..3c2a5f2489c --- /dev/null +++ b/markets/pricing/cli.go @@ -0,0 +1,48 @@ +package pricing + +import ( + "bytes" + "context" + "encoding/json" + "os/exec" + + "github.com/filecoin-project/go-fil-markets/retrievalmarket" + "github.com/filecoin-project/lotus/node/modules/dtypes" + "golang.org/x/xerrors" +) + +func ExternalRetrievalPricingFunc(cmd string) dtypes.RetrievalPricingFunc { + return func(ctx context.Context, pricingInput retrievalmarket.PricingInput) (retrievalmarket.Ask, error) { + return runPricingFunc(ctx, cmd, pricingInput) + } +} + +func runPricingFunc(_ context.Context, cmd string, params interface{}) (retrievalmarket.Ask, error) { + j, err := json.Marshal(params) + if err != nil { + return retrievalmarket.Ask{}, err + } + + var out bytes.Buffer + var errb bytes.Buffer + + c := exec.Command("sh", "-c", cmd) + c.Stdin = bytes.NewReader(j) + c.Stdout = &out + c.Stderr = &errb + + switch err := c.Run().(type) { + case nil: + bz := out.Bytes() + resp := retrievalmarket.Ask{} + + if err := json.Unmarshal(bz, &resp); err != nil { + return resp, xerrors.Errorf("failed to parse pricing output %s, err=%w", string(bz), err) + } + return resp, nil + case *exec.ExitError: + return retrievalmarket.Ask{}, xerrors.Errorf("pricing func exited with error: %s", errb.String()) + default: + return retrievalmarket.Ask{}, xerrors.Errorf("pricing func cmd run error: %w", err) + } +} diff --git a/markets/retrievaladapter/provider.go b/markets/retrievaladapter/provider.go index e58257c8abc..95b7e1b3ce0 100644 --- a/markets/retrievaladapter/provider.go +++ b/markets/retrievaladapter/provider.go @@ -5,6 +5,7 @@ import ( "io" "github.com/filecoin-project/lotus/api/v1api" + "golang.org/x/xerrors" "github.com/ipfs/go-cid" logging "github.com/ipfs/go-log/v2" @@ -25,15 +26,15 @@ import ( var log = logging.Logger("retrievaladapter") type retrievalProviderNode struct { - miner *storage.Miner - sealer sectorstorage.SectorManager - full v1api.FullNode + miner *storage.Miner + pp sectorstorage.PieceProvider + 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 v1api.FullNode) retrievalmarket.RetrievalProviderNode { - return &retrievalProviderNode{miner, sealer, full} +func NewRetrievalProviderNode(miner *storage.Miner, pp sectorstorage.PieceProvider, full v1api.FullNode) retrievalmarket.RetrievalProviderNode { + return &retrievalProviderNode{miner, pp, full} } func (rpn *retrievalProviderNode) GetMinerWorkerAddress(ctx context.Context, miner address.Address, tok shared.TipSetToken) (address.Address, error) { @@ -67,24 +68,18 @@ func (rpn *retrievalProviderNode) UnsealSector(ctx context.Context, sectorID abi ProofType: si.SectorType, } - // Set up a pipe so that data can be written from the unsealing process - // into the reader returned by this function - r, w := io.Pipe() - go func() { - var commD cid.Cid - if si.CommD != nil { - commD = *si.CommD - } + var commD cid.Cid + 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) - } - // Close the reader with any error that was returned while reading the piece - _ = w.CloseWithError(err) - }() + // Get a reader for the piece, unsealing the piece if necessary + log.Debugf("read piece in sector %d, offset %d, length %d from miner %d", sectorID, offset, length, mid) + r, unsealed, err := rpn.pp.ReadPiece(ctx, ref, storiface.UnpaddedByteIndex(offset), length, si.TicketValue, commD) + if err != nil { + return nil, xerrors.Errorf("failed to unseal piece from sector %d: %w", sectorID, err) + } + _ = unsealed // todo: use return r, nil } @@ -104,3 +99,67 @@ func (rpn *retrievalProviderNode) GetChainHead(ctx context.Context) (shared.TipS return head.Key().Bytes(), head.Height(), nil } + +func (rpn *retrievalProviderNode) IsUnsealed(ctx context.Context, sectorID abi.SectorNumber, offset abi.UnpaddedPieceSize, length abi.UnpaddedPieceSize) (bool, error) { + si, err := rpn.miner.GetSectorInfo(sectorID) + if err != nil { + return false, xerrors.Errorf("failed to get sectorinfo, err=%s", err) + } + + mid, err := address.IDFromAddress(rpn.miner.Address()) + if err != nil { + return false, err + } + + ref := specstorage.SectorRef{ + ID: abi.SectorID{ + Miner: abi.ActorID(mid), + Number: sectorID, + }, + ProofType: si.SectorType, + } + + log.Debugf("will call IsUnsealed now sector=%+v, offset=%d, size=%d", sectorID, offset, length) + return rpn.pp.IsUnsealed(ctx, ref, storiface.UnpaddedByteIndex(offset), length) +} + +// GetRetrievalPricingInput takes a set of candidate storage deals that can serve a retrieval request, +// and returns an minimally populated PricingInput. This PricingInput should be enhanced +// with more data, and passed to the pricing function to determine the final quoted price. +func (rpn *retrievalProviderNode) GetRetrievalPricingInput(ctx context.Context, pieceCID cid.Cid, storageDeals []abi.DealID) (retrievalmarket.PricingInput, error) { + resp := retrievalmarket.PricingInput{} + + head, err := rpn.full.ChainHead(ctx) + if err != nil { + return resp, xerrors.Errorf("failed to get chain head: %w", err) + } + tsk := head.Key() + + for _, dealID := range storageDeals { + ds, err := rpn.full.StateMarketStorageDeal(ctx, dealID, tsk) + if err != nil { + return resp, xerrors.Errorf("failed to look up deal %d on chain: err=%w", dealID, err) + } + if ds.Proposal.VerifiedDeal { + resp.VerifiedDeal = true + } + + if ds.Proposal.PieceCID.Equals(pieceCID) { + resp.PieceSize = ds.Proposal.PieceSize.Unpadded() + } + + // If we've discovered a verified deal with the required PieceCID, we don't need + // to lookup more deals and we're done. + if resp.VerifiedDeal && resp.PieceSize != 0 { + break + } + } + + // Note: The piece size can never actually be zero. We only use it to here + // to assert that we didn't find a matching piece. + if resp.PieceSize == 0 { + return resp, xerrors.New("failed to find matching piece") + } + + return resp, nil +} diff --git a/markets/retrievaladapter/provider_test.go b/markets/retrievaladapter/provider_test.go new file mode 100644 index 00000000000..5cdf5d0600f --- /dev/null +++ b/markets/retrievaladapter/provider_test.go @@ -0,0 +1,151 @@ +package retrievaladapter + +import ( + "context" + "testing" + + "github.com/filecoin-project/go-fil-markets/retrievalmarket" + testnet "github.com/filecoin-project/go-fil-markets/shared_testutil" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/mocks" + "github.com/filecoin-project/lotus/chain/actors/builtin/market" + "github.com/filecoin-project/lotus/chain/types" + "github.com/golang/mock/gomock" + "github.com/ipfs/go-cid" + "github.com/stretchr/testify/require" + "golang.org/x/xerrors" +) + +func TestGetPricingInput(t *testing.T) { + ctx := context.Background() + tsk := &types.TipSet{} + key := tsk.Key() + + pcid := testnet.GenerateCids(1)[0] + deals := []abi.DealID{1, 2} + paddedSize := abi.PaddedPieceSize(128) + unpaddedSize := paddedSize.Unpadded() + + tcs := map[string]struct { + pieceCid cid.Cid + deals []abi.DealID + fFnc func(node *mocks.MockFullNode) + + expectedErrorStr string + expectedVerified bool + expectedPieceSize abi.UnpaddedPieceSize + }{ + "error when fails to fetch chain head": { + fFnc: func(n *mocks.MockFullNode) { + n.EXPECT().ChainHead(gomock.Any()).Return(tsk, xerrors.New("chain head error")).Times(1) + }, + expectedErrorStr: "chain head error", + }, + + "error when no piece matches": { + fFnc: func(n *mocks.MockFullNode) { + out1 := &api.MarketDeal{ + Proposal: market.DealProposal{ + PieceCID: testnet.GenerateCids(1)[0], + }, + } + out2 := &api.MarketDeal{ + Proposal: market.DealProposal{ + PieceCID: testnet.GenerateCids(1)[0], + }, + } + + n.EXPECT().ChainHead(gomock.Any()).Return(tsk, nil).Times(1) + gomock.InOrder( + n.EXPECT().StateMarketStorageDeal(gomock.Any(), deals[0], key).Return(out1, nil), + n.EXPECT().StateMarketStorageDeal(gomock.Any(), deals[1], key).Return(out2, nil), + ) + + }, + expectedErrorStr: "failed to find matching piece", + }, + + "verified is true even if one deal is verified and we get the correct piecesize": { + fFnc: func(n *mocks.MockFullNode) { + out1 := &api.MarketDeal{ + Proposal: market.DealProposal{ + PieceCID: pcid, + PieceSize: paddedSize, + }, + } + out2 := &api.MarketDeal{ + Proposal: market.DealProposal{ + PieceCID: testnet.GenerateCids(1)[0], + VerifiedDeal: true, + }, + } + + n.EXPECT().ChainHead(gomock.Any()).Return(tsk, nil).Times(1) + gomock.InOrder( + n.EXPECT().StateMarketStorageDeal(gomock.Any(), deals[0], key).Return(out1, nil), + n.EXPECT().StateMarketStorageDeal(gomock.Any(), deals[1], key).Return(out2, nil), + ) + + }, + expectedPieceSize: unpaddedSize, + expectedVerified: true, + }, + + "verified is false if both deals are unverified and we get the correct piece size": { + fFnc: func(n *mocks.MockFullNode) { + out1 := &api.MarketDeal{ + Proposal: market.DealProposal{ + PieceCID: pcid, + PieceSize: paddedSize, + VerifiedDeal: false, + }, + } + out2 := &api.MarketDeal{ + Proposal: market.DealProposal{ + PieceCID: testnet.GenerateCids(1)[0], + VerifiedDeal: false, + }, + } + + n.EXPECT().ChainHead(gomock.Any()).Return(tsk, nil).Times(1) + gomock.InOrder( + n.EXPECT().StateMarketStorageDeal(gomock.Any(), deals[0], key).Return(out1, nil), + n.EXPECT().StateMarketStorageDeal(gomock.Any(), deals[1], key).Return(out2, nil), + ) + + }, + expectedPieceSize: unpaddedSize, + expectedVerified: false, + }, + } + + for name, tc := range tcs { + tc := tc + t.Run(name, func(t *testing.T) { + mockCtrl := gomock.NewController(t) + // when test is done, assert expectations on all mock objects. + defer mockCtrl.Finish() + + mockFull := mocks.NewMockFullNode(mockCtrl) + rpn := &retrievalProviderNode{ + full: mockFull, + } + if tc.fFnc != nil { + tc.fFnc(mockFull) + } + + resp, err := rpn.GetRetrievalPricingInput(ctx, pcid, deals) + + if tc.expectedErrorStr != "" { + require.Error(t, err) + require.Contains(t, err.Error(), tc.expectedErrorStr) + require.Equal(t, retrievalmarket.PricingInput{}, resp) + } else { + require.NoError(t, err) + require.Equal(t, tc.expectedPieceSize, resp.PieceSize) + require.Equal(t, tc.expectedVerified, resp.VerifiedDeal) + } + }) + } +} diff --git a/metrics/metrics.go b/metrics/metrics.go index 9f6eb4b4283..33fecc606ff 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -38,6 +38,7 @@ var ( MessageTo, _ = tag.NewKey("message_to") MessageNonce, _ = tag.NewKey("message_nonce") ReceivedFrom, _ = tag.NewKey("received_from") + MsgValid, _ = tag.NewKey("message_valid") Endpoint, _ = tag.NewKey("endpoint") APIInterface, _ = tag.NewKey("api") // to distinguish between gateway api and full node api endpoint calls @@ -61,6 +62,12 @@ var ( MessageReceived = stats.Int64("message/received", "Counter for total received messages", stats.UnitDimensionless) MessageValidationFailure = stats.Int64("message/failure", "Counter for message validation failures", stats.UnitDimensionless) MessageValidationSuccess = stats.Int64("message/success", "Counter for message validation successes", stats.UnitDimensionless) + MessageValidationDuration = stats.Float64("message/validation_ms", "Duration of message validation", stats.UnitMilliseconds) + MpoolGetNonceDuration = stats.Float64("mpool/getnonce_ms", "Duration of getStateNonce in mpool", stats.UnitMilliseconds) + MpoolGetBalanceDuration = stats.Float64("mpool/getbalance_ms", "Duration of getStateBalance in mpool", stats.UnitMilliseconds) + MpoolAddTsDuration = stats.Float64("mpool/addts_ms", "Duration of addTs in mpool", stats.UnitMilliseconds) + MpoolAddDuration = stats.Float64("mpool/add_ms", "Duration of Add in mpool", stats.UnitMilliseconds) + MpoolPushDuration = stats.Float64("mpool/push_ms", "Duration of Push in mpool", stats.UnitMilliseconds) BlockPublished = stats.Int64("block/published", "Counter for total locally published blocks", stats.UnitDimensionless) BlockReceived = stats.Int64("block/received", "Counter for total received blocks", stats.UnitDimensionless) BlockValidationFailure = stats.Int64("block/failure", "Counter for block validation failures", stats.UnitDimensionless) @@ -170,6 +177,31 @@ var ( Measure: MessageValidationSuccess, Aggregation: view.Count(), } + MessageValidationDurationView = &view.View{ + Measure: MessageValidationDuration, + Aggregation: defaultMillisecondsDistribution, + TagKeys: []tag.Key{MsgValid, Local}, + } + MpoolGetNonceDurationView = &view.View{ + Measure: MpoolGetNonceDuration, + Aggregation: defaultMillisecondsDistribution, + } + MpoolGetBalanceDurationView = &view.View{ + Measure: MpoolGetBalanceDuration, + Aggregation: defaultMillisecondsDistribution, + } + MpoolAddTsDurationView = &view.View{ + Measure: MpoolAddTsDuration, + Aggregation: defaultMillisecondsDistribution, + } + MpoolAddDurationView = &view.View{ + Measure: MpoolAddDuration, + Aggregation: defaultMillisecondsDistribution, + } + MpoolPushDurationView = &view.View{ + Measure: MpoolPushDuration, + Aggregation: defaultMillisecondsDistribution, + } PeerCountView = &view.View{ Measure: PeerCount, Aggregation: view.LastValue(), @@ -313,6 +345,12 @@ var ChainNodeViews = append([]*view.View{ MessageReceivedView, MessageValidationFailureView, MessageValidationSuccessView, + MessageValidationDurationView, + MpoolGetNonceDurationView, + MpoolGetBalanceDurationView, + MpoolAddTsDurationView, + MpoolAddDurationView, + MpoolPushDurationView, PubsubPublishMessageView, PubsubDeliverMessageView, PubsubRejectMessageView, diff --git a/node/builder.go b/node/builder.go index 9d9c81a850c..c737e85b82c 100644 --- a/node/builder.go +++ b/node/builder.go @@ -375,9 +375,12 @@ var MinerNode = Options( Override(new(*stores.Index), stores.NewIndex), Override(new(stores.SectorIndex), From(new(*stores.Index))), Override(new(stores.LocalStorage), From(new(repo.LockedRepo))), + Override(new(*stores.Local), modules.LocalStorage), + Override(new(*stores.Remote), modules.RemoteStorage), Override(new(*sectorstorage.Manager), modules.SectorStorage), Override(new(sectorstorage.SectorManager), From(new(*sectorstorage.Manager))), Override(new(storiface.WorkerReturn), From(new(sectorstorage.SectorManager))), + Override(new(sectorstorage.Unsealer), From(new(*sectorstorage.Manager))), // Sector storage: Proofs Override(new(ffiwrapper.Verifier), ffiwrapper.ProofVerifier), @@ -405,8 +408,17 @@ var MinerNode = Options( Override(new(*sectorblocks.SectorBlocks), sectorblocks.NewSectorBlocks), // Markets (retrieval) + Override(new(sectorstorage.PieceProvider), sectorstorage.NewPieceProvider), + Override(new(dtypes.RetrievalPricingFunc), modules.RetrievalPricingFunc(config.DealmakingConfig{ + RetrievalPricing: &config.RetrievalPricing{ + Strategy: config.RetrievalPricingDefaultMode, + Default: &config.RetrievalPricingDefault{}, + }, + })), + Override(new(sectorstorage.PieceProvider), sectorstorage.NewPieceProvider), Override(new(retrievalmarket.RetrievalProvider), modules.RetrievalProvider), Override(new(dtypes.RetrievalDealFilter), modules.RetrievalDealFilter(nil)), + Override(HandleRetrievalKey, modules.HandleRetrieval), // Markets (storage) @@ -438,6 +450,8 @@ var MinerNode = Options( Override(new(dtypes.GetSealingConfigFunc), modules.NewGetSealConfigFunc), Override(new(dtypes.SetExpectedSealDurationFunc), modules.NewSetExpectedSealDurationFunc), Override(new(dtypes.GetExpectedSealDurationFunc), modules.NewGetExpectedSealDurationFunc), + Override(new(dtypes.SetMaxDealStartDelayFunc), modules.NewSetMaxDealStartDelayFunc), + Override(new(dtypes.GetMaxDealStartDelayFunc), modules.NewGetMaxDealStartDelayFunc), ) // Online sets up basic libp2p node @@ -560,6 +574,19 @@ func ConfigStorageMiner(c interface{}) Option { return Error(xerrors.Errorf("invalid config from repo, got: %T", c)) } + pricingConfig := cfg.Dealmaking.RetrievalPricing + if pricingConfig.Strategy == config.RetrievalPricingExternalMode { + if pricingConfig.External == nil { + return Error(xerrors.New("retrieval pricing policy has been to set to external but external policy config is nil")) + } + + if pricingConfig.External.Path == "" { + return Error(xerrors.New("retrieval pricing policy has been to set to external but external script path is empty")) + } + } else if pricingConfig.Strategy != config.RetrievalPricingDefaultMode { + return Error(xerrors.New("retrieval pricing policy must be either default or external")) + } + return Options( ConfigCommon(&cfg.Common), @@ -571,6 +598,8 @@ func ConfigStorageMiner(c interface{}) Option { Override(new(dtypes.RetrievalDealFilter), modules.RetrievalDealFilter(dealfilter.CliRetrievalDealFilter(cfg.Dealmaking.RetrievalFilter))), ), + Override(new(dtypes.RetrievalPricingFunc), modules.RetrievalPricingFunc(cfg.Dealmaking)), + Override(new(*storageadapter.DealPublisher), storageadapter.NewDealPublisher(&cfg.Fees, storageadapter.PublishMsgConfig{ Period: time.Duration(cfg.Dealmaking.PublishMsgPeriod), MaxDealsPerMsg: cfg.Dealmaking.MaxDealsPerPublishMsg, diff --git a/node/config/def.go b/node/config/def.go index c18f60a7a9b..b2ed43ac657 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -6,12 +6,22 @@ import ( "github.com/ipfs/go-cid" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/big" miner5 "github.com/filecoin-project/specs-actors/v5/actors/builtin/miner" "github.com/filecoin-project/lotus/chain/types" sectorstorage "github.com/filecoin-project/lotus/extern/sector-storage" ) +const ( + // RetrievalPricingDefault configures the node to use the default retrieval pricing policy. + RetrievalPricingDefaultMode = "default" + // RetrievalPricingExternal configures the node to use the external retrieval pricing script + // configured by the user. + RetrievalPricingExternalMode = "external" +) + // Common is common config between full node and miner type Common struct { API API @@ -56,6 +66,8 @@ type DealmakingConfig struct { ConsiderUnverifiedStorageDeals bool PieceCidBlocklist []cid.Cid ExpectedSealDuration Duration + // Maximum amount of time proposed deal StartEpoch can be in future + MaxDealStartDelay Duration // The amount of time to wait for more deals to arrive before // publishing PublishMsgPeriod Duration @@ -68,6 +80,29 @@ type DealmakingConfig struct { Filter string RetrievalFilter string + + RetrievalPricing *RetrievalPricing +} + +type RetrievalPricing struct { + Strategy string // possible values: "default", "external" + + Default *RetrievalPricingDefault + External *RetrievalPricingExternal +} + +type RetrievalPricingExternal struct { + // Path of the external script that will be run to price a retrieval deal. + // This parameter is ONLY applicable if the retrieval pricing policy strategy has been configured to "external". + Path string +} + +type RetrievalPricingDefault struct { + // VerifiedDealsFreeTransfer configures zero fees for data transfer for a retrieval deal + // of a payloadCid that belongs to a verified storage deal. + // This parameter is ONLY applicable if the retrieval pricing policy strategy has been configured to "default". + // default value is true + VerifiedDealsFreeTransfer bool } type SealingConfig struct { @@ -84,14 +119,16 @@ type SealingConfig struct { AlwaysKeepUnsealedCopy bool + // Run sector finalization before submitting sector proof to the chain + FinalizeEarly bool + // enable / disable precommit batching (takes effect after nv13) BatchPreCommits bool // maximum precommit batch size - batches will be sent immediately above this size MaxPreCommitBatch int - MinPreCommitBatch int // how long to wait before submitting a batch after crossing the minimum batch size PreCommitBatchWait Duration - // time buffer for forceful batch submission before sectors in batch would start expiring + // time buffer for forceful batch submission before sectors/deal in batch would start expiring PreCommitBatchSlack Duration // enable / disable commit aggregation (takes effect after nv13) @@ -101,7 +138,7 @@ type SealingConfig struct { MaxCommitBatch int // how long to wait before submitting a batch after crossing the minimum batch size CommitBatchWait Duration - // time buffer for forceful batch submission before sectors in batch would start expiring + // time buffer for forceful batch submission before sectors/deals in batch would start expiring CommitBatchSlack Duration TerminateBatchMax uint64 @@ -114,9 +151,23 @@ type SealingConfig struct { // todo TargetSectors - stop auto-pleding new sectors after this many sectors are sealed, default CC upgrade for deals sectors if above } +type BatchFeeConfig struct { + Base types.FIL + PerSector types.FIL +} + +func (b *BatchFeeConfig) FeeForSectors(nSectors int) abi.TokenAmount { + return big.Add(big.Int(b.Base), big.Mul(big.NewInt(int64(nSectors)), big.Int(b.PerSector))) +} + type MinerFeeConfig struct { - MaxPreCommitGasFee types.FIL - MaxCommitGasFee types.FIL + MaxPreCommitGasFee types.FIL + MaxCommitGasFee types.FIL + + // maxBatchFee = maxBase + maxPerSector * nSectors + MaxPreCommitBatchGasFee BatchFeeConfig + MaxCommitBatchGasFee BatchFeeConfig + MaxTerminateGasFee types.FIL MaxWindowPoStGasFee types.FIL MaxPublishDealsFee types.FIL @@ -263,18 +314,18 @@ func DefaultStorageMiner() *StorageMiner { MaxSealingSectorsForDeals: 0, WaitDealsDelay: Duration(time.Hour * 6), AlwaysKeepUnsealedCopy: true, + FinalizeEarly: false, BatchPreCommits: true, - MinPreCommitBatch: 1, // we must have at least one proof to aggregate - MaxPreCommitBatch: miner5.PreCommitSectorBatchMaxSize, // - PreCommitBatchWait: Duration(24 * time.Hour), // this can be up to 6 days - PreCommitBatchSlack: Duration(3 * time.Hour), + MaxPreCommitBatch: miner5.PreCommitSectorBatchMaxSize, // up to 256 sectors + PreCommitBatchWait: Duration(24 * time.Hour), // this should be less than 31.5 hours, which is the expiration of a precommit ticket + PreCommitBatchSlack: Duration(3 * time.Hour), // time buffer for forceful batch submission before sectors/deals in batch would start expiring, higher value will lower the chances for message fail due to expiration AggregateCommits: true, - MinCommitBatch: miner5.MinAggregatedSectors, // we must have at least four proofs to aggregate - MaxCommitBatch: miner5.MaxAggregatedSectors, // this is the maximum aggregation per FIP13 - CommitBatchWait: Duration(24 * time.Hour), // this can be up to 6 days - CommitBatchSlack: Duration(1 * time.Hour), + MinCommitBatch: miner5.MinAggregatedSectors, // per FIP13, we must have at least four proofs to aggregate, where 4 is the cross over point where aggregation wins out on single provecommit gas costs + MaxCommitBatch: miner5.MaxAggregatedSectors, // maximum 819 sectors, this is the maximum aggregation per FIP13 + CommitBatchWait: Duration(24 * time.Hour), // this can be up to 30 days + CommitBatchSlack: Duration(1 * time.Hour), // time buffer for forceful batch submission before sectors/deals in batch would start expiring, higher value will lower the chances for message fail due to expiration TerminateBatchMin: 1, TerminateBatchMax: 100, @@ -291,6 +342,9 @@ func DefaultStorageMiner() *StorageMiner { // Default to 10 - tcp should still be able to figure this out, and // it's the ratio between 10gbit / 1gbit ParallelFetchLimit: 10, + + // By default use the hardware resource filtering strategy. + ResourceFiltering: sectorstorage.ResourceFilteringHardware, }, Dealmaking: DealmakingConfig{ @@ -302,15 +356,36 @@ func DefaultStorageMiner() *StorageMiner { ConsiderUnverifiedStorageDeals: true, PieceCidBlocklist: []cid.Cid{}, // TODO: It'd be nice to set this based on sector size + MaxDealStartDelay: Duration(time.Hour * 24 * 14), ExpectedSealDuration: Duration(time.Hour * 24), PublishMsgPeriod: Duration(time.Hour), MaxDealsPerPublishMsg: 8, MaxProviderCollateralMultiplier: 2, + + RetrievalPricing: &RetrievalPricing{ + Strategy: RetrievalPricingDefaultMode, + Default: &RetrievalPricingDefault{ + VerifiedDealsFreeTransfer: true, + }, + External: &RetrievalPricingExternal{ + Path: "", + }, + }, }, Fees: MinerFeeConfig{ - MaxPreCommitGasFee: types.MustParseFIL("0.025"), - MaxCommitGasFee: types.MustParseFIL("0.05"), + MaxPreCommitGasFee: types.MustParseFIL("0.025"), + MaxCommitGasFee: types.MustParseFIL("0.05"), + + MaxPreCommitBatchGasFee: BatchFeeConfig{ + Base: types.MustParseFIL("0"), + PerSector: types.MustParseFIL("0.02"), + }, + MaxCommitBatchGasFee: BatchFeeConfig{ + Base: types.MustParseFIL("0"), + PerSector: types.MustParseFIL("0.03"), // enough for 6 agg and 1nFIL base fee + }, + MaxTerminateGasFee: types.MustParseFIL("0.5"), MaxWindowPoStGasFee: types.MustParseFIL("5"), MaxPublishDealsFee: types.MustParseFIL("0.05"), diff --git a/node/hello/hello.go b/node/hello/hello.go index daa088dcf7e..e31b7d25b47 100644 --- a/node/hello/hello.go +++ b/node/hello/hello.go @@ -5,7 +5,7 @@ import ( "time" "github.com/filecoin-project/go-state-types/abi" - xerrors "golang.org/x/xerrors" + "golang.org/x/xerrors" "github.com/filecoin-project/go-state-types/big" "github.com/ipfs/go-cid" @@ -13,7 +13,7 @@ import ( "github.com/libp2p/go-libp2p-core/host" inet "github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/peer" - protocol "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p-core/protocol" cborutil "github.com/filecoin-project/go-cbor-util" "github.com/filecoin-project/lotus/build" @@ -23,6 +23,8 @@ import ( "github.com/filecoin-project/lotus/lib/peermgr" ) +// TODO(TEST): missing test coverage. + const ProtocolID = "/fil/hello/1.0.0" var log = logging.Logger("hello") @@ -33,12 +35,14 @@ type HelloMessage struct { HeaviestTipSetWeight big.Int GenesisHash cid.Cid } + type LatencyMessage struct { TArrival int64 TSent int64 } type NewStreamFunc func(context.Context, peer.ID, ...protocol.ID) (inet.Stream, error) + type Service struct { h host.Host @@ -62,7 +66,6 @@ func NewHelloService(h host.Host, cs *store.ChainStore, syncer *chain.Syncer, pm } func (hs *Service) HandleStream(s inet.Stream) { - var hmsg HelloMessage if err := cborutil.ReadCborRPC(s, &hmsg); err != nil { log.Infow("failed to read hello message, disconnecting", "error", err) @@ -121,7 +124,6 @@ func (hs *Service) HandleStream(s inet.Stream) { log.Debugf("Got new tipset through Hello: %s from %s", ts.Cids(), s.Conn().RemotePeer()) hs.syncer.InformNewHead(s.Conn().RemotePeer(), ts) } - } func (hs *Service) SayHello(ctx context.Context, pid peer.ID) error { diff --git a/node/impl/client/client.go b/node/impl/client/client.go index 59c35ae16f3..8fba7f1ada1 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "os" + "sort" "time" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" @@ -884,6 +885,83 @@ func (a *API) clientRetrieve(ctx context.Context, order api.RetrievalOrder, ref return } +func (a *API) ClientListRetrievals(ctx context.Context) ([]api.RetrievalInfo, error) { + deals, err := a.Retrieval.ListDeals() + if err != nil { + return nil, err + } + dataTransfersByID, err := a.transfersByID(ctx) + if err != nil { + return nil, err + } + out := make([]api.RetrievalInfo, 0, len(deals)) + for _, v := range deals { + // Find the data transfer associated with this deal + var transferCh *api.DataTransferChannel + if v.ChannelID != nil { + if ch, ok := dataTransfersByID[*v.ChannelID]; ok { + transferCh = &ch + } + } + out = append(out, a.newRetrievalInfoWithTransfer(transferCh, v)) + } + sort.Slice(out, func(a, b int) bool { + return out[a].ID < out[b].ID + }) + return out, nil +} + +func (a *API) ClientGetRetrievalUpdates(ctx context.Context) (<-chan api.RetrievalInfo, error) { + updates := make(chan api.RetrievalInfo) + + unsub := a.Retrieval.SubscribeToEvents(func(_ rm.ClientEvent, deal rm.ClientDealState) { + updates <- a.newRetrievalInfo(ctx, deal) + }) + + go func() { + defer unsub() + <-ctx.Done() + }() + + return updates, nil +} + +func (a *API) newRetrievalInfoWithTransfer(ch *api.DataTransferChannel, deal rm.ClientDealState) api.RetrievalInfo { + return api.RetrievalInfo{ + PayloadCID: deal.PayloadCID, + ID: deal.ID, + PieceCID: deal.PieceCID, + PricePerByte: deal.PricePerByte, + UnsealPrice: deal.UnsealPrice, + Status: deal.Status, + Message: deal.Message, + Provider: deal.Sender, + BytesReceived: deal.TotalReceived, + BytesPaidFor: deal.BytesPaidFor, + TotalPaid: deal.FundsSpent, + TransferChannelID: deal.ChannelID, + DataTransfer: ch, + } +} + +func (a *API) newRetrievalInfo(ctx context.Context, v rm.ClientDealState) api.RetrievalInfo { + // Find the data transfer associated with this deal + var transferCh *api.DataTransferChannel + if v.ChannelID != nil { + state, err := a.DataTransfer.ChannelState(ctx, *v.ChannelID) + + // Note: If there was an error just ignore it, as the data transfer may + // 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.newRetrievalInfoWithTransfer(transferCh, v) +} + type multiStoreRetrievalStore struct { storeID multistore.StoreID store *multistore.Store diff --git a/node/impl/common/common.go b/node/impl/common/common.go index 7d99fb42ac9..f1c57665cff 100644 --- a/node/impl/common/common.go +++ b/node/impl/common/common.go @@ -156,7 +156,7 @@ func (a *CommonAPI) NetFindPeer(ctx context.Context, p peer.ID) (peer.AddrInfo, } func (a *CommonAPI) NetAutoNatStatus(ctx context.Context) (i api.NatInfo, err error) { - autonat := a.RawHost.(*basichost.BasicHost).AutoNat + autonat := a.RawHost.(*basichost.BasicHost).GetAutoNat() if autonat == nil { return api.NatInfo{ diff --git a/node/impl/full/mpool.go b/node/impl/full/mpool.go index 5fe5fbec1ad..bd91387a2be 100644 --- a/node/impl/full/mpool.go +++ b/node/impl/full/mpool.go @@ -226,15 +226,15 @@ func (a *MpoolAPI) MpoolBatchPushMessage(ctx context.Context, msgs []*types.Mess } func (a *MpoolAPI) MpoolCheckMessages(ctx context.Context, protos []*api.MessagePrototype) ([][]api.MessageCheckStatus, error) { - return a.Mpool.CheckMessages(protos) + return a.Mpool.CheckMessages(ctx, protos) } func (a *MpoolAPI) MpoolCheckPendingMessages(ctx context.Context, from address.Address) ([][]api.MessageCheckStatus, error) { - return a.Mpool.CheckPendingMessages(from) + return a.Mpool.CheckPendingMessages(ctx, from) } func (a *MpoolAPI) MpoolCheckReplaceMessages(ctx context.Context, msgs []*types.Message) ([][]api.MessageCheckStatus, error) { - return a.Mpool.CheckReplaceMessages(msgs) + return a.Mpool.CheckReplaceMessages(ctx, msgs) } func (a *MpoolAPI) MpoolGetNonce(ctx context.Context, addr address.Address) (uint64, error) { diff --git a/node/impl/remoteworker.go b/node/impl/remoteworker.go index 8dc7510b48e..d27b3baff42 100644 --- a/node/impl/remoteworker.go +++ b/node/impl/remoteworker.go @@ -38,6 +38,16 @@ func connectRemoteWorker(ctx context.Context, fa api.Common, url string) (*remot return nil, xerrors.Errorf("creating jsonrpc client: %w", err) } + wver, err := wapi.Version(ctx) + if err != nil { + closer() + return nil, err + } + + if !wver.EqMajorMinor(api.WorkerAPIVersion0) { + return nil, xerrors.Errorf("unsupported worker api version: %s (expected %s)", wver, api.WorkerAPIVersion0) + } + return &remoteWorker{wapi, closer}, nil } diff --git a/node/modules/dtypes/miner.go b/node/modules/dtypes/miner.go index 16af48add62..9a391223dc9 100644 --- a/node/modules/dtypes/miner.go +++ b/node/modules/dtypes/miner.go @@ -74,10 +74,12 @@ type ConsiderUnverifiedStorageDealsConfigFunc func() (bool, error) // disable or enable unverified storage deal acceptance. type SetConsiderUnverifiedStorageDealsConfigFunc func(bool) error -// SetSealingDelay sets how long a sector waits for more deals before sealing begins. +// SetSealingConfigFunc is a function which is used to +// sets the sealing config. type SetSealingConfigFunc func(sealiface.Config) error -// GetSealingDelay returns how long a sector waits for more deals before sealing begins. +// GetSealingConfigFunc is a function which is used to +// get the sealing config. type GetSealingConfigFunc func() (sealiface.Config, error) // SetExpectedSealDurationFunc is a function which is used to set how long sealing is expected to take. @@ -88,5 +90,10 @@ type SetExpectedSealDurationFunc func(time.Duration) error // too determine how long sealing is expected to take type GetExpectedSealDurationFunc func() (time.Duration, error) +type SetMaxDealStartDelayFunc func(time.Duration) error +type GetMaxDealStartDelayFunc func() (time.Duration, error) + type StorageDealFilter func(ctx context.Context, deal storagemarket.MinerDeal) (bool, string, error) type RetrievalDealFilter func(ctx context.Context, deal retrievalmarket.ProviderDealState) (bool, string, error) + +type RetrievalPricingFunc func(ctx context.Context, dealPricingParams retrievalmarket.PricingInput) (retrievalmarket.Ask, error) diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index 25ae2fcab08..a7b877f7050 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -10,6 +10,7 @@ import ( "path/filepath" "time" + "github.com/filecoin-project/lotus/markets/pricing" "go.uber.org/fx" "go.uber.org/multierr" "golang.org/x/xerrors" @@ -59,7 +60,6 @@ import ( "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" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" "github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/gen/slashfilter" @@ -485,6 +485,7 @@ func BasicDealFilter(user dtypes.StorageDealFilter) func(onlineOk dtypes.Conside unverifiedOk dtypes.ConsiderUnverifiedStorageDealsConfigFunc, blocklistFunc dtypes.StorageDealPieceCidBlocklistConfigFunc, expectedSealTimeFunc dtypes.GetExpectedSealDurationFunc, + startDelay dtypes.GetMaxDealStartDelayFunc, spn storagemarket.StorageProviderNode) dtypes.StorageDealFilter { return func(onlineOk dtypes.ConsiderOnlineStorageDealsConfigFunc, offlineOk dtypes.ConsiderOfflineStorageDealsConfigFunc, @@ -492,6 +493,7 @@ func BasicDealFilter(user dtypes.StorageDealFilter) func(onlineOk dtypes.Conside unverifiedOk dtypes.ConsiderUnverifiedStorageDealsConfigFunc, blocklistFunc dtypes.StorageDealPieceCidBlocklistConfigFunc, expectedSealTimeFunc dtypes.GetExpectedSealDurationFunc, + startDelay dtypes.GetMaxDealStartDelayFunc, spn storagemarket.StorageProviderNode) dtypes.StorageDealFilter { return func(ctx context.Context, deal storagemarket.MinerDeal) (bool, string, error) { @@ -563,9 +565,14 @@ func BasicDealFilter(user dtypes.StorageDealFilter) func(onlineOk dtypes.Conside return false, fmt.Sprintf("cannot seal a sector before %s", deal.Proposal.StartEpoch), nil } + sd, err := startDelay() + if err != nil { + return false, "miner error", err + } + // Reject if it's more than 7 days in the future // TODO: read from cfg - maxStartEpoch := earliest + abi.ChainEpoch(7*builtin.SecondsInDay/build.BlockDelaySecs) + maxStartEpoch := earliest + abi.ChainEpoch(uint64(sd.Seconds())/build.BlockDelaySecs) if deal.Proposal.StartEpoch > maxStartEpoch { return false, fmt.Sprintf("deal start epoch is too far in the future: %s > %s", deal.Proposal.StartEpoch, maxStartEpoch), nil } @@ -633,20 +640,33 @@ func RetrievalDealFilter(userFilter dtypes.RetrievalDealFilter) func(onlineOk dt } } +// RetrievalPricingFunc configures the pricing function to use for retrieval deals. +func RetrievalPricingFunc(cfg config.DealmakingConfig) func(_ dtypes.ConsiderOnlineRetrievalDealsConfigFunc, + _ dtypes.ConsiderOfflineRetrievalDealsConfigFunc) dtypes.RetrievalPricingFunc { + + return func(_ dtypes.ConsiderOnlineRetrievalDealsConfigFunc, + _ dtypes.ConsiderOfflineRetrievalDealsConfigFunc) dtypes.RetrievalPricingFunc { + if cfg.RetrievalPricing.Strategy == config.RetrievalPricingExternalMode { + return pricing.ExternalRetrievalPricingFunc(cfg.RetrievalPricing.External.Path) + } + + return retrievalimpl.DefaultPricingFunc(cfg.RetrievalPricing.Default.VerifiedDealsFreeTransfer) + } +} + // RetrievalProvider creates a new retrieval provider attached to the provider blockstore func RetrievalProvider(h host.Host, miner *storage.Miner, - sealer sectorstorage.SectorManager, full v1api.FullNode, ds dtypes.MetadataDS, pieceStore dtypes.ProviderPieceStore, mds dtypes.StagingMultiDstore, dt dtypes.ProviderDataTransfer, - onlineOk dtypes.ConsiderOnlineRetrievalDealsConfigFunc, - offlineOk dtypes.ConsiderOfflineRetrievalDealsConfigFunc, + pieceProvider sectorstorage.PieceProvider, + pricingFnc dtypes.RetrievalPricingFunc, userFilter dtypes.RetrievalDealFilter, ) (retrievalmarket.RetrievalProvider, error) { - adapter := retrievaladapter.NewRetrievalProviderNode(miner, sealer, full) + adapter := retrievaladapter.NewRetrievalProviderNode(miner, pieceProvider, full) maddr, err := minerAddrFromDS(ds) if err != nil { @@ -656,19 +676,29 @@ func RetrievalProvider(h host.Host, netwk := rmnet.NewFromLibp2pHost(h) opt := retrievalimpl.DealDeciderOpt(retrievalimpl.DealDecider(userFilter)) - return retrievalimpl.NewProvider(maddr, adapter, netwk, pieceStore, mds, dt, namespace.Wrap(ds, datastore.NewKey("/retrievals/provider")), opt) + return retrievalimpl.NewProvider(maddr, adapter, netwk, pieceStore, mds, dt, namespace.Wrap(ds, datastore.NewKey("/retrievals/provider")), + retrievalimpl.RetrievalPricingFunc(pricingFnc), opt) } var WorkerCallsPrefix = datastore.NewKey("/worker/calls") var ManagerWorkPrefix = datastore.NewKey("/stmgr/calls") -func SectorStorage(mctx helpers.MetricsCtx, lc fx.Lifecycle, ls stores.LocalStorage, si stores.SectorIndex, sc sectorstorage.SealerConfig, urls sectorstorage.URLs, sa sectorstorage.StorageAuth, ds dtypes.MetadataDS) (*sectorstorage.Manager, error) { +func LocalStorage(mctx helpers.MetricsCtx, lc fx.Lifecycle, ls stores.LocalStorage, si stores.SectorIndex, urls sectorstorage.URLs) (*stores.Local, error) { + ctx := helpers.LifecycleCtx(mctx, lc) + return stores.NewLocal(ctx, ls, si, urls) +} + +func RemoteStorage(lstor *stores.Local, si stores.SectorIndex, sa sectorstorage.StorageAuth, sc sectorstorage.SealerConfig) *stores.Remote { + return stores.NewRemote(lstor, si, http.Header(sa), sc.ParallelFetchLimit, &stores.DefaultPartialFileHandler{}) +} + +func SectorStorage(mctx helpers.MetricsCtx, lc fx.Lifecycle, lstor *stores.Local, stor *stores.Remote, ls stores.LocalStorage, si stores.SectorIndex, sc sectorstorage.SealerConfig, ds dtypes.MetadataDS) (*sectorstorage.Manager, error) { ctx := helpers.LifecycleCtx(mctx, lc) wsts := statestore.New(namespace.Wrap(ds, WorkerCallsPrefix)) smsts := statestore.New(namespace.Wrap(ds, ManagerWorkPrefix)) - sst, err := sectorstorage.New(ctx, ls, si, sc, urls, sa, wsts, smsts) + sst, err := sectorstorage.New(ctx, lstor, stor, ls, si, sc, wsts, smsts) if err != nil { return nil, err } @@ -826,9 +856,9 @@ func NewSetSealConfigFunc(r repo.LockedRepo) (dtypes.SetSealingConfigFunc, error MaxSealingSectorsForDeals: cfg.MaxSealingSectorsForDeals, WaitDealsDelay: config.Duration(cfg.WaitDealsDelay), AlwaysKeepUnsealedCopy: cfg.AlwaysKeepUnsealedCopy, + FinalizeEarly: cfg.FinalizeEarly, BatchPreCommits: cfg.BatchPreCommits, - MinPreCommitBatch: cfg.MinPreCommitBatch, MaxPreCommitBatch: cfg.MaxPreCommitBatch, PreCommitBatchWait: config.Duration(cfg.PreCommitBatchWait), PreCommitBatchSlack: config.Duration(cfg.PreCommitBatchSlack), @@ -857,9 +887,9 @@ func NewGetSealConfigFunc(r repo.LockedRepo) (dtypes.GetSealingConfigFunc, error MaxSealingSectorsForDeals: cfg.Sealing.MaxSealingSectorsForDeals, WaitDealsDelay: time.Duration(cfg.Sealing.WaitDealsDelay), AlwaysKeepUnsealedCopy: cfg.Sealing.AlwaysKeepUnsealedCopy, + FinalizeEarly: cfg.Sealing.FinalizeEarly, BatchPreCommits: cfg.Sealing.BatchPreCommits, - MinPreCommitBatch: cfg.Sealing.MinPreCommitBatch, MaxPreCommitBatch: cfg.Sealing.MaxPreCommitBatch, PreCommitBatchWait: time.Duration(cfg.Sealing.PreCommitBatchWait), PreCommitBatchSlack: time.Duration(cfg.Sealing.PreCommitBatchSlack), @@ -897,6 +927,24 @@ func NewGetExpectedSealDurationFunc(r repo.LockedRepo) (dtypes.GetExpectedSealDu }, nil } +func NewSetMaxDealStartDelayFunc(r repo.LockedRepo) (dtypes.SetMaxDealStartDelayFunc, error) { + return func(delay time.Duration) (err error) { + err = mutateCfg(r, func(cfg *config.StorageMiner) { + cfg.Dealmaking.MaxDealStartDelay = config.Duration(delay) + }) + return + }, nil +} + +func NewGetMaxDealStartDelayFunc(r repo.LockedRepo) (dtypes.GetMaxDealStartDelayFunc, error) { + return func() (out time.Duration, err error) { + err = readCfg(r, func(cfg *config.StorageMiner) { + out = time.Duration(cfg.Dealmaking.MaxDealStartDelay) + }) + return + }, nil +} + func readCfg(r repo.LockedRepo, accessor func(*config.StorageMiner)) error { raw, err := r.Config() if err != nil { diff --git a/node/node_test.go b/node/node_test.go deleted file mode 100644 index dcbc70469c6..00000000000 --- a/node/node_test.go +++ /dev/null @@ -1,309 +0,0 @@ -package node_test - -import ( - "os" - "testing" - "time" - - "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/lotus/api/test" - "github.com/filecoin-project/lotus/chain/actors/policy" - "github.com/filecoin-project/lotus/lib/lotuslog" - builder "github.com/filecoin-project/lotus/node/test" - logging "github.com/ipfs/go-log/v2" -) - -func init() { - _ = logging.SetLogLevel("*", "INFO") - - policy.SetConsensusMinerMinPower(abi.NewStoragePower(2048)) - policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1) - policy.SetMinVerifiedDealSize(abi.NewStoragePower(256)) -} - -func TestAPI(t *testing.T) { - test.TestApis(t, builder.Builder) -} - -func TestAPIRPC(t *testing.T) { - test.TestApis(t, builder.RPCBuilder) -} - -func TestAPIDealFlow(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) - - t.Run("TestDealFlow", func(t *testing.T) { - test.TestDealFlow(t, builder.MockSbBuilder, blockTime, false, false, dealStartEpoch) - }) - t.Run("WithExportedCAR", func(t *testing.T) { - test.TestDealFlow(t, builder.MockSbBuilder, blockTime, true, false, dealStartEpoch) - }) - t.Run("TestDoubleDealFlow", func(t *testing.T) { - test.TestDoubleDealFlow(t, builder.MockSbBuilder, blockTime, dealStartEpoch) - }) - t.Run("TestFastRetrievalDealFlow", func(t *testing.T) { - test.TestFastRetrievalDealFlow(t, builder.MockSbBuilder, blockTime, dealStartEpoch) - }) - t.Run("TestPublishDealsBatching", func(t *testing.T) { - test.TestPublishDealsBatching(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") - logging.SetLogLevel("sectors", "DEBUG") - - 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) { - if testing.Short() { - t.Skip("skipping test in short mode") - } - lotuslog.SetupLogLevels() - logging.SetLogLevel("miner", "ERROR") - logging.SetLogLevel("chainstore", "ERROR") - logging.SetLogLevel("chain", "ERROR") - logging.SetLogLevel("sub", "ERROR") - logging.SetLogLevel("storageminer", "ERROR") - - // TODO: just set this globally? - oldDelay := policy.GetPreCommitChallengeDelay() - policy.SetPreCommitChallengeDelay(5) - t.Cleanup(func() { - policy.SetPreCommitChallengeDelay(oldDelay) - }) - - t.Run("basic", func(t *testing.T) { - test.TestDealFlow(t, builder.Builder, time.Second, false, false, 0) - }) - - t.Run("fast-retrieval", func(t *testing.T) { - test.TestDealFlow(t, builder.Builder, time.Second, false, true, 0) - }) - - t.Run("retrieval-second", func(t *testing.T) { - test.TestSecondDealRetrieval(t, builder.Builder, time.Second) - }) -} - -func TestDealMining(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode") - } - - logging.SetLogLevel("miner", "ERROR") - logging.SetLogLevel("chainstore", "ERROR") - logging.SetLogLevel("chain", "ERROR") - logging.SetLogLevel("sub", "ERROR") - logging.SetLogLevel("storageminer", "ERROR") - - test.TestDealMining(t, builder.MockSbBuilder, 50*time.Millisecond, false) -} - -func TestSDRUpgrade(t *testing.T) { - logging.SetLogLevel("miner", "ERROR") - logging.SetLogLevel("chainstore", "ERROR") - logging.SetLogLevel("chain", "ERROR") - logging.SetLogLevel("sub", "ERROR") - logging.SetLogLevel("storageminer", "ERROR") - - oldDelay := policy.GetPreCommitChallengeDelay() - policy.SetPreCommitChallengeDelay(5) - t.Cleanup(func() { - policy.SetPreCommitChallengeDelay(oldDelay) - }) - - test.TestSDRUpgrade(t, builder.MockSbBuilder, 50*time.Millisecond) -} - -func TestPledgeSectors(t *testing.T) { - logging.SetLogLevel("miner", "ERROR") - logging.SetLogLevel("chainstore", "ERROR") - logging.SetLogLevel("chain", "ERROR") - logging.SetLogLevel("sub", "ERROR") - logging.SetLogLevel("storageminer", "ERROR") - - t.Run("1", func(t *testing.T) { - test.TestPledgeSector(t, builder.MockSbBuilder, 50*time.Millisecond, 1) - }) - - t.Run("100", func(t *testing.T) { - test.TestPledgeSector(t, builder.MockSbBuilder, 50*time.Millisecond, 100) - }) - - t.Run("1000", func(t *testing.T) { - if testing.Short() { // takes ~16s - t.Skip("skipping test in short mode") - } - - test.TestPledgeSector(t, builder.MockSbBuilder, 50*time.Millisecond, 1000) - }) -} - -func TestPledgeBatching(t *testing.T) { - t.Run("100", func(t *testing.T) { - test.TestPledgeBatching(t, builder.MockSbBuilder, 50*time.Millisecond, 100) - }) - t.Run("100-before-nv13", func(t *testing.T) { - test.TestPledgeBeforeNv13(t, builder.MockSbBuilder, 50*time.Millisecond, 100) - }) -} - -func TestTapeFix(t *testing.T) { - logging.SetLogLevel("miner", "ERROR") - logging.SetLogLevel("chainstore", "ERROR") - logging.SetLogLevel("chain", "ERROR") - logging.SetLogLevel("sub", "ERROR") - logging.SetLogLevel("storageminer", "ERROR") - - test.TestTapeFix(t, builder.MockSbBuilder, 2*time.Millisecond) -} - -func TestWindowedPost(t *testing.T) { - if os.Getenv("LOTUS_TEST_WINDOW_POST") != "1" { - t.Skip("this takes a few minutes, set LOTUS_TEST_WINDOW_POST=1 to run") - } - - logging.SetLogLevel("miner", "ERROR") - logging.SetLogLevel("gen", "ERROR") - logging.SetLogLevel("chainstore", "ERROR") - logging.SetLogLevel("chain", "ERROR") - logging.SetLogLevel("sub", "ERROR") - logging.SetLogLevel("storageminer", "ERROR") - - test.TestWindowPost(t, builder.MockSbBuilder, 2*time.Millisecond, 10) -} - -func TestTerminate(t *testing.T) { - if os.Getenv("LOTUS_TEST_WINDOW_POST") != "1" { - t.Skip("this takes a few minutes, set LOTUS_TEST_WINDOW_POST=1 to run") - } - - logging.SetLogLevel("miner", "ERROR") - logging.SetLogLevel("chainstore", "ERROR") - logging.SetLogLevel("chain", "ERROR") - logging.SetLogLevel("sub", "ERROR") - logging.SetLogLevel("storageminer", "ERROR") - - test.TestTerminate(t, builder.MockSbBuilder, 2*time.Millisecond) -} - -func TestCCUpgrade(t *testing.T) { - logging.SetLogLevel("miner", "ERROR") - logging.SetLogLevel("chainstore", "ERROR") - logging.SetLogLevel("chain", "ERROR") - logging.SetLogLevel("sub", "ERROR") - logging.SetLogLevel("storageminer", "ERROR") - - test.TestCCUpgrade(t, builder.MockSbBuilder, 5*time.Millisecond) -} - -func TestPaymentChannels(t *testing.T) { - logging.SetLogLevel("miner", "ERROR") - logging.SetLogLevel("chainstore", "ERROR") - logging.SetLogLevel("chain", "ERROR") - logging.SetLogLevel("sub", "ERROR") - logging.SetLogLevel("pubsub", "ERROR") - logging.SetLogLevel("storageminer", "ERROR") - - test.TestPaymentChannels(t, builder.MockSbBuilder, 5*time.Millisecond) -} - -func TestWindowPostDispute(t *testing.T) { - if os.Getenv("LOTUS_TEST_WINDOW_POST") != "1" { - t.Skip("this takes a few minutes, set LOTUS_TEST_WINDOW_POST=1 to run") - } - logging.SetLogLevel("miner", "ERROR") - logging.SetLogLevel("gen", "ERROR") - logging.SetLogLevel("chainstore", "ERROR") - logging.SetLogLevel("chain", "ERROR") - logging.SetLogLevel("sub", "ERROR") - logging.SetLogLevel("storageminer", "ERROR") - - test.TestWindowPostDispute(t, builder.MockSbBuilder, 2*time.Millisecond) -} - -func TestWindowPostDisputeFails(t *testing.T) { - if os.Getenv("LOTUS_TEST_WINDOW_POST") != "1" { - t.Skip("this takes a few minutes, set LOTUS_TEST_WINDOW_POST=1 to run") - } - logging.SetLogLevel("miner", "ERROR") - logging.SetLogLevel("gen", "ERROR") - logging.SetLogLevel("chainstore", "ERROR") - logging.SetLogLevel("chain", "ERROR") - logging.SetLogLevel("sub", "ERROR") - logging.SetLogLevel("storageminer", "ERROR") - - test.TestWindowPostDisputeFails(t, builder.MockSbBuilder, 2*time.Millisecond) -} - -func TestWindowPostBaseFeeNoBurn(t *testing.T) { - if os.Getenv("LOTUS_TEST_WINDOW_POST") != "1" { - t.Skip("this takes a few minutes, set LOTUS_TEST_WINDOW_POST=1 to run") - } - logging.SetLogLevel("miner", "ERROR") - logging.SetLogLevel("gen", "ERROR") - logging.SetLogLevel("chainstore", "ERROR") - logging.SetLogLevel("chain", "ERROR") - logging.SetLogLevel("sub", "ERROR") - logging.SetLogLevel("storageminer", "ERROR") - - test.TestWindowPostBaseFeeNoBurn(t, builder.MockSbBuilder, 2*time.Millisecond) -} - -func TestWindowPostBaseFeeBurn(t *testing.T) { - if os.Getenv("LOTUS_TEST_WINDOW_POST") != "1" { - t.Skip("this takes a few minutes, set LOTUS_TEST_WINDOW_POST=1 to run") - } - logging.SetLogLevel("miner", "ERROR") - logging.SetLogLevel("gen", "ERROR") - logging.SetLogLevel("chainstore", "ERROR") - logging.SetLogLevel("chain", "ERROR") - logging.SetLogLevel("sub", "ERROR") - logging.SetLogLevel("storageminer", "ERROR") - - test.TestWindowPostBaseFeeBurn(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("gen", "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) -} - -func TestVerifiedClientTopUp(t *testing.T) { - logging.SetLogLevel("storageminer", "FATAL") - logging.SetLogLevel("chain", "ERROR") - test.AddVerifiedClient(t, builder.MockSbBuilder) -} diff --git a/node/rpc.go b/node/rpc.go new file mode 100644 index 00000000000..9b84792bb55 --- /dev/null +++ b/node/rpc.go @@ -0,0 +1,193 @@ +package node + +import ( + "context" + "encoding/json" + "net" + "net/http" + _ "net/http/pprof" + "runtime" + "strconv" + + "github.com/gorilla/mux" + "github.com/ipfs/go-cid" + logging "github.com/ipfs/go-log/v2" + "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr/net" + "go.opencensus.io/tag" + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-jsonrpc" + "github.com/filecoin-project/go-jsonrpc/auth" + + "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/metrics" + "github.com/filecoin-project/lotus/node/impl" +) + +var rpclog = logging.Logger("rpc") + +// ServeRPC serves an HTTP handler over the supplied listen multiaddr. +// +// This function spawns a goroutine to run the server, and returns immediately. +// It returns the stop function to be called to terminate the endpoint. +// +// The supplied ID is used in tracing, by inserting a tag in the context. +func ServeRPC(h http.Handler, id string, addr multiaddr.Multiaddr) (StopFunc, error) { + // Start listening to the addr; if invalid or occupied, we will fail early. + lst, err := manet.Listen(addr) + if err != nil { + return nil, xerrors.Errorf("could not listen: %w", err) + } + + // Instantiate the server and start listening. + srv := &http.Server{ + Handler: h, + BaseContext: func(listener net.Listener) context.Context { + ctx, _ := tag.New(context.Background(), tag.Upsert(metrics.APIInterface, id)) + return ctx + }, + } + + go func() { + err = srv.Serve(manet.NetListener(lst)) + if err != http.ErrServerClosed { + rpclog.Warnf("rpc server failed: %s", err) + } + }() + + return srv.Shutdown, err +} + +// FullNodeHandler returns a full node handler, to be mounted as-is on the server. +func FullNodeHandler(a v1api.FullNode, permissioned bool, opts ...jsonrpc.ServerOption) (http.Handler, error) { + m := mux.NewRouter() + + serveRpc := func(path string, hnd interface{}) { + rpcServer := jsonrpc.NewServer(opts...) + rpcServer.Register("Filecoin", hnd) + + var handler http.Handler = rpcServer + if permissioned { + handler = &auth.Handler{Verify: a.AuthVerify, Next: rpcServer.ServeHTTP} + } + + m.Handle(path, handler) + } + + fnapi := metrics.MetricedFullAPI(a) + if permissioned { + fnapi = api.PermissionedFullAPI(fnapi) + } + + serveRpc("/rpc/v1", fnapi) + serveRpc("/rpc/v0", &v0api.WrapperV1Full{FullNode: fnapi}) + + // Import handler + handleImportFunc := handleImport(a.(*impl.FullNodeAPI)) + if permissioned { + importAH := &auth.Handler{ + Verify: a.AuthVerify, + Next: handleImportFunc, + } + m.Handle("/rest/v0/import", importAH) + } else { + m.HandleFunc("/rest/v0/import", handleImportFunc) + } + + // debugging + m.Handle("/debug/metrics", metrics.Exporter()) + m.Handle("/debug/pprof-set/block", handleFractionOpt("BlockProfileRate", runtime.SetBlockProfileRate)) + m.Handle("/debug/pprof-set/mutex", handleFractionOpt("MutexProfileFraction", func(x int) { + runtime.SetMutexProfileFraction(x) + })) + m.PathPrefix("/").Handler(http.DefaultServeMux) // pprof + + return m, nil +} + +// MinerHandler returns a miner handler, to be mounted as-is on the server. +func MinerHandler(a api.StorageMiner, permissioned bool) (http.Handler, error) { + m := mux.NewRouter() + + mapi := metrics.MetricedStorMinerAPI(a) + if permissioned { + mapi = api.PermissionedStorMinerAPI(mapi) + } + + rpcServer := jsonrpc.NewServer() + rpcServer.Register("Filecoin", mapi) + + m.Handle("/rpc/v0", rpcServer) + m.PathPrefix("/remote").HandlerFunc(a.(*impl.StorageMinerAPI).ServeRemote) + + // debugging + m.Handle("/debug/metrics", metrics.Exporter()) + m.PathPrefix("/").Handler(http.DefaultServeMux) // pprof + + if !permissioned { + return rpcServer, nil + } + + ah := &auth.Handler{ + Verify: a.AuthVerify, + Next: m.ServeHTTP, + } + return ah, nil +} + +func handleImport(a *impl.FullNodeAPI) func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + if r.Method != "PUT" { + w.WriteHeader(404) + return + } + if !auth.HasPerm(r.Context(), nil, api.PermWrite) { + w.WriteHeader(401) + _ = json.NewEncoder(w).Encode(struct{ Error string }{"unauthorized: missing write permission"}) + return + } + + c, err := a.ClientImportLocal(r.Context(), r.Body) + if err != nil { + w.WriteHeader(500) + _ = json.NewEncoder(w).Encode(struct{ Error string }{err.Error()}) + return + } + w.WriteHeader(200) + err = json.NewEncoder(w).Encode(struct{ Cid cid.Cid }{c}) + if err != nil { + rpclog.Errorf("/rest/v0/import: Writing response failed: %+v", err) + return + } + } +} + +func handleFractionOpt(name string, setter func(int)) http.HandlerFunc { + return func(rw http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + http.Error(rw, "only POST allowed", http.StatusMethodNotAllowed) + return + } + if err := r.ParseForm(); err != nil { + http.Error(rw, err.Error(), http.StatusBadRequest) + return + } + + asfr := r.Form.Get("x") + if len(asfr) == 0 { + http.Error(rw, "parameter 'x' must be set", http.StatusBadRequest) + return + } + + fr, err := strconv.Atoi(asfr) + if err != nil { + http.Error(rw, err.Error(), http.StatusBadRequest) + return + } + rpclog.Infof("setting %s to %d", name, fr) + setter(fr) + } +} diff --git a/node/shutdown.go b/node/shutdown.go new file mode 100644 index 00000000000..e630031dac7 --- /dev/null +++ b/node/shutdown.go @@ -0,0 +1,56 @@ +package node + +import ( + "context" + "os" + "os/signal" + "syscall" +) + +type ShutdownHandler struct { + Component string + StopFunc StopFunc +} + +// MonitorShutdown manages shutdown requests, by watching signals and invoking +// the supplied handlers in order. +// +// It watches SIGTERM and SIGINT OS signals, as well as the trigger channel. +// When any of them fire, it calls the supplied handlers in order. If any of +// them errors, it merely logs the error. +// +// Once the shutdown has completed, it closes the returned channel. The caller +// can watch this channel +func MonitorShutdown(triggerCh <-chan struct{}, handlers ...ShutdownHandler) <-chan struct{} { + sigCh := make(chan os.Signal, 2) + out := make(chan struct{}) + + go func() { + select { + case sig := <-sigCh: + log.Warnw("received shutdown", "signal", sig) + case <-triggerCh: + log.Warn("received shutdown") + } + + log.Warn("Shutting down...") + + // Call all the handlers, logging on failure and success. + for _, h := range handlers { + if err := h.StopFunc(context.TODO()); err != nil { + log.Errorf("shutting down %s failed: %s", h.Component, err) + continue + } + log.Infof("%s shut down successfully ", h.Component) + } + + log.Warn("Graceful shutdown successful") + + // Sync all loggers. + _ = log.Sync() //nolint:errcheck + close(out) + }() + + signal.Notify(sigCh, syscall.SIGTERM, syscall.SIGINT) + return out +} diff --git a/node/shutdown_test.go b/node/shutdown_test.go new file mode 100644 index 00000000000..15e2af93e5e --- /dev/null +++ b/node/shutdown_test.go @@ -0,0 +1,36 @@ +package node + +import ( + "context" + "sync" + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +func TestMonitorShutdown(t *testing.T) { + signalCh := make(chan struct{}) + + // Three shutdown handlers. + var wg sync.WaitGroup + wg.Add(3) + h := ShutdownHandler{ + Component: "handler", + StopFunc: func(_ context.Context) error { + wg.Done() + return nil + }, + } + + finishCh := MonitorShutdown(signalCh, h, h, h) + + // Nothing here after 10ms. + time.Sleep(10 * time.Millisecond) + require.Len(t, finishCh, 0) + + // Now trigger the shutdown. + close(signalCh) + wg.Wait() + <-finishCh +} diff --git a/paychmgr/settler/settler.go b/paychmgr/settler/settler.go index 676b15c271f..ce31ab223b0 100644 --- a/paychmgr/settler/settler.go +++ b/paychmgr/settler/settler.go @@ -96,6 +96,7 @@ func (pcs *paymentChannelSettler) messageHandler(msg *types.Message, rec *types. msgLookup, err := pcs.api.StateWaitMsg(pcs.ctx, submitMessageCID, build.MessageConfidence, api.LookbackNoLimit, true) if err != nil { log.Errorf("submitting voucher: %s", err.Error()) + return } if msgLookup.Receipt.ExitCode != 0 { log.Errorf("failed submitting voucher: %+v", voucher) diff --git a/scripts/build-bundle.sh b/scripts/build-bundle.sh index 7d37edff87e..fe1c886114e 100755 --- a/scripts/build-bundle.sh +++ b/scripts/build-bundle.sh @@ -49,4 +49,7 @@ do ipfs add -q "lotus_${CIRCLE_TAG}_${ARCH}-amd64.tar.gz" > "lotus_${CIRCLE_TAG}_${ARCH}-amd64.tar.gz.cid" done +cp "../appimage/Lotus-${CIRCLE_TAG}-x86_64.AppImage" . +sha512sum "Lotus-${CIRCLE_TAG}-x86_64.AppImage" > "Lotus-${CIRCLE_TAG}-x86_64.AppImage.sha512" +ipfs add -q "Lotus-${CIRCLE_TAG}-x86_64.AppImage" > "Lotus-${CIRCLE_TAG}-x86_64.AppImage.cid" popd diff --git a/scripts/mkreleaselog b/scripts/mkreleaselog index ffc3d935eb3..c9eaef4fb47 100755 --- a/scripts/mkreleaselog +++ b/scripts/mkreleaselog @@ -1,31 +1,11 @@ #!/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 -) +AUTHORS=(filecoin-project) [[ -n "${REPO_FILTER+x}" ]] || REPO_FILTER="github.com/(${$(printf "|%s" "${AUTHORS[@]}"):1})" @@ -49,13 +29,15 @@ statlog() { 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 + local stack=() + git -C "$rpath" -c mailmap.file="$mailmap_file" log --use-mailmap --shortstat --no-merges --pretty="tformat:%H%x09%aN%x09%aE" "$start..$end" | while read -r line; do + if [[ -n "$line" ]]; then + stack+=("$line") + continue + fi + + read -r changes + changed=0 insertions=0 deletions=0 @@ -72,14 +54,18 @@ statlog() { 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}' + for author in "${stack[@]}"; do + IFS=$'\t' read -r hash name email <<<"$author" + 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 + stack=() done } diff --git a/scripts/publish-release.sh b/scripts/publish-release.sh index ad2a52dcf49..22572de600d 100755 --- a/scripts/publish-release.sh +++ b/scripts/publish-release.sh @@ -68,6 +68,9 @@ artifacts=( "lotus_${CIRCLE_TAG}_darwin-amd64.tar.gz" "lotus_${CIRCLE_TAG}_darwin-amd64.tar.gz.cid" "lotus_${CIRCLE_TAG}_darwin-amd64.tar.gz.sha512" + "Lotus-${CIRCLE_TAG}-x86_64.AppImage" + "Lotus-${CIRCLE_TAG}-x86_64.AppImage.cid" + "Lotus-${CIRCLE_TAG}-x86_64.AppImage.sha512" ) for RELEASE_FILE in "${artifacts[@]}" diff --git a/snap/local/icon.svg b/snap/local/icon.svg new file mode 100644 index 00000000000..da992296a1a --- /dev/null +++ b/snap/local/icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 7cdc1746d3b..472621c2a48 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -1,28 +1,76 @@ -name: lotus -base: core18 -version: '1.8.0' +name: lotus-filecoin +base: core20 +version: latest summary: filecoin daemon/client +icon: snap/local/icon.svg description: | Filecoin is a peer-to-peer network that stores files on the internet with built-in economic incentives to ensure files are stored reliably over time + + For documentation and additional information, please see the following resources + + https://filecoin.io + + https://fil.org + + https://docs.filecoin.io + + https://github.com/filecoin-project/lotus + grade: devel -confinement: devmode # use 'strict' once you have the right plugs and slots +confinement: strict parts: - libs: - plugin: dump + lotus: + plugin: make source: ./ - organize: - 'lotus' : bin/ - 'lotus-*' : bin/ + build-snaps: + - go + - rustup + build-packages: + - git + - jq + - libhwloc-dev + - ocl-icd-opencl-dev + - pkg-config stage-packages: + - libhwloc15 - ocl-icd-libopencl1 - - libhwloc1 - - libgcc1 + override-build: | + LDFLAGS="" make lotus lotus-miner lotus-worker + cp lotus lotus-miner lotus-worker $SNAPCRAFT_PART_INSTALL + apps: lotus: - command: bin/lotus + command: lotus + plugs: + - network + - network-bind + - home + environment: + FIL_PROOFS_PARAMETER_CACHE: $SNAP_USER_COMMON/filecoin-proof-parameters + LOTUS_PATH: $SNAP_USER_COMMON/lotus + LOTUS_MINER_PATH: $SNAP_USER_COMMON/lotus-miner + LOTUS_WORKER_PATH: $SNAP_USER_COMMON/lotus-worker lotus-miner: - command: bin/lotus-miner + command: lotus-miner + plugs: + - network + - network-bind + - opengl + environment: + FIL_PROOFS_PARAMETER_CACHE: $SNAP_USER_COMMON/filecoin-proof-parameters + LOTUS_PATH: $SNAP_USER_COMMON/lotus + LOTUS_MINER_PATH: $SNAP_USER_COMMON/lotus-miner + LOTUS_WORKER_PATH: $SNAP_USER_COMMON/lotus-worker lotus-worker: - command: bin/lotus-worker + command: lotus-worker + plugs: + - network + - network-bind + - opengl + environment: + FIL_PROOFS_PARAMETER_CACHE: $SNAP_USER_COMMON/filecoin-proof-parameters + LOTUS_PATH: $SNAP_USER_COMMON/lotus + LOTUS_MINER_PATH: $SNAP_USER_COMMON/lotus-miner + LOTUS_WORKER_PATH: $SNAP_USER_COMMON/lotus-worker diff --git a/storage/adapter_storage_miner.go b/storage/adapter_storage_miner.go index 1376ae5fb7d..895e7846db3 100644 --- a/storage/adapter_storage_miner.go +++ b/storage/adapter_storage_miner.go @@ -360,6 +360,20 @@ func (s SealingAPIAdapter) ChainHead(ctx context.Context) (sealing.TipSetToken, return head.Key().Bytes(), head.Height(), nil } +func (s SealingAPIAdapter) ChainBaseFee(ctx context.Context, tok sealing.TipSetToken) (abi.TokenAmount, error) { + tsk, err := types.TipSetKeyFromBytes(tok) + if err != nil { + return big.Zero(), err + } + + ts, err := s.delegate.ChainGetTipSet(ctx, tsk) + if err != nil { + return big.Zero(), err + } + + return ts.Blocks()[0].ParentBaseFee, nil +} + func (s SealingAPIAdapter) ChainGetMessage(ctx context.Context, mc cid.Cid) (*types.Message, error) { return s.delegate.ChainGetMessage(ctx, mc) } diff --git a/storage/miner.go b/storage/miner.go index 106c0929180..3d29e0ef11e 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -171,12 +171,6 @@ func (m *Miner) Run(ctx context.Context) error { return xerrors.Errorf("getting miner info: %w", err) } - fc := sealing.FeeConfig{ - MaxPreCommitGasFee: abi.TokenAmount(m.feeCfg.MaxPreCommitGasFee), - MaxCommitGasFee: abi.TokenAmount(m.feeCfg.MaxCommitGasFee), - MaxTerminateGasFee: abi.TokenAmount(m.feeCfg.MaxTerminateGasFee), - } - var ( // consumer of chain head changes. evts = events.NewEvents(ctx, m.api) @@ -205,7 +199,7 @@ func (m *Miner) Run(ctx context.Context) error { ) // Instantiate the sealing FSM. - m.sealing = sealing.New(adaptedAPI, fc, evtsAdapter, m.maddr, m.ds, m.sealer, m.sc, m.verif, m.prover, &pcp, cfg, m.handleSealingNotifications, as) + m.sealing = sealing.New(ctx, adaptedAPI, m.feeCfg, evtsAdapter, m.maddr, m.ds, m.sealer, m.sc, m.verif, m.prover, &pcp, cfg, m.handleSealingNotifications, as) // Run the sealing FSM. go m.sealing.Run(ctx) //nolint:errcheck // logged intside the function diff --git a/storage/wdpost_run.go b/storage/wdpost_run.go index d62b5e8513c..0fe7ea85179 100644 --- a/storage/wdpost_run.go +++ b/storage/wdpost_run.go @@ -732,7 +732,7 @@ func (s *WindowPoStScheduler) batchPartitions(partitions []api.Partition, nv net // sectors per partition 3: ooo // partitions per message 2: oooOOO // <1><2> (3rd doesn't fit) - partitionsPerMsg, err := policy.GetMaxPoStPartitions(s.proofType) + partitionsPerMsg, err := policy.GetMaxPoStPartitions(nv, s.proofType) if err != nil { return nil, xerrors.Errorf("getting sectors per partition: %w", err) } diff --git a/storage/wdpost_run_test.go b/storage/wdpost_run_test.go index b878ff97e3c..61f2a324b08 100644 --- a/storage/wdpost_run_test.go +++ b/storage/wdpost_run_test.go @@ -31,6 +31,7 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + "github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/extern/sector-storage/storiface" "github.com/filecoin-project/lotus/journal" @@ -185,8 +186,8 @@ func TestWDPostDoPost(t *testing.T) { // Work out the number of partitions that can be included in a message // without exceeding the message sector limit + partitionsPerMsg, err := policy.GetMaxPoStPartitions(network.Version13, proofType) require.NoError(t, err) - partitionsPerMsg := int(miner5.AddressedSectorsMax / sectorsPerPartition) if partitionsPerMsg > miner5.AddressedPartitionsMax { partitionsPerMsg = miner5.AddressedPartitionsMax } diff --git a/testplans/Makefile b/testplans/Makefile index 0bf685005dc..38f46baa8f8 100644 --- a/testplans/Makefile +++ b/testplans/Makefile @@ -6,18 +6,18 @@ download-proofs: go run github.com/filecoin-project/go-paramfetch/paramfetch 2048 ./docker-images/proof-parameters.json build-images: - docker build -t "iptestground/oni-buildbase:v14-lotus" -f "docker-images/Dockerfile.oni-buildbase" "docker-images" - docker build -t "iptestground/oni-runtime:v9" -f "docker-images/Dockerfile.oni-runtime" "docker-images" - docker build -t "iptestground/oni-runtime:v9-debug" -f "docker-images/Dockerfile.oni-runtime-debug" "docker-images" + docker build -t "iptestground/oni-buildbase:v15-lotus" -f "docker-images/Dockerfile.oni-buildbase" "docker-images" + docker build -t "iptestground/oni-runtime:v10" -f "docker-images/Dockerfile.oni-runtime" "docker-images" + docker build -t "iptestground/oni-runtime:v10-debug" -f "docker-images/Dockerfile.oni-runtime-debug" "docker-images" push-images: - docker push iptestground/oni-buildbase:v14-lotus - docker push iptestground/oni-runtime:v9 - docker push iptestground/oni-runtime:v9-debug + docker push iptestground/oni-buildbase:v15-lotus + docker push iptestground/oni-runtime:v10 + docker push iptestground/oni-runtime:v10-debug pull-images: - docker pull iptestground/oni-buildbase:v14-lotus - docker pull iptestground/oni-runtime:v9 - docker pull iptestground/oni-runtime:v9-debug + docker pull iptestground/oni-buildbase:v15-lotus + docker pull iptestground/oni-runtime:v10 + docker pull iptestground/oni-runtime:v10-debug .PHONY: download-proofs build-images push-images pull-images diff --git a/testplans/docker-images/Dockerfile.oni-buildbase b/testplans/docker-images/Dockerfile.oni-buildbase index 306d40f9a65..265066537f3 100644 --- a/testplans/docker-images/Dockerfile.oni-buildbase +++ b/testplans/docker-images/Dockerfile.oni-buildbase @@ -4,7 +4,7 @@ FROM golang:${GO_VERSION}-buster RUN apt-get update && apt-get install -y ca-certificates llvm clang mesa-opencl-icd ocl-icd-opencl-dev jq gcc git pkg-config bzr libhwloc-dev -ARG FILECOIN_FFI_COMMIT=d82899449741ce190e950a3582ebe33806f018a9 +ARG FILECOIN_FFI_COMMIT=8b97bd8230b77bd32f4f27e4766a6d8a03b4e801 ARG FFI_DIR=/extern/filecoin-ffi RUN mkdir -p ${FFI_DIR} \ diff --git a/testplans/docker-images/Dockerfile.oni-runtime-debug b/testplans/docker-images/Dockerfile.oni-runtime-debug index 126ae8de7e4..856fcc1fc27 100644 --- a/testplans/docker-images/Dockerfile.oni-runtime-debug +++ b/testplans/docker-images/Dockerfile.oni-runtime-debug @@ -12,7 +12,7 @@ RUN go get github.com/filecoin-project/go-paramfetch/paramfetch@master COPY /proof-parameters.json / RUN paramfetch 8388608 /proof-parameters.json -ARG LOTUS_COMMIT=7e25a811c3d80ea3e007a54aa1da089985110c2c +ARG LOTUS_COMMIT=b8deee048eaf850113e8626a73f64b17ba69a9f6 ## for debug purposes RUN apt update && apt install -y mesa-opencl-icd ocl-icd-opencl-dev gcc git bzr jq pkg-config libhwloc-dev curl && git clone https://github.com/filecoin-project/lotus.git && cd lotus/ && git checkout ${LOTUS_COMMIT} && make clean && make all && make install diff --git a/testplans/lotus-soup/go.mod b/testplans/lotus-soup/go.mod index 0c8e92a1b73..4253a49fb6e 100644 --- a/testplans/lotus-soup/go.mod +++ b/testplans/lotus-soup/go.mod @@ -13,9 +13,8 @@ require ( github.com/filecoin-project/go-jsonrpc v0.1.4-0.20210217175800-45ea43ac2bec github.com/filecoin-project/go-state-types v0.1.1-0.20210506134452-99b279731c48 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b - github.com/filecoin-project/lotus v1.9.1-0.20210602131226-e1dc7ad6eb9e + github.com/filecoin-project/lotus v1.10.0-rc3.0.20210616215353-9c7db6d305e3 github.com/filecoin-project/specs-actors v0.9.14 - github.com/filecoin-project/specs-actors/v5 v5.0.0-20210602024058-0c296bb386bf // indirect github.com/google/uuid v1.1.2 github.com/gorilla/mux v1.7.4 github.com/hashicorp/go-multierror v1.1.0 @@ -25,19 +24,19 @@ require ( github.com/ipfs/go-graphsync v0.6.2-0.20210428121800-88edb5462e17 // indirect github.com/ipfs/go-ipfs-files v0.0.8 github.com/ipfs/go-ipld-format v0.2.0 - github.com/ipfs/go-log/v2 v2.1.2 + github.com/ipfs/go-log/v2 v2.1.3 github.com/ipfs/go-merkledag v0.3.2 github.com/ipfs/go-unixfs v0.2.4 github.com/ipld/go-car v0.1.1-0.20201119040415-11b6074b6d4d github.com/kpacha/opencensus-influxdb v0.0.0-20181102202715-663e2683a27c - github.com/libp2p/go-libp2p v0.12.0 - github.com/libp2p/go-libp2p-core v0.7.0 + github.com/libp2p/go-libp2p v0.14.2 + github.com/libp2p/go-libp2p-core v0.8.5 github.com/libp2p/go-libp2p-pubsub-tracer v0.0.0-20200626141350-e730b32bf1e6 github.com/multiformats/go-multiaddr v0.3.1 github.com/multiformats/go-multiaddr-net v0.2.0 github.com/testground/sdk-go v0.2.6 - go.opencensus.io v0.22.5 - golang.org/x/sync v0.0.0-20201207232520-09787c993a3a + go.opencensus.io v0.23.0 + golang.org/x/sync v0.0.0-20210220032951-036812b2e83c ) // This will work in all build modes: docker:go, exec:go, and local go build. diff --git a/testplans/lotus-soup/go.sum b/testplans/lotus-soup/go.sum index 926f625cf55..e1690a213b2 100644 --- a/testplans/lotus-soup/go.sum +++ b/testplans/lotus-soup/go.sum @@ -114,14 +114,18 @@ github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dm github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.0.0-20190605094302-a0d1e3e36d50/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= -github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= +github.com/btcsuite/btcd v0.21.0-beta h1:At9hIZdJW0s9E/fAz28nrz6AmcNlSVucCH796ZteX1M= +github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/buger/goterm v0.0.0-20200322175922-2f3e71b85129 h1:gfAMKE626QEuKG3si0pdTRcr/YEbBoxY+3GOH3gWvl4= @@ -195,8 +199,10 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davidlazar/go-crypto v0.0.0-20170701192655-dcfb0a7ac018/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4= -github.com/davidlazar/go-crypto v0.0.0-20190912175916-7055855a373f h1:BOaYiTvg8p9vBUXpklC22XSK/mifLF7lG9jtmYYi3Tc= github.com/davidlazar/go-crypto v0.0.0-20190912175916-7055855a373f/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4= +github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= +github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= +github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/detailyang/go-fallocate v0.0.0-20180908115635-432fa640bd2e h1:lj77EKYUpYXTd8CD/+QMIf8b6OIOTsfEBSXiAzuEHTU= github.com/detailyang/go-fallocate v0.0.0-20180908115635-432fa640bd2e/go.mod h1:3ZQK6DMPSz/QZ73jlWxBtUhNA8xZx7LzUFSq/OfP8vk= github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= @@ -280,12 +286,16 @@ github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03/go.mod github.com/filecoin-project/go-data-transfer v1.0.1/go.mod h1:UxvfUAY9v3ub0a21BSK9u3pB2aq30Y0KMsG+w9/ysyo= github.com/filecoin-project/go-data-transfer v1.6.0 h1:DHIzEc23ydRCCBwtFet3MfgO8gMpZEnw60Y+s71oX6o= github.com/filecoin-project/go-data-transfer v1.6.0/go.mod h1:E3WW4mCEYwU2y65swPEajSZoFWFmfXt7uwGduoACZQc= +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.2.5 h1:bQgtXbwxKyPxSEQoUI5EaTHJ0qfzyd5NosspuADCm6Y= +github.com/filecoin-project/go-fil-markets v1.2.5/go.mod h1:7JIqNBmFvOyBzk/EiPYnweVdQnWhshixb5B9b1653Ag= github.com/filecoin-project/go-fil-markets v1.4.0 h1:J4L6o+FVOmS7ZWV6wxLPiuoDzGC7iS3S5NRFL1enEr0= github.com/filecoin-project/go-fil-markets v1.4.0/go.mod h1:7be6zzFwaN8kxVeYZf/UUj/JilHC0ogPvWqE1TW8Ptk= github.com/filecoin-project/go-hamt-ipld v0.1.5 h1:uoXrKbCQZ49OHpsTCkrThPNelC4W3LPEk0OrS/ytIBM= @@ -301,8 +311,8 @@ github.com/filecoin-project/go-multistore v0.0.3 h1:vaRBY4YiA2UZFPK57RNuewypB8u0 github.com/filecoin-project/go-multistore v0.0.3/go.mod h1:kaNqCC4IhU4B1uyr7YWFHd23TL4KM32aChS0jNkyUvQ= github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20 h1:+/4aUeUoKr6AKfPE3mBhXA5spIV6UcKdTYDPNU2Tdmg= github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20/go.mod h1:mPn+LRRd5gEKNAtc+r3ScpW2JRU/pj4NBKdADYWHiak= -github.com/filecoin-project/go-paramfetch v0.0.2-0.20210330140417-936748d3f5ec h1:gExwWUiT1TcARkxGneS4nvp9C+wBsKU0bFdg7qFpNco= -github.com/filecoin-project/go-paramfetch v0.0.2-0.20210330140417-936748d3f5ec/go.mod h1:fZzmf4tftbwf9S37XRifoJlz7nCjRdIrMGLR07dKLCc= +github.com/filecoin-project/go-paramfetch v0.0.2-0.20210614165157-25a6c7769498 h1:G10ezOvpH1CLXQ19EA9VWNwyL0mg536ujSayjV0yg0k= +github.com/filecoin-project/go-paramfetch v0.0.2-0.20210614165157-25a6c7769498/go.mod h1:1FH85P8U+DUEmWk1Jkw3Bw7FrwTVUNHk/95PSPG+dts= github.com/filecoin-project/go-state-types v0.0.0-20200903145444-247639ffa6ad/go.mod h1:IQ0MBPnonv35CJHtWSN3YY1Hz2gkPru1Q9qoaYLxx9I= github.com/filecoin-project/go-state-types v0.0.0-20200904021452-1883f36ca2f4/go.mod h1:IQ0MBPnonv35CJHtWSN3YY1Hz2gkPru1Q9qoaYLxx9I= github.com/filecoin-project/go-state-types v0.0.0-20200928172055-2df22083d8ab/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= @@ -317,8 +327,10 @@ github.com/filecoin-project/go-statestore v0.1.1 h1:ufMFq00VqnT2CAuDpcGnwLnCX1I/ 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/lotus v1.9.1-0.20210602131226-e1dc7ad6eb9e h1:JvtYGk30nM7K0TD4sTOUKYUePcSzZNj5ZD6g5vdrqMI= -github.com/filecoin-project/lotus v1.9.1-0.20210602131226-e1dc7ad6eb9e/go.mod h1:/ZeMXR8jPxJslaHSIW3ZxO9YPIaxcnsP+niEoBatzo8= +github.com/filecoin-project/lotus v1.10.0-rc3.0.20210616215353-9c7db6d305e3 h1:oeVa5wjoNx888oIs83L+LqAG75yqa5DCj94I2dRK+Ms= +github.com/filecoin-project/lotus v1.10.0-rc3.0.20210616215353-9c7db6d305e3/go.mod h1:a4kSO7IY58nxXhc29lpZwgZksbdTQFQ4nhBscFYPAjw= +github.com/filecoin-project/lotus v1.9.0 h1:TDKDLbmgYTL8M0mlfd9HmJVEYRlSSOQnakg4+9rfyWM= +github.com/filecoin-project/lotus v1.9.0/go.mod h1:4YC/8rizrrp2wKOYvHQEjCxZbziXi68BhrzvI+FCye0= github.com/filecoin-project/specs-actors v0.9.4/go.mod h1:BStZQzx5x7TmCkLv0Bpa07U6cPKol6fd3w9KjMPZ6Z4= github.com/filecoin-project/specs-actors v0.9.12/go.mod h1:TS1AW/7LbG+615j4NsjMK1qlpAwaFsG9w0V2tg2gSao= github.com/filecoin-project/specs-actors v0.9.13/go.mod h1:TS1AW/7LbG+615j4NsjMK1qlpAwaFsG9w0V2tg2gSao= @@ -326,25 +338,28 @@ github.com/filecoin-project/specs-actors v0.9.14 h1:68PVstg2UB3ZsMLF+DKFTAs/YKsq github.com/filecoin-project/specs-actors v0.9.14/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.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/v2 v2.3.5 h1:PbT4tPlSXZ8sRgajhb4D8AOEmiaaZ+jg6tc6BBv8VQc= github.com/filecoin-project/specs-actors/v2 v2.3.5/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/v3 v3.1.1 h1:BE8fsns1GnEOxt1DTE5LxBK2FThXtWmCChgcJoHTg0E= github.com/filecoin-project/specs-actors/v3 v3.1.1/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-actors/v4 v4.0.1 h1:AiWrtvJZ63MHGe6rn7tPu4nSUY8bA1KDNszqJaD5+Fg= github.com/filecoin-project/specs-actors/v4 v4.0.1/go.mod h1:TkHXf/l7Wyw4ZejyXIPS2rK8bBO0rdwhTZyQQgaglng= github.com/filecoin-project/specs-actors/v5 v5.0.0-20210512015452-4fe3889fff57/go.mod h1:283yBMMUSDB2abcjP/hhrwTkhb9h3sfM6KGrep/ZlBI= -github.com/filecoin-project/specs-actors/v5 v5.0.0-20210528202914-a9f9f95f5e93/go.mod h1:kSDmoQuO8jlhMVzKNoesbhka1e6gHKcLQjKm9mE9Qhw= -github.com/filecoin-project/specs-actors/v5 v5.0.0-20210602024058-0c296bb386bf h1:xt9A1omyhSDbQvpVk7Na1J15a/n8y0y4GQDLeiWLpFs= -github.com/filecoin-project/specs-actors/v5 v5.0.0-20210602024058-0c296bb386bf/go.mod h1:b/btpRl84Q9SeDKlyIoORBQwe2OTmq14POrYrVvBWCM= +github.com/filecoin-project/specs-actors/v5 v5.0.0-20210609212542-73e0409ac77c h1:GnDJ6q3QEm2ytTKjPFQSvczAltgCSb3j9F1FeynwvPA= +github.com/filecoin-project/specs-actors/v5 v5.0.0-20210609212542-73e0409ac77c/go.mod h1:b/btpRl84Q9SeDKlyIoORBQwe2OTmq14POrYrVvBWCM= 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/go.mod h1:iQ9QXLpYWL3m7warwvK1JC/pTri8mnfEmKygNDqqY6E= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6 h1:u/UEqS66A5ckRmS4yNpjmVH56sVtS/RfclBAYocb4as= github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6/go.mod h1:1i71OnUq3iUe1ma7Lr6yG6/rjvM3emb6yoL7xLFzcVQ= +github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= +github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= @@ -411,8 +426,9 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/gogo/status v1.0.3/go.mod h1:SavQ51ycCLnc7dGyJxp8YAmudx8xqiVrRf+6IXRsugc= github.com/gogo/status v1.1.0 h1:+eIkrewn5q6b30y+g/BJINVVdi2xH7je5MPJ3ZPK3JA= github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= @@ -431,8 +447,9 @@ github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -444,8 +461,9 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.2-0.20190904063534-ff6b7dc882cf h1:gFVkHXmVAhEbxZVDln5V9GKrLaluNoFHDbrZwAWZgws= @@ -458,14 +476,16 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= -github.com/google/gopacket v1.1.18 h1:lum7VRA9kdlvBi7/v2p7/zcbkduHaCH/SVVyurs7OpY= github.com/google/gopacket v1.1.18/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= +github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= +github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -639,6 +659,8 @@ 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.6.0 h1:x6UvDUGA7wjaKNqx5Vbo7FGT8aJ5ryYA0dMQ5jN3dF0= +github.com/ipfs/go-graphsync v0.6.0/go.mod h1:e2ZxnClqBBYAtd901g9vXMJzS47labjAtOzsWtOzKNk= github.com/ipfs/go-graphsync v0.6.1/go.mod h1:e2ZxnClqBBYAtd901g9vXMJzS47labjAtOzsWtOzKNk= github.com/ipfs/go-graphsync v0.6.2-0.20210428121800-88edb5462e17 h1:rOoF88dVuDGbIx7idSdimN7JvXriyOIT96WD3eX9sHA= github.com/ipfs/go-graphsync v0.6.2-0.20210428121800-88edb5462e17/go.mod h1:5WyaeigpNdpiYQuW2vwpuecOoEfB4h747ZGEOKmAGTg= @@ -716,8 +738,9 @@ github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscw 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/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-log/v2 v2.1.3 h1:1iS3IU7aXRlbgUpN8yTTpJ53NXYjAe37vcI5+5nYrzk= +github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= 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= @@ -821,6 +844,7 @@ github.com/kilic/bls12-381 v0.0.0-20200820230200-6b2c19996391 h1:51kHw7l/dUDdOdW github.com/kilic/bls12-381 v0.0.0-20200820230200-6b2c19996391/go.mod h1:XXfR6YFCRSrkEXbNlIyDsgXVNJWVUV30m/ebkVy9n6s= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= @@ -837,6 +861,7 @@ github.com/kpacha/opencensus-influxdb v0.0.0-20181102202715-663e2683a27c/go.mod github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -856,8 +881,9 @@ github.com/libp2p/go-conn-security v0.0.1/go.mod h1:bGmu51N0KU9IEjX7kl2PQjgZa40J github.com/libp2p/go-conn-security-multistream v0.0.1/go.mod h1:nc9vud7inQ+d6SO0I/6dSWrdMnHnzZNHeyUQqrAJulE= github.com/libp2p/go-conn-security-multistream v0.0.2/go.mod h1:nc9vud7inQ+d6SO0I/6dSWrdMnHnzZNHeyUQqrAJulE= github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= -github.com/libp2p/go-conn-security-multistream v0.2.0 h1:uNiDjS58vrvJTg9jO6bySd1rMKejieG7v45ekqHbZ1M= github.com/libp2p/go-conn-security-multistream v0.2.0/go.mod h1:hZN4MjlNetKD3Rq5Jb/P5ohUnFLNzEAR4DLSzpn2QLU= +github.com/libp2p/go-conn-security-multistream v0.2.1 h1:ft6/POSK7F+vl/2qzegnHDaXFU0iWB4yVTYrioC6Zy0= +github.com/libp2p/go-conn-security-multistream v0.2.1/go.mod h1:cR1d8gA0Hr59Fj6NhaTpFhJZrjSYuNmhpT2r25zYR70= github.com/libp2p/go-eventbus v0.0.2/go.mod h1:Hr/yGlwxA/stuLnpMiu82lpNKpvRy3EaJxPu40XYOwk= github.com/libp2p/go-eventbus v0.1.0/go.mod h1:vROgu5cs5T7cv7POWlWxBaVLxfSegC5UGQf8A2eEmx4= github.com/libp2p/go-eventbus v0.2.1 h1:VanAdErQnpTioN2TowqNcOijf6YwhuODe4pPKSDpxGc= @@ -880,8 +906,9 @@ github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qD github.com/libp2p/go-libp2p v0.8.3/go.mod h1:EsH1A+8yoWK+L4iKcbPYu6MPluZ+CHWI9El8cTaefiM= github.com/libp2p/go-libp2p v0.9.2/go.mod h1:cunHNLDVus66Ct9iXXcjKRLdmHdFdHVe1TAnbubJQqQ= github.com/libp2p/go-libp2p v0.10.0/go.mod h1:yBJNpb+mGJdgrwbKAKrhPU0u3ogyNFTfjJ6bdM+Q/G8= -github.com/libp2p/go-libp2p v0.12.0 h1:+xai9RQnQ9l5elFOKvp5wRyjyWisSwEx+6nU2+onpUA= github.com/libp2p/go-libp2p v0.12.0/go.mod h1:FpHZrfC1q7nA8jitvdjKBDF31hguaC676g/nT9PgQM0= +github.com/libp2p/go-libp2p v0.14.2 h1:qs0ABtjjNjS+RIXT1uM7sMJEvIc0pq2nKR0VQxFXhHI= +github.com/libp2p/go-libp2p v0.14.2/go.mod h1:0PQMADQEjCM2l8cSMYDpTgsb8gr6Zq7i4LUgq1mlW2E= github.com/libp2p/go-libp2p-asn-util v0.0.0-20200825225859-85005c6cf052 h1:BM7aaOF7RpmNn9+9g6uTjGJ0cTzWr5j9i9IKeun2M8U= github.com/libp2p/go-libp2p-asn-util v0.0.0-20200825225859-85005c6cf052/go.mod h1:nRMRTab+kZuk0LnKZpxhOVH/ndsdr2Nr//Zltc/vwgo= github.com/libp2p/go-libp2p-autonat v0.0.2/go.mod h1:fs71q5Xk+pdnKU014o2iq1RhMs9/PMaG5zXRFNnIIT4= @@ -892,8 +919,9 @@ github.com/libp2p/go-libp2p-autonat v0.2.0/go.mod h1:DX+9teU4pEEoZUqR1PiMlqliONQ github.com/libp2p/go-libp2p-autonat v0.2.1/go.mod h1:MWtAhV5Ko1l6QBsHQNSuM6b1sRkXrpk0/LqCr+vCVxI= github.com/libp2p/go-libp2p-autonat v0.2.2/go.mod h1:HsM62HkqZmHR2k1xgX34WuWDzk/nBwNHoeyyT4IWV6A= github.com/libp2p/go-libp2p-autonat v0.2.3/go.mod h1:2U6bNWCNsAG9LEbwccBDQbjzQ8Krdjge1jLTE9rdoMM= -github.com/libp2p/go-libp2p-autonat v0.4.0 h1:3y8XQbpr+ssX8QfZUHekjHCYK64sj6/4hnf/awD4+Ug= github.com/libp2p/go-libp2p-autonat v0.4.0/go.mod h1:YxaJlpr81FhdOv3W3BTconZPfhaYivRdf53g+S2wobk= +github.com/libp2p/go-libp2p-autonat v0.4.2 h1:YMp7StMi2dof+baaxkbxaizXjY1RPvU71CXfxExzcUU= +github.com/libp2p/go-libp2p-autonat v0.4.2/go.mod h1:YxaJlpr81FhdOv3W3BTconZPfhaYivRdf53g+S2wobk= github.com/libp2p/go-libp2p-autonat-svc v0.1.0/go.mod h1:fqi8Obl/z3R4PFVLm8xFtZ6PBL9MlV/xumymRFkKq5A= github.com/libp2p/go-libp2p-blankhost v0.0.1/go.mod h1:Ibpbw/7cPPYwFb7PACIWdvxxv0t0XCCI10t7czjAjTc= github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro= @@ -940,8 +968,12 @@ github.com/libp2p/go-libp2p-core v0.5.6/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX github.com/libp2p/go-libp2p-core v0.5.7/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= github.com/libp2p/go-libp2p-core v0.6.0/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= github.com/libp2p/go-libp2p-core v0.6.1/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= -github.com/libp2p/go-libp2p-core v0.7.0 h1:4a0TMjrWNTZlNvcqxZmrMRDi/NQWrhwO2pkTuLSQ/IQ= github.com/libp2p/go-libp2p-core v0.7.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.1/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.2/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.5 h1:aEgbIcPGsKy6zYcC+5AJivYFedhYa4sW7mIpWpUaLKw= +github.com/libp2p/go-libp2p-core v0.8.5/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= github.com/libp2p/go-libp2p-crypto v0.0.1/go.mod h1:yJkNyDmO341d5wwXxDUGO0LykUVT72ImHNUqh5D/dBE= github.com/libp2p/go-libp2p-crypto v0.0.2/go.mod h1:eETI5OUfBnvARGOHrJz2eWNyTUxEGZnBxMcbUjfIj4I= github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= @@ -976,8 +1008,10 @@ github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3 github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= github.com/libp2p/go-libp2p-mplex v0.2.2/go.mod h1:74S9eum0tVQdAfFiKxAyKzNdSuLqw5oadDq7+L/FELo= github.com/libp2p/go-libp2p-mplex v0.2.3/go.mod h1:CK3p2+9qH9x+7ER/gWWDYJ3QW5ZxWDkm+dVvjfuG3ek= -github.com/libp2p/go-libp2p-mplex v0.3.0 h1:CZyqqKP0BSGQyPLvpRQougbfXaaaJZdGgzhCpJNuNSk= github.com/libp2p/go-libp2p-mplex v0.3.0/go.mod h1:l9QWxRbbb5/hQMECEb908GbS9Sm2UAR2KFZKUJEynEs= +github.com/libp2p/go-libp2p-mplex v0.4.0/go.mod h1:yCyWJE2sc6TBTnFpjvLuEJgTSw/u+MamvzILKdX7asw= +github.com/libp2p/go-libp2p-mplex v0.4.1 h1:/pyhkP1nLwjG3OM+VuaNJkQT/Pqq73WzB3aDN3Fx1sc= +github.com/libp2p/go-libp2p-mplex v0.4.1/go.mod h1:cmy+3GfqfM1PceHTLL7zQzAAYaryDu6iPSC+CIb094g= github.com/libp2p/go-libp2p-nat v0.0.2/go.mod h1:QrjXQSD5Dj4IJOdEcjHRkWTSomyxRo6HnUkf/TfQpLQ= github.com/libp2p/go-libp2p-nat v0.0.4/go.mod h1:N9Js/zVtAXqaeT99cXgTV9e75KpnWCvVOiGzlcHmBbY= github.com/libp2p/go-libp2p-nat v0.0.5/go.mod h1:1qubaE5bTZMJE+E/uu2URroMbzdubFz1ChgiN79yKPE= @@ -989,8 +1023,8 @@ github.com/libp2p/go-libp2p-netutil v0.0.1/go.mod h1:GdusFvujWZI9Vt0X5BKqwWWmZFx github.com/libp2p/go-libp2p-netutil v0.1.0 h1:zscYDNVEcGxyUpMd0JReUZTrpMfia8PmLKcKF72EAMQ= github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU= github.com/libp2p/go-libp2p-noise v0.1.1/go.mod h1:QDFLdKX7nluB7DEnlVPbz7xlLHdwHFA9HiohJRr3vwM= -github.com/libp2p/go-libp2p-noise v0.1.2 h1:IH9GRihQJTx56obm+GnpdPX4KeVIlvpXrP6xnJ0wxWk= -github.com/libp2p/go-libp2p-noise v0.1.2/go.mod h1:9B10b7ueo7TIxZHHcjcDCo5Hd6kfKT2m77by82SFRfE= +github.com/libp2p/go-libp2p-noise v0.2.0 h1:wmk5nhB9a2w2RxMOyvsoKjizgJOEaJdfAakr0jN8gds= +github.com/libp2p/go-libp2p-noise v0.2.0/go.mod h1:IEbYhBBzGyvdLBoxxULL/SGbJARhUeqlO8lVSREYu2Q= github.com/libp2p/go-libp2p-peer v0.0.1/go.mod h1:nXQvOBbwVqoP+T5Y5nCjeH4sP9IX/J0AMzcDUVruVoo= github.com/libp2p/go-libp2p-peer v0.1.1/go.mod h1:jkF12jGB4Gk/IOo+yomm+7oLWxF278F7UnrYUQ1Q8es= github.com/libp2p/go-libp2p-peer v0.2.0 h1:EQ8kMjaCUwt/Y5uLgjT8iY2qg0mGUT0N1zUjer50DsY= @@ -1005,8 +1039,9 @@ github.com/libp2p/go-libp2p-peerstore v0.2.1/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRj github.com/libp2p/go-libp2p-peerstore v0.2.2/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRjwRLBr4TYKfNgrUkOPA= github.com/libp2p/go-libp2p-peerstore v0.2.3/go.mod h1:K8ljLdFn590GMttg/luh4caB/3g0vKuY01psze0upRw= github.com/libp2p/go-libp2p-peerstore v0.2.4/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= -github.com/libp2p/go-libp2p-peerstore v0.2.6 h1:2ACefBX23iMdJU9Ke+dcXt3w86MIryes9v7In4+Qq3U= github.com/libp2p/go-libp2p-peerstore v0.2.6/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= +github.com/libp2p/go-libp2p-peerstore v0.2.7 h1:83JoLxyR9OYTnNfB5vvFqvMUv/xDNa6NoPHnENhBsGw= +github.com/libp2p/go-libp2p-peerstore v0.2.7/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= github.com/libp2p/go-libp2p-pnet v0.2.0 h1:J6htxttBipJujEjz1y0a5+eYoiPcFHhSYHH6na5f0/k= github.com/libp2p/go-libp2p-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYcO0BW4wssv21LA= github.com/libp2p/go-libp2p-protocol v0.0.1/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1VZNHYcK8cLgFJLZ4s= @@ -1020,8 +1055,8 @@ github.com/libp2p/go-libp2p-pubsub-tracer v0.0.0-20200626141350-e730b32bf1e6 h1: github.com/libp2p/go-libp2p-pubsub-tracer v0.0.0-20200626141350-e730b32bf1e6/go.mod h1:8ZodgKS4qRLayfw9FDKDd9DX4C16/GMofDxSldG8QPI= github.com/libp2p/go-libp2p-quic-transport v0.1.1/go.mod h1:wqG/jzhF3Pu2NrhJEvE+IE0NTHNXslOPn9JQzyCAxzU= github.com/libp2p/go-libp2p-quic-transport v0.5.0/go.mod h1:IEcuC5MLxvZ5KuHKjRu+dr3LjCT1Be3rcD/4d8JrX8M= -github.com/libp2p/go-libp2p-quic-transport v0.9.0 h1:WPuq5nV/chmIZIzvrkC2ulSdAQ0P0BDvgvAhZFOZ59E= -github.com/libp2p/go-libp2p-quic-transport v0.9.0/go.mod h1:xyY+IgxL0qsW7Kiutab0+NlxM0/p9yRtrGTYsuMWf70= +github.com/libp2p/go-libp2p-quic-transport v0.10.0 h1:koDCbWD9CCHwcHZL3/WEvP2A+e/o5/W5L3QS/2SPMA0= +github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqUEJqjiiY8xmEuq3HUDS993MkA= github.com/libp2p/go-libp2p-record v0.0.1/go.mod h1:grzqg263Rug/sRex85QrDOLntdFAymLDLm7lxMgU79Q= github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= github.com/libp2p/go-libp2p-record v0.1.1/go.mod h1:VRgKajOyMVgP/F0L5g3kH7SVskp17vFi2xheb5uMJtg= @@ -1048,8 +1083,9 @@ github.com/libp2p/go-libp2p-swarm v0.2.4/go.mod h1:/xIpHFPPh3wmSthtxdGbkHZ0OET1h github.com/libp2p/go-libp2p-swarm v0.2.7/go.mod h1:ZSJ0Q+oq/B1JgfPHJAT2HTall+xYRNYp1xs4S2FBWKA= github.com/libp2p/go-libp2p-swarm v0.2.8/go.mod h1:JQKMGSth4SMqonruY0a8yjlPVIkb0mdNSwckW7OYziM= github.com/libp2p/go-libp2p-swarm v0.3.0/go.mod h1:hdv95GWCTmzkgeJpP+GK/9D9puJegb7H57B5hWQR5Kk= -github.com/libp2p/go-libp2p-swarm v0.3.1 h1:UTobu+oQHGdXTOGpZ4RefuVqYoJXcT0EBtSR74m2LkI= github.com/libp2p/go-libp2p-swarm v0.3.1/go.mod h1:hdv95GWCTmzkgeJpP+GK/9D9puJegb7H57B5hWQR5Kk= +github.com/libp2p/go-libp2p-swarm v0.5.0 h1:HIK0z3Eqoo8ugmN8YqWAhD2RORgR+3iNXYG4U2PFd1E= +github.com/libp2p/go-libp2p-swarm v0.5.0/go.mod h1:sU9i6BoHE0Ve5SKz3y9WfKrh8dUat6JknzUehFx8xW4= github.com/libp2p/go-libp2p-testing v0.0.1/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= @@ -1057,8 +1093,9 @@ github.com/libp2p/go-libp2p-testing v0.0.4/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MB github.com/libp2p/go-libp2p-testing v0.1.0/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0= github.com/libp2p/go-libp2p-testing v0.1.1/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0= github.com/libp2p/go-libp2p-testing v0.1.2-0.20200422005655-8775583591d8/go.mod h1:Qy8sAncLKpwXtS2dSnDOP8ktexIAHKu+J+pnZOFZLTc= -github.com/libp2p/go-libp2p-testing v0.3.0 h1:ZiBYstPamsi7y6NJZebRudUzsYmVkt998hltyLqf8+g= github.com/libp2p/go-libp2p-testing v0.3.0/go.mod h1:efZkql4UZ7OVsEfaxNHZPzIehtsBXMrXnCfJIgDti5g= +github.com/libp2p/go-libp2p-testing v0.4.0 h1:PrwHRi0IGqOwVQWR3xzgigSlhlLfxgfXgkHxr77EghQ= +github.com/libp2p/go-libp2p-testing v0.4.0/go.mod h1:Q+PFXYoiYFN5CAEG2w3gLPEzotlKsNSbKQ/lImlOWF0= github.com/libp2p/go-libp2p-tls v0.1.3 h1:twKMhMu44jQO+HgQK9X8NHO5HkeJu2QbhLzLJpa8oNM= github.com/libp2p/go-libp2p-tls v0.1.3/go.mod h1:wZfuewxOndz5RTnCAxFliGjvYSDA40sKitV4c50uI1M= github.com/libp2p/go-libp2p-transport v0.0.1/go.mod h1:UzbUs9X+PHOSw7S3ZmeOxfnwaQY5vGDzZmKPod3N3tk= @@ -1068,8 +1105,9 @@ github.com/libp2p/go-libp2p-transport-upgrader v0.0.1/go.mod h1:NJpUAgQab/8K6K0m github.com/libp2p/go-libp2p-transport-upgrader v0.0.4/go.mod h1:RGq+tupk+oj7PzL2kn/m1w6YXxcIAYJYeI90h6BGgUc= github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= github.com/libp2p/go-libp2p-transport-upgrader v0.2.0/go.mod h1:mQcrHj4asu6ArfSoMuyojOdjx73Q47cYD7s5+gZOlns= -github.com/libp2p/go-libp2p-transport-upgrader v0.3.0 h1:q3ULhsknEQ34eVDhv4YwKS8iet69ffs9+Fir6a7weN4= github.com/libp2p/go-libp2p-transport-upgrader v0.3.0/go.mod h1:i+SKzbRnvXdVbU3D1dwydnTmKRPXiAR/fyvi1dXuL4o= +github.com/libp2p/go-libp2p-transport-upgrader v0.4.2 h1:4JsnbfJzgZeRS9AWN7B9dPqn/LY/HoQTlO9gtdJTIYM= +github.com/libp2p/go-libp2p-transport-upgrader v0.4.2/go.mod h1:NR8ne1VwfreD5VIWIU62Agt/J18ekORFU/j1i2y8zvk= github.com/libp2p/go-libp2p-yamux v0.1.2/go.mod h1:xUoV/RmYkg6BW/qGxA9XJyg+HzXFYkeXbnhjmnYzKp8= github.com/libp2p/go-libp2p-yamux v0.1.3/go.mod h1:VGSQVrqkh6y4nm0189qqxMtvyBft44MOYYPpYKXiVt4= github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= @@ -1079,8 +1117,9 @@ github.com/libp2p/go-libp2p-yamux v0.2.5/go.mod h1:Zpgj6arbyQrmZ3wxSZxfBmbdnWtbZ github.com/libp2p/go-libp2p-yamux v0.2.7/go.mod h1:X28ENrBMU/nm4I3Nx4sZ4dgjZ6VhLEn0XhIoZ5viCwU= github.com/libp2p/go-libp2p-yamux v0.2.8/go.mod h1:/t6tDqeuZf0INZMTgd0WxIRbtK2EzI2h7HbFm9eAKI4= github.com/libp2p/go-libp2p-yamux v0.4.0/go.mod h1:+DWDjtFMzoAwYLVkNZftoucn7PelNoy5nm3tZ3/Zw30= -github.com/libp2p/go-libp2p-yamux v0.4.1 h1:TJxRVPY9SjH7TNrNC80l1OJMBiWhs1qpKmeB+1Ug3xU= -github.com/libp2p/go-libp2p-yamux v0.4.1/go.mod h1:FA/NjRYRVNjqOzpGuGqcruH7jAU2mYIjtKBicVOL3dc= +github.com/libp2p/go-libp2p-yamux v0.5.0/go.mod h1:AyR8k5EzyM2QN9Bbdg6X1SkVVuqLwTGf0L4DFq9g6po= +github.com/libp2p/go-libp2p-yamux v0.5.4 h1:/UOPtT/6DHPtr3TtKXBHa6g0Le0szYuI33Xc/Xpd7fQ= +github.com/libp2p/go-libp2p-yamux v0.5.4/go.mod h1:tfrXbyaTqqSU654GTvK3ocnSZL3BuHoeTSqhcel1wsE= github.com/libp2p/go-maddr-filter v0.0.1/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= github.com/libp2p/go-maddr-filter v0.0.5/go.mod h1:Jk+36PMfIqCJhAnaASRH83bdAvfDRp/w6ENFaC9bG+M= @@ -1092,8 +1131,9 @@ github.com/libp2p/go-mplex v0.0.4/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTW github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= github.com/libp2p/go-mplex v0.1.1/go.mod h1:Xgz2RDCi3co0LeZfgjm4OgUF15+sVR8SRcu3SFXI1lk= github.com/libp2p/go-mplex v0.1.2/go.mod h1:Xgz2RDCi3co0LeZfgjm4OgUF15+sVR8SRcu3SFXI1lk= -github.com/libp2p/go-mplex v0.2.0 h1:Ov/D+8oBlbRkjBs1R1Iua8hJ8cUfbdiW8EOdZuxcgaI= github.com/libp2p/go-mplex v0.2.0/go.mod h1:0Oy/A9PQlwBytDRp4wSkFnzHYDKcpLot35JQ6msjvYQ= +github.com/libp2p/go-mplex v0.3.0 h1:U1T+vmCYJaEoDJPV1aq31N56hS+lJgb397GsylNSgrU= +github.com/libp2p/go-mplex v0.3.0/go.mod h1:0Oy/A9PQlwBytDRp4wSkFnzHYDKcpLot35JQ6msjvYQ= github.com/libp2p/go-msgio v0.0.1/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= github.com/libp2p/go-msgio v0.0.3/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= @@ -1105,8 +1145,9 @@ github.com/libp2p/go-nat v0.0.4/go.mod h1:Nmw50VAvKuk38jUBcmNh6p9lUJLoODbJRvYAa/ github.com/libp2p/go-nat v0.0.5 h1:qxnwkco8RLKqVh1NmjQ+tJ8p8khNLFxuElYG/TwqW4Q= github.com/libp2p/go-nat v0.0.5/go.mod h1:B7NxsVNPZmRLvMOwiEO1scOSyjA56zxYAGv1yQgRkEU= github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= -github.com/libp2p/go-netroute v0.1.3 h1:1ngWRx61us/EpaKkdqkMjKk/ufr/JlIFYQAxV2XX8Ig= github.com/libp2p/go-netroute v0.1.3/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= +github.com/libp2p/go-netroute v0.1.6 h1:ruPJStbYyXVYGQ81uzEDzuvbYRLKRrLvTYd33yomC38= +github.com/libp2p/go-netroute v0.1.6/go.mod h1:AqhkMh0VuWmfgtxKPp3Oc1LdU5QSWS7wl0QLhSZqXxQ= github.com/libp2p/go-openssl v0.0.2/go.mod h1:v8Zw2ijCSWBQi8Pq5GAixw6DbFfa9u6VIYDXnvOXkc0= github.com/libp2p/go-openssl v0.0.3/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= github.com/libp2p/go-openssl v0.0.4/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= @@ -1122,8 +1163,9 @@ github.com/libp2p/go-reuseport-transport v0.0.3/go.mod h1:Spv+MPft1exxARzP2Sruj2 github.com/libp2p/go-reuseport-transport v0.0.4 h1:OZGz0RB620QDGpv300n1zaOcKGGAoGVf8h9txtt/1uM= github.com/libp2p/go-reuseport-transport v0.0.4/go.mod h1:trPa7r/7TJK/d+0hdBLOCGvpQQVOU74OXbNCIMkufGw= github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= -github.com/libp2p/go-sockaddr v0.1.0 h1:Y4s3/jNoryVRKEBrkJ576F17CPOaMIzUeCsg7dlTDj0= github.com/libp2p/go-sockaddr v0.1.0/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= +github.com/libp2p/go-sockaddr v0.1.1 h1:yD80l2ZOdGksnOyHrhxDdTDFrf7Oy+v3FMVArIRgZxQ= +github.com/libp2p/go-sockaddr v0.1.1/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= github.com/libp2p/go-stream-muxer v0.1.0/go.mod h1:8JAVsjeRBCWwPoZeH0W1imLOcriqXJyFvB0mR4A04sQ= github.com/libp2p/go-stream-muxer-multistream v0.1.1/go.mod h1:zmGdfkQ1AzOECIAcccoL8L//laqawOsO03zX8Sa+eGw= @@ -1145,8 +1187,9 @@ github.com/libp2p/go-ws-transport v0.1.0/go.mod h1:rjw1MG1LU9YDC6gzmwObkPd/Sqwhw github.com/libp2p/go-ws-transport v0.1.2/go.mod h1:dsh2Ld8F+XNmzpkaAijmg5Is+e9l6/1tK/6VFOdN69Y= github.com/libp2p/go-ws-transport v0.2.0/go.mod h1:9BHJz/4Q5A9ludYWKoGCFC5gUElzlHoKzu0yY9p/klM= github.com/libp2p/go-ws-transport v0.3.0/go.mod h1:bpgTJmRZAvVHrgHybCVyqoBmyLQ1fiZuEaBYusP5zsk= -github.com/libp2p/go-ws-transport v0.3.1 h1:ZX5rWB8nhRRJVaPO6tmkGI/Xx8XNboYX20PW5hXIscw= github.com/libp2p/go-ws-transport v0.3.1/go.mod h1:bpgTJmRZAvVHrgHybCVyqoBmyLQ1fiZuEaBYusP5zsk= +github.com/libp2p/go-ws-transport v0.4.0 h1:9tvtQ9xbws6cA5LvqdE6Ne3vcmGB4f1z9SByggk4s0k= +github.com/libp2p/go-ws-transport v0.4.0/go.mod h1:EcIEKqf/7GDjth6ksuS/6p7R49V4CBY6/E7R/iyhYUA= github.com/libp2p/go-yamux v1.2.1/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= github.com/libp2p/go-yamux v1.2.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= @@ -1158,12 +1201,14 @@ github.com/libp2p/go-yamux v1.3.7/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/h github.com/libp2p/go-yamux v1.4.0/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= github.com/libp2p/go-yamux v1.4.1 h1:P1Fe9vF4th5JOxxgQvfbOHkrGqIZniTLf+ddhZp8YTI= github.com/libp2p/go-yamux v1.4.1/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= +github.com/libp2p/go-yamux/v2 v2.2.0 h1:RwtpYZ2/wVviZ5+3pjC8qdQ4TKnrak0/E01N1UWoAFU= +github.com/libp2p/go-yamux/v2 v2.2.0/go.mod h1:3So6P6TV6r75R9jiBpiIKgU/66lOarCZjqROGxzPpPQ= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/lucas-clemente/quic-go v0.11.2/go.mod h1:PpMmPfPKO9nKJ/psF49ESTAGQSdfXxlg1otPbEB2nOw= github.com/lucas-clemente/quic-go v0.16.0/go.mod h1:I0+fcNTdb9eS1ZcjQZbDVPGchJ86chcIxPALn9lEJqE= -github.com/lucas-clemente/quic-go v0.18.1 h1:DMR7guC0NtVS8zNZR3IO7NARZvZygkSC56GGtC6cyys= -github.com/lucas-clemente/quic-go v0.18.1/go.mod h1:yXttHsSNxQi8AWijC/vLP+OJczXqzHSOcJrM5ITUlCg= +github.com/lucas-clemente/quic-go v0.19.3 h1:eCDQqvGBB+kCTkA0XrAFtNe81FMa0/fn4QSoeAbmiF4= +github.com/lucas-clemente/quic-go v0.19.3/go.mod h1:ADXpNbTQjq1hIzCpB+y/k5iz4n4z4IwqoLb94Kh5Hu8= github.com/lucasb-eyer/go-colorful v1.0.3 h1:QIbQXiugsb+q10B+MI+7DI1oQLdmnep86tWFlaaUAac= github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lufia/iostat v1.1.0/go.mod h1:rEPNA0xXgjHQjuI5Cy05sLlS2oRcSlWHRLrvh/AQ+Pg= @@ -1177,13 +1222,13 @@ github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/marten-seemann/qpack v0.1.0/go.mod h1:LFt1NU/Ptjip0C2CPkhimBz5CGE3WGDAUWqna+CNTrI= -github.com/marten-seemann/qpack v0.2.0/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= +github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= github.com/marten-seemann/qtls v0.2.3/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk= github.com/marten-seemann/qtls v0.9.1/go.mod h1:T1MmAdDPyISzxlK6kjRr0pcZFBVd1OZbBb/j3cvzHhk= github.com/marten-seemann/qtls v0.10.0 h1:ECsuYUKalRL240rRD4Ri33ISb7kAQ3qGDlrrl55b2pc= github.com/marten-seemann/qtls v0.10.0/go.mod h1:UvMd1oaYDACI99/oZUYLzMCkBXQVT0aGm99sJhbT8hs= -github.com/marten-seemann/qtls-go1-15 v0.1.0 h1:i/YPXVxz8q9umso/5y474CNcHmTpA+5DH+mFPjx6PZg= -github.com/marten-seemann/qtls-go1-15 v0.1.0/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= +github.com/marten-seemann/qtls-go1-15 v0.1.1 h1:LIH6K34bPVttyXnUWixk0bzH6/N07VxbSabxn5A5gZQ= +github.com/marten-seemann/qtls-go1-15 v0.1.1/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -1220,6 +1265,8 @@ github.com/miekg/dns v1.1.4/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nr github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.28/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= +github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY= +github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= @@ -1267,8 +1314,9 @@ github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/94 github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= github.com/multiformats/go-multiaddr-dns v0.0.3/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= github.com/multiformats/go-multiaddr-dns v0.1.0/go.mod h1:01k2RAqtoXIuPa3DCavAE9/6jc6nM0H3EgZyfUhN2oY= -github.com/multiformats/go-multiaddr-dns v0.2.0 h1:YWJoIDwLePniH7OU5hBnDZV6SWuvJqJ0YtN6pLeH9zA= github.com/multiformats/go-multiaddr-dns v0.2.0/go.mod h1:TJ5pr5bBO7Y1B18djPuRsVkduhQH2YqYSbxWJzYGdK0= +github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= +github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= @@ -1298,8 +1346,10 @@ github.com/multiformats/go-multistream v0.0.1/go.mod h1:fJTiDfXJVmItycydCnNx4+wS github.com/multiformats/go-multistream v0.0.4/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= github.com/multiformats/go-multistream v0.1.1/go.mod h1:KmHZ40hzVxiaiwlj3MEbYgK9JFk2/9UktWZAF54Du38= -github.com/multiformats/go-multistream v0.2.0 h1:6AuNmQVKUkRnddw2YiDjt5Elit40SFxMJkVnhmETXtU= github.com/multiformats/go-multistream v0.2.0/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= +github.com/multiformats/go-multistream v0.2.1/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= +github.com/multiformats/go-multistream v0.2.2 h1:TCYu1BHTDr1F/Qm75qwYISQdzGcRdC21nFgQW7l7GBo= +github.com/multiformats/go-multistream v0.2.2/go.mod h1:UIcnm7Zuo8HKG+HkWgfQsGL+/MIEhyTqbODbIUwSXKs= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.2/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= @@ -1316,8 +1366,6 @@ github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OS github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/ngdinhtoan/glide-cleanup v0.2.0/go.mod h1:UQzsmiDOb8YV3nOsCxK/c9zPpCZVNoHScRE3EO9pVMM= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nikkolasg/hexjson v0.0.0-20181101101858-78e39397e00c h1:5bFTChQxSKNwy8ALwOebjekYExl9HTT9urdawqC95tA= github.com/nikkolasg/hexjson v0.0.0-20181101101858-78e39397e00c/go.mod h1:7qN3Y0BvzRUf4LofcoJplQL10lsFDb4PYlePTVwrP28= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229 h1:E2B8qYyeSgv5MXpmzZXRNp8IAQ4vjxIjhpAf5hv/tAg= @@ -1336,6 +1384,7 @@ github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0 github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -1635,6 +1684,7 @@ github.com/xorcare/golden v0.6.0/go.mod h1:7T39/ZMvaSEZlBPoYfVFmsBLmUl3uz9IuzWj/ github.com/xorcare/golden v0.6.1-0.20191112154924-b87f686d7542 h1:oWgZJmC1DorFZDpfMfWg7xk29yEOZiXmo/wZl+utTI8= github.com/xorcare/golden v0.6.1-0.20191112154924-b87f686d7542/go.mod h1:7T39/ZMvaSEZlBPoYfVFmsBLmUl3uz9IuzWj/U6FtvQ= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/zondax/hid v0.9.0 h1:eiT3P6vNxAEVxXMw66eZUAAnU2zD33JBkfG/EnfAKl8= @@ -1663,8 +1713,8 @@ go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -1718,16 +1768,19 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20181106170214-d68db9428509/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1754,8 +1807,9 @@ golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367 h1:0IiAsCRByjO2QjX7ZPkw5oU9x+n1YqRL802rjC0c3Aw= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -1766,6 +1820,7 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180524181706-dfa909b99c79/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1801,6 +1856,7 @@ golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200519113804-d87ec0cfa476/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= @@ -1808,8 +1864,11 @@ golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201022231255-08b38378de70 h1:Z6x4N9mAi4oF0TbHweCsH618MO6OI6UFgV0FP5n0wBY= golang.org/x/net v0.0.0-20201022231255-08b38378de70/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6 h1:0PC75Fz/kyMGhL0e1QnypqK2kQMqKt9csD1GnMJR+Zk= +golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1827,8 +1886,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180202135801-37707fdb30a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1898,16 +1957,21 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200812155832-6a926be9bd1d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200926100807-9d91bd62050c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210426080607-c94f62235c83 h1:kHSDPqCtsHZOg0nVylfTo20DDhE9gG4Y0jn7hKQ0QAM= +golang.org/x/sys v0.0.0-20210426080607-c94f62235c83/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf h1:MZ2shdL+ZM/XzY3ZGOnh4Nlpnxz5GSOhOmtHo3iPU6M= 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= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1953,10 +2017,12 @@ golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200216192241-b320d3a0f5a2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200711155855-7342f9734a7d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200827010519-17fd2f27a9e3/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20201112185108-eeaa07dd7696 h1:Bfazo+enXJET5SbHeh95NtxabJF6fJ9r/jpfRJgd3j4= golang.org/x/tools v0.0.0-20201112185108-eeaa07dd7696/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a h1:CB3a9Nez8M13wwlr/E2YtwoU+qYHKfC+JrDa45RXXoQ= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -2031,8 +2097,9 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.31.1 h1:SfXqXS5hkufcdZ/mHtYCh53P2b+92WQq/DZcKLgsFRs= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -2048,8 +2115,8 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/cheggaaa/pb.v1 v1.0.28 h1:n1tBJnnK2r7g9OW2btFH91V92STTUevLXYFb8gy9EMk= gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= diff --git a/testplans/lotus-soup/init.go b/testplans/lotus-soup/init.go index 7eada2ed6e1..c20f5f2b8e2 100644 --- a/testplans/lotus-soup/init.go +++ b/testplans/lotus-soup/init.go @@ -42,7 +42,7 @@ func init() { // deadline when the challenge is available. // // This will auto-scale the proving period. - policy.SetWPoStChallengeWindow(abi.ChainEpoch(5)) + // policy.SetWPoStChallengeWindow(abi.ChainEpoch(5)) // commented-out until we enable PoSt faults tests // Number of epochs between publishing the precommit and when the challenge for interactive PoRep is drawn // used to ensure it is not predictable by miner. diff --git a/testplans/lotus-soup/manifest.toml b/testplans/lotus-soup/manifest.toml index fc58fbd5ba0..9f5a574440b 100644 --- a/testplans/lotus-soup/manifest.toml +++ b/testplans/lotus-soup/manifest.toml @@ -9,8 +9,8 @@ enabled = true [builders."docker:go"] enabled = true -build_base_image = "iptestground/oni-buildbase:v14-lotus" -runtime_image = "iptestground/oni-runtime:v9-debug" +build_base_image = "iptestground/oni-buildbase:v15-lotus" +runtime_image = "iptestground/oni-runtime:v10-debug" [runners."local:exec"] enabled = true diff --git a/testplans/lotus-soup/rfwp/chain_state.go b/testplans/lotus-soup/rfwp/chain_state.go index 90159e92410..d91acdff9f3 100644 --- a/testplans/lotus-soup/rfwp/chain_state.go +++ b/testplans/lotus-soup/rfwp/chain_state.go @@ -7,6 +7,8 @@ import ( "encoding/json" "fmt" "io" + "math" + corebig "math/big" "os" "sort" "text/tabwriter" @@ -27,6 +29,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" sealing "github.com/filecoin-project/lotus/extern/storage-sealing" + "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" tstats "github.com/filecoin-project/lotus/tools/stats" ) @@ -581,18 +584,24 @@ func (i *MinerInfo) MarshalPlainText() ([]byte, error) { fmt.Fprintf(w, "Sector Size: %s\n", i.SectorSize) pow := i.MinerPower - rpercI := types.BigDiv(types.BigMul(pow.MinerPower.RawBytePower, types.NewInt(1000000)), pow.TotalPower.RawBytePower) - qpercI := types.BigDiv(types.BigMul(pow.MinerPower.QualityAdjPower, types.NewInt(1000000)), pow.TotalPower.QualityAdjPower) fmt.Fprintf(w, "Byte Power: %s / %s (%0.4f%%)\n", types.SizeStr(pow.MinerPower.RawBytePower), types.SizeStr(pow.TotalPower.RawBytePower), - float64(rpercI.Int64())/10000) + types.BigDivFloat( + types.BigMul(pow.MinerPower.RawBytePower, big.NewInt(100)), + pow.TotalPower.RawBytePower, + ), + ) fmt.Fprintf(w, "Actual Power: %s / %s (%0.4f%%)\n", types.DeciStr(pow.MinerPower.QualityAdjPower), types.DeciStr(pow.TotalPower.QualityAdjPower), - float64(qpercI.Int64())/10000) + types.BigDivFloat( + types.BigMul(pow.MinerPower.QualityAdjPower, big.NewInt(100)), + pow.TotalPower.QualityAdjPower, + ), + ) fmt.Fprintf(w, "\tCommitted: %s\n", types.SizeStr(i.CommittedBytes)) @@ -608,16 +617,50 @@ func (i *MinerInfo) MarshalPlainText() ([]byte, error) { if !i.MinerPower.HasMinPower { fmt.Fprintf(w, "Below minimum power threshold, no blocks will be won\n") } else { - expWinChance := float64(types.BigMul(qpercI, types.NewInt(build.BlocksPerEpoch)).Int64()) / 1000000 - if expWinChance > 0 { - if expWinChance > 1 { - expWinChance = 1 + + winRatio := new(corebig.Rat).SetFrac( + types.BigMul(pow.MinerPower.QualityAdjPower, types.NewInt(build.BlocksPerEpoch)).Int, + pow.TotalPower.QualityAdjPower.Int, + ) + + if winRatioFloat, _ := winRatio.Float64(); winRatioFloat > 0 { + + // if the corresponding poisson distribution isn't infinitely small then + // throw it into the mix as well, accounting for multi-wins + winRationWithPoissonFloat := -math.Expm1(-winRatioFloat) + winRationWithPoisson := new(corebig.Rat).SetFloat64(winRationWithPoissonFloat) + if winRationWithPoisson != nil { + winRatio = winRationWithPoisson + winRatioFloat = winRationWithPoissonFloat } - winRate := time.Duration(float64(time.Second*time.Duration(build.BlockDelaySecs)) / expWinChance) - winPerDay := float64(time.Hour*24) / float64(winRate) - fmt.Fprintln(w, "Expected block win rate: ") - fmt.Fprintf(w, "%.4f/day (every %s)\n", winPerDay, winRate.Truncate(time.Second)) + weekly, _ := new(corebig.Rat).Mul( + winRatio, + new(corebig.Rat).SetInt64(7*builtin.EpochsInDay), + ).Float64() + + avgDuration, _ := new(corebig.Rat).Mul( + new(corebig.Rat).SetInt64(builtin.EpochDurationSeconds), + new(corebig.Rat).Inv(winRatio), + ).Float64() + + fmt.Fprintf(w, "Projected average block win rate: %.02f/week (every %s)\n", + weekly, + (time.Second * time.Duration(avgDuration)).Truncate(time.Second).String(), + ) + + // Geometric distribution of P(Y < k) calculated as described in https://en.wikipedia.org/wiki/Geometric_distribution#Probability_Outcomes_Examples + // https://www.wolframalpha.com/input/?i=t+%3E+0%3B+p+%3E+0%3B+p+%3C+1%3B+c+%3E+0%3B+c+%3C1%3B+1-%281-p%29%5E%28t%29%3Dc%3B+solve+t + // t == how many dice-rolls (epochs) before win + // p == winRate == ( minerPower / netPower ) + // c == target probability of win ( 99.9% in this case ) + fmt.Fprintf(w, "Projected block win with 99.9%% probability every %s\n", + (time.Second * time.Duration( + builtin.EpochDurationSeconds*math.Log(1-0.999)/ + math.Log(1-winRatioFloat), + )).Truncate(time.Second).String(), + ) + fmt.Fprintln(w, "(projections DO NOT account for future network and miner growth)") } }