diff --git a/.circleci/config.yml b/.circleci/config.yml index 4af2bfc12..4338c7937 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -23,11 +23,6 @@ executors: commands: - install-deps: - steps: - - run: | - sudo apt update - sudo apt install python-is-python3 prepare: parameters: linux: @@ -41,9 +36,8 @@ commands: steps: - checkout - git_fetch_all_tags - - checkout - when: - condition: << parameters.linux >> + condition: <> steps: - run: name: Check Go Version @@ -56,6 +50,8 @@ commands: fi - run: sudo apt-get update - run: sudo apt-get install ocl-icd-opencl-dev libhwloc-dev + - run: sudo apt-get install python-is-python3 + - when: condition: <> steps: @@ -70,21 +66,12 @@ commands: echo 'export GOPATH="${HOME}/go"' >> $BASH_ENV - run: go version - run: - name: Install pkg-config, goreleaser, and sha512sum - command: HOMEBREW_NO_AUTO_UPDATE=1 brew install pkg-config goreleaser/tap/goreleaser coreutils + name: Install dependencies with Homebrew + command: HOMEBREW_NO_AUTO_UPDATE=1 brew install pkg-config coreutils jq hwloc - run: name: Install Rust command: | curl https://sh.rustup.rs -sSf | sh -s -- -y - - 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 - run: git submodule sync - run: git submodule update --init download-params: @@ -104,28 +91,13 @@ commands: install_ipfs: steps: - run: | - apt update - apt install -y wget - wget https://github.com/ipfs/go-ipfs/releases/download/v0.12.2/go-ipfs_v0.12.2_linux-amd64.tar.gz - wget https://github.com/ipfs/go-ipfs/releases/download/v0.12.2/go-ipfs_v0.12.2_linux-amd64.tar.gz.sha512 - if [ "$(sha512sum go-ipfs_v0.12.2_linux-amd64.tar.gz)" != "$(cat go-ipfs_v0.12.2_linux-amd64.tar.gz.sha512)" ] - then - echo "ipfs failed checksum check" - exit 1 - fi - tar -xf go-ipfs_v0.12.2_linux-amd64.tar.gz - mv go-ipfs/ipfs /usr/local/bin/ipfs - chmod +x /usr/local/bin/ipfs - install_ipfs_macos: - steps: - - run: | - curl -O https://dist.ipfs.io/kubo/v0.14.0/kubo_v0.14.0_darwin-amd64.tar.gz - tar -xvzf kubo_v0.14.0_darwin-amd64.tar.gz + curl -O https://dist.ipfs.tech/kubo/v0.16.0/kubo_v0.16.0_linux-amd64.tar.gz + tar -xvzf kubo_v0.16.0_linux-amd64.tar.gz pushd kubo sudo bash install.sh popd - rm -rf kubo/ - rm kubo_v0.14.0_darwin-amd64.tar.gz + rm -rf kubo + rm kubo_v0.16.0_linux-amd64.tar.gz git_fetch_all_tags: steps: - run: @@ -156,7 +128,6 @@ jobs: mod-tidy-check: executor: golang steps: - - install-deps - prepare - run: go mod tidy -v - run: @@ -164,34 +135,9 @@ jobs: command: | git --no-pager diff go.mod go.sum git --no-pager diff --quiet go.mod go.sum - build-linux: - executor: golang - steps: - - install-deps - - prepare - - run: sudo apt-get update - - run: sudo apt-get install npm - - run: - command: make buildall - - run: - name: check tag and version output match - command: ./scripts/version-check.sh ./lotus - - 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 @@ -224,7 +170,6 @@ jobs: description: gotestsum format. https://github.com/gotestyourself/gotestsum#format executor: << parameters.executor >> steps: - - install-deps - prepare - run: command: make deps lotus @@ -268,7 +213,6 @@ jobs: submodule is used. executor: << parameters.executor >> steps: - - install-deps - prepare - run: command: make deps lotus @@ -311,36 +255,6 @@ jobs: 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-lotus-soup: description: | Compile `lotus-soup` Testground test plan @@ -348,7 +262,6 @@ jobs: <<: *test-params executor: << parameters.executor >> steps: - - install-deps - prepare - run: cd extern/filecoin-ffi && make - run: @@ -364,7 +277,6 @@ jobs: <<: *test-params executor: << parameters.executor >> steps: - - install-deps - prepare - run: name: "download testground" @@ -384,48 +296,104 @@ jobs: - 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 - build-macos: + + build-linux-amd64: + executor: golang + steps: + - prepare + - run: make lotus lotus-miner lotus-worker + - run: + name: check tag and version output match + command: ./scripts/version-check.sh ./lotus + - run: | + mkdir -p /tmp/workspace/linux_amd64_v1 && \ + mv lotus lotus-miner lotus-worker /tmp/workspace/linux_amd64_v1/ + - persist_to_workspace: + root: /tmp/workspace + paths: + - linux_amd64_v1 + + build-darwin-amd64: description: build darwin lotus binary - parameters: - publish: - default: false - description: publish github release and homebrew? - type: boolean + working_directory: ~/go/src/github.com/filecoin-project/lotus macos: xcode: "13.4.1" - working_directory: ~/go/src/github.com/filecoin-project/lotus steps: - prepare: linux: false darwin: true - - install_ipfs_macos - - restore_cache: - name: restore cargo cache - key: v3-go-deps-{{ arch }}-{{ checksum "~/go/src/github.com/filecoin-project/lotus/go.sum" }} + - run: make lotus lotus-miner lotus-worker + - run: + name: check tag and version output match + command: ./scripts/version-check.sh ./lotus + - run: | + mkdir -p /tmp/workspace/darwin_amd64_v1 && \ + mv lotus lotus-miner lotus-worker /tmp/workspace/darwin_amd64_v1/ + - persist_to_workspace: + root: /tmp/workspace + paths: + - darwin_amd64_v1 + + build-darwin-arm64: + description: self-hosted m1 runner + working_directory: ~/go/src/github.com/filecoin-project/lotus + machine: true + resource_class: filecoin-project/self-hosted-m1 + steps: + - run: echo 'export PATH=/opt/homebrew/bin:"$PATH"' >> "$BASH_ENV" + - prepare: + linux: false + darwin: true + - run: | + export CPATH=$(brew --prefix)/include + export LIBRARY_PATH=$(brew --prefix)/lib + make lotus lotus-miner lotus-worker + - run: + name: check tag and version output match + command: ./scripts/version-check.sh ./lotus + - run: | + mkdir -p /tmp/workspace/darwin_arm64 && \ + mv lotus lotus-miner lotus-worker /tmp/workspace/darwin_arm64/ + - persist_to_workspace: + root: /tmp/workspace + paths: + - darwin_arm64 + - run: + command: make clean + when: always + - run: + name: cleanup homebrew + command: HOMEBREW_NO_AUTO_UPDATE=1 brew uninstall pkg-config coreutils jq hwloc + when: always + + release: + executor: golang + parameters: + dry-run: + default: false + description: should this release actually publish it's artifacts? + type: boolean + steps: + - checkout + - run: | + echo 'deb [trusted=yes] https://repo.goreleaser.com/apt/ /' | sudo tee /etc/apt/sources.list.d/goreleaser.list + sudo apt update + sudo apt install goreleaser-pro + - install_ipfs + - attach_workspace: + at: /tmp/workspace - when: - condition: << parameters.publish >> + condition: << parameters.dry-run >> steps: - - run: goreleaser release --rm-dist + - run: goreleaser release --rm-dist --snapshot --debug - run: ./scripts/generate-checksums.sh - - run: ./scripts/publish-checksums.sh - when: condition: - not: << parameters.publish >> + not: << parameters.dry-run >> steps: - - run: goreleaser release --rm-dist --snapshot + - run: goreleaser release --rm-dist --debug - run: ./scripts/generate-checksums.sh - - store_artifacts: - path: dist - - persist_to_workspace: - root: "." - paths: - - dist - - save_cache: - name: save cargo cache - key: v3-go-deps-{{ arch }}-{{ checksum "~/go/src/github.com/filecoin-project/lotus/go.sum" }} - paths: - - "~/.rustup" - - "~/.cargo" + - run: ./scripts/publish-checksums.sh build-appimage: machine: @@ -433,7 +401,7 @@ jobs: steps: - checkout - attach_workspace: - at: "." + at: /tmp/workspace - run: name: Update Go command: | @@ -468,13 +436,11 @@ jobs: command: | sed -i "s/version: latest/version: ${CIRCLE_TAG:-latest}/" AppImageBuilder.yml make appimage - - run: - name: prepare workspace - command: | - mkdir appimage - mv Lotus-*.AppImage appimage + - run: | + mkdir -p /tmp/workspace/appimage && \ + mv Lotus-*.AppImage /tmp/workspace/appimage/ - persist_to_workspace: - root: "." + root: /tmp/workspace paths: - appimage @@ -482,7 +448,6 @@ jobs: gofmt: executor: golang steps: - - install-deps - prepare - run: command: "! go fmt ./... 2>&1 | read" @@ -490,7 +455,6 @@ jobs: gen-check: executor: golang steps: - - install-deps - prepare - run: make deps - run: go install golang.org/x/tools/cmd/goimports @@ -505,7 +469,6 @@ jobs: 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 @@ -542,7 +505,6 @@ jobs: Arguments to pass to golangci-lint executor: << parameters.executor >> steps: - - install-deps - prepare - run: command: make deps @@ -570,13 +532,13 @@ jobs: steps: - run: name: Install git jq curl - command: apt update && apt install -y git jq curl + command: apt update && apt install -y git jq curl sudo - checkout - git_fetch_all_tags - checkout - install_ipfs - attach_workspace: - at: "." + at: /tmp/workspace - when: condition: << parameters.linux >> steps: @@ -751,8 +713,6 @@ jobs: name: packer steps: - checkout - - attach_workspace: - at: "." - packer_build: template: tools/packer/lotus-snap.pkr.hcl publish-dockerhub: @@ -896,6 +856,11 @@ workflows: suite: itest-deals_publish target: "./itests/deals_publish_test.go" + - test: + name: test-itest-deals_remote_retrieval + suite: itest-deals_remote_retrieval + target: "./itests/deals_remote_retrieval_test.go" + - test: name: test-itest-deals_retry_deal_no_funds suite: itest-deals_retry_deal_no_funds @@ -951,6 +916,11 @@ workflows: suite: itest-mpool_msg_uuid target: "./itests/mpool_msg_uuid_test.go" + - test: + name: test-itest-mpool_push_with_uuid + suite: itest-mpool_push_with_uuid + target: "./itests/mpool_push_with_uuid_test.go" + - test: name: test-itest-multisig suite: itest-multisig @@ -991,6 +961,11 @@ workflows: suite: itest-pending_deal_allocation target: "./itests/pending_deal_allocation_test.go" + - test: + name: test-itest-raft_messagesigner + suite: itest-raft_messagesigner + target: "./itests/raft_messagesigner_test.go" + - test: name: test-itest-remove_verifreg_datacap suite: itest-remove_verifreg_datacap @@ -1136,41 +1111,12 @@ workflows: only: - master - build-debug - - build-linux: - 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-lotus-soup - - build-macos: - name: publish-macos - publish: true - filters: - branches: - ignore: - - /.*/ - tags: - only: - - /^v\d+\.\d+\.\d+$/ - - build-macos: - filters: - branches: - only: - - /^release\/v\d+\.\d+\.\d+(-rc\d+)?$/ - tags: - only: - - /^v\d+\.\d+\.\d+-rc\d+$/ - - build-appimage: + + release: + jobs: + - build-linux-amd64: + name: "Build ( linux / amd64 )" filters: branches: only: @@ -1178,11 +1124,32 @@ workflows: tags: only: - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - - publish: - name: publish-linux - linux: true + - build-darwin-amd64: + name: "Build ( darwin / amd64 )" + filters: + branches: + only: + - /^release\/v\d+\.\d+\.\d+(-rc\d+)?$/ + tags: + only: + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + - build-darwin-arm64: + name: "Build ( darwin / arm64 )" + filters: + branches: + only: + - /^release\/v\d+\.\d+\.\d+(-rc\d+)?$/ + tags: + only: + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + - release: + name: "Release" + context: + - filecoin-goreleaser-key requires: - - build-linux + - "Build ( darwin / amd64 )" + - "Build ( linux / amd64 )" + - "Build ( darwin / arm64 )" filters: branches: ignore: @@ -1190,11 +1157,33 @@ workflows: tags: only: - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + - release: + name: "Release (dry-run)" + context: + - filecoin-goreleaser-key + dry-run: true + requires: + - "Build ( darwin / amd64 )" + - "Build ( linux / amd64 )" + - "Build ( darwin / arm64 )" + filters: + branches: + only: + - /^release\/v\d+\.\d+\.\d+(-rc\d+)?$/ + - build-appimage: + name: "Build AppImage" + filters: + branches: + only: + - /^release\/v\d+\.\d+\.\d+(-rc\d+)?$/ + tags: + only: + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - publish: - name: publish-appimage + name: "Publish AppImage" appimage: true requires: - - build-appimage + - "Build AppImage" filters: branches: ignore: @@ -1203,14 +1192,14 @@ workflows: only: - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - build-and-push-image: - name: build-and-push/lotus-all-in-one + name: "Publish ECR (lotus-all-in-one)" dockerfile: Dockerfile.lotus path: . repo: lotus-dev tag: '${CIRCLE_SHA1:0:8}' target: lotus-all-in-one - build-and-push-image: - name: build-and-push/lotus-test + name: "Publish ECR (lotus-test)" dockerfile: Dockerfile.lotus path: . repo: lotus-test @@ -1261,7 +1250,7 @@ workflows: only: - /^v\d+\.\d+\.\d+-rc\d+$/ - publish-dockerhub: - name: publish-dockerhub + name: "Publish Dockerhub (stable)" tag: stable filters: branches: @@ -1269,7 +1258,17 @@ workflows: - /.*/ tags: only: - - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + - /^v\d+\.\d+\.\d+$/ + - publish-dockerhub: + name: "Publish Dockerhub (candidate)" + tag: candidate + filters: + branches: + ignore: + - /.*/ + tags: + only: + - /^v\d+\.\d+\.\d+-rc\d+$/ nightly: triggers: diff --git a/.circleci/template.yml b/.circleci/template.yml index ed4129006..62daa347c 100644 --- a/.circleci/template.yml +++ b/.circleci/template.yml @@ -23,11 +23,6 @@ executors: commands: - install-deps: - steps: - - run: | - sudo apt update - sudo apt install python-is-python3 prepare: parameters: linux: @@ -41,9 +36,8 @@ commands: steps: - checkout - git_fetch_all_tags - - checkout - when: - condition: << parameters.linux >> + condition: <> steps: - run: name: Check Go Version @@ -56,6 +50,8 @@ commands: fi - run: sudo apt-get update - run: sudo apt-get install ocl-icd-opencl-dev libhwloc-dev + - run: sudo apt-get install python-is-python3 + - when: condition: <> steps: @@ -70,21 +66,12 @@ commands: echo 'export GOPATH="${HOME}/go"' >> $BASH_ENV - run: go version - run: - name: Install pkg-config, goreleaser, and sha512sum - command: HOMEBREW_NO_AUTO_UPDATE=1 brew install pkg-config goreleaser/tap/goreleaser coreutils + name: Install dependencies with Homebrew + command: HOMEBREW_NO_AUTO_UPDATE=1 brew install pkg-config coreutils jq hwloc - run: name: Install Rust command: | curl https://sh.rustup.rs -sSf | sh -s -- -y - - 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 - run: git submodule sync - run: git submodule update --init download-params: @@ -104,28 +91,13 @@ commands: install_ipfs: steps: - run: | - apt update - apt install -y wget - wget https://github.com/ipfs/go-ipfs/releases/download/v0.12.2/go-ipfs_v0.12.2_linux-amd64.tar.gz - wget https://github.com/ipfs/go-ipfs/releases/download/v0.12.2/go-ipfs_v0.12.2_linux-amd64.tar.gz.sha512 - if [ "$(sha512sum go-ipfs_v0.12.2_linux-amd64.tar.gz)" != "$(cat go-ipfs_v0.12.2_linux-amd64.tar.gz.sha512)" ] - then - echo "ipfs failed checksum check" - exit 1 - fi - tar -xf go-ipfs_v0.12.2_linux-amd64.tar.gz - mv go-ipfs/ipfs /usr/local/bin/ipfs - chmod +x /usr/local/bin/ipfs - install_ipfs_macos: - steps: - - run: | - curl -O https://dist.ipfs.io/kubo/v0.14.0/kubo_v0.14.0_darwin-amd64.tar.gz - tar -xvzf kubo_v0.14.0_darwin-amd64.tar.gz + curl -O https://dist.ipfs.tech/kubo/v0.16.0/kubo_v0.16.0_linux-amd64.tar.gz + tar -xvzf kubo_v0.16.0_linux-amd64.tar.gz pushd kubo sudo bash install.sh popd - rm -rf kubo/ - rm kubo_v0.14.0_darwin-amd64.tar.gz + rm -rf kubo + rm kubo_v0.16.0_linux-amd64.tar.gz git_fetch_all_tags: steps: - run: @@ -156,7 +128,6 @@ jobs: mod-tidy-check: executor: golang steps: - - install-deps - prepare - run: go mod tidy -v - run: @@ -164,34 +135,9 @@ jobs: command: | git --no-pager diff go.mod go.sum git --no-pager diff --quiet go.mod go.sum - build-linux: - executor: golang - steps: - - install-deps - - prepare - - run: sudo apt-get update - - run: sudo apt-get install npm - - run: - command: make buildall - - run: - name: check tag and version output match - command: ./scripts/version-check.sh ./lotus - - 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 @@ -224,7 +170,6 @@ jobs: description: gotestsum format. https://github.com/gotestyourself/gotestsum#format executor: << parameters.executor >> steps: - - install-deps - prepare - run: command: make deps lotus @@ -268,7 +213,6 @@ jobs: submodule is used. executor: << parameters.executor >> steps: - - install-deps - prepare - run: command: make deps lotus @@ -311,36 +255,6 @@ jobs: 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-lotus-soup: description: | Compile `lotus-soup` Testground test plan @@ -348,7 +262,6 @@ jobs: <<: *test-params executor: << parameters.executor >> steps: - - install-deps - prepare - run: cd extern/filecoin-ffi && make - run: @@ -364,7 +277,6 @@ jobs: <<: *test-params executor: << parameters.executor >> steps: - - install-deps - prepare - run: name: "download testground" @@ -384,48 +296,104 @@ jobs: - 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 - build-macos: + + build-linux-amd64: + executor: golang + steps: + - prepare + - run: make lotus lotus-miner lotus-worker + - run: + name: check tag and version output match + command: ./scripts/version-check.sh ./lotus + - run: | + mkdir -p /tmp/workspace/linux_amd64_v1 && \ + mv lotus lotus-miner lotus-worker /tmp/workspace/linux_amd64_v1/ + - persist_to_workspace: + root: /tmp/workspace + paths: + - linux_amd64_v1 + + build-darwin-amd64: description: build darwin lotus binary - parameters: - publish: - default: false - description: publish github release and homebrew? - type: boolean + working_directory: ~/go/src/github.com/filecoin-project/lotus macos: xcode: "13.4.1" - working_directory: ~/go/src/github.com/filecoin-project/lotus steps: - prepare: linux: false darwin: true - - install_ipfs_macos - - restore_cache: - name: restore cargo cache - key: v3-go-deps-{{ arch }}-{{ checksum "~/go/src/github.com/filecoin-project/lotus/go.sum" }} + - run: make lotus lotus-miner lotus-worker + - run: + name: check tag and version output match + command: ./scripts/version-check.sh ./lotus + - run: | + mkdir -p /tmp/workspace/darwin_amd64_v1 && \ + mv lotus lotus-miner lotus-worker /tmp/workspace/darwin_amd64_v1/ + - persist_to_workspace: + root: /tmp/workspace + paths: + - darwin_amd64_v1 + + build-darwin-arm64: + description: self-hosted m1 runner + working_directory: ~/go/src/github.com/filecoin-project/lotus + machine: true + resource_class: filecoin-project/self-hosted-m1 + steps: + - run: echo 'export PATH=/opt/homebrew/bin:"$PATH"' >> "$BASH_ENV" + - prepare: + linux: false + darwin: true + - run: | + export CPATH=$(brew --prefix)/include + export LIBRARY_PATH=$(brew --prefix)/lib + make lotus lotus-miner lotus-worker + - run: + name: check tag and version output match + command: ./scripts/version-check.sh ./lotus + - run: | + mkdir -p /tmp/workspace/darwin_arm64 && \ + mv lotus lotus-miner lotus-worker /tmp/workspace/darwin_arm64/ + - persist_to_workspace: + root: /tmp/workspace + paths: + - darwin_arm64 + - run: + command: make clean + when: always + - run: + name: cleanup homebrew + command: HOMEBREW_NO_AUTO_UPDATE=1 brew uninstall pkg-config coreutils jq hwloc + when: always + + release: + executor: golang + parameters: + dry-run: + default: false + description: should this release actually publish it's artifacts? + type: boolean + steps: + - checkout + - run: | + echo 'deb [trusted=yes] https://repo.goreleaser.com/apt/ /' | sudo tee /etc/apt/sources.list.d/goreleaser.list + sudo apt update + sudo apt install goreleaser-pro + - install_ipfs + - attach_workspace: + at: /tmp/workspace - when: - condition: << parameters.publish >> + condition: << parameters.dry-run >> steps: - - run: goreleaser release --rm-dist + - run: goreleaser release --rm-dist --snapshot --debug - run: ./scripts/generate-checksums.sh - - run: ./scripts/publish-checksums.sh - when: condition: - not: << parameters.publish >> + not: << parameters.dry-run >> steps: - - run: goreleaser release --rm-dist --snapshot + - run: goreleaser release --rm-dist --debug - run: ./scripts/generate-checksums.sh - - store_artifacts: - path: dist - - persist_to_workspace: - root: "." - paths: - - dist - - save_cache: - name: save cargo cache - key: v3-go-deps-{{ arch }}-{{ checksum "~/go/src/github.com/filecoin-project/lotus/go.sum" }} - paths: - - "~/.rustup" - - "~/.cargo" + - run: ./scripts/publish-checksums.sh build-appimage: machine: @@ -433,7 +401,7 @@ jobs: steps: - checkout - attach_workspace: - at: "." + at: /tmp/workspace - run: name: Update Go command: | @@ -468,13 +436,11 @@ jobs: command: | sed -i "s/version: latest/version: ${CIRCLE_TAG:-latest}/" AppImageBuilder.yml make appimage - - run: - name: prepare workspace - command: | - mkdir appimage - mv Lotus-*.AppImage appimage + - run: | + mkdir -p /tmp/workspace/appimage && \ + mv Lotus-*.AppImage /tmp/workspace/appimage/ - persist_to_workspace: - root: "." + root: /tmp/workspace paths: - appimage @@ -482,7 +448,6 @@ jobs: gofmt: executor: golang steps: - - install-deps - prepare - run: command: "! go fmt ./... 2>&1 | read" @@ -490,7 +455,6 @@ jobs: gen-check: executor: golang steps: - - install-deps - prepare - run: make deps - run: go install golang.org/x/tools/cmd/goimports @@ -505,7 +469,6 @@ jobs: 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 @@ -542,7 +505,6 @@ jobs: Arguments to pass to golangci-lint executor: << parameters.executor >> steps: - - install-deps - prepare - run: command: make deps @@ -570,13 +532,13 @@ jobs: steps: - run: name: Install git jq curl - command: apt update && apt install -y git jq curl + command: apt update && apt install -y git jq curl sudo - checkout - git_fetch_all_tags - checkout - install_ipfs - attach_workspace: - at: "." + at: /tmp/workspace - when: condition: << parameters.linux >> steps: @@ -751,8 +713,6 @@ jobs: name: packer steps: - checkout - - attach_workspace: - at: "." - packer_build: template: tools/packer/lotus-snap.pkr.hcl publish-dockerhub: @@ -846,41 +806,12 @@ workflows: only: - master - build-debug - - build-linux: - 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-lotus-soup - - build-macos: - name: publish-macos - publish: true - filters: - branches: - ignore: - - /.*/ - tags: - only: - - /^v\d+\.\d+\.\d+$/ - - build-macos: - filters: - branches: - only: - - /^release\/v\d+\.\d+\.\d+(-rc\d+)?$/ - tags: - only: - - /^v\d+\.\d+\.\d+-rc\d+$/ - - build-appimage: + + release: + jobs: + - build-linux-amd64: + name: "Build ( linux / amd64 )" filters: branches: only: @@ -888,11 +819,32 @@ workflows: tags: only: - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - - publish: - name: publish-linux - linux: true + - build-darwin-amd64: + name: "Build ( darwin / amd64 )" + filters: + branches: + only: + - /^release\/v\d+\.\d+\.\d+(-rc\d+)?$/ + tags: + only: + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + - build-darwin-arm64: + name: "Build ( darwin / arm64 )" + filters: + branches: + only: + - /^release\/v\d+\.\d+\.\d+(-rc\d+)?$/ + tags: + only: + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + - release: + name: "Release" + context: + - filecoin-goreleaser-key requires: - - build-linux + - "Build ( darwin / amd64 )" + - "Build ( linux / amd64 )" + - "Build ( darwin / arm64 )" filters: branches: ignore: @@ -900,11 +852,33 @@ workflows: tags: only: - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + - release: + name: "Release (dry-run)" + context: + - filecoin-goreleaser-key + dry-run: true + requires: + - "Build ( darwin / amd64 )" + - "Build ( linux / amd64 )" + - "Build ( darwin / arm64 )" + filters: + branches: + only: + - /^release\/v\d+\.\d+\.\d+(-rc\d+)?$/ + - build-appimage: + name: "Build AppImage" + filters: + branches: + only: + - /^release\/v\d+\.\d+\.\d+(-rc\d+)?$/ + tags: + only: + - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - publish: - name: publish-appimage + name: "Publish AppImage" appimage: true requires: - - build-appimage + - "Build AppImage" filters: branches: ignore: @@ -913,14 +887,14 @@ workflows: only: - /^v\d+\.\d+\.\d+(-rc\d+)?$/ - build-and-push-image: - name: build-and-push/lotus-all-in-one + name: "Publish ECR (lotus-all-in-one)" dockerfile: Dockerfile.lotus path: . repo: lotus-dev tag: '${CIRCLE_SHA1:0:8}' target: lotus-all-in-one - build-and-push-image: - name: build-and-push/lotus-test + name: "Publish ECR (lotus-test)" dockerfile: Dockerfile.lotus path: . repo: lotus-test @@ -971,7 +945,7 @@ workflows: only: - /^v\d+\.\d+\.\d+-rc\d+$/ - publish-dockerhub: - name: publish-dockerhub + name: "Publish Dockerhub (stable)" tag: stable filters: branches: @@ -979,7 +953,17 @@ workflows: - /.*/ tags: only: - - /^v\d+\.\d+\.\d+(-rc\d+)?$/ + - /^v\d+\.\d+\.\d+$/ + - publish-dockerhub: + name: "Publish Dockerhub (candidate)" + tag: candidate + filters: + branches: + ignore: + - /.*/ + tags: + only: + - /^v\d+\.\d+\.\d+-rc\d+$/ nightly: triggers: diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..cf5b209d7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +chain/actors/builtin/*/v* linguist-generated=true +chain/actors/builtin/*/message* linguist-generated=true diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 9c613d8cf..021945acf 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -1,119 +1,65 @@ project_name: lotus -before: - hooks: - - go mod tidy - - make deps universal_binaries: - id: lotus replace: true name_template: lotus - ids: - - lotus_darwin_amd64 - - lotus_darwin_arm64 - id: lotus-miner replace: true name_template: lotus-miner - ids: - - lotus-miner_darwin_amd64 - - lotus-miner_darwin_arm64 - id: lotus-worker replace: true name_template: lotus-worker - ids: - - lotus-worker_darwin_amd64 - - lotus-worker_darwin_arm64 builds: - - id: lotus_darwin_amd64 - main: ./cmd/lotus + - id: lotus binary: lotus + builder: prebuilt goos: - darwin + - linux goarch: - amd64 - env: - - CGO_ENABLED=1 - - FFI_BUILD_FROM_SOURCE=1 - ldflags: - - -X=github.com/filecoin-project/lotus/build.CurrentCommit=+git.{{.ShortCommit}} - - id: lotus-miner_darwin_amd64 - main: ./cmd/lotus-miner + - arm64 + goamd64: + - v1 + ignore: + - goos: linux + goarch: arm64 + prebuilt: + path: /tmp/workspace/{{ .Os }}_{{ .Arch }}{{ with .Amd64 }}_{{ . }}{{ end }}/lotus + - id: lotus-miner binary: lotus-miner + builder: prebuilt goos: - darwin + - linux goarch: - amd64 - env: - - CGO_ENABLED=1 - - FFI_BUILD_FROM_SOURCE=1 - ldflags: - - -X=github.com/filecoin-project/lotus/build.CurrentCommit=+git.{{.ShortCommit}} - - id: lotus-worker_darwin_amd64 - main: ./cmd/lotus-worker + - arm64 + goamd64: + - v1 + ignore: + - goos: linux + goarch: arm64 + prebuilt: + path: /tmp/workspace/{{ .Os }}_{{ .Arch }}{{ with .Amd64 }}_{{ . }}{{ end }}/lotus-miner + - id: lotus-worker binary: lotus-worker + builder: prebuilt goos: - darwin + - linux goarch: - amd64 - env: - - CGO_ENABLED=1 - - FFI_BUILD_FROM_SOURCE=1 - ldflags: - - -X=github.com/filecoin-project/lotus/build.CurrentCommit=+git.{{.ShortCommit}} - - id: lotus_darwin_arm64 - main: ./cmd/lotus - binary: lotus - goos: - - darwin - goarch: - arm64 - env: - - CGO_ENABLED=1 - - FFI_BUILD_FROM_SOURCE=1 - - CPATH=/opt/homebrew/include - - LIBRARY_PATH=/opt/homebrew/lib - ldflags: - - -X=github.com/filecoin-project/lotus/build.CurrentCommit=+git.{{.ShortCommit}} - - id: lotus-miner_darwin_arm64 - main: ./cmd/lotus-miner - binary: lotus-miner - goos: - - darwin - goarch: - - arm64 - env: - - CGO_ENABLED=1 - - FFI_BUILD_FROM_SOURCE=1 - - CPATH=/opt/homebrew/include - - LIBRARY_PATH=/opt/homebrew/lib - ldflags: - - -X=github.com/filecoin-project/lotus/build.CurrentCommit=+git.{{.ShortCommit}} - - id: lotus-worker_darwin_arm64 - main: ./cmd/lotus-worker - binary: lotus-worker - goos: - - darwin - goarch: - - arm64 - env: - - CGO_ENABLED=1 - - FFI_BUILD_FROM_SOURCE=1 - - CPATH=/opt/homebrew/include - - LIBRARY_PATH=/opt/homebrew/lib - ldflags: - - -X=github.com/filecoin-project/lotus/build.CurrentCommit=+git.{{.ShortCommit}} -# - id: linux -# main: ./cmd/lotus -# binary: lotus -# goos: -# - linux -# goarch: -# - amd64 -# env: -# - CGO_ENABLED=1 -# ldflags: -# - -X=github.com/filecoin-project/lotus/build.CurrentCommit=+git.{{.ShortCommit}} + goamd64: + - v1 + ignore: + - goos: linux + goarch: arm64 + prebuilt: + path: /tmp/workspace/{{ .Os }}_{{ .Arch }}{{ with .Amd64 }}_{{ . }}{{ end }}/lotus-worker archives: - id: primary @@ -131,7 +77,6 @@ release: prerelease: auto name_template: "Release v{{.Version}}" - brews: - tap: owner: filecoin-project @@ -151,6 +96,7 @@ brews: homepage: "https://filecoin.io" description: "A homebrew cask for installing filecoin-project/lotus on MacOS" license: MIT + skip_upload: auto dependencies: - name: hwloc diff --git a/CHANGELOG.md b/CHANGELOG.md index 70445d597..9bca338c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,29 +1,30 @@ # Lotus changelog -# 1.18.0-rc5 / 2022-11-1 +# 1.18.0 / 2022-11-15 > ⚠️ **Please note that from Lotus v1.17.2&^ will require a Go-version of v1.18.1&^** -This is the fifth release canadiate of the upcoming MANDATORY release of Lotus that introduces [Filecoin network v17, +This is the final release of the upcoming MANDATORY release of Lotus that introduces [Filecoin network v17, codenamed the Shark upgrade](https://github.com/filecoin-project/community/discussions/74?sort=top#discussioncomment-3825422). Shark upgrade delivers a wave of protocol refinements that will allow for useful smart contracts to be written using the FVM (eg. programmable markets, lending contracts, etc.). -A full changelog will be published upon final release. +**The Filecoin mainnet is scheduled to upgrade to nv17 at epoch 2383680, on Nov 30th on 2022-11-30T14:00:00Z. All node operators, including storage providers, must upgrade to this release before that time. Storage providers must update their daemons, miners, market and worker(s)/boost.** -The Shark upgrade introduces the following FIPs, delivered in [actors v9](https://github.com/filecoin-project/specs-actors/releases/tag/v9.0.1): +The Shark upgrade introduces the following FIPs, delivered in [actors v9](https://github.com/filecoin-project/builtin-actors/releases/tag/v9.0.3): - [FIP0029 Beneficiary Address for Storage Providers](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0029.md): step towards better lending market for SP - [FIP0034 Fix PreCommit Deposit Independent of Sector Content](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0034.md): resolves a significant weakening of Filecoin PoRep’s security guarantees - - ❗Pre-commit deposit will be calculated as the 20-day projection of expected reward earned by a sector with a sector quality of 10 (i.e. full of verified deals), regardless of sector content. Leave the initial pledge value, due when the sector is proven, unchanged. + - ❗Pre-commit deposit will be calculated as the 20-day projection of expected reward earned by a sector with **a sector quality of 10 (i.e. full of verified deals)**, regardless of sector content. The Initial Pledge value, due when the sector is proven, is left **unchanged**. - [FIP0041 Forward Compatibility for PreCommit](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0041.md): enables a cleaner and easier transition to Programmable Storage Markets - [FIP0044 Standard Message Authentication](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0044.md): enable metadata authentication for user defined actor -- [FIP0045 Decoupling Fil+ from Marketplace](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0045.md): DataCap and the QAP it brings is now associated with DATA. DataCap for the data many have terms where anyone who cares about that piece of data may extend the term, which incentives SPs to store the data longer on the network - - HUGE step towards user programmable storage market - - ⭐️ First Fungible Token Contract - Datacap Actor, on Filecoin! ([fungible token standard](https://github.com/filecoin-project/FIPs/blob/master/FRCs/frc-0046.md), [token contract library](https://github.com/helix-onchain/filecoin/tree/5455f4f831e0f3f20005a9a789623d7ad6dada15/frc46_token)) - - -## Calibration-net Upgrade - -This release candidate sets the calibration-net upgrade at epoch 16800. The bundle the network will be using is [v9.0.3](https://github.com/filecoin-project/builtin-actors/releases/tag/v9.0.3)(located at `build/actors/v9.tar.zst` ). Upon the migration, the manifest CID should be `bafy2bzacedbedgynklc4dgpyxippkxmba2mgtw7ecntoneclsvvl4klqwuyyy`. - +- [FIP0045 Decoupling Fil+ from Marketplace](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0045.md): DataCap and the 10x QAP is now only associated with how long DATA is wanted to be stored on the network. + - This is a transitional state to enabling far more efficient and dynamic storage markets on Filecoin network in the future. + - ⭐️ First Fungible Token Contract - Datacap Actor, on Filecoin! ([fungible token standard](https://github.com/filecoin-project/FIPs/blob/master/FRCs/frc-0046.md), [token contract library](https://github.com/helix-onchain/filecoin/tree/5455f4f831e0f3f20005a9a789623d7ad6dada15/frc46_token)). + - For storage deal participants (clients and storage providers): + - `PublishStorageDeals`/`ProveCommit(Aggregate)`/`ProveReplicaUpdates` message that includes verified deals will see a gas usage increase, more details can be found [here](https://github.com/filecoin-project/FIPs/blob/385f069b3b146c5fef4fdc1109a0e2f35f399e48/FIPS/fip-0045.md?plain=1#L784) + - `Term` is introduced for defining how long the DataCap is assigned to a piece of data. Anyone who cares about that piece of data may extend the _term_, which incentives SPs to store the data longer on the network without a new deal/resealing. + - There is no more diluted verified deal QAP due to deal/sector space time for new sectors that contains verified deals after this upgrade. + - SPs may enjoy 90 days of extra QAP than deal duration by default, given `term_max` is always `deal duration + 90 days`. +❗ We highly recommend all lotus users, especially storage providers, developers and clients to read the FIPs in detail to understand the protocol changes and potential impact to network participants! + ## Snapshots The [#fil-infra](https://filecoinproject.slack.com/archives/C039RBG3RPC) team at PL has launched a brand new Lightweight Filecoin Chain Snapshots Service to support chain management needs for the node operators, check [here](https://www.notion.so/pl-strflt/Lightweight-Filecoin-Chain-Snapshots-17e4c386f35c44548f5863afb7b5e024) for the full detail. @@ -31,7 +32,34 @@ We are planning to switch [the snapshot service listed in lotus docs](https://lo ## Migration -(TBC) +We are expecting a heavier than normal state migration for this upgrade due to the amount of the state changes introduced. +All node operators, including storage providers, should be aware that two pre-migrations are being scheduled. The first pre-migration will begin at 2022-11-30T12:00:00Z (120 minutes before the real upgrade), the second pre-migration will begin at 2022-11-30T13:45:00Z (7.5 minutes before the real upgrade). +The first pre-migration will take up to 1.5hr, depending on the amount of the historical state in the node blockstore and the hardware specs the node is running on. During this time, expect slower block validation times, increased CPU and memory usage, and longer delays for API queries. +We recommend node operators (who haven't enbabled splistore `universal` mode) that do not care about historical chain states, to prune the chain blockstore by syncing from a snapshot 1-2 days before the upgrade. +Note to full archival node operators: you may expect a migration that takes up to 20 min upon the upgrade, during this period your node will fall out of sync and your chain service may have some disruption. However, you can expect the node to catch up soon after the migration completes. + +### v9 Built-in actor bundles + +Bundles for all networks(mainnet, calibnet, and etc) are included in the lotus source tree (`build/actors/`) and embedded on build, for v9 actors you can find it [here](https://github.com/filecoin-project/lotus/blob/master/build/actors/v9.tar.zst). +Reminder: Lotus verifies that the bundle CIDs are the right ones upon build & upgrade against the values in `build/builtin_actors_gen.go`, according to the network you are building. You may also check the bundle manifest CID matches the bundle gen-ed values by running `lotus state actor-cids --network-version 17`. + +The manifest CID & full list of actor code CIDs for nv17 using [actor v9](https://github.com/filecoin-project/builtin-actors/releases/tag/v9.0.3) is: + +``` +"_manifest": "bafy2bzaceb6j6666h36xnhksu3ww4kxb6e25niayfgkdnifaqi6m6ooc66i6i" +"account": "bafk2bzacect2p7urje3pylrrrjy3tngn6yaih4gtzauuatf2jllk3ksgfiw2y" +"cron": "bafk2bzacebcec3lffmos3nawm5cvwehssxeqwxixoyyfvejy7viszzsxzyu26" +"datacap": "bafk2bzacebb6uy2ys7tapekmtj7apnjg7oyj4ia5t7tlkvbmwtxwv74lb2pug" +"init": "bafk2bzacebtdq4zyuxk2fzbdkva6kc4mx75mkbfmldplfntayhbl5wkqou33i" +"multisig": "bafk2bzacec4va3nmugyqjqrs3lqyr2ij67jhjia5frvx7omnh2isha6abxzya" +"paymentchannel": "bafk2bzacebhdvjbjcgupklddfavzef4e4gnkt3xk3rbmgfmk7xhecszhfxeds" +"reward": "bafk2bzacebezgbbmcm2gbcqwisus5fjvpj7hhmu5ubd37phuku3hmkfulxm2o" +"storagemarket": "bafk2bzacec3j7p6gklk64stax5px3xxd7hdtejaepnd4nw7s2adihde6emkcu" +"storageminer": "bafk2bzacedyux5hlrildwutvvjdcsvjtwsoc5xnqdjl73ouiukgklekeuyfl4" +"storagepower": "bafk2bzacedsetphfajgne4qy3vdrpyd6ekcmtfs2zkjut4r34cvnuoqemdrtw" +"system": "bafk2bzaceagvlo2jtahj7dloshrmwfulrd6e2izqev32qm46eumf754weec6c" +"verifiedregistry": "bafk2bzacecf3yodlyudzukumehbuabgqljyhjt5ifiv4vetcfohnvsxzynwga" +``` ## New Features - Integrate actor v9: @@ -61,7 +89,6 @@ We are planning to switch [the snapshot service listed in lotus docs](https://lo - github.com/filecoin-project/go-jsonrpc (v0.1.7 -> v0.1.8) - github.com/filecoin-project/go-state-types (v0.1.12-beta -> v0.9.0): - ## Others - fix: upgrade: no splash banner for nv17 :( ([filecoin-project/lotus#9486](https://github.com/filecoin-project/lotus/pull/9486)) - chore: build: add calib upgrade param for shark ([filecoin-project/lotus#9483](https://github.com/filecoin-project/lotus/pull/9483)) @@ -70,22 +97,35 @@ We are planning to switch [the snapshot service listed in lotus docs](https://lo - Delete lotus-pond (#9352) ([filecoin-project/lotus#9352](https://github.com/filecoin-project/lotus/pull/9352)) - build: set version to v1.18.0-dev +## lotus-market EOL notice + +As mentioned in [lotus v1.17.0 release notes](https://github.com/filecoin-project/lotus/releases/tag/v1.17.0), markets related features, enhancements and fixes is now lower priority for Lotus. We recommend our users to migrate to other deal making focused software, like [boost](https://boost.filecoin.io/) as soon as possible. That being said, the lotus maintainers will be: +- Lotus maintainers will stop supporting lotus-market subcomponent/**storage** deal making related issues or enhancements on Jan 31, 2023. +- In Q2 2023, we will be deprecating/removing lotus-market related code from this repository. +If you have any questions or concerns, please raise them in [Lotus discussion](https://github.com/filecoin-project/lotus/discussions/categories/market)! + + ## Contributors | Contributor | Commits | Lines ± | Files Changed | |-------------|---------|---------|---------------| -| Geoff Stuart | 51 | +8677/-19320 | 401 | -| Aayush Rajasekaran | 5 | +1452/-166 | 34 | -| Łukasz Magiera | 5 | +429/-135 | 45 | -| Aayush | 19 | +281/-157 | 72 | -| Shrenuj Bansal | 3 | +176/-61 | 10 | -| Jennifer Wang | 7 | +19/-18 | 15 | -| simlecode | 1 | +5/-5 | 4 | +| @geoff-vball | 73 | +14533/-19712 | 509 | +| @arajasek | 16 | +2230/-303 | 49 | +| @arajasek | 29 | +701/-297 | 117 | +| @magik6k | 5 | +429/-135 | 45 | +| @Frrist | 1 | +246/-203 | 25 | +| @stebalien | 2 | +323/-2 | 6 | +| @shrenujbansal | 3 | +176/-61 | 10 | +| @ZenGround0 | 2 | +78/-38 | 5 | +| @jennijuju | 8 | +97/-18 | 16 | +| @simlecode | 5 | +18/-9 | 11 | | Kevin Li | 1 | +7/-0 | 1 | +| @zenground0 | 2 | +3/-3 | 3 | +| @jennijuju | 1 | +3/-3 | 2 | | Rod Vagg | 1 | +3/-2 | 2 | +| @jennijuju | 1 | +2/-2 | 2 | | Peter Rabbitson | 1 | +3/-0 | 1 | -| ZenGround0 | 1 | +2/-0 | 1 | - +| Jakub Sztandera | 1 | +1/-1 | 1 | # v1.17.2 / 2022-10-05 diff --git a/Dockerfile.lotus b/Dockerfile.lotus index 2f139a3c4..7037a5813 100644 --- a/Dockerfile.lotus +++ b/Dockerfile.lotus @@ -3,28 +3,43 @@ MAINTAINER Lotus Development Team RUN apt-get update && apt-get install -y ca-certificates build-essential clang ocl-icd-opencl-dev ocl-icd-libopencl1 jq libhwloc-dev -ARG RUST_VERSION=nightly ENV XDG_CACHE_HOME="/tmp" +### taken from https://github.com/rust-lang/docker-rust/blob/master/1.63.0/buster/Dockerfile ENV RUSTUP_HOME=/usr/local/rustup \ CARGO_HOME=/usr/local/cargo \ - PATH=/usr/local/cargo/bin:$PATH + PATH=/usr/local/cargo/bin:$PATH \ + RUST_VERSION=1.63.0 -RUN wget "https://static.rust-lang.org/rustup/dist/x86_64-unknown-linux-gnu/rustup-init"; \ +RUN set -eux; \ + dpkgArch="$(dpkg --print-architecture)"; \ + case "${dpkgArch##*-}" in \ + amd64) rustArch='x86_64-unknown-linux-gnu'; rustupSha256='5cc9ffd1026e82e7fb2eec2121ad71f4b0f044e88bca39207b3f6b769aaa799c' ;; \ + arm64) rustArch='aarch64-unknown-linux-gnu'; rustupSha256='e189948e396d47254103a49c987e7fb0e5dd8e34b200aa4481ecc4b8e41fb929' ;; \ + *) echo >&2 "unsupported architecture: ${dpkgArch}"; exit 1 ;; \ + esac; \ + url="https://static.rust-lang.org/rustup/archive/1.25.1/${rustArch}/rustup-init"; \ + wget "$url"; \ + echo "${rustupSha256} *rustup-init" | sha256sum -c -; \ chmod +x rustup-init; \ - ./rustup-init -y --no-modify-path --profile minimal --default-toolchain $RUST_VERSION; \ + ./rustup-init -y --no-modify-path --profile minimal --default-toolchain $RUST_VERSION --default-host ${rustArch}; \ rm rustup-init; \ chmod -R a+w $RUSTUP_HOME $CARGO_HOME; \ rustup --version; \ cargo --version; \ rustc --version; - +### end rust FROM builder-deps AS builder-local MAINTAINER Lotus Development Team COPY ./ /opt/filecoin WORKDIR /opt/filecoin + +### make configurable filecoin-ffi build +ARG FFI_BUILD_FROM_SOURCE=0 +ENV FFI_BUILD_FROM_SOURCE=${FFI_BUILD_FROM_SOURCE} + RUN make clean deps @@ -52,14 +67,14 @@ MAINTAINER Lotus Development Team # Base resources COPY --from=builder /etc/ssl/certs /etc/ssl/certs -COPY --from=builder /lib/x86_64-linux-gnu/libdl.so.2 /lib/ -COPY --from=builder /lib/x86_64-linux-gnu/librt.so.1 /lib/ -COPY --from=builder /lib/x86_64-linux-gnu/libgcc_s.so.1 /lib/ -COPY --from=builder /lib/x86_64-linux-gnu/libutil.so.1 /lib/ -COPY --from=builder /usr/lib/x86_64-linux-gnu/libltdl.so.7 /lib/ -COPY --from=builder /usr/lib/x86_64-linux-gnu/libnuma.so.1 /lib/ -COPY --from=builder /usr/lib/x86_64-linux-gnu/libhwloc.so.5 /lib/ -COPY --from=builder /usr/lib/x86_64-linux-gnu/libOpenCL.so.1 /lib/ +COPY --from=builder /lib/*/libdl.so.2 /lib/ +COPY --from=builder /lib/*/librt.so.1 /lib/ +COPY --from=builder /lib/*/libgcc_s.so.1 /lib/ +COPY --from=builder /lib/*/libutil.so.1 /lib/ +COPY --from=builder /usr/lib/*/libltdl.so.7 /lib/ +COPY --from=builder /usr/lib/*/libnuma.so.1 /lib/ +COPY --from=builder /usr/lib/*/libhwloc.so.5 /lib/ +COPY --from=builder /usr/lib/*/libOpenCL.so.1 /lib/ RUN useradd -r -u 532 -U fc \ && mkdir -p /etc/OpenCL/vendors \ diff --git a/api/api_full.go b/api/api_full.go index 320a20687..0c281c12d 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -6,6 +6,7 @@ import ( "fmt" "time" + "github.com/google/uuid" blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" "github.com/libp2p/go-libp2p/core/peer" @@ -763,6 +764,9 @@ type FullNode interface { // LOTUS_BACKUP_BASE_PATH environment variable set to some path, and that // the path specified when calling CreateBackup is within the base path CreateBackup(ctx context.Context, fpath string) error //perm:admin + + RaftState(ctx context.Context) (*RaftStateData, error) //perm:read + RaftLeader(ctx context.Context) (peer.ID, error) //perm:read } type StorageAsk struct { @@ -1012,8 +1016,12 @@ type RetrievalOrder struct { Client address.Address Miner address.Address MinerPeer *retrievalmarket.RetrievalPeer + + RemoteStore *RemoteStoreID `json:"RemoteStore,omitempty"` } +type RemoteStoreID = uuid.UUID + type InvocResult struct { MsgCid cid.Cid Msg *types.Message diff --git a/api/api_storage.go b/api/api_storage.go index 100be5cca..9a6eeb230 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -320,7 +320,7 @@ type StorageMiner interface { // the path specified when calling CreateBackup is within the base path CreateBackup(ctx context.Context, fpath string) error //perm:admin - CheckProvable(ctx context.Context, pp abi.RegisteredPoStProof, sectors []storiface.SectorRef, expensive bool) (map[abi.SectorNumber]string, error) //perm:admin + CheckProvable(ctx context.Context, pp abi.RegisteredPoStProof, sectors []storiface.SectorRef) (map[abi.SectorNumber]string, error) //perm:admin ComputeProof(ctx context.Context, ssi []builtin.ExtendedSectorInfo, rand abi.PoStRandomness, poStEpoch abi.ChainEpoch, nv abinetwork.Version) ([]builtin.PoStProof, error) //perm:read diff --git a/api/docgen/docgen.go b/api/docgen/docgen.go index 5bddef2ec..96fc068cc 100644 --- a/api/docgen/docgen.go +++ b/api/docgen/docgen.go @@ -349,6 +349,10 @@ func init() { addExample(map[string]bitfield.BitField{ "": bitfield.NewFromSet([]uint64{5, 6, 7, 10}), }) + addExample(&api.RaftStateData{ + NonceMap: make(map[address.Address]uint64), + MsgUuids: make(map[uuid.UUID]*types.SignedMessage), + }) addExample(http.Header{ "Authorization": []string{"Bearer ey.."}, @@ -361,6 +365,7 @@ func init() { Headers: nil, }, }) + addExample(&uuid.UUID{}) } func GetAPIType(name, pkg string) (i interface{}, t reflect.Type, permStruct []reflect.Type) { diff --git a/api/mocks/mock_full.go b/api/mocks/mock_full.go index f6ab05def..b5bf2bfea 100644 --- a/api/mocks/mock_full.go +++ b/api/mocks/mock_full.go @@ -2244,6 +2244,36 @@ func (mr *MockFullNodeMockRecorder) PaychVoucherSubmit(arg0, arg1, arg2, arg3, a return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychVoucherSubmit", reflect.TypeOf((*MockFullNode)(nil).PaychVoucherSubmit), arg0, arg1, arg2, arg3, arg4) } +// RaftLeader mocks base method. +func (m *MockFullNode) RaftLeader(arg0 context.Context) (peer.ID, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RaftLeader", arg0) + ret0, _ := ret[0].(peer.ID) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// RaftLeader indicates an expected call of RaftLeader. +func (mr *MockFullNodeMockRecorder) RaftLeader(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RaftLeader", reflect.TypeOf((*MockFullNode)(nil).RaftLeader), arg0) +} + +// RaftState mocks base method. +func (m *MockFullNode) RaftState(arg0 context.Context) (*api.RaftStateData, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RaftState", arg0) + ret0, _ := ret[0].(*api.RaftStateData) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// RaftState indicates an expected call of RaftState. +func (mr *MockFullNodeMockRecorder) RaftState(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RaftState", reflect.TypeOf((*MockFullNode)(nil).RaftState), arg0) +} + // Session mocks base method. func (m *MockFullNode) Session(arg0 context.Context) (uuid.UUID, error) { m.ctrl.T.Helper() diff --git a/api/proxy_gen.go b/api/proxy_gen.go index 54bc766b8..0631a22bd 100644 --- a/api/proxy_gen.go +++ b/api/proxy_gen.go @@ -342,6 +342,10 @@ type FullNodeStruct struct { PaychVoucherSubmit func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (cid.Cid, error) `perm:"sign"` + RaftLeader func(p0 context.Context) (peer.ID, error) `perm:"read"` + + RaftState func(p0 context.Context) (*RaftStateData, error) `perm:"read"` + StateAccountKey func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `perm:"read"` StateActorCodeCIDs func(p0 context.Context, p1 abinetwork.Version) (map[string]cid.Cid, error) `perm:"read"` @@ -679,7 +683,7 @@ type StorageMinerStruct struct { BeneficiaryWithdrawBalance func(p0 context.Context, p1 abi.TokenAmount) (cid.Cid, error) `perm:"admin"` - CheckProvable func(p0 context.Context, p1 abi.RegisteredPoStProof, p2 []storiface.SectorRef, p3 bool) (map[abi.SectorNumber]string, error) `perm:"admin"` + CheckProvable func(p0 context.Context, p1 abi.RegisteredPoStProof, p2 []storiface.SectorRef) (map[abi.SectorNumber]string, error) `perm:"admin"` ComputeDataCid func(p0 context.Context, p1 abi.UnpaddedPieceSize, p2 storiface.Data) (abi.PieceInfo, error) `perm:"admin"` @@ -2473,6 +2477,28 @@ func (s *FullNodeStub) PaychVoucherSubmit(p0 context.Context, p1 address.Address return *new(cid.Cid), ErrNotSupported } +func (s *FullNodeStruct) RaftLeader(p0 context.Context) (peer.ID, error) { + if s.Internal.RaftLeader == nil { + return *new(peer.ID), ErrNotSupported + } + return s.Internal.RaftLeader(p0) +} + +func (s *FullNodeStub) RaftLeader(p0 context.Context) (peer.ID, error) { + return *new(peer.ID), ErrNotSupported +} + +func (s *FullNodeStruct) RaftState(p0 context.Context) (*RaftStateData, error) { + if s.Internal.RaftState == nil { + return nil, ErrNotSupported + } + return s.Internal.RaftState(p0) +} + +func (s *FullNodeStub) RaftState(p0 context.Context) (*RaftStateData, error) { + return nil, ErrNotSupported +} + func (s *FullNodeStruct) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { if s.Internal.StateAccountKey == nil { return *new(address.Address), ErrNotSupported @@ -4134,14 +4160,14 @@ func (s *StorageMinerStub) BeneficiaryWithdrawBalance(p0 context.Context, p1 abi return *new(cid.Cid), ErrNotSupported } -func (s *StorageMinerStruct) CheckProvable(p0 context.Context, p1 abi.RegisteredPoStProof, p2 []storiface.SectorRef, p3 bool) (map[abi.SectorNumber]string, error) { +func (s *StorageMinerStruct) CheckProvable(p0 context.Context, p1 abi.RegisteredPoStProof, p2 []storiface.SectorRef) (map[abi.SectorNumber]string, error) { if s.Internal.CheckProvable == nil { return *new(map[abi.SectorNumber]string), ErrNotSupported } - return s.Internal.CheckProvable(p0, p1, p2, p3) + return s.Internal.CheckProvable(p0, p1, p2) } -func (s *StorageMinerStub) CheckProvable(p0 context.Context, p1 abi.RegisteredPoStProof, p2 []storiface.SectorRef, p3 bool) (map[abi.SectorNumber]string, error) { +func (s *StorageMinerStub) CheckProvable(p0 context.Context, p1 abi.RegisteredPoStProof, p2 []storiface.SectorRef) (map[abi.SectorNumber]string, error) { return *new(map[abi.SectorNumber]string), ErrNotSupported } diff --git a/api/types.go b/api/types.go index 0de44549f..5cbe0edef 100644 --- a/api/types.go +++ b/api/types.go @@ -59,6 +59,11 @@ type MessageSendSpec struct { MsgUuid uuid.UUID } +type MpoolMessageWhole struct { + Msg *types.Message + Spec *MessageSendSpec +} + // GraphSyncDataTransfer provides diagnostics on a data transfer happening over graphsync type GraphSyncDataTransfer struct { // GraphSync request id for this transfer @@ -334,3 +339,61 @@ type ForkUpgradeParams struct { UpgradeSkyrHeight abi.ChainEpoch UpgradeSharkHeight abi.ChainEpoch } + +type NonceMapType map[address.Address]uint64 +type MsgUuidMapType map[uuid.UUID]*types.SignedMessage + +type RaftStateData struct { + NonceMap NonceMapType + MsgUuids MsgUuidMapType +} + +func (n *NonceMapType) MarshalJSON() ([]byte, error) { + marshalled := make(map[string]uint64) + for a, n := range *n { + marshalled[a.String()] = n + } + return json.Marshal(marshalled) +} + +func (n *NonceMapType) UnmarshalJSON(b []byte) error { + unmarshalled := make(map[string]uint64) + err := json.Unmarshal(b, &unmarshalled) + if err != nil { + return err + } + *n = make(map[address.Address]uint64) + for saddr, nonce := range unmarshalled { + a, err := address.NewFromString(saddr) + if err != nil { + return err + } + (*n)[a] = nonce + } + return nil +} + +func (m *MsgUuidMapType) MarshalJSON() ([]byte, error) { + marshalled := make(map[string]*types.SignedMessage) + for u, msg := range *m { + marshalled[u.String()] = msg + } + return json.Marshal(marshalled) +} + +func (m *MsgUuidMapType) UnmarshalJSON(b []byte) error { + unmarshalled := make(map[string]*types.SignedMessage) + err := json.Unmarshal(b, &unmarshalled) + if err != nil { + return err + } + *m = make(map[uuid.UUID]*types.SignedMessage) + for suid, msg := range unmarshalled { + u, err := uuid.Parse(suid) + if err != nil { + return err + } + (*m)[u] = msg + } + return nil +} diff --git a/blockstore/cbor_gen.go b/blockstore/cbor_gen.go new file mode 100644 index 000000000..b8ebdb474 --- /dev/null +++ b/blockstore/cbor_gen.go @@ -0,0 +1,441 @@ +// Code generated by github.com/whyrusleeping/cbor-gen. DO NOT EDIT. + +package blockstore + +import ( + "fmt" + "io" + "math" + "sort" + + cid "github.com/ipfs/go-cid" + cbg "github.com/whyrusleeping/cbor-gen" + xerrors "golang.org/x/xerrors" +) + +var _ = xerrors.Errorf +var _ = cid.Undef +var _ = math.E +var _ = sort.Sort + +var lengthBufNetRpcReq = []byte{132} + +func (t *NetRpcReq) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + + if _, err := cw.Write(lengthBufNetRpcReq); err != nil { + return err + } + + // t.Type (blockstore.NetRPCReqType) (uint8) + if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.Type)); err != nil { + return err + } + + // t.ID (uint64) (uint64) + + if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.ID)); err != nil { + return err + } + + // t.Cid ([]cid.Cid) (slice) + if len(t.Cid) > cbg.MaxLength { + return xerrors.Errorf("Slice value in field t.Cid was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.Cid))); err != nil { + return err + } + for _, v := range t.Cid { + if err := cbg.WriteCid(w, v); err != nil { + return xerrors.Errorf("failed writing cid field t.Cid: %w", err) + } + } + + // t.Data ([][]uint8) (slice) + if len(t.Data) > cbg.MaxLength { + return xerrors.Errorf("Slice value in field t.Data was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.Data))); err != nil { + return err + } + for _, v := range t.Data { + if len(v) > cbg.ByteArrayMaxLen { + return xerrors.Errorf("Byte array in field v was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajByteString, uint64(len(v))); err != nil { + return err + } + + if _, err := cw.Write(v[:]); err != nil { + return err + } + } + return nil +} + +func (t *NetRpcReq) UnmarshalCBOR(r io.Reader) (err error) { + *t = NetRpcReq{} + + cr := cbg.NewCborReader(r) + + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + + if maj != cbg.MajArray { + return fmt.Errorf("cbor input should be of type array") + } + + if extra != 4 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + // t.Type (blockstore.NetRPCReqType) (uint8) + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint8 field") + } + if extra > math.MaxUint8 { + return fmt.Errorf("integer in input was too large for uint8 field") + } + t.Type = NetRPCReqType(extra) + // t.ID (uint64) (uint64) + + { + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.ID = uint64(extra) + + } + // t.Cid ([]cid.Cid) (slice) + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > cbg.MaxLength { + return fmt.Errorf("t.Cid: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + + if extra > 0 { + t.Cid = make([]cid.Cid, extra) + } + + for i := 0; i < int(extra); i++ { + + c, err := cbg.ReadCid(cr) + if err != nil { + return xerrors.Errorf("reading cid field t.Cid failed: %w", err) + } + t.Cid[i] = c + } + + // t.Data ([][]uint8) (slice) + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > cbg.MaxLength { + return fmt.Errorf("t.Data: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + + if extra > 0 { + t.Data = make([][]uint8, extra) + } + + for i := 0; i < int(extra); i++ { + { + var maj byte + var extra uint64 + var err error + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > cbg.ByteArrayMaxLen { + return fmt.Errorf("t.Data[i]: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + + if extra > 0 { + t.Data[i] = make([]uint8, extra) + } + + if _, err := io.ReadFull(cr, t.Data[i][:]); err != nil { + return err + } + } + } + + return nil +} + +var lengthBufNetRpcResp = []byte{131} + +func (t *NetRpcResp) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + + if _, err := cw.Write(lengthBufNetRpcResp); err != nil { + return err + } + + // t.Type (blockstore.NetRPCRespType) (uint8) + if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.Type)); err != nil { + return err + } + + // t.ID (uint64) (uint64) + + if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.ID)); err != nil { + return err + } + + // t.Data ([]uint8) (slice) + if len(t.Data) > cbg.ByteArrayMaxLen { + return xerrors.Errorf("Byte array in field t.Data was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajByteString, uint64(len(t.Data))); err != nil { + return err + } + + if _, err := cw.Write(t.Data[:]); err != nil { + return err + } + return nil +} + +func (t *NetRpcResp) UnmarshalCBOR(r io.Reader) (err error) { + *t = NetRpcResp{} + + cr := cbg.NewCborReader(r) + + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + + if maj != cbg.MajArray { + return fmt.Errorf("cbor input should be of type array") + } + + if extra != 3 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + // t.Type (blockstore.NetRPCRespType) (uint8) + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint8 field") + } + if extra > math.MaxUint8 { + return fmt.Errorf("integer in input was too large for uint8 field") + } + t.Type = NetRPCRespType(extra) + // t.ID (uint64) (uint64) + + { + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.ID = uint64(extra) + + } + // t.Data ([]uint8) (slice) + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > cbg.ByteArrayMaxLen { + return fmt.Errorf("t.Data: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + + if extra > 0 { + t.Data = make([]uint8, extra) + } + + if _, err := io.ReadFull(cr, t.Data[:]); err != nil { + return err + } + return nil +} + +var lengthBufNetRpcErr = []byte{131} + +func (t *NetRpcErr) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + + if _, err := cw.Write(lengthBufNetRpcErr); err != nil { + return err + } + + // t.Type (blockstore.NetRPCErrType) (uint8) + if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.Type)); err != nil { + return err + } + + // t.Msg (string) (string) + if len(t.Msg) > cbg.MaxLength { + return xerrors.Errorf("Value in field t.Msg was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Msg))); err != nil { + return err + } + if _, err := io.WriteString(w, string(t.Msg)); err != nil { + return err + } + + // t.Cid (cid.Cid) (struct) + + if t.Cid == nil { + if _, err := cw.Write(cbg.CborNull); err != nil { + return err + } + } else { + if err := cbg.WriteCid(cw, *t.Cid); err != nil { + return xerrors.Errorf("failed to write cid field t.Cid: %w", err) + } + } + + return nil +} + +func (t *NetRpcErr) UnmarshalCBOR(r io.Reader) (err error) { + *t = NetRpcErr{} + + cr := cbg.NewCborReader(r) + + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + + if maj != cbg.MajArray { + return fmt.Errorf("cbor input should be of type array") + } + + if extra != 3 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + // t.Type (blockstore.NetRPCErrType) (uint8) + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint8 field") + } + if extra > math.MaxUint8 { + return fmt.Errorf("integer in input was too large for uint8 field") + } + t.Type = NetRPCErrType(extra) + // t.Msg (string) (string) + + { + sval, err := cbg.ReadString(cr) + if err != nil { + return err + } + + t.Msg = string(sval) + } + // t.Cid (cid.Cid) (struct) + + { + + b, err := cr.ReadByte() + if err != nil { + return err + } + if b != cbg.CborNull[0] { + if err := cr.UnreadByte(); err != nil { + return err + } + + c, err := cbg.ReadCid(cr) + if err != nil { + return xerrors.Errorf("failed to read cid field t.Cid: %w", err) + } + + t.Cid = &c + } + + } + return nil +} diff --git a/blockstore/net.go b/blockstore/net.go new file mode 100644 index 000000000..77da764a5 --- /dev/null +++ b/blockstore/net.go @@ -0,0 +1,424 @@ +package blockstore + +import ( + "bytes" + "context" + "encoding/binary" + "fmt" + "sync" + "sync/atomic" + + blocks "github.com/ipfs/go-block-format" + "github.com/ipfs/go-cid" + ipld "github.com/ipfs/go-ipld-format" + "github.com/libp2p/go-msgio" + cbg "github.com/whyrusleeping/cbor-gen" + "golang.org/x/xerrors" +) + +type NetRPCReqType byte + +const ( + NRpcHas NetRPCReqType = iota + NRpcGet + NRpcGetSize + NRpcPut + NRpcDelete + + // todo cancel req +) + +type NetRPCRespType byte + +const ( + NRpcOK NetRPCRespType = iota + NRpcErr + NRpcMore +) + +type NetRPCErrType byte + +const ( + NRpcErrGeneric NetRPCErrType = iota + NRpcErrNotFound +) + +type NetRpcReq struct { + Type NetRPCReqType + ID uint64 + + Cid []cid.Cid // todo maxsize? + Data [][]byte // todo maxsize? +} + +type NetRpcResp struct { + Type NetRPCRespType + ID uint64 + + // error or cids in allkeys + Data []byte // todo maxsize? + + next <-chan NetRpcResp +} + +type NetRpcErr struct { + Type NetRPCErrType + + Msg string + + // in case of NRpcErrNotFound + Cid *cid.Cid +} + +type NetworkStore struct { + // note: writer is thread-safe + msgStream msgio.ReadWriteCloser + + // atomic + reqCount uint64 + + respLk sync.Mutex + + // respMap is nil after store closes + respMap map[uint64]chan<- NetRpcResp + + closing chan struct{} + closed chan struct{} + + closeLk sync.Mutex + onClose []func() +} + +func NewNetworkStore(mss msgio.ReadWriteCloser) *NetworkStore { + ns := &NetworkStore{ + msgStream: mss, + + respMap: map[uint64]chan<- NetRpcResp{}, + + closing: make(chan struct{}), + closed: make(chan struct{}), + } + + go ns.receive() + + return ns +} + +func (n *NetworkStore) shutdown(msg string) { + if err := n.msgStream.Close(); err != nil { + log.Errorw("closing netstore msg stream", "error", err) + } + + nerr := NetRpcErr{ + Type: NRpcErrGeneric, + Msg: msg, + Cid: nil, + } + + var errb bytes.Buffer + if err := nerr.MarshalCBOR(&errb); err != nil { + log.Errorw("netstore shutdown: error marshaling error", "err", err) + } + + n.respLk.Lock() + for id, resps := range n.respMap { + resps <- NetRpcResp{ + Type: NRpcErr, + ID: id, + Data: errb.Bytes(), + } + } + + n.respMap = nil + + n.respLk.Unlock() +} + +func (n *NetworkStore) OnClose(cb func()) { + n.closeLk.Lock() + defer n.closeLk.Unlock() + + select { + case <-n.closed: + cb() + default: + n.onClose = append(n.onClose, cb) + } +} + +func (n *NetworkStore) receive() { + defer func() { + n.closeLk.Lock() + defer n.closeLk.Unlock() + + close(n.closed) + if n.onClose != nil { + for _, f := range n.onClose { + f() + } + } + }() + + for { + select { + case <-n.closing: + n.shutdown("netstore stopping") + return + default: + } + + msg, err := n.msgStream.ReadMsg() + if err != nil { + n.shutdown(fmt.Sprintf("netstore ReadMsg: %s", err)) + return + } + + var resp NetRpcResp + if err := resp.UnmarshalCBOR(bytes.NewReader(msg)); err != nil { + n.shutdown(fmt.Sprintf("unmarshaling netstore response: %s", err)) + return + } + + n.msgStream.ReleaseMsg(msg) + + n.respLk.Lock() + if ch, ok := n.respMap[resp.ID]; ok { + if resp.Type == NRpcMore { + nch := make(chan NetRpcResp, 1) + resp.next = nch + n.respMap[resp.ID] = nch + } else { + delete(n.respMap, resp.ID) + } + + ch <- resp + } + n.respLk.Unlock() + } +} + +func (n *NetworkStore) sendRpc(rt NetRPCReqType, cids []cid.Cid, data [][]byte) (uint64, <-chan NetRpcResp, error) { + rid := atomic.AddUint64(&n.reqCount, 1) + + respCh := make(chan NetRpcResp, 1) // todo pool? + + n.respLk.Lock() + if n.respMap == nil { + n.respLk.Unlock() + return 0, nil, xerrors.Errorf("netstore closed") + } + n.respMap[rid] = respCh + n.respLk.Unlock() + + req := NetRpcReq{ + Type: rt, + ID: rid, + Cid: cids, + Data: data, + } + + var rbuf bytes.Buffer // todo buffer pool + if err := req.MarshalCBOR(&rbuf); err != nil { + n.respLk.Lock() + defer n.respLk.Unlock() + + if n.respMap == nil { + return 0, nil, xerrors.Errorf("netstore closed") + } + delete(n.respMap, rid) + + return 0, nil, err + } + + if err := n.msgStream.WriteMsg(rbuf.Bytes()); err != nil { + n.respLk.Lock() + defer n.respLk.Unlock() + + if n.respMap == nil { + return 0, nil, xerrors.Errorf("netstore closed") + } + delete(n.respMap, rid) + + return 0, nil, err + } + + return rid, respCh, nil +} + +func (n *NetworkStore) waitResp(ctx context.Context, rch <-chan NetRpcResp, rid uint64) (NetRpcResp, error) { + select { + case resp := <-rch: + if resp.Type == NRpcErr { + var e NetRpcErr + if err := e.UnmarshalCBOR(bytes.NewReader(resp.Data)); err != nil { + return NetRpcResp{}, xerrors.Errorf("unmarshaling error data: %w", err) + } + + var err error + switch e.Type { + case NRpcErrNotFound: + if e.Cid != nil { + err = ipld.ErrNotFound{ + Cid: *e.Cid, + } + } else { + err = xerrors.Errorf("block not found, but cid was null") + } + case NRpcErrGeneric: + err = xerrors.Errorf("generic error") + default: + err = xerrors.Errorf("unknown error type") + } + + return NetRpcResp{}, xerrors.Errorf("netstore error response: %s (%w)", e.Msg, err) + } + + return resp, nil + case <-ctx.Done(): + // todo send cancel req + + n.respLk.Lock() + if n.respMap != nil { + delete(n.respMap, rid) + } + n.respLk.Unlock() + + return NetRpcResp{}, ctx.Err() + } +} + +func (n *NetworkStore) Has(ctx context.Context, c cid.Cid) (bool, error) { + req, rch, err := n.sendRpc(NRpcHas, []cid.Cid{c}, nil) + if err != nil { + return false, err + } + + resp, err := n.waitResp(ctx, rch, req) + if err != nil { + return false, err + } + + if len(resp.Data) != 1 { + return false, xerrors.Errorf("expected reposnse length to be 1 byte") + } + switch resp.Data[0] { + case cbg.CborBoolTrue[0]: + return true, nil + case cbg.CborBoolFalse[0]: + return false, nil + default: + return false, xerrors.Errorf("has: bad response: %x", resp.Data[0]) + } +} + +func (n *NetworkStore) Get(ctx context.Context, c cid.Cid) (blocks.Block, error) { + req, rch, err := n.sendRpc(NRpcGet, []cid.Cid{c}, nil) + if err != nil { + return nil, err + } + + resp, err := n.waitResp(ctx, rch, req) + if err != nil { + return nil, err + } + + return blocks.NewBlockWithCid(resp.Data, c) +} + +func (n *NetworkStore) View(ctx context.Context, c cid.Cid, callback func([]byte) error) error { + req, rch, err := n.sendRpc(NRpcGet, []cid.Cid{c}, nil) + if err != nil { + return err + } + + resp, err := n.waitResp(ctx, rch, req) + if err != nil { + return err + } + + return callback(resp.Data) // todo return buf to pool +} + +func (n *NetworkStore) GetSize(ctx context.Context, c cid.Cid) (int, error) { + req, rch, err := n.sendRpc(NRpcGetSize, []cid.Cid{c}, nil) + if err != nil { + return 0, err + } + + resp, err := n.waitResp(ctx, rch, req) + if err != nil { + return 0, err + } + + if len(resp.Data) != 4 { + return 0, xerrors.Errorf("expected getsize response to be 4 bytes, was %d", resp.Data) + } + + return int(binary.LittleEndian.Uint32(resp.Data)), nil +} + +func (n *NetworkStore) Put(ctx context.Context, block blocks.Block) error { + return n.PutMany(ctx, []blocks.Block{block}) +} + +func (n *NetworkStore) PutMany(ctx context.Context, blocks []blocks.Block) error { + // todo pool + cids := make([]cid.Cid, len(blocks)) + blkDatas := make([][]byte, len(blocks)) + for i, block := range blocks { + cids[i] = block.Cid() + blkDatas[i] = block.RawData() + } + + req, rch, err := n.sendRpc(NRpcPut, cids, blkDatas) + if err != nil { + return err + } + + _, err = n.waitResp(ctx, rch, req) + if err != nil { + return err + } + + return nil +} + +func (n *NetworkStore) DeleteBlock(ctx context.Context, c cid.Cid) error { + return n.DeleteMany(ctx, []cid.Cid{c}) +} + +func (n *NetworkStore) DeleteMany(ctx context.Context, cids []cid.Cid) error { + req, rch, err := n.sendRpc(NRpcDelete, cids, nil) + if err != nil { + return err + } + + _, err = n.waitResp(ctx, rch, req) + if err != nil { + return err + } + + return nil +} + +func (n *NetworkStore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) { + return nil, xerrors.Errorf("not supported") +} + +func (n *NetworkStore) HashOnRead(enabled bool) { + // todo + return +} + +func (n *NetworkStore) Stop(ctx context.Context) error { + close(n.closing) + + select { + case <-n.closed: + return nil + case <-ctx.Done(): + return ctx.Err() + } +} + +var _ Blockstore = &NetworkStore{} diff --git a/blockstore/net_serve.go b/blockstore/net_serve.go new file mode 100644 index 000000000..2540c845e --- /dev/null +++ b/blockstore/net_serve.go @@ -0,0 +1,237 @@ +package blockstore + +import ( + "bytes" + "context" + "encoding/binary" + + block "github.com/ipfs/go-block-format" + "github.com/ipfs/go-cid" + ipld "github.com/ipfs/go-ipld-format" + "github.com/libp2p/go-msgio" + cbg "github.com/whyrusleeping/cbor-gen" + "golang.org/x/xerrors" +) + +type NetworkStoreHandler struct { + msgStream msgio.ReadWriteCloser + + bs Blockstore +} + +// NOTE: This code isn't yet hardened to accept untrusted input. See TODOs here and in net.go +func HandleNetBstoreStream(ctx context.Context, bs Blockstore, mss msgio.ReadWriteCloser) *NetworkStoreHandler { + ns := &NetworkStoreHandler{ + msgStream: mss, + bs: bs, + } + + go ns.handle(ctx) + + return ns +} + +func (h *NetworkStoreHandler) handle(ctx context.Context) { + defer func() { + if err := h.msgStream.Close(); err != nil { + log.Errorw("error closing blockstore stream", "error", err) + } + }() + + for { + var req NetRpcReq + + ms, err := h.msgStream.ReadMsg() + if err != nil { + log.Warnw("bstore stream err", "error", err) + return + } + + if err := req.UnmarshalCBOR(bytes.NewReader(ms)); err != nil { + return + } + + h.msgStream.ReleaseMsg(ms) + + switch req.Type { + case NRpcHas: + if len(req.Cid) != 1 { + if err := h.respondError(req.ID, xerrors.New("expected request for 1 cid"), cid.Undef); err != nil { + log.Warnw("writing error response", "error", err) + return + } + continue + } + + res, err := h.bs.Has(ctx, req.Cid[0]) + if err != nil { + if err := h.respondError(req.ID, err, req.Cid[0]); err != nil { + log.Warnw("writing error response", "error", err) + return + } + continue + } + + var resData [1]byte + if res { + resData[0] = cbg.CborBoolTrue[0] + } else { + resData[0] = cbg.CborBoolFalse[0] + } + + if err := h.respond(req.ID, NRpcOK, resData[:]); err != nil { + log.Warnw("writing response", "error", err) + return + } + + case NRpcGet: + if len(req.Cid) != 1 { + if err := h.respondError(req.ID, xerrors.New("expected request for 1 cid"), cid.Undef); err != nil { + log.Warnw("writing error response", "error", err) + return + } + continue + } + + err := h.bs.View(ctx, req.Cid[0], func(bdata []byte) error { + return h.respond(req.ID, NRpcOK, bdata) + }) + if err != nil { + if err := h.respondError(req.ID, err, req.Cid[0]); err != nil { + log.Warnw("writing error response", "error", err) + return + } + continue + } + + case NRpcGetSize: + if len(req.Cid) != 1 { + if err := h.respondError(req.ID, xerrors.New("expected request for 1 cid"), cid.Undef); err != nil { + log.Warnw("writing error response", "error", err) + return + } + continue + } + + sz, err := h.bs.GetSize(ctx, req.Cid[0]) + if err != nil { + if err := h.respondError(req.ID, err, req.Cid[0]); err != nil { + log.Warnw("writing error response", "error", err) + return + } + continue + } + + var resData [4]byte + binary.LittleEndian.PutUint32(resData[:], uint32(sz)) + + if err := h.respond(req.ID, NRpcOK, resData[:]); err != nil { + log.Warnw("writing response", "error", err) + return + } + + case NRpcPut: + blocks := make([]block.Block, len(req.Cid)) + + if len(req.Cid) != len(req.Data) { + if err := h.respondError(req.ID, xerrors.New("cid count didn't match data count"), cid.Undef); err != nil { + log.Warnw("writing error response", "error", err) + } + return + } + + for i := range req.Cid { + blocks[i], err = block.NewBlockWithCid(req.Data[i], req.Cid[i]) + if err != nil { + log.Warnw("make block", "error", err) + return + } + } + + err := h.bs.PutMany(ctx, blocks) + if err != nil { + if err := h.respondError(req.ID, err, cid.Undef); err != nil { + log.Warnw("writing error response", "error", err) + return + } + continue + } + + if err := h.respond(req.ID, NRpcOK, []byte{}); err != nil { + log.Warnw("writing response", "error", err) + return + } + case NRpcDelete: + err := h.bs.DeleteMany(ctx, req.Cid) + if err != nil { + if err := h.respondError(req.ID, err, cid.Undef); err != nil { + log.Warnw("writing error response", "error", err) + return + } + continue + } + + if err := h.respond(req.ID, NRpcOK, []byte{}); err != nil { + log.Warnw("writing response", "error", err) + return + } + default: + if err := h.respondError(req.ID, xerrors.New("unsupported request type"), cid.Undef); err != nil { + log.Warnw("writing error response", "error", err) + return + } + continue + } + } +} + +func (h *NetworkStoreHandler) respondError(req uint64, uerr error, c cid.Cid) error { + var resp NetRpcResp + resp.ID = req + resp.Type = NRpcErr + + nerr := NetRpcErr{ + Type: NRpcErrGeneric, + Msg: uerr.Error(), + } + if ipld.IsNotFound(uerr) { + nerr.Type = NRpcErrNotFound + nerr.Cid = &c + } + + var edata bytes.Buffer + if err := nerr.MarshalCBOR(&edata); err != nil { + return xerrors.Errorf("marshaling error data: %w", err) + } + + resp.Data = edata.Bytes() + + var msg bytes.Buffer + if err := resp.MarshalCBOR(&msg); err != nil { + return xerrors.Errorf("marshaling error response: %w", err) + } + + if err := h.msgStream.WriteMsg(msg.Bytes()); err != nil { + return xerrors.Errorf("write error response: %w", err) + } + + return nil +} + +func (h *NetworkStoreHandler) respond(req uint64, rt NetRPCRespType, data []byte) error { + var resp NetRpcResp + resp.ID = req + resp.Type = rt + resp.Data = data + + var msg bytes.Buffer + if err := resp.MarshalCBOR(&msg); err != nil { + return xerrors.Errorf("marshaling response: %w", err) + } + + if err := h.msgStream.WriteMsg(msg.Bytes()); err != nil { + return xerrors.Errorf("write response: %w", err) + } + + return nil +} diff --git a/blockstore/net_test.go b/blockstore/net_test.go new file mode 100644 index 000000000..d8c33818e --- /dev/null +++ b/blockstore/net_test.go @@ -0,0 +1,63 @@ +package blockstore + +import ( + "context" + "fmt" + "io" + "testing" + + block "github.com/ipfs/go-block-format" + ipld "github.com/ipfs/go-ipld-format" + "github.com/libp2p/go-msgio" + "github.com/stretchr/testify/require" +) + +func TestNetBstore(t *testing.T) { + ctx := context.Background() + + cr, sw := io.Pipe() + sr, cw := io.Pipe() + + cm := msgio.Combine(msgio.NewWriter(cw), msgio.NewReader(cr)) + sm := msgio.Combine(msgio.NewWriter(sw), msgio.NewReader(sr)) + + bbs := NewMemorySync() + _ = HandleNetBstoreStream(ctx, bbs, sm) + + nbs := NewNetworkStore(cm) + + tb1 := block.NewBlock([]byte("aoeu")) + + h, err := nbs.Has(ctx, tb1.Cid()) + require.NoError(t, err) + require.False(t, h) + + err = nbs.Put(ctx, tb1) + require.NoError(t, err) + + h, err = nbs.Has(ctx, tb1.Cid()) + require.NoError(t, err) + require.True(t, h) + + sz, err := nbs.GetSize(ctx, tb1.Cid()) + require.NoError(t, err) + require.Equal(t, 4, sz) + + err = nbs.DeleteBlock(ctx, tb1.Cid()) + require.NoError(t, err) + + h, err = nbs.Has(ctx, tb1.Cid()) + require.NoError(t, err) + require.False(t, h) + + _, err = nbs.Get(ctx, tb1.Cid()) + fmt.Println(err) + require.True(t, ipld.IsNotFound(err)) + + err = nbs.Put(ctx, tb1) + require.NoError(t, err) + + b, err := nbs.Get(ctx, tb1.Cid()) + require.NoError(t, err) + require.Equal(t, "aoeu", string(b.RawData())) +} diff --git a/blockstore/net_ws.go b/blockstore/net_ws.go new file mode 100644 index 000000000..5c9a70d84 --- /dev/null +++ b/blockstore/net_ws.go @@ -0,0 +1,100 @@ +package blockstore + +import ( + "bytes" + "context" + + "github.com/gorilla/websocket" + "github.com/libp2p/go-msgio" + "golang.org/x/xerrors" +) + +type wsWrapper struct { + wc *websocket.Conn + + nextMsg []byte +} + +func (w *wsWrapper) Read(b []byte) (int, error) { + return 0, xerrors.New("read unsupported") +} + +func (w *wsWrapper) ReadMsg() ([]byte, error) { + if w.nextMsg != nil { + nm := w.nextMsg + w.nextMsg = nil + return nm, nil + } + + mt, r, err := w.wc.NextReader() + if err != nil { + return nil, err + } + + switch mt { + case websocket.BinaryMessage, websocket.TextMessage: + default: + return nil, xerrors.Errorf("unexpected message type") + } + + // todo pool + // todo limit sizes + var mbuf bytes.Buffer + if _, err := mbuf.ReadFrom(r); err != nil { + return nil, err + } + + return mbuf.Bytes(), nil +} + +func (w *wsWrapper) ReleaseMsg(bytes []byte) { + // todo use a pool +} + +func (w *wsWrapper) NextMsgLen() (int, error) { + if w.nextMsg != nil { + return len(w.nextMsg), nil + } + + mt, msg, err := w.wc.ReadMessage() + if err != nil { + return 0, err + } + + switch mt { + case websocket.BinaryMessage, websocket.TextMessage: + default: + return 0, xerrors.Errorf("unexpected message type") + } + + w.nextMsg = msg + return len(w.nextMsg), nil +} + +func (w *wsWrapper) Write(bytes []byte) (int, error) { + return 0, xerrors.New("write unsupported") +} + +func (w *wsWrapper) WriteMsg(bytes []byte) error { + return w.wc.WriteMessage(websocket.BinaryMessage, bytes) +} + +func (w *wsWrapper) Close() error { + return w.wc.Close() +} + +var _ msgio.ReadWriteCloser = &wsWrapper{} + +func wsConnToMio(wc *websocket.Conn) msgio.ReadWriteCloser { + return &wsWrapper{ + wc: wc, + } +} + +func HandleNetBstoreWS(ctx context.Context, bs Blockstore, wc *websocket.Conn) *NetworkStoreHandler { + return HandleNetBstoreStream(ctx, bs, wsConnToMio(wc)) +} + +func NewNetworkStoreWS(wc *websocket.Conn) *NetworkStore { + return NewNetworkStore(wsConnToMio(wc)) +} diff --git a/build/actors/v10.tar.zst b/build/actors/v10.tar.zst index 6748162a0..a8e0e8378 100644 Binary files a/build/actors/v10.tar.zst and b/build/actors/v10.tar.zst differ diff --git a/build/builtin_actors_gen.go b/build/builtin_actors_gen.go index 988de1a48..84c152493 100644 --- a/build/builtin_actors_gen.go +++ b/build/builtin_actors_gen.go @@ -44,23 +44,23 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet }, { Network: "butterflynet", Version: 10, - ManifestCid: MustParseCid("bafy2bzacech5zikzhyspdibj7ozpo5q7edmq4wnz2bkqsv532w5dbn36gv6pg"), + ManifestCid: MustParseCid("bafy2bzacedrip7ekfxytqyx2dj5ggg7itm6w3lywgqsfs4lr4hlcrve6vgiqc"), Actors: map[string]cid.Cid{ - "account": MustParseCid("bafk2bzaceczu2o5v46l6jj6oe4v5pwlbacmjmmpo6klpbbzi35uexw6jx2sjg"), - "cron": MustParseCid("bafk2bzaced7h7pnzvpawfjoaauzl4rmeowsbew66zjoqx7lzfaxnifc3t4dda"), - "datacap": MustParseCid("bafk2bzacebbmaksmfux5ht7ucbxqdftkwlannhx3p5nd3jxoz6pc4vhuuomxc"), - "eam": MustParseCid("bafk2bzacedzdp6jr2w46mnnmztittt7md2krcicotqmuoil4ic5c6l3jkg2ju"), - "embryo": MustParseCid("bafk2bzacecau3tohdilfx66pohfqdrngpuqd5oew2j5iv3c7sjlrkcm5npqos"), - "evm": MustParseCid("bafk2bzaceblv2mbvueap3f4tavi5aozgspebdqmqzskuhmd3fe2xe4jx7zkam"), - "init": MustParseCid("bafk2bzacecdylyzglnbo7j4hmkqeba2n3bmjegvsb4osoictknq4vovufrcku"), - "multisig": MustParseCid("bafk2bzaceb2kcz3342uaslo5hxgazmz6j6fx6nkrpquf43jqp6qskhpwznzes"), - "paymentchannel": MustParseCid("bafk2bzaceclkwohvisshvhunzi7fnouwlginejje2xdxxy4mf4krofi7hbhtc"), - "reward": MustParseCid("bafk2bzacecn2rkubqfohtxipehwsshez3zegailjsgjaws74cqqmz45vlistu"), - "storagemarket": MustParseCid("bafk2bzacedu3rtlofbeguc7qwdsctomv5rph2jdtebgxruitmudgh5orop77m"), - "storageminer": MustParseCid("bafk2bzaceawyrwb6e6xktx765fv3oozryfqc7z2qhynjg3thtrlykmvgodlzs"), - "storagepower": MustParseCid("bafk2bzacecwmkw5anen277bofe2nhd7bum62jwuibp4o7iqcz4lj3rbk53ylg"), - "system": MustParseCid("bafk2bzacea7kozhxosbrh3lc4azas2vqxldiclxftni7nhdip2uzghdpme6ou"), - "verifiedregistry": MustParseCid("bafk2bzacec5probznte3gi5wrb6wpuzqtynsa7xmaccbe2itlgyciwplg45uc"), + "account": MustParseCid("bafk2bzacebui5xw2dlftdkdo7lalrcjceohc6xpqnmmyrtdhsihi555c34w3m"), + "cron": MustParseCid("bafk2bzacea7kk5jbwcl3hmy7lmuoswj2vwvm7enbibt4hwxoqdla7yuoqn3hy"), + "datacap": MustParseCid("bafk2bzacebnhnt3tubzngnzmlgxrfbjaf6dcsijplaz5nbdzye75fexdlpndq"), + "eam": MustParseCid("bafk2bzaceb5tc576ogvaafng6wm5qt5vonyha6dcfzyieu7zsaseulo6hogka"), + "embryo": MustParseCid("bafk2bzaceb5shyqwqsogg2izzfteoxcqji6pzqakuc3auvjo44uv5ndhaxt5i"), + "evm": MustParseCid("bafk2bzaceaxcgbhb2smi7yp7vjdqcclxc3iuma4rharhuavpwzgqxnhx6plss"), + "init": MustParseCid("bafk2bzaceddlj7vpdmsjhpafxfb3ltgwgzlckcss6khxllwiwwu5ml3d46pga"), + "multisig": MustParseCid("bafk2bzacecxryfy3nips4lmoehiim2gbhm5brxdeefslbenlhg2tix3rpkpnc"), + "paymentchannel": MustParseCid("bafk2bzacedu3xgcuftzf5xthcbwm55sd5rp4ptc2ulwciw56jajfy54kswiw6"), + "reward": MustParseCid("bafk2bzacedoojima37co6gllv35osnewurtycv6yudvjq2cgdwavll7sn6gbc"), + "storagemarket": MustParseCid("bafk2bzacedvtynnpaxuyunegh3x3cql3sidflwkjtrxkkaqcukdrmdox7xziw"), + "storageminer": MustParseCid("bafk2bzacednwhb2l4xth5tqgtmftybaj52rpehidesp2xjg7xbi7u62dgst6g"), + "storagepower": MustParseCid("bafk2bzacebx5cu7mkxiqxcwht3j45yd3mrstcvncpipgrqv2velnwpzkrcvzs"), + "system": MustParseCid("bafk2bzacedigfwdw7pjmmvsyzo2vajmfa53ctyp2yz35hsd5c63h4xrxskmmq"), + "verifiedregistry": MustParseCid("bafk2bzacedfq3vluteepuco72n6f7jlp6sbfsstpecjhukiou6g4jivrtkvx2"), }, }, { Network: "calibrationnet", @@ -100,23 +100,23 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet }, { Network: "calibrationnet", Version: 10, - ManifestCid: MustParseCid("bafy2bzaceakll7cw4xednc7fagkpcuigmskgnqwclloskurdpwe6ksowsveem"), + ManifestCid: MustParseCid("bafy2bzacebenfsnosatbwn2vskkduv5dd4fclymp3szy5rudwjjnpacjwgabw"), Actors: map[string]cid.Cid{ - "account": MustParseCid("bafk2bzacedym6hvldrhewweusr3o47jw6ppnoqybwxfpizukin4jqm2utanc6"), - "cron": MustParseCid("bafk2bzaceajvgdgkcmyum2rgkoohf2igmjlgft6rm6cmlm6e2n2mq5vsjtbc6"), - "datacap": MustParseCid("bafk2bzacebqdsmsoomixknyc7rot4sgomvxlcnvctdzyzspdsvmvtsbzo3adw"), - "eam": MustParseCid("bafk2bzacedtrp6jlak7kfnb4w6juwys672raifm5l6fkjovtfxnsbel7nraa6"), - "embryo": MustParseCid("bafk2bzacecau3tohdilfx66pohfqdrngpuqd5oew2j5iv3c7sjlrkcm5npqos"), - "evm": MustParseCid("bafk2bzaceavkezg7jk6hhlyvlmfxuygxphnmhlparlrpuiu26om5lm5sqea2i"), - "init": MustParseCid("bafk2bzaceddk4flq2hsni3foc3uwsia4gaugmu6ntnj6lo2gcynj5vsncp44c"), - "multisig": MustParseCid("bafk2bzacebok4642anm3443a7qcdenkr5rbfea6ghjrsattp24qfltokvw3au"), - "paymentchannel": MustParseCid("bafk2bzaceamay6icwp2h42uhdksljsydyz5fjolgfrkj5wyocg437ud3xg2t4"), - "reward": MustParseCid("bafk2bzaceb2psfhos5ozxacng3naeizijn6z25hp64ze4udmzjfxwy2357gqc"), - "storagemarket": MustParseCid("bafk2bzacedwyvhlc5bd3u2hmcweetkica6elj6myswrqsgi7d2ojfccfz22yw"), - "storageminer": MustParseCid("bafk2bzaceb7k267d6w7iktrr6xbyxgyqrl4ahdwabjyndgbnxe2q236wydaoo"), - "storagepower": MustParseCid("bafk2bzacebfm23kwvby4rp66pygqppevdg5adw6cmeneg4vt3ahbtqhj42n3i"), - "system": MustParseCid("bafk2bzacedrn4b7otr4uq5zhb4urbpxaoo26t3srbxvyyrvknhrx466ax5neq"), - "verifiedregistry": MustParseCid("bafk2bzacedydpsphnnmtp2q56phftt674i5ew4feb2idjxhbvilxkma4yavw2"), + "account": MustParseCid("bafk2bzacebvkqmplmi4qta56c3o7xenxfnh52ubcru4oqaavx2mel6h7f3r26"), + "cron": MustParseCid("bafk2bzaceddqlwubzbrhdnkvgzoo6jinmn35qqnh4vtmkxhhnqmvoy7z3ovm4"), + "datacap": MustParseCid("bafk2bzacedce7wj2kdujhvo55bfqwxup4gccdahvxpxtn4oqand67cnm7oaes"), + "eam": MustParseCid("bafk2bzacebvs75jzsh74vs43i5ve4ikbiy4h2sbg7fbqiv53lybwufhk6gntc"), + "embryo": MustParseCid("bafk2bzaceb5shyqwqsogg2izzfteoxcqji6pzqakuc3auvjo44uv5ndhaxt5i"), + "evm": MustParseCid("bafk2bzacebni52v7johlrrvfagunysb5b7ssruapbuw3lkw4raavhrf5dbjy2"), + "init": MustParseCid("bafk2bzacebdjvjkidqczhk2dfmmfastxihuru7qssdsegxibx2u6zsmwxbr6y"), + "multisig": MustParseCid("bafk2bzacea53zxqqchdykxyklsuuxr2nxavzym5prtw5jrnarrjldttcqxluo"), + "paymentchannel": MustParseCid("bafk2bzaceck54j7jukcc22ubrzf4yyiaxz6p5hmwkxqgzvevsn7x5nrpghxf4"), + "reward": MustParseCid("bafk2bzacedlh4i2phmiqfbfl2zyajpzaigbgqp3fcdwtphststpap6e3pe2xg"), + "storagemarket": MustParseCid("bafk2bzacednr26koccefqs3pkab4e3bu7g2hxtwodrqaidj7lmxtaj4l4qbyw"), + "storageminer": MustParseCid("bafk2bzaceb2vgdzj7ydnhfr4exyat2aiuigglhwqv7pu5p65l5syankhjbaeo"), + "storagepower": MustParseCid("bafk2bzacedbqdw62m5fah32bkvns2ubz32lgqu4fngp77aezzm3af7b6vmvsu"), + "system": MustParseCid("bafk2bzaceazgpbdm5nzg35jwmt6s4nqgy5ok2ne3ndhomkq6erits4l2ruyac"), + "verifiedregistry": MustParseCid("bafk2bzacebs7l5v7b74fy5eqkmcdccbkjqpxykn6au34p4si7m2hc3utrpwhq"), }, }, { Network: "caterpillarnet", @@ -156,23 +156,23 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet }, { Network: "caterpillarnet", Version: 10, - ManifestCid: MustParseCid("bafy2bzacec7dckmatj6aqieerpjzyvtgonnwjghzx6nxwgeftyp4x63sjyzji"), + ManifestCid: MustParseCid("bafy2bzacecprcdvekabbiozu6jaferly4jpw4uxoxy55ouioopv2uhsyfnatg"), Actors: map[string]cid.Cid{ - "account": MustParseCid("bafk2bzacea7ltxlbxq5t735tvokfw3vutsv5vcvmarrt3smvy6ityxc7kzyjo"), - "cron": MustParseCid("bafk2bzacebkyepynkejhiwwer4fqzgnodx4qoesueon5gkvfrsoo5qqnon7xq"), - "datacap": MustParseCid("bafk2bzaced4oa6qiyl64xaawitscelc3b7wxqlzyrorsawjz5aveyib7gifg2"), - "eam": MustParseCid("bafk2bzaceadxs6yx43da4bcleqbpdho7h72hbl27yxzxr6r42qfpga2pn5i64"), - "embryo": MustParseCid("bafk2bzacecau3tohdilfx66pohfqdrngpuqd5oew2j5iv3c7sjlrkcm5npqos"), - "evm": MustParseCid("bafk2bzacechzhg6vwsnbsshj7exshd3ptt73tyvvnby2dir3l3ugmq2jub3ja"), - "init": MustParseCid("bafk2bzacecpvier4hsrkzhnojtupquugx4jj372uco4kdyfm7smxhdrvrl75k"), - "multisig": MustParseCid("bafk2bzacebrqip3wapds4ks46ba2yc5hcatppu5mu7eug25o6veolrwglxzem"), - "paymentchannel": MustParseCid("bafk2bzaced6i6kpzze22rbsx6pqqdsrpgzxulwbsuqjk6v6wjgei5rmetwkcg"), - "reward": MustParseCid("bafk2bzaced3j6bmqbdun7x7kv7um26n37kmbmjhrzlayo6ixqp26jlprof4jo"), - "storagemarket": MustParseCid("bafk2bzacebc25u4aoostddz4c3ayz7q4lumdxnpedtu33c3t7zv3csqujdzlq"), - "storageminer": MustParseCid("bafk2bzacedveye4v5wj44eukdgr52jxeyqkencpbnddbksqjq7gibn7zro75c"), - "storagepower": MustParseCid("bafk2bzacedwg6am6kwujhaw4pk72j6nmnwyvbblzctkdeqerz3o3ftum6vyuk"), - "system": MustParseCid("bafk2bzacebaxz63jyxokfiyi2fjzaevnn55e5wja3fkygwfmxr7rgtstzeh7s"), - "verifiedregistry": MustParseCid("bafk2bzacebhtptnl7rvega7pckyi6wvjg3jknbbqiblz7pi466kkxfakr4v3o"), + "account": MustParseCid("bafk2bzaceasuszw5iqejn3afhc2oftpmnhgwg5gt7d3fryfi3pzyuv4vaifzq"), + "cron": MustParseCid("bafk2bzaceadt6coa6p7cgwt7k7sz7hafpy3ilma4q4obghn6xsywjedar43om"), + "datacap": MustParseCid("bafk2bzacec3hswe3wucjxlqavck4ijdto65gwuzlqlhstpj22icx3xgy6y25m"), + "eam": MustParseCid("bafk2bzaceb52bwd7ikj7dnpeebaak2aaoeqdp6sm5n3qu75gyhym7o7sa64oo"), + "embryo": MustParseCid("bafk2bzaceb5shyqwqsogg2izzfteoxcqji6pzqakuc3auvjo44uv5ndhaxt5i"), + "evm": MustParseCid("bafk2bzacecw44r27pmmurhlkf5vqnqjxpivnh5oopegonnl2o7rtu3wyc4h4s"), + "init": MustParseCid("bafk2bzaceb2hcbworiltqg5227d6xcuhypgd2x2olsnqdk5ung5rzps5hze4y"), + "multisig": MustParseCid("bafk2bzacecwcqghlxf76d5a6uwn65ryb4ogrgktlfb6pc2625v5uznnz5sshc"), + "paymentchannel": MustParseCid("bafk2bzacebk5bxknqhlsrvgdnleflwpmkc25hfx4zrqxasszo3ktkkvp7w6oo"), + "reward": MustParseCid("bafk2bzacebdl4woa2et6x2cg2gnw3zpx3a6jhuw3xnkcy4vjhu2zsd52cpgbc"), + "storagemarket": MustParseCid("bafk2bzacectrnbmdzux4ktjezov2eghyf4b6khne5bbx57fbw4ubdrplpkesi"), + "storageminer": MustParseCid("bafk2bzacebzwofvflpycvpl2oikql3o4gcd2alhoa7vtz4crj34ioegzl6h7i"), + "storagepower": MustParseCid("bafk2bzaced7p4fzea2j4hs2cz52uxtxy2pie4avjs5hsdrjwxas2d247v645c"), + "system": MustParseCid("bafk2bzacea4nhoud6kwlrnayplpwfwlo5jlqqplu3gj5kp5e3i3pxzwzdmakq"), + "verifiedregistry": MustParseCid("bafk2bzacecuz22dwb56p4z67fyqsb4qfw3qk3lz6tq5kc3lsxuo7znlbjczqu"), }, }, { Network: "devnet", @@ -212,23 +212,23 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet }, { Network: "devnet", Version: 10, - ManifestCid: MustParseCid("bafy2bzacedozgcap7rarf3wb7fyi7efzu6qtf7w3g3lul45yhgflovpj5czkm"), + ManifestCid: MustParseCid("bafy2bzacecwysahkxh4jgpmby7lboxalqv2fbvoohi4tcf6unllzwlrgb6n3u"), Actors: map[string]cid.Cid{ - "account": MustParseCid("bafk2bzacedewxnpn7dso7fypubae2w7ovnw4gj5kpb7lzohygm34mc7eqa3hm"), - "cron": MustParseCid("bafk2bzacecuj4iqhstejynmnq6c5rqkyqhkemk6pr3kz3pnlsiqw6zmqkr72c"), - "datacap": MustParseCid("bafk2bzacec645kiqnun4pgkru5jmnuzeh24p556bwgh3af3fv7erumg7poypg"), - "eam": MustParseCid("bafk2bzacedqquawjg4yowzgzh4gjo6uqsi5i2fn5orks5a5oueg2alo7zlss4"), - "embryo": MustParseCid("bafk2bzacecau3tohdilfx66pohfqdrngpuqd5oew2j5iv3c7sjlrkcm5npqos"), - "evm": MustParseCid("bafk2bzacec7reu4kwibnazp2jw6trkh777w6njt4fwrmza7nxalwqsigggfio"), - "init": MustParseCid("bafk2bzaceclig55sktlhe3ws2kbkkteinlyotc2drcupmp53porrn6xzxd6t6"), - "multisig": MustParseCid("bafk2bzacea5r262zfroswf3j2qkgqbfkzmdugxxgd4fkol673spsyp5x2fezu"), - "paymentchannel": MustParseCid("bafk2bzacebn2whw2uauxcjxnu4xqmaxp7jvipbwfbjrbqyzglzbzbjm7o2lzy"), - "reward": MustParseCid("bafk2bzacebv26kdmzyif45jugv5odyavzf33jo5l6grk7f2rkeqwuuuwpa45u"), - "storagemarket": MustParseCid("bafk2bzacebbw6mxowf4wolutjjckl45u2fig67ltbqyxhdlv5zao3geh5mkvw"), - "storageminer": MustParseCid("bafk2bzacedlxojnzgyz6nd3nopt73hhknx3i2pbajqo42mqajlonu73vh6iie"), - "storagepower": MustParseCid("bafk2bzacea6vslpi6dinukglk62ko52z2irkqbp4uzf3lcdrzqttuqv6ugw6u"), - "system": MustParseCid("bafk2bzacecyrjaxcqsahor6eqdvl3qologclu5dmuqrbidors4tsmkjtmfqzi"), - "verifiedregistry": MustParseCid("bafk2bzacebqrndjputpy5wivtb6jhv7bmnlq2ly27da5gt5432c5viafreff4"), + "account": MustParseCid("bafk2bzacecui4vegcaloi3dt2rob6dytzr7iag257jfszwdtvqgcun6vi2ggi"), + "cron": MustParseCid("bafk2bzacedukjjklhrahhnbwqcbe3ppowu6cdd3ev2ncsynjg63ese36zg5es"), + "datacap": MustParseCid("bafk2bzaceaucxyfovggh3hn3iwfqm45z2wxovyasp47ji6vhwv4zlfmtcfg3s"), + "eam": MustParseCid("bafk2bzaceazgazurwhvwoj4evuxmw5sd2bje2dr4kvyklunlapvw7kyhpzn46"), + "embryo": MustParseCid("bafk2bzaceb5shyqwqsogg2izzfteoxcqji6pzqakuc3auvjo44uv5ndhaxt5i"), + "evm": MustParseCid("bafk2bzaceam256namf22qqvbj4owo6jhsz5ai2lv6bgp2cqe6mqpyklzl4v2c"), + "init": MustParseCid("bafk2bzacecwy6qxelpbblzgq5ehzqjfe2k47olme3a2kmegth6qsyvykxyfui"), + "multisig": MustParseCid("bafk2bzaceab6p4qg2jmqdylrgcam5u4md3ho7wiigxtnrj7h5qwplvuhe3qm2"), + "paymentchannel": MustParseCid("bafk2bzaceda4axurklqhlb3w3t2skgqj2xqi66cdufcdkgsl5v3f6qdvp7neg"), + "reward": MustParseCid("bafk2bzaceax2wjon7qzsfha3cm3w2cl6rplwxg4onhyvermyhmeu7gubzdcha"), + "storagemarket": MustParseCid("bafk2bzacechmh6ufrhsodqxt2kf5kys2e7mtzom73l6qqemrebsatxxzvfkfy"), + "storageminer": MustParseCid("bafk2bzacebvtukozkvkmcj74o3wvozvi5iese5ijmhjd7u73aqcp55oc3z2tq"), + "storagepower": MustParseCid("bafk2bzaceaun3ipavgb3axpt7zjkkfserw6rhnorpvoicqihdmsyxuhymv6mq"), + "system": MustParseCid("bafk2bzacecrpokwc27mww4zf3l7kaxe2m6sgbzuuvouzzpkk7uh5ax4ufrx2w"), + "verifiedregistry": MustParseCid("bafk2bzacecnbhvtkipjzczzwekkgmohikkeftconlvpdqkmuxrke24eb7trzq"), }, }, { Network: "mainnet", @@ -268,23 +268,23 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet }, { Network: "mainnet", Version: 10, - ManifestCid: MustParseCid("bafy2bzacecgsf5euzqplra4vxqhfim7zgsy6fpy2hvb6u3eplovclpfctdcnc"), + ManifestCid: MustParseCid("bafy2bzaceb2ssutz56smwc6vwigjgo2kfqirnwkwq7zthxscynvtzn7ebywt4"), Actors: map[string]cid.Cid{ - "account": MustParseCid("bafk2bzacebrferb5v5mldmtcd5u3ln7uold6esrkqjy3cmcn5gajur5ymgj64"), - "cron": MustParseCid("bafk2bzacecixoe7cnx2233hxy5xdovoghp7mcaydk4vaj4bp6oa4nwiatzqim"), - "datacap": MustParseCid("bafk2bzacecyfsfp3vftqbsxeqe76exjck54tsuupcpxtrendjvrjb4g5ot6bi"), - "eam": MustParseCid("bafk2bzaceahedp5yhhnmk76spnvtx4cmtbjz463o3qhgamdftor4denxpzmh2"), - "embryo": MustParseCid("bafk2bzacecau3tohdilfx66pohfqdrngpuqd5oew2j5iv3c7sjlrkcm5npqos"), - "evm": MustParseCid("bafk2bzaced4cftxbo3h3wa4htlgjmfmqqrvqk5ddckmdua5ikc4syxfpup7gs"), - "init": MustParseCid("bafk2bzaceamsma6u3hxnfea6b7h3mfekbiufcdtghtqxpp2w45pt4d472oxak"), - "multisig": MustParseCid("bafk2bzaced2dxdjxgottjchlc2kdlw2z2hd4oirwsu67ca72sdbnc5y75zveu"), - "paymentchannel": MustParseCid("bafk2bzacedr5eoysu45rvm4tfsp3hiay6kyucmlyj4flsxow2ag3omuwhgmee"), - "reward": MustParseCid("bafk2bzaceaua7nxqwk5uuqjdwvwth57citforok365ybfcmtwfg2glmykke2y"), - "storagemarket": MustParseCid("bafk2bzacebdvnxh3bj6yuvvnmygiloge5b246iiawtc4s4ldjby67ykop46m2"), - "storageminer": MustParseCid("bafk2bzaceby25xk5l2st6grf5jsqshccuhrxw57x2ws54vjifaipip5i27oiw"), - "storagepower": MustParseCid("bafk2bzaceabh35xpju4yd57ro2by7gq6zdqcmrbm2vvrb43esxflbr47uaeym"), - "system": MustParseCid("bafk2bzaceaymi5z5hanmqbqlcaglyg65ib4t6wx7glvzcwir7g3sa57zchzpi"), - "verifiedregistry": MustParseCid("bafk2bzacebw5tjiqj36dnhr6osgw5rfpunweoeeu2onah3xsfdc54hznidmga"), + "account": MustParseCid("bafk2bzacea34fwixc5x473laalyitolzttxxus5ulxi2ukylsubhrl2m32zhc"), + "cron": MustParseCid("bafk2bzacebxkofxwtkzmncfb77slj4hvwlhazb2x7li7gbdhfbh3gxdmud2eq"), + "datacap": MustParseCid("bafk2bzaceac4u53w2fwsez4fmk5to4u5f6tls2obsutsep24nswiclqme75uy"), + "eam": MustParseCid("bafk2bzaced25owr5v4k4ypzm5qxi7c3juobbudekogapqaqia23chcyo43ofu"), + "embryo": MustParseCid("bafk2bzaceb5shyqwqsogg2izzfteoxcqji6pzqakuc3auvjo44uv5ndhaxt5i"), + "evm": MustParseCid("bafk2bzacechckrenio2m67kvacfbzmpm2uosnrw5zmrzsj4b6cukwmhpjfg6c"), + "init": MustParseCid("bafk2bzaceblbm5moflcetob6wbl3tjbi2zhyangfrmp4jux7wyeixi7ptctu6"), + "multisig": MustParseCid("bafk2bzaceadileikmkovoi4ewl4jbyjgnntl7rqsqlxs2plj2ruv776qxp5hq"), + "paymentchannel": MustParseCid("bafk2bzaceasjtgnksm3infcphwhyg675hip3t65q3pzknatf6aqb3mi57pj2c"), + "reward": MustParseCid("bafk2bzacecozr3gal2ywayykdgrhjbttqvwktptyvlvph6dunqrlp2rnl5rbq"), + "storagemarket": MustParseCid("bafk2bzacedv5grgmgmoxjvvrszb4phdnhzvlsjv6g3ugirjhgghfuncc67zvu"), + "storageminer": MustParseCid("bafk2bzaceb7wvvvx6dduzodqanerefg5q6k2qvbrlzcbhal5yjhkzun64vtvk"), + "storagepower": MustParseCid("bafk2bzacecauoq7xxccmc3hrbbsktonlivg7pibysrnplelsvgdzpzpryv6mm"), + "system": MustParseCid("bafk2bzaceapfdn6eteiqvvhape3iyybobhcyg6lbmncmerhcpckcj444uk6qo"), + "verifiedregistry": MustParseCid("bafk2bzacec4v5cozakcgq5btelyjz6hkmcmftj35a2qvcjfcynb6hw4ifxbeq"), }, }, { Network: "testing", @@ -324,23 +324,23 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet }, { Network: "testing", Version: 10, - ManifestCid: MustParseCid("bafy2bzaceblyvl5vpmg5vsiheag37rmxbhyysppiducdiwrjigfmqzxzmeiw2"), + ManifestCid: MustParseCid("bafy2bzaceaxppo7nkcn456lgend7oqb4pcxdtvk4rw7xqu4qfxsg76hpgjzdm"), Actors: map[string]cid.Cid{ - "account": MustParseCid("bafk2bzacecbss2ettatvrznxisyfokry3e3iseviub37giux6gu4xd4oufyuq"), - "cron": MustParseCid("bafk2bzacecznld24ktoctdwdnztgjgfm7vc2xpxy2bs4rvh54i42nhadfy6hm"), - "datacap": MustParseCid("bafk2bzacedkxqprqldjle5gr4exhevmpejc4u2hv6abs7gymh4kwo2bdyaixg"), - "eam": MustParseCid("bafk2bzacedfvxauqyelthrgu5i43quivikf3ndsc7345n7qm5sevf6ujl6bds"), - "embryo": MustParseCid("bafk2bzacecau3tohdilfx66pohfqdrngpuqd5oew2j5iv3c7sjlrkcm5npqos"), - "evm": MustParseCid("bafk2bzacecvk7sj5hqeirku3fyemeexatl6gyuggahr2sh5vmnwq36e36jolo"), - "init": MustParseCid("bafk2bzacecv4vkplbdumw3hoyx22dr6frfh63h5k7wbwlb3vbyrzqnbwm3hq2"), - "multisig": MustParseCid("bafk2bzacecchofadvbkmrw3sal6vya3j3vgzm7fdqsv6exxdn5tkyfy7aqika"), - "paymentchannel": MustParseCid("bafk2bzaceares72arkoutsqffr3mpys2yxawuwadvo22mnwjvm7krwzw2vvis"), - "reward": MustParseCid("bafk2bzacebateijm6usif3etrbnepz5qaraynbaiefwzykxkchym4or3aw6bi"), - "storagemarket": MustParseCid("bafk2bzacebbrlxtkfwoyv6b3dpowsuza35gmqmqhgyuqzjnrouc5suuvottdw"), - "storageminer": MustParseCid("bafk2bzacecrnmcy75hs3gv4ixyed4b77ctdg2fezmoijdoviwp777zwvflu3o"), - "storagepower": MustParseCid("bafk2bzacecozrbsk3lyo6ttn27g4hhzxpoc5ekcmu7njq7chqfyk2iewm3nq6"), - "system": MustParseCid("bafk2bzacedg37rk2nyluufudaheng5illo7qlv5gsux3b57rzsoa4puaeu27a"), - "verifiedregistry": MustParseCid("bafk2bzaceblkqi3jhrzhrl5qgfkyhy2jhvm7dj6fhbp3rm5c3bmslk4apl45c"), + "account": MustParseCid("bafk2bzacecasu6oljznrdqpljjomlstq3yf2c6jbofwn5eoivjkgnl65a52lq"), + "cron": MustParseCid("bafk2bzacec535ytbuh2ycyjwyhnnyjz2jolzfzuny6kdyg6a4h6jtjwqfwfdo"), + "datacap": MustParseCid("bafk2bzaceay7k6yf5ccms37l2pggjioffyklnzyz4b3sm6567k5dvetlpctfo"), + "eam": MustParseCid("bafk2bzaceb5c32bdqtnpteri5okrwyg6m57vvcjqf5hggvhgqxgarpdski7e6"), + "embryo": MustParseCid("bafk2bzaceb5shyqwqsogg2izzfteoxcqji6pzqakuc3auvjo44uv5ndhaxt5i"), + "evm": MustParseCid("bafk2bzacedq6wp33m7oif4hgro52g4h2gdaxoymaic5js4cyyb5emqjfevi5k"), + "init": MustParseCid("bafk2bzacedk5bo33m4bjhii6mc35wmth6sx36azjgc4qbus3q45rtsb4xwl26"), + "multisig": MustParseCid("bafk2bzaceal376rbj6h6g3wlrs2kiik57ie7rcdb4jldzhd5i2vhq6lgsek3i"), + "paymentchannel": MustParseCid("bafk2bzacec7nsh23sha54ete2jl4eupj2hz4rxzyp4wm4jfu466czhkg7vdwq"), + "reward": MustParseCid("bafk2bzacecc4kkj7shrexyjb4bamnjlficb2hfnoqnmobcflx2bmzl4b5vqay"), + "storagemarket": MustParseCid("bafk2bzaceat4aedqcvjb42nl2yotog462uy5brffvpnurrvxaghem4ppwdn3y"), + "storageminer": MustParseCid("bafk2bzaceaeefkoaj7qpae6hivizqau6me4xdbajl2eny5hnexfbzqyooe4kg"), + "storagepower": MustParseCid("bafk2bzacecgejk3gyjauoalkdbwaq5kfdx7nnlvkjh4yfa6g7a43332xc2ajm"), + "system": MustParseCid("bafk2bzacebtg7ijnioa4xmscxvu6kk4mrnehfrddqgj4nqmj6f32nmvcc2ray"), + "verifiedregistry": MustParseCid("bafk2bzacecvdxtzrbtrrgtgw6t3nxw3zsslzdz6dybefzti45qbrlvuwqqt3q"), }, }, { Network: "testing-fake-proofs", @@ -380,22 +380,22 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet }, { Network: "testing-fake-proofs", Version: 10, - ManifestCid: MustParseCid("bafy2bzaceb2w3nde3bk73rkvsircwvj43qnw7f6hbcabtxkemku3tyixoyydc"), + ManifestCid: MustParseCid("bafy2bzaceb2ablvyxqk2vjhwxq5f5ptat7xiv3euwshwruppxp6ui7b64tvbu"), Actors: map[string]cid.Cid{ - "account": MustParseCid("bafk2bzacecbss2ettatvrznxisyfokry3e3iseviub37giux6gu4xd4oufyuq"), - "cron": MustParseCid("bafk2bzacecznld24ktoctdwdnztgjgfm7vc2xpxy2bs4rvh54i42nhadfy6hm"), - "datacap": MustParseCid("bafk2bzacedkxqprqldjle5gr4exhevmpejc4u2hv6abs7gymh4kwo2bdyaixg"), - "eam": MustParseCid("bafk2bzacedfvxauqyelthrgu5i43quivikf3ndsc7345n7qm5sevf6ujl6bds"), - "embryo": MustParseCid("bafk2bzacecau3tohdilfx66pohfqdrngpuqd5oew2j5iv3c7sjlrkcm5npqos"), - "evm": MustParseCid("bafk2bzacecvk7sj5hqeirku3fyemeexatl6gyuggahr2sh5vmnwq36e36jolo"), - "init": MustParseCid("bafk2bzacecv4vkplbdumw3hoyx22dr6frfh63h5k7wbwlb3vbyrzqnbwm3hq2"), - "multisig": MustParseCid("bafk2bzacecchofadvbkmrw3sal6vya3j3vgzm7fdqsv6exxdn5tkyfy7aqika"), - "paymentchannel": MustParseCid("bafk2bzaceares72arkoutsqffr3mpys2yxawuwadvo22mnwjvm7krwzw2vvis"), - "reward": MustParseCid("bafk2bzacebateijm6usif3etrbnepz5qaraynbaiefwzykxkchym4or3aw6bi"), - "storagemarket": MustParseCid("bafk2bzacebbrlxtkfwoyv6b3dpowsuza35gmqmqhgyuqzjnrouc5suuvottdw"), - "storageminer": MustParseCid("bafk2bzacedehmf7vjcvsnsa2vrbc2oofjvy4mrosn5guudt7tt7cbcc26ggqu"), - "storagepower": MustParseCid("bafk2bzaceayqib4titfnswzcphrwvdcqkhnwuuhdvk2yafxgumtmnkuwkibbo"), - "system": MustParseCid("bafk2bzacedg37rk2nyluufudaheng5illo7qlv5gsux3b57rzsoa4puaeu27a"), - "verifiedregistry": MustParseCid("bafk2bzaceblkqi3jhrzhrl5qgfkyhy2jhvm7dj6fhbp3rm5c3bmslk4apl45c"), + "account": MustParseCid("bafk2bzacecasu6oljznrdqpljjomlstq3yf2c6jbofwn5eoivjkgnl65a52lq"), + "cron": MustParseCid("bafk2bzacec535ytbuh2ycyjwyhnnyjz2jolzfzuny6kdyg6a4h6jtjwqfwfdo"), + "datacap": MustParseCid("bafk2bzaceay7k6yf5ccms37l2pggjioffyklnzyz4b3sm6567k5dvetlpctfo"), + "eam": MustParseCid("bafk2bzaceb5c32bdqtnpteri5okrwyg6m57vvcjqf5hggvhgqxgarpdski7e6"), + "embryo": MustParseCid("bafk2bzaceb5shyqwqsogg2izzfteoxcqji6pzqakuc3auvjo44uv5ndhaxt5i"), + "evm": MustParseCid("bafk2bzacedq6wp33m7oif4hgro52g4h2gdaxoymaic5js4cyyb5emqjfevi5k"), + "init": MustParseCid("bafk2bzacedk5bo33m4bjhii6mc35wmth6sx36azjgc4qbus3q45rtsb4xwl26"), + "multisig": MustParseCid("bafk2bzaceal376rbj6h6g3wlrs2kiik57ie7rcdb4jldzhd5i2vhq6lgsek3i"), + "paymentchannel": MustParseCid("bafk2bzacec7nsh23sha54ete2jl4eupj2hz4rxzyp4wm4jfu466czhkg7vdwq"), + "reward": MustParseCid("bafk2bzacecc4kkj7shrexyjb4bamnjlficb2hfnoqnmobcflx2bmzl4b5vqay"), + "storagemarket": MustParseCid("bafk2bzaceat4aedqcvjb42nl2yotog462uy5brffvpnurrvxaghem4ppwdn3y"), + "storageminer": MustParseCid("bafk2bzacec4sgyamy6iobuxesdwkg3zwffkwxnur57tisfpotbbs6kammr4ds"), + "storagepower": MustParseCid("bafk2bzacecqxuizz2wxujshjeh7rsric3fkwpa5mucizzamevdpafqewdtm4y"), + "system": MustParseCid("bafk2bzacebtg7ijnioa4xmscxvu6kk4mrnehfrddqgj4nqmj6f32nmvcc2ray"), + "verifiedregistry": MustParseCid("bafk2bzacecvdxtzrbtrrgtgw6t3nxw3zsslzdz6dybefzti45qbrlvuwqqt3q"), }, }} diff --git a/build/builtin_actors_test.go b/build/builtin_actors_test.go index ca98bf9bf..384193fee 100644 --- a/build/builtin_actors_test.go +++ b/build/builtin_actors_test.go @@ -21,16 +21,18 @@ func TestEmbeddedMetadata(t *testing.T) { // Test that we're registering the manifest correctly. func TestRegistration(t *testing.T) { - manifestCid, found := actors.GetManifest(actorstypes.Version9) - require.True(t, found) - require.True(t, manifestCid.Defined()) + for _, av := range []actorstypes.Version{actorstypes.Version8, actorstypes.Version9} { + manifestCid, found := actors.GetManifest(av) + require.True(t, found) + require.True(t, manifestCid.Defined()) - for _, key := range actors.GetBuiltinActorsKeys(actorstypes.Version9) { - actorCid, found := actors.GetActorCodeID(actorstypes.Version9, key) - require.True(t, found) - name, version, found := actors.GetActorMetaByCode(actorCid) - require.True(t, found) - require.Equal(t, actorstypes.Version9, version) - require.Equal(t, key, name) + for _, key := range actors.GetBuiltinActorsKeys(av) { + actorCid, found := actors.GetActorCodeID(av, key) + require.True(t, found) + name, version, found := actors.GetActorMetaByCode(actorCid) + require.True(t, found) + require.Equal(t, av, version) + require.Equal(t, key, name) + } } } diff --git a/build/drand.go b/build/drand.go index 3b976ac92..3027d930b 100644 --- a/build/drand.go +++ b/build/drand.go @@ -69,6 +69,10 @@ var DrandConfigs = map[DrandEnum]dtypes.DrandConfig{ ChainInfoJSON: `{"public_key":"8cda589f88914aa728fd183f383980b35789ce81b274e5daee1f338b77d02566ef4d3fb0098af1f844f10f9c803c1827","period":25,"genesis_time":1595348225,"hash":"e73b7dc3c4f6a236378220c0dd6aa110eb16eed26c11259606e07ee122838d4f","groupHash":"567d4785122a5a3e75a9bc9911d7ea807dd85ff76b78dc4ff06b075712898607"}`, }, DrandIncentinet: { + Servers: []string{ + "https://dev1.drand.sh", + "https://dev2.drand.sh", + }, ChainInfoJSON: `{"public_key":"8cad0c72c606ab27d36ee06de1d5b2db1faf92e447025ca37575ab3a8aac2eaae83192f846fc9e158bc738423753d000","period":30,"genesis_time":1595873820,"hash":"80c8b872c714f4c00fdd3daa465d5514049f457f01f85a4caf68cdcd394ba039","groupHash":"d9406aaed487f7af71851b4399448e311f2328923d454e971536c05398ce2d9b"}`, }, } diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 34f290040..114fb584a 100644 Binary files a/build/openrpc/full.json.gz and b/build/openrpc/full.json.gz differ diff --git a/build/openrpc/gateway.json.gz b/build/openrpc/gateway.json.gz index 77acd5668..8b3fc78f2 100644 Binary files a/build/openrpc/gateway.json.gz and b/build/openrpc/gateway.json.gz differ diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz index 61e3853fc..0424b7cad 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 160706e03..bef5adfce 100644 Binary files a/build/openrpc/worker.json.gz and b/build/openrpc/worker.json.gz differ diff --git a/build/params_mainnet.go b/build/params_mainnet.go index a1a6ae56c..296793131 100644 --- a/build/params_mainnet.go +++ b/build/params_mainnet.go @@ -79,14 +79,14 @@ const UpgradeOhSnapHeight = 1594680 // 2022-07-06T14:00:00Z const UpgradeSkyrHeight = 1960320 -var UpgradeSharkHeight = abi.ChainEpoch(99999999999999) +// 2022-11-30T14:00:00Z +var UpgradeSharkHeight = abi.ChainEpoch(2383680) var SupportedProofTypes = []abi.RegisteredSealProof{ abi.RegisteredSealProof_StackedDrg32GiBV1, abi.RegisteredSealProof_StackedDrg64GiBV1, } var ConsensusMinerMinPower = abi.NewStoragePower(10 << 40) -var MinVerifiedDealSize = abi.NewStoragePower(1 << 20) var PreCommitChallengeDelay = abi.ChainEpoch(150) var PropagationDelaySecs = uint64(10) diff --git a/build/version.go b/build/version.go index 600ec326f..70e27ad50 100644 --- a/build/version.go +++ b/build/version.go @@ -37,7 +37,7 @@ func BuildTypeString() string { } // BuildVersion is the local build version -const BuildVersion = "1.19.0-dev" +const BuildVersion = "1.19.1-dev" func UserVersion() string { if os.Getenv("LOTUS_VERSION_IGNORE_COMMIT") == "1" { diff --git a/chain/actors/builtin/account/account.go b/chain/actors/builtin/account/account.go index 2a3f6faca..5a2d55961 100644 --- a/chain/actors/builtin/account/account.go +++ b/chain/actors/builtin/account/account.go @@ -1,6 +1,7 @@ package account import ( + "github.com/ipfs/go-cid" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" @@ -110,6 +111,25 @@ func MakeState(store adt.Store, av actorstypes.Version, addr address.Address) (S type State interface { cbor.Marshaler + Code() cid.Cid + ActorKey() string + ActorVersion() actorstypes.Version + PubkeyAddress() (address.Address, error) GetState() interface{} } + +func AllCodes() []cid.Cid { + return []cid.Cid{ + (&state0{}).Code(), + (&state2{}).Code(), + (&state3{}).Code(), + (&state4{}).Code(), + (&state5{}).Code(), + (&state6{}).Code(), + (&state7{}).Code(), + (&state8{}).Code(), + (&state9{}).Code(), + (&state10{}).Code(), + } +} diff --git a/chain/actors/builtin/account/actor.go.template b/chain/actors/builtin/account/actor.go.template index 07b4cc94b..ef6e7ac3d 100644 --- a/chain/actors/builtin/account/actor.go.template +++ b/chain/actors/builtin/account/actor.go.template @@ -1,6 +1,7 @@ package account import ( + "github.com/ipfs/go-cid" actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/lotus/chain/actors" "golang.org/x/xerrors" @@ -62,6 +63,17 @@ func MakeState(store adt.Store, av actorstypes.Version, addr address.Address) (S type State interface { cbor.Marshaler + Code() cid.Cid + ActorKey() string + ActorVersion() actorstypes.Version + PubkeyAddress() (address.Address, error) GetState() interface{} } + +func AllCodes() []cid.Cid { + return []cid.Cid{ {{range .versions}} + (&state{{.}}{}).Code(), + {{- end}} + } +} diff --git a/chain/actors/builtin/account/state.go.template b/chain/actors/builtin/account/state.go.template index 93e7dc0db..9b623519d 100644 --- a/chain/actors/builtin/account/state.go.template +++ b/chain/actors/builtin/account/state.go.template @@ -1,10 +1,14 @@ package account import ( + "fmt" + actorstypes "github.com/filecoin-project/go-state-types/actors" + "github.com/filecoin-project/go-address" "github.com/ipfs/go-cid" "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors" {{if (le .v 7)}} account{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/account" @@ -41,4 +45,21 @@ func (s *state{{.v}}) PubkeyAddress() (address.Address, error) { func (s *state{{.v}}) GetState() interface{} { return &s.State +} + +func (s *state{{.v}}) ActorKey() string { + return actors.AccountKey +} + +func (s *state{{.v}}) ActorVersion() actorstypes.Version { + return actorstypes.Version{{.v}} +} + +func (s *state{{.v}}) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code } \ No newline at end of file diff --git a/chain/actors/builtin/account/v0.go b/chain/actors/builtin/account/v0.go index 314bd4b29..f6af2c79c 100644 --- a/chain/actors/builtin/account/v0.go +++ b/chain/actors/builtin/account/v0.go @@ -1,11 +1,15 @@ package account import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-address" + actorstypes "github.com/filecoin-project/go-state-types/actors" account0 "github.com/filecoin-project/specs-actors/actors/builtin/account" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -38,3 +42,20 @@ func (s *state0) PubkeyAddress() (address.Address, error) { func (s *state0) GetState() interface{} { return &s.State } + +func (s *state0) ActorKey() string { + return actors.AccountKey +} + +func (s *state0) ActorVersion() actorstypes.Version { + return actorstypes.Version0 +} + +func (s *state0) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/account/v10.go b/chain/actors/builtin/account/v10.go index 50a68c00c..dbe7c609e 100644 --- a/chain/actors/builtin/account/v10.go +++ b/chain/actors/builtin/account/v10.go @@ -1,11 +1,15 @@ package account import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-address" + actorstypes "github.com/filecoin-project/go-state-types/actors" account10 "github.com/filecoin-project/go-state-types/builtin/v10/account" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -38,3 +42,20 @@ func (s *state10) PubkeyAddress() (address.Address, error) { func (s *state10) GetState() interface{} { return &s.State } + +func (s *state10) ActorKey() string { + return actors.AccountKey +} + +func (s *state10) ActorVersion() actorstypes.Version { + return actorstypes.Version10 +} + +func (s *state10) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/account/v2.go b/chain/actors/builtin/account/v2.go index 605065424..5e2297b4a 100644 --- a/chain/actors/builtin/account/v2.go +++ b/chain/actors/builtin/account/v2.go @@ -1,11 +1,15 @@ package account import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-address" + actorstypes "github.com/filecoin-project/go-state-types/actors" account2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/account" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -38,3 +42,20 @@ func (s *state2) PubkeyAddress() (address.Address, error) { func (s *state2) GetState() interface{} { return &s.State } + +func (s *state2) ActorKey() string { + return actors.AccountKey +} + +func (s *state2) ActorVersion() actorstypes.Version { + return actorstypes.Version2 +} + +func (s *state2) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/account/v3.go b/chain/actors/builtin/account/v3.go index d070476ea..4e142bcf7 100644 --- a/chain/actors/builtin/account/v3.go +++ b/chain/actors/builtin/account/v3.go @@ -1,11 +1,15 @@ package account import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-address" + actorstypes "github.com/filecoin-project/go-state-types/actors" account3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/account" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -38,3 +42,20 @@ func (s *state3) PubkeyAddress() (address.Address, error) { func (s *state3) GetState() interface{} { return &s.State } + +func (s *state3) ActorKey() string { + return actors.AccountKey +} + +func (s *state3) ActorVersion() actorstypes.Version { + return actorstypes.Version3 +} + +func (s *state3) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/account/v4.go b/chain/actors/builtin/account/v4.go index f4d9f7a06..7b1e7f0dd 100644 --- a/chain/actors/builtin/account/v4.go +++ b/chain/actors/builtin/account/v4.go @@ -1,11 +1,15 @@ package account import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-address" + actorstypes "github.com/filecoin-project/go-state-types/actors" account4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/account" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -38,3 +42,20 @@ func (s *state4) PubkeyAddress() (address.Address, error) { func (s *state4) GetState() interface{} { return &s.State } + +func (s *state4) ActorKey() string { + return actors.AccountKey +} + +func (s *state4) ActorVersion() actorstypes.Version { + return actorstypes.Version4 +} + +func (s *state4) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/account/v5.go b/chain/actors/builtin/account/v5.go index 5e01ce152..ad8bed522 100644 --- a/chain/actors/builtin/account/v5.go +++ b/chain/actors/builtin/account/v5.go @@ -1,11 +1,15 @@ package account import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-address" + actorstypes "github.com/filecoin-project/go-state-types/actors" account5 "github.com/filecoin-project/specs-actors/v5/actors/builtin/account" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -38,3 +42,20 @@ func (s *state5) PubkeyAddress() (address.Address, error) { func (s *state5) GetState() interface{} { return &s.State } + +func (s *state5) ActorKey() string { + return actors.AccountKey +} + +func (s *state5) ActorVersion() actorstypes.Version { + return actorstypes.Version5 +} + +func (s *state5) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/account/v6.go b/chain/actors/builtin/account/v6.go index 85135dcda..74c959c5f 100644 --- a/chain/actors/builtin/account/v6.go +++ b/chain/actors/builtin/account/v6.go @@ -1,11 +1,15 @@ package account import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-address" + actorstypes "github.com/filecoin-project/go-state-types/actors" account6 "github.com/filecoin-project/specs-actors/v6/actors/builtin/account" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -38,3 +42,20 @@ func (s *state6) PubkeyAddress() (address.Address, error) { func (s *state6) GetState() interface{} { return &s.State } + +func (s *state6) ActorKey() string { + return actors.AccountKey +} + +func (s *state6) ActorVersion() actorstypes.Version { + return actorstypes.Version6 +} + +func (s *state6) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/account/v7.go b/chain/actors/builtin/account/v7.go index 4ae979b82..24d259f33 100644 --- a/chain/actors/builtin/account/v7.go +++ b/chain/actors/builtin/account/v7.go @@ -1,11 +1,15 @@ package account import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-address" + actorstypes "github.com/filecoin-project/go-state-types/actors" account7 "github.com/filecoin-project/specs-actors/v7/actors/builtin/account" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -38,3 +42,20 @@ func (s *state7) PubkeyAddress() (address.Address, error) { func (s *state7) GetState() interface{} { return &s.State } + +func (s *state7) ActorKey() string { + return actors.AccountKey +} + +func (s *state7) ActorVersion() actorstypes.Version { + return actorstypes.Version7 +} + +func (s *state7) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/account/v8.go b/chain/actors/builtin/account/v8.go index 211deea33..2a4a74ca4 100644 --- a/chain/actors/builtin/account/v8.go +++ b/chain/actors/builtin/account/v8.go @@ -1,11 +1,15 @@ package account import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-address" + actorstypes "github.com/filecoin-project/go-state-types/actors" account8 "github.com/filecoin-project/go-state-types/builtin/v8/account" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -38,3 +42,20 @@ func (s *state8) PubkeyAddress() (address.Address, error) { func (s *state8) GetState() interface{} { return &s.State } + +func (s *state8) ActorKey() string { + return actors.AccountKey +} + +func (s *state8) ActorVersion() actorstypes.Version { + return actorstypes.Version8 +} + +func (s *state8) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/account/v9.go b/chain/actors/builtin/account/v9.go index 7e172b33c..97bcd43d7 100644 --- a/chain/actors/builtin/account/v9.go +++ b/chain/actors/builtin/account/v9.go @@ -1,11 +1,15 @@ package account import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-address" + actorstypes "github.com/filecoin-project/go-state-types/actors" account9 "github.com/filecoin-project/go-state-types/builtin/v9/account" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -38,3 +42,20 @@ func (s *state9) PubkeyAddress() (address.Address, error) { func (s *state9) GetState() interface{} { return &s.State } + +func (s *state9) ActorKey() string { + return actors.AccountKey +} + +func (s *state9) ActorVersion() actorstypes.Version { + return actorstypes.Version9 +} + +func (s *state9) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/cron/actor.go.template b/chain/actors/builtin/cron/actor.go.template index 67c781fb2..3abb33e63 100644 --- a/chain/actors/builtin/cron/actor.go.template +++ b/chain/actors/builtin/cron/actor.go.template @@ -1,6 +1,7 @@ package cron import ( + "github.com/ipfs/go-cid" actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" @@ -60,5 +61,16 @@ var ( type State interface { + Code() cid.Cid + ActorKey() string + ActorVersion() actorstypes.Version + GetState() interface{} } + +func AllCodes() []cid.Cid { + return []cid.Cid{ {{range .versions}} + (&state{{.}}{}).Code(), + {{- end}} + } +} diff --git a/chain/actors/builtin/cron/cron.go b/chain/actors/builtin/cron/cron.go index 2c761b75f..3f573789a 100644 --- a/chain/actors/builtin/cron/cron.go +++ b/chain/actors/builtin/cron/cron.go @@ -1,6 +1,7 @@ package cron import ( + "github.com/ipfs/go-cid" "golang.org/x/xerrors" actorstypes "github.com/filecoin-project/go-state-types/actors" @@ -109,5 +110,24 @@ var ( ) type State interface { + Code() cid.Cid + ActorKey() string + ActorVersion() actorstypes.Version + GetState() interface{} } + +func AllCodes() []cid.Cid { + return []cid.Cid{ + (&state0{}).Code(), + (&state2{}).Code(), + (&state3{}).Code(), + (&state4{}).Code(), + (&state5{}).Code(), + (&state6{}).Code(), + (&state7{}).Code(), + (&state8{}).Code(), + (&state9{}).Code(), + (&state10{}).Code(), + } +} diff --git a/chain/actors/builtin/cron/state.go.template b/chain/actors/builtin/cron/state.go.template index 13cdc46c9..24739f162 100644 --- a/chain/actors/builtin/cron/state.go.template +++ b/chain/actors/builtin/cron/state.go.template @@ -1,9 +1,12 @@ package cron import ( + "fmt" "github.com/ipfs/go-cid" "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors" + actorstypes "github.com/filecoin-project/go-state-types/actors" {{if (le .v 7)}} cron{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/cron" @@ -36,4 +39,21 @@ type state{{.v}} struct { func (s *state{{.v}}) GetState() interface{} { return &s.State -} \ No newline at end of file +} + +func (s *state{{.v}}) ActorKey() string { + return actors.CronKey +} + +func (s *state{{.v}}) ActorVersion() actorstypes.Version { + return actorstypes.Version{{.v}} +} + +func (s *state{{.v}}) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/cron/v0.go b/chain/actors/builtin/cron/v0.go index baa81aac3..ef5f6d93e 100644 --- a/chain/actors/builtin/cron/v0.go +++ b/chain/actors/builtin/cron/v0.go @@ -1,10 +1,14 @@ package cron import ( + "fmt" + "github.com/ipfs/go-cid" + actorstypes "github.com/filecoin-project/go-state-types/actors" cron0 "github.com/filecoin-project/specs-actors/actors/builtin/cron" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -33,3 +37,20 @@ type state0 struct { func (s *state0) GetState() interface{} { return &s.State } + +func (s *state0) ActorKey() string { + return actors.CronKey +} + +func (s *state0) ActorVersion() actorstypes.Version { + return actorstypes.Version0 +} + +func (s *state0) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/cron/v10.go b/chain/actors/builtin/cron/v10.go index c1ef1b4e7..4e2e1c815 100644 --- a/chain/actors/builtin/cron/v10.go +++ b/chain/actors/builtin/cron/v10.go @@ -1,10 +1,14 @@ package cron import ( + "fmt" + "github.com/ipfs/go-cid" + actorstypes "github.com/filecoin-project/go-state-types/actors" cron10 "github.com/filecoin-project/go-state-types/builtin/v10/cron" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -33,3 +37,20 @@ type state10 struct { func (s *state10) GetState() interface{} { return &s.State } + +func (s *state10) ActorKey() string { + return actors.CronKey +} + +func (s *state10) ActorVersion() actorstypes.Version { + return actorstypes.Version10 +} + +func (s *state10) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/cron/v2.go b/chain/actors/builtin/cron/v2.go index d6ee35935..fc45be0de 100644 --- a/chain/actors/builtin/cron/v2.go +++ b/chain/actors/builtin/cron/v2.go @@ -1,10 +1,14 @@ package cron import ( + "fmt" + "github.com/ipfs/go-cid" + actorstypes "github.com/filecoin-project/go-state-types/actors" cron2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/cron" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -33,3 +37,20 @@ type state2 struct { func (s *state2) GetState() interface{} { return &s.State } + +func (s *state2) ActorKey() string { + return actors.CronKey +} + +func (s *state2) ActorVersion() actorstypes.Version { + return actorstypes.Version2 +} + +func (s *state2) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/cron/v3.go b/chain/actors/builtin/cron/v3.go index 356d385cd..6f8e66a3b 100644 --- a/chain/actors/builtin/cron/v3.go +++ b/chain/actors/builtin/cron/v3.go @@ -1,10 +1,14 @@ package cron import ( + "fmt" + "github.com/ipfs/go-cid" + actorstypes "github.com/filecoin-project/go-state-types/actors" cron3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/cron" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -33,3 +37,20 @@ type state3 struct { func (s *state3) GetState() interface{} { return &s.State } + +func (s *state3) ActorKey() string { + return actors.CronKey +} + +func (s *state3) ActorVersion() actorstypes.Version { + return actorstypes.Version3 +} + +func (s *state3) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/cron/v4.go b/chain/actors/builtin/cron/v4.go index 3db3c95aa..2539f2b1c 100644 --- a/chain/actors/builtin/cron/v4.go +++ b/chain/actors/builtin/cron/v4.go @@ -1,10 +1,14 @@ package cron import ( + "fmt" + "github.com/ipfs/go-cid" + actorstypes "github.com/filecoin-project/go-state-types/actors" cron4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/cron" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -33,3 +37,20 @@ type state4 struct { func (s *state4) GetState() interface{} { return &s.State } + +func (s *state4) ActorKey() string { + return actors.CronKey +} + +func (s *state4) ActorVersion() actorstypes.Version { + return actorstypes.Version4 +} + +func (s *state4) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/cron/v5.go b/chain/actors/builtin/cron/v5.go index 5d99af1fd..8aba47a2b 100644 --- a/chain/actors/builtin/cron/v5.go +++ b/chain/actors/builtin/cron/v5.go @@ -1,10 +1,14 @@ package cron import ( + "fmt" + "github.com/ipfs/go-cid" + actorstypes "github.com/filecoin-project/go-state-types/actors" cron5 "github.com/filecoin-project/specs-actors/v5/actors/builtin/cron" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -33,3 +37,20 @@ type state5 struct { func (s *state5) GetState() interface{} { return &s.State } + +func (s *state5) ActorKey() string { + return actors.CronKey +} + +func (s *state5) ActorVersion() actorstypes.Version { + return actorstypes.Version5 +} + +func (s *state5) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/cron/v6.go b/chain/actors/builtin/cron/v6.go index c86cd6c42..f607a409f 100644 --- a/chain/actors/builtin/cron/v6.go +++ b/chain/actors/builtin/cron/v6.go @@ -1,10 +1,14 @@ package cron import ( + "fmt" + "github.com/ipfs/go-cid" + actorstypes "github.com/filecoin-project/go-state-types/actors" cron6 "github.com/filecoin-project/specs-actors/v6/actors/builtin/cron" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -33,3 +37,20 @@ type state6 struct { func (s *state6) GetState() interface{} { return &s.State } + +func (s *state6) ActorKey() string { + return actors.CronKey +} + +func (s *state6) ActorVersion() actorstypes.Version { + return actorstypes.Version6 +} + +func (s *state6) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/cron/v7.go b/chain/actors/builtin/cron/v7.go index db9f8f9e2..ef962fd41 100644 --- a/chain/actors/builtin/cron/v7.go +++ b/chain/actors/builtin/cron/v7.go @@ -1,10 +1,14 @@ package cron import ( + "fmt" + "github.com/ipfs/go-cid" + actorstypes "github.com/filecoin-project/go-state-types/actors" cron7 "github.com/filecoin-project/specs-actors/v7/actors/builtin/cron" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -33,3 +37,20 @@ type state7 struct { func (s *state7) GetState() interface{} { return &s.State } + +func (s *state7) ActorKey() string { + return actors.CronKey +} + +func (s *state7) ActorVersion() actorstypes.Version { + return actorstypes.Version7 +} + +func (s *state7) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/cron/v8.go b/chain/actors/builtin/cron/v8.go index 00567acf9..377cba060 100644 --- a/chain/actors/builtin/cron/v8.go +++ b/chain/actors/builtin/cron/v8.go @@ -1,10 +1,14 @@ package cron import ( + "fmt" + "github.com/ipfs/go-cid" + actorstypes "github.com/filecoin-project/go-state-types/actors" cron8 "github.com/filecoin-project/go-state-types/builtin/v8/cron" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -33,3 +37,20 @@ type state8 struct { func (s *state8) GetState() interface{} { return &s.State } + +func (s *state8) ActorKey() string { + return actors.CronKey +} + +func (s *state8) ActorVersion() actorstypes.Version { + return actorstypes.Version8 +} + +func (s *state8) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/cron/v9.go b/chain/actors/builtin/cron/v9.go index 312a33b68..b2e1d1265 100644 --- a/chain/actors/builtin/cron/v9.go +++ b/chain/actors/builtin/cron/v9.go @@ -1,10 +1,14 @@ package cron import ( + "fmt" + "github.com/ipfs/go-cid" + actorstypes "github.com/filecoin-project/go-state-types/actors" cron9 "github.com/filecoin-project/go-state-types/builtin/v9/cron" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -33,3 +37,20 @@ type state9 struct { func (s *state9) GetState() interface{} { return &s.State } + +func (s *state9) ActorKey() string { + return actors.CronKey +} + +func (s *state9) ActorVersion() actorstypes.Version { + return actorstypes.Version9 +} + +func (s *state9) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/datacap/actor.go.template b/chain/actors/builtin/datacap/actor.go.template index c62bdaa21..15272d7d1 100644 --- a/chain/actors/builtin/datacap/actor.go.template +++ b/chain/actors/builtin/datacap/actor.go.template @@ -3,6 +3,8 @@ package datacap import ( "golang.org/x/xerrors" + "github.com/ipfs/go-cid" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" actorstypes "github.com/filecoin-project/go-state-types/actors" @@ -49,8 +51,19 @@ func MakeState(store adt.Store, av actorstypes.Version, governor address.Address type State interface { cbor.Marshaler + Code() cid.Cid + ActorKey() string + ActorVersion() actorstypes.Version + ForEachClient(func(addr address.Address, dcap abi.StoragePower) error) error VerifiedClientDataCap(address.Address) (bool, abi.StoragePower, error) Governor() (address.Address, error) GetState() interface{} } + +func AllCodes() []cid.Cid { + return []cid.Cid{ {{range .versions}} + (&state{{.}}{}).Code(), + {{- end}} + } +} diff --git a/chain/actors/builtin/datacap/datacap.go b/chain/actors/builtin/datacap/datacap.go index 2526024da..977c020d3 100644 --- a/chain/actors/builtin/datacap/datacap.go +++ b/chain/actors/builtin/datacap/datacap.go @@ -1,6 +1,7 @@ package datacap import ( + "github.com/ipfs/go-cid" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" @@ -56,8 +57,19 @@ func MakeState(store adt.Store, av actorstypes.Version, governor address.Address type State interface { cbor.Marshaler + Code() cid.Cid + ActorKey() string + ActorVersion() actorstypes.Version + ForEachClient(func(addr address.Address, dcap abi.StoragePower) error) error VerifiedClientDataCap(address.Address) (bool, abi.StoragePower, error) Governor() (address.Address, error) GetState() interface{} } + +func AllCodes() []cid.Cid { + return []cid.Cid{ + (&state9{}).Code(), + (&state10{}).Code(), + } +} diff --git a/chain/actors/builtin/datacap/state.go.template b/chain/actors/builtin/datacap/state.go.template index 297f9f79f..dfb6eaad4 100644 --- a/chain/actors/builtin/datacap/state.go.template +++ b/chain/actors/builtin/datacap/state.go.template @@ -1,12 +1,14 @@ package datacap import ( + "fmt" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/ipfs/go-cid" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" + actorstypes "github.com/filecoin-project/go-state-types/actors" datacap{{.v}} "github.com/filecoin-project/go-state-types/builtin{{.import}}datacap" adt{{.v}} "github.com/filecoin-project/go-state-types/builtin{{.import}}util/adt" @@ -59,3 +61,20 @@ func (s *state{{.v}}) verifiedClients() (adt.Map, error) { func (s *state{{.v}}) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) { return getDataCap(s.store, actors.Version{{.v}}, s.verifiedClients, addr) } + +func (s *state{{.v}}) ActorKey() string { + return actors.DatacapKey +} + +func (s *state{{.v}}) ActorVersion() actorstypes.Version { + return actorstypes.Version{{.v}} +} + +func (s *state{{.v}}) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/datacap/v10.go b/chain/actors/builtin/datacap/v10.go index aa34fe2cd..6f4c8593d 100644 --- a/chain/actors/builtin/datacap/v10.go +++ b/chain/actors/builtin/datacap/v10.go @@ -1,10 +1,13 @@ package datacap import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" datacap10 "github.com/filecoin-project/go-state-types/builtin/v10/datacap" adt10 "github.com/filecoin-project/go-state-types/builtin/v10/util/adt" @@ -59,3 +62,20 @@ func (s *state10) verifiedClients() (adt.Map, error) { func (s *state10) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) { return getDataCap(s.store, actors.Version10, s.verifiedClients, addr) } + +func (s *state10) ActorKey() string { + return actors.DatacapKey +} + +func (s *state10) ActorVersion() actorstypes.Version { + return actorstypes.Version10 +} + +func (s *state10) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/datacap/v9.go b/chain/actors/builtin/datacap/v9.go index a6e4bbcd6..6dcf04477 100644 --- a/chain/actors/builtin/datacap/v9.go +++ b/chain/actors/builtin/datacap/v9.go @@ -1,10 +1,13 @@ package datacap import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" datacap9 "github.com/filecoin-project/go-state-types/builtin/v9/datacap" adt9 "github.com/filecoin-project/go-state-types/builtin/v9/util/adt" @@ -59,3 +62,20 @@ func (s *state9) verifiedClients() (adt.Map, error) { func (s *state9) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) { return getDataCap(s.store, actors.Version9, s.verifiedClients, addr) } + +func (s *state9) ActorKey() string { + return actors.DatacapKey +} + +func (s *state9) ActorVersion() actorstypes.Version { + return actorstypes.Version9 +} + +func (s *state9) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/init/actor.go.template b/chain/actors/builtin/init/actor.go.template index 43bb70c4c..453aba963 100644 --- a/chain/actors/builtin/init/actor.go.template +++ b/chain/actors/builtin/init/actor.go.template @@ -67,6 +67,10 @@ func MakeState(store adt.Store, av actorstypes.Version, networkName string) (Sta type State interface { cbor.Marshaler + Code() cid.Cid + ActorKey() string + ActorVersion() actorstypes.Version + ResolveAddress(address address.Address) (address.Address, bool, error) MapAddressToNewID(address address.Address) (address.Address, error) NetworkName() (dtypes.NetworkName, error) @@ -87,6 +91,16 @@ type State interface { // Sets the address map for the init actor. This should only be used for testing. SetAddressMap(mcid cid.Cid) error - AddressMap() (adt.Map, error) GetState() interface{} + + AddressMap() (adt.Map, error) + AddressMapBitWidth() int + AddressMapHashFunction() func(input []byte) []byte +} + +func AllCodes() []cid.Cid { + return []cid.Cid{ {{range .versions}} + (&state{{.}}{}).Code(), + {{- end}} + } } diff --git a/chain/actors/builtin/init/init.go b/chain/actors/builtin/init/init.go index a14f33826..a97d40297 100644 --- a/chain/actors/builtin/init/init.go +++ b/chain/actors/builtin/init/init.go @@ -116,6 +116,10 @@ func MakeState(store adt.Store, av actorstypes.Version, networkName string) (Sta type State interface { cbor.Marshaler + Code() cid.Cid + ActorKey() string + ActorVersion() actorstypes.Version + ResolveAddress(address address.Address) (address.Address, bool, error) MapAddressToNewID(address address.Address) (address.Address, error) NetworkName() (dtypes.NetworkName, error) @@ -136,6 +140,24 @@ type State interface { // Sets the address map for the init actor. This should only be used for testing. SetAddressMap(mcid cid.Cid) error - AddressMap() (adt.Map, error) GetState() interface{} + + AddressMap() (adt.Map, error) + AddressMapBitWidth() int + AddressMapHashFunction() func(input []byte) []byte +} + +func AllCodes() []cid.Cid { + return []cid.Cid{ + (&state0{}).Code(), + (&state2{}).Code(), + (&state3{}).Code(), + (&state4{}).Code(), + (&state5{}).Code(), + (&state6{}).Code(), + (&state7{}).Code(), + (&state8{}).Code(), + (&state9{}).Code(), + (&state10{}).Code(), + } } diff --git a/chain/actors/builtin/init/state.go.template b/chain/actors/builtin/init/state.go.template index 0e56f5da4..c31aef6a0 100644 --- a/chain/actors/builtin/init/state.go.template +++ b/chain/actors/builtin/init/state.go.template @@ -1,13 +1,18 @@ package init import ( + "crypto/sha256" + "fmt" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" + actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/lotus/node/modules/dtypes" {{if (le .v 7)}} @@ -119,10 +124,42 @@ func (s *state{{.v}}) SetAddressMap(mcid cid.Cid) error { return nil } +func (s *state{{.v}}) GetState() interface{} { + return &s.State +} + func (s *state{{.v}}) AddressMap() (adt.Map, error) { return adt{{.v}}.AsMap(s.store, s.State.AddressMap{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}}) } -func (s *state{{.v}}) GetState() interface{} { - return &s.State -} \ No newline at end of file +func (s *state{{.v}}) AddressMapBitWidth() int { + {{- if (ge .v 3)}} + return builtin{{.v}}.DefaultHamtBitwidth + {{- else}} + return 5 + {{- end}} +} + +func (s *state{{.v}}) AddressMapHashFunction() func(input []byte) []byte { + return func(input []byte) []byte { + res := sha256.Sum256(input) + return res[:] + } +} + +func (s *state{{.v}}) ActorKey() string { + return actors.InitKey +} + +func (s *state{{.v}}) ActorVersion() actorstypes.Version { + return actorstypes.Version{{.v}} +} + +func (s *state{{.v}}) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/init/v0.go b/chain/actors/builtin/init/v0.go index 2f6b213c0..61ae3f2db 100644 --- a/chain/actors/builtin/init/v0.go +++ b/chain/actors/builtin/init/v0.go @@ -1,15 +1,20 @@ package init import ( + "crypto/sha256" + "fmt" + "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" init0 "github.com/filecoin-project/specs-actors/actors/builtin/init" adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/node/modules/dtypes" ) @@ -103,10 +108,38 @@ func (s *state0) SetAddressMap(mcid cid.Cid) error { return nil } +func (s *state0) GetState() interface{} { + return &s.State +} + func (s *state0) AddressMap() (adt.Map, error) { return adt0.AsMap(s.store, s.State.AddressMap) } -func (s *state0) GetState() interface{} { - return &s.State +func (s *state0) AddressMapBitWidth() int { + return 5 +} + +func (s *state0) AddressMapHashFunction() func(input []byte) []byte { + return func(input []byte) []byte { + res := sha256.Sum256(input) + return res[:] + } +} + +func (s *state0) ActorKey() string { + return actors.InitKey +} + +func (s *state0) ActorVersion() actorstypes.Version { + return actorstypes.Version0 +} + +func (s *state0) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code } diff --git a/chain/actors/builtin/init/v10.go b/chain/actors/builtin/init/v10.go index 248d627fc..761f9dacc 100644 --- a/chain/actors/builtin/init/v10.go +++ b/chain/actors/builtin/init/v10.go @@ -1,16 +1,21 @@ package init import ( + "crypto/sha256" + "fmt" + "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" builtin10 "github.com/filecoin-project/go-state-types/builtin" init10 "github.com/filecoin-project/go-state-types/builtin/v10/init" adt10 "github.com/filecoin-project/go-state-types/builtin/v10/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/node/modules/dtypes" ) @@ -104,10 +109,38 @@ func (s *state10) SetAddressMap(mcid cid.Cid) error { return nil } +func (s *state10) GetState() interface{} { + return &s.State +} + func (s *state10) AddressMap() (adt.Map, error) { return adt10.AsMap(s.store, s.State.AddressMap, builtin10.DefaultHamtBitwidth) } -func (s *state10) GetState() interface{} { - return &s.State +func (s *state10) AddressMapBitWidth() int { + return builtin10.DefaultHamtBitwidth +} + +func (s *state10) AddressMapHashFunction() func(input []byte) []byte { + return func(input []byte) []byte { + res := sha256.Sum256(input) + return res[:] + } +} + +func (s *state10) ActorKey() string { + return actors.InitKey +} + +func (s *state10) ActorVersion() actorstypes.Version { + return actorstypes.Version10 +} + +func (s *state10) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code } diff --git a/chain/actors/builtin/init/v2.go b/chain/actors/builtin/init/v2.go index d780a1fe9..dfbdde6c9 100644 --- a/chain/actors/builtin/init/v2.go +++ b/chain/actors/builtin/init/v2.go @@ -1,15 +1,20 @@ package init import ( + "crypto/sha256" + "fmt" + "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" init2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/init" adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/node/modules/dtypes" ) @@ -103,10 +108,38 @@ func (s *state2) SetAddressMap(mcid cid.Cid) error { return nil } +func (s *state2) GetState() interface{} { + return &s.State +} + func (s *state2) AddressMap() (adt.Map, error) { return adt2.AsMap(s.store, s.State.AddressMap) } -func (s *state2) GetState() interface{} { - return &s.State +func (s *state2) AddressMapBitWidth() int { + return 5 +} + +func (s *state2) AddressMapHashFunction() func(input []byte) []byte { + return func(input []byte) []byte { + res := sha256.Sum256(input) + return res[:] + } +} + +func (s *state2) ActorKey() string { + return actors.InitKey +} + +func (s *state2) ActorVersion() actorstypes.Version { + return actorstypes.Version2 +} + +func (s *state2) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code } diff --git a/chain/actors/builtin/init/v3.go b/chain/actors/builtin/init/v3.go index b2f713b1f..56a5e4afd 100644 --- a/chain/actors/builtin/init/v3.go +++ b/chain/actors/builtin/init/v3.go @@ -1,16 +1,21 @@ package init import ( + "crypto/sha256" + "fmt" + "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" init3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/init" adt3 "github.com/filecoin-project/specs-actors/v3/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/node/modules/dtypes" ) @@ -104,10 +109,38 @@ func (s *state3) SetAddressMap(mcid cid.Cid) error { return nil } +func (s *state3) GetState() interface{} { + return &s.State +} + func (s *state3) AddressMap() (adt.Map, error) { return adt3.AsMap(s.store, s.State.AddressMap, builtin3.DefaultHamtBitwidth) } -func (s *state3) GetState() interface{} { - return &s.State +func (s *state3) AddressMapBitWidth() int { + return builtin3.DefaultHamtBitwidth +} + +func (s *state3) AddressMapHashFunction() func(input []byte) []byte { + return func(input []byte) []byte { + res := sha256.Sum256(input) + return res[:] + } +} + +func (s *state3) ActorKey() string { + return actors.InitKey +} + +func (s *state3) ActorVersion() actorstypes.Version { + return actorstypes.Version3 +} + +func (s *state3) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code } diff --git a/chain/actors/builtin/init/v4.go b/chain/actors/builtin/init/v4.go index 9de02816f..b1ecd3188 100644 --- a/chain/actors/builtin/init/v4.go +++ b/chain/actors/builtin/init/v4.go @@ -1,16 +1,21 @@ package init import ( + "crypto/sha256" + "fmt" + "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" init4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/init" adt4 "github.com/filecoin-project/specs-actors/v4/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/node/modules/dtypes" ) @@ -104,10 +109,38 @@ func (s *state4) SetAddressMap(mcid cid.Cid) error { return nil } +func (s *state4) GetState() interface{} { + return &s.State +} + func (s *state4) AddressMap() (adt.Map, error) { return adt4.AsMap(s.store, s.State.AddressMap, builtin4.DefaultHamtBitwidth) } -func (s *state4) GetState() interface{} { - return &s.State +func (s *state4) AddressMapBitWidth() int { + return builtin4.DefaultHamtBitwidth +} + +func (s *state4) AddressMapHashFunction() func(input []byte) []byte { + return func(input []byte) []byte { + res := sha256.Sum256(input) + return res[:] + } +} + +func (s *state4) ActorKey() string { + return actors.InitKey +} + +func (s *state4) ActorVersion() actorstypes.Version { + return actorstypes.Version4 +} + +func (s *state4) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code } diff --git a/chain/actors/builtin/init/v5.go b/chain/actors/builtin/init/v5.go index f9c59f83a..b8a6438d7 100644 --- a/chain/actors/builtin/init/v5.go +++ b/chain/actors/builtin/init/v5.go @@ -1,16 +1,21 @@ package init import ( + "crypto/sha256" + "fmt" + "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" builtin5 "github.com/filecoin-project/specs-actors/v5/actors/builtin" init5 "github.com/filecoin-project/specs-actors/v5/actors/builtin/init" adt5 "github.com/filecoin-project/specs-actors/v5/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/node/modules/dtypes" ) @@ -104,10 +109,38 @@ func (s *state5) SetAddressMap(mcid cid.Cid) error { return nil } +func (s *state5) GetState() interface{} { + return &s.State +} + func (s *state5) AddressMap() (adt.Map, error) { return adt5.AsMap(s.store, s.State.AddressMap, builtin5.DefaultHamtBitwidth) } -func (s *state5) GetState() interface{} { - return &s.State +func (s *state5) AddressMapBitWidth() int { + return builtin5.DefaultHamtBitwidth +} + +func (s *state5) AddressMapHashFunction() func(input []byte) []byte { + return func(input []byte) []byte { + res := sha256.Sum256(input) + return res[:] + } +} + +func (s *state5) ActorKey() string { + return actors.InitKey +} + +func (s *state5) ActorVersion() actorstypes.Version { + return actorstypes.Version5 +} + +func (s *state5) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code } diff --git a/chain/actors/builtin/init/v6.go b/chain/actors/builtin/init/v6.go index 494b6aaa0..aeadc2caf 100644 --- a/chain/actors/builtin/init/v6.go +++ b/chain/actors/builtin/init/v6.go @@ -1,16 +1,21 @@ package init import ( + "crypto/sha256" + "fmt" + "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" builtin6 "github.com/filecoin-project/specs-actors/v6/actors/builtin" init6 "github.com/filecoin-project/specs-actors/v6/actors/builtin/init" adt6 "github.com/filecoin-project/specs-actors/v6/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/node/modules/dtypes" ) @@ -104,10 +109,38 @@ func (s *state6) SetAddressMap(mcid cid.Cid) error { return nil } +func (s *state6) GetState() interface{} { + return &s.State +} + func (s *state6) AddressMap() (adt.Map, error) { return adt6.AsMap(s.store, s.State.AddressMap, builtin6.DefaultHamtBitwidth) } -func (s *state6) GetState() interface{} { - return &s.State +func (s *state6) AddressMapBitWidth() int { + return builtin6.DefaultHamtBitwidth +} + +func (s *state6) AddressMapHashFunction() func(input []byte) []byte { + return func(input []byte) []byte { + res := sha256.Sum256(input) + return res[:] + } +} + +func (s *state6) ActorKey() string { + return actors.InitKey +} + +func (s *state6) ActorVersion() actorstypes.Version { + return actorstypes.Version6 +} + +func (s *state6) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code } diff --git a/chain/actors/builtin/init/v7.go b/chain/actors/builtin/init/v7.go index bc378a141..e62c56277 100644 --- a/chain/actors/builtin/init/v7.go +++ b/chain/actors/builtin/init/v7.go @@ -1,16 +1,21 @@ package init import ( + "crypto/sha256" + "fmt" + "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" builtin7 "github.com/filecoin-project/specs-actors/v7/actors/builtin" init7 "github.com/filecoin-project/specs-actors/v7/actors/builtin/init" adt7 "github.com/filecoin-project/specs-actors/v7/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/node/modules/dtypes" ) @@ -104,10 +109,38 @@ func (s *state7) SetAddressMap(mcid cid.Cid) error { return nil } +func (s *state7) GetState() interface{} { + return &s.State +} + func (s *state7) AddressMap() (adt.Map, error) { return adt7.AsMap(s.store, s.State.AddressMap, builtin7.DefaultHamtBitwidth) } -func (s *state7) GetState() interface{} { - return &s.State +func (s *state7) AddressMapBitWidth() int { + return builtin7.DefaultHamtBitwidth +} + +func (s *state7) AddressMapHashFunction() func(input []byte) []byte { + return func(input []byte) []byte { + res := sha256.Sum256(input) + return res[:] + } +} + +func (s *state7) ActorKey() string { + return actors.InitKey +} + +func (s *state7) ActorVersion() actorstypes.Version { + return actorstypes.Version7 +} + +func (s *state7) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code } diff --git a/chain/actors/builtin/init/v8.go b/chain/actors/builtin/init/v8.go index 63b058e57..145b75551 100644 --- a/chain/actors/builtin/init/v8.go +++ b/chain/actors/builtin/init/v8.go @@ -1,16 +1,21 @@ package init import ( + "crypto/sha256" + "fmt" + "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" builtin8 "github.com/filecoin-project/go-state-types/builtin" init8 "github.com/filecoin-project/go-state-types/builtin/v8/init" adt8 "github.com/filecoin-project/go-state-types/builtin/v8/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/node/modules/dtypes" ) @@ -104,10 +109,38 @@ func (s *state8) SetAddressMap(mcid cid.Cid) error { return nil } +func (s *state8) GetState() interface{} { + return &s.State +} + func (s *state8) AddressMap() (adt.Map, error) { return adt8.AsMap(s.store, s.State.AddressMap, builtin8.DefaultHamtBitwidth) } -func (s *state8) GetState() interface{} { - return &s.State +func (s *state8) AddressMapBitWidth() int { + return builtin8.DefaultHamtBitwidth +} + +func (s *state8) AddressMapHashFunction() func(input []byte) []byte { + return func(input []byte) []byte { + res := sha256.Sum256(input) + return res[:] + } +} + +func (s *state8) ActorKey() string { + return actors.InitKey +} + +func (s *state8) ActorVersion() actorstypes.Version { + return actorstypes.Version8 +} + +func (s *state8) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code } diff --git a/chain/actors/builtin/init/v9.go b/chain/actors/builtin/init/v9.go index 6153b4f73..8cba18e7a 100644 --- a/chain/actors/builtin/init/v9.go +++ b/chain/actors/builtin/init/v9.go @@ -1,16 +1,21 @@ package init import ( + "crypto/sha256" + "fmt" + "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" builtin9 "github.com/filecoin-project/go-state-types/builtin" init9 "github.com/filecoin-project/go-state-types/builtin/v9/init" adt9 "github.com/filecoin-project/go-state-types/builtin/v9/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/node/modules/dtypes" ) @@ -104,10 +109,38 @@ func (s *state9) SetAddressMap(mcid cid.Cid) error { return nil } +func (s *state9) GetState() interface{} { + return &s.State +} + func (s *state9) AddressMap() (adt.Map, error) { return adt9.AsMap(s.store, s.State.AddressMap, builtin9.DefaultHamtBitwidth) } -func (s *state9) GetState() interface{} { - return &s.State +func (s *state9) AddressMapBitWidth() int { + return builtin9.DefaultHamtBitwidth +} + +func (s *state9) AddressMapHashFunction() func(input []byte) []byte { + return func(input []byte) []byte { + res := sha256.Sum256(input) + return res[:] + } +} + +func (s *state9) ActorKey() string { + return actors.InitKey +} + +func (s *state9) ActorVersion() actorstypes.Version { + return actorstypes.Version9 +} + +func (s *state9) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code } diff --git a/chain/actors/builtin/market/actor.go.template b/chain/actors/builtin/market/actor.go.template index fa0622ff0..b8d8c987b 100644 --- a/chain/actors/builtin/market/actor.go.template +++ b/chain/actors/builtin/market/actor.go.template @@ -1,6 +1,7 @@ package market import ( + "github.com/ipfs/go-cid" actorstypes "github.com/filecoin-project/go-state-types/actors" "unicode/utf8" @@ -73,6 +74,11 @@ func MakeState(store adt.Store, av actorstypes.Version) (State, error) { type State interface { cbor.Marshaler + + Code() cid.Cid + ActorKey() string + ActorVersion() actorstypes.Version + BalancesChanged(State) (bool, error) EscrowTable() (BalanceTable, error) LockedTable() (BalanceTable, error) @@ -200,3 +206,10 @@ func labelFromGoString(s string) (markettypes.DealLabel, error) { return markettypes.NewLabelFromBytes([]byte(s)) } } + +func AllCodes() []cid.Cid { + return []cid.Cid{ {{range .versions}} + (&state{{.}}{}).Code(), + {{- end}} + } +} diff --git a/chain/actors/builtin/market/market.go b/chain/actors/builtin/market/market.go index f41e80d59..e96484d64 100644 --- a/chain/actors/builtin/market/market.go +++ b/chain/actors/builtin/market/market.go @@ -3,6 +3,7 @@ package market import ( "unicode/utf8" + "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" @@ -120,6 +121,11 @@ func MakeState(store adt.Store, av actorstypes.Version) (State, error) { type State interface { cbor.Marshaler + + Code() cid.Cid + ActorKey() string + ActorVersion() actorstypes.Version + BalancesChanged(State) (bool, error) EscrowTable() (BalanceTable, error) LockedTable() (BalanceTable, error) @@ -273,3 +279,18 @@ func labelFromGoString(s string) (markettypes.DealLabel, error) { return markettypes.NewLabelFromBytes([]byte(s)) } } + +func AllCodes() []cid.Cid { + return []cid.Cid{ + (&state0{}).Code(), + (&state2{}).Code(), + (&state3{}).Code(), + (&state4{}).Code(), + (&state5{}).Code(), + (&state6{}).Code(), + (&state7{}).Code(), + (&state8{}).Code(), + (&state9{}).Code(), + (&state10{}).Code(), + } +} diff --git a/chain/actors/builtin/market/state.go.template b/chain/actors/builtin/market/state.go.template index 61d1de5eb..2f7652673 100644 --- a/chain/actors/builtin/market/state.go.template +++ b/chain/actors/builtin/market/state.go.template @@ -1,6 +1,7 @@ package market import ( + "fmt" "bytes" "github.com/filecoin-project/go-address" @@ -14,7 +15,9 @@ import ( {{end}} + actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/types" verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" @@ -387,3 +390,21 @@ func (s *state{{.v}}) GetAllocationIdForPendingDeal(dealId abi.DealID) (verifreg return verifregtypes.AllocationId(allocationId), nil {{end}} } + + +func (s *state{{.v}}) ActorKey() string { + return actors.MarketKey +} + +func (s *state{{.v}}) ActorVersion() actorstypes.Version { + return actorstypes.Version{{.v}} +} + +func (s *state{{.v}}) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/market/v0.go b/chain/actors/builtin/market/v0.go index aa68049bb..fe50dc04e 100644 --- a/chain/actors/builtin/market/v0.go +++ b/chain/actors/builtin/market/v0.go @@ -2,6 +2,7 @@ package market import ( "bytes" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -9,10 +10,12 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" market0 "github.com/filecoin-project/specs-actors/actors/builtin/market" adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/types" ) @@ -307,3 +310,20 @@ func (s *state0) GetAllocationIdForPendingDeal(dealId abi.DealID) (verifregtypes return verifregtypes.NoAllocationID, xerrors.Errorf("unsupported before actors v9") } + +func (s *state0) ActorKey() string { + return actors.MarketKey +} + +func (s *state0) ActorVersion() actorstypes.Version { + return actorstypes.Version0 +} + +func (s *state0) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/market/v10.go b/chain/actors/builtin/market/v10.go index 8159f213b..d66942846 100644 --- a/chain/actors/builtin/market/v10.go +++ b/chain/actors/builtin/market/v10.go @@ -2,6 +2,7 @@ package market import ( "bytes" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -11,12 +12,14 @@ import ( "github.com/filecoin-project/go-bitfield" rlepluslazy "github.com/filecoin-project/go-bitfield/rle" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/go-state-types/builtin" market10 "github.com/filecoin-project/go-state-types/builtin/v10/market" adt10 "github.com/filecoin-project/go-state-types/builtin/v10/util/adt" markettypes "github.com/filecoin-project/go-state-types/builtin/v9/market" verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/types" ) @@ -347,3 +350,20 @@ func (s *state10) GetAllocationIdForPendingDeal(dealId abi.DealID) (verifregtype return verifregtypes.AllocationId(allocationId), nil } + +func (s *state10) ActorKey() string { + return actors.MarketKey +} + +func (s *state10) ActorVersion() actorstypes.Version { + return actorstypes.Version10 +} + +func (s *state10) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/market/v2.go b/chain/actors/builtin/market/v2.go index 777a17cd0..a10895dc7 100644 --- a/chain/actors/builtin/market/v2.go +++ b/chain/actors/builtin/market/v2.go @@ -2,6 +2,7 @@ package market import ( "bytes" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -9,10 +10,12 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market" adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/types" ) @@ -307,3 +310,20 @@ func (s *state2) GetAllocationIdForPendingDeal(dealId abi.DealID) (verifregtypes return verifregtypes.NoAllocationID, xerrors.Errorf("unsupported before actors v9") } + +func (s *state2) ActorKey() string { + return actors.MarketKey +} + +func (s *state2) ActorVersion() actorstypes.Version { + return actorstypes.Version2 +} + +func (s *state2) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/market/v3.go b/chain/actors/builtin/market/v3.go index 5ca09fdfb..c207ebab1 100644 --- a/chain/actors/builtin/market/v3.go +++ b/chain/actors/builtin/market/v3.go @@ -2,6 +2,7 @@ package market import ( "bytes" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -9,10 +10,12 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" market3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/market" adt3 "github.com/filecoin-project/specs-actors/v3/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/types" ) @@ -302,3 +305,20 @@ func (s *state3) GetAllocationIdForPendingDeal(dealId abi.DealID) (verifregtypes return verifregtypes.NoAllocationID, xerrors.Errorf("unsupported before actors v9") } + +func (s *state3) ActorKey() string { + return actors.MarketKey +} + +func (s *state3) ActorVersion() actorstypes.Version { + return actorstypes.Version3 +} + +func (s *state3) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/market/v4.go b/chain/actors/builtin/market/v4.go index 23422ec31..e90f67720 100644 --- a/chain/actors/builtin/market/v4.go +++ b/chain/actors/builtin/market/v4.go @@ -2,6 +2,7 @@ package market import ( "bytes" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -9,10 +10,12 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" market4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/market" adt4 "github.com/filecoin-project/specs-actors/v4/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/types" ) @@ -302,3 +305,20 @@ func (s *state4) GetAllocationIdForPendingDeal(dealId abi.DealID) (verifregtypes return verifregtypes.NoAllocationID, xerrors.Errorf("unsupported before actors v9") } + +func (s *state4) ActorKey() string { + return actors.MarketKey +} + +func (s *state4) ActorVersion() actorstypes.Version { + return actorstypes.Version4 +} + +func (s *state4) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/market/v5.go b/chain/actors/builtin/market/v5.go index 8e8833c37..0015389b0 100644 --- a/chain/actors/builtin/market/v5.go +++ b/chain/actors/builtin/market/v5.go @@ -2,6 +2,7 @@ package market import ( "bytes" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -9,10 +10,12 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" market5 "github.com/filecoin-project/specs-actors/v5/actors/builtin/market" adt5 "github.com/filecoin-project/specs-actors/v5/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/types" ) @@ -302,3 +305,20 @@ func (s *state5) GetAllocationIdForPendingDeal(dealId abi.DealID) (verifregtypes return verifregtypes.NoAllocationID, xerrors.Errorf("unsupported before actors v9") } + +func (s *state5) ActorKey() string { + return actors.MarketKey +} + +func (s *state5) ActorVersion() actorstypes.Version { + return actorstypes.Version5 +} + +func (s *state5) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/market/v6.go b/chain/actors/builtin/market/v6.go index d86f73108..0856bed48 100644 --- a/chain/actors/builtin/market/v6.go +++ b/chain/actors/builtin/market/v6.go @@ -2,6 +2,7 @@ package market import ( "bytes" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -11,10 +12,12 @@ import ( "github.com/filecoin-project/go-bitfield" rlepluslazy "github.com/filecoin-project/go-bitfield/rle" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" market6 "github.com/filecoin-project/specs-actors/v6/actors/builtin/market" adt6 "github.com/filecoin-project/specs-actors/v6/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/types" ) @@ -320,3 +323,20 @@ func (s *state6) GetAllocationIdForPendingDeal(dealId abi.DealID) (verifregtypes return verifregtypes.NoAllocationID, xerrors.Errorf("unsupported before actors v9") } + +func (s *state6) ActorKey() string { + return actors.MarketKey +} + +func (s *state6) ActorVersion() actorstypes.Version { + return actorstypes.Version6 +} + +func (s *state6) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/market/v7.go b/chain/actors/builtin/market/v7.go index 5f6547e3f..3df6cef31 100644 --- a/chain/actors/builtin/market/v7.go +++ b/chain/actors/builtin/market/v7.go @@ -2,6 +2,7 @@ package market import ( "bytes" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -11,10 +12,12 @@ import ( "github.com/filecoin-project/go-bitfield" rlepluslazy "github.com/filecoin-project/go-bitfield/rle" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" market7 "github.com/filecoin-project/specs-actors/v7/actors/builtin/market" adt7 "github.com/filecoin-project/specs-actors/v7/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/types" ) @@ -320,3 +323,20 @@ func (s *state7) GetAllocationIdForPendingDeal(dealId abi.DealID) (verifregtypes return verifregtypes.NoAllocationID, xerrors.Errorf("unsupported before actors v9") } + +func (s *state7) ActorKey() string { + return actors.MarketKey +} + +func (s *state7) ActorVersion() actorstypes.Version { + return actorstypes.Version7 +} + +func (s *state7) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/market/v8.go b/chain/actors/builtin/market/v8.go index 5f3b690bb..c73eed137 100644 --- a/chain/actors/builtin/market/v8.go +++ b/chain/actors/builtin/market/v8.go @@ -2,6 +2,7 @@ package market import ( "bytes" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -11,11 +12,13 @@ import ( "github.com/filecoin-project/go-bitfield" rlepluslazy "github.com/filecoin-project/go-bitfield/rle" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" market8 "github.com/filecoin-project/go-state-types/builtin/v8/market" adt8 "github.com/filecoin-project/go-state-types/builtin/v8/util/adt" markettypes "github.com/filecoin-project/go-state-types/builtin/v9/market" verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/types" ) @@ -337,3 +340,20 @@ func (s *state8) GetAllocationIdForPendingDeal(dealId abi.DealID) (verifregtypes return verifregtypes.NoAllocationID, xerrors.Errorf("unsupported before actors v9") } + +func (s *state8) ActorKey() string { + return actors.MarketKey +} + +func (s *state8) ActorVersion() actorstypes.Version { + return actorstypes.Version8 +} + +func (s *state8) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/market/v9.go b/chain/actors/builtin/market/v9.go index 9fed45ae8..230ea5a01 100644 --- a/chain/actors/builtin/market/v9.go +++ b/chain/actors/builtin/market/v9.go @@ -2,6 +2,7 @@ package market import ( "bytes" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -11,12 +12,14 @@ import ( "github.com/filecoin-project/go-bitfield" rlepluslazy "github.com/filecoin-project/go-bitfield/rle" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/go-state-types/builtin" market9 "github.com/filecoin-project/go-state-types/builtin/v9/market" markettypes "github.com/filecoin-project/go-state-types/builtin/v9/market" adt9 "github.com/filecoin-project/go-state-types/builtin/v9/util/adt" verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/types" ) @@ -347,3 +350,20 @@ func (s *state9) GetAllocationIdForPendingDeal(dealId abi.DealID) (verifregtypes return verifregtypes.AllocationId(allocationId), nil } + +func (s *state9) ActorKey() string { + return actors.MarketKey +} + +func (s *state9) ActorVersion() actorstypes.Version { + return actorstypes.Version9 +} + +func (s *state9) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/miner/actor.go.template b/chain/actors/builtin/miner/actor.go.template index 751ab698f..c23cbec7e 100644 --- a/chain/actors/builtin/miner/actor.go.template +++ b/chain/actors/builtin/miner/actor.go.template @@ -1,6 +1,7 @@ package miner import ( + "github.com/ipfs/go-cid" actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/network" @@ -66,6 +67,10 @@ func MakeState(store adt.Store, av actors.Version) (State, error) { type State interface { cbor.Marshaler + Code() cid.Cid + ActorKey() string + ActorVersion() actorstypes.Version + // Total available balance to spend. AvailableBalance(abi.TokenAmount) (abi.TokenAmount, error) // Funds that will vest by the given epoch. @@ -243,3 +248,10 @@ type LockedFunds struct { func (lf LockedFunds) TotalLockedFunds() abi.TokenAmount { return big.Add(lf.VestingFunds, big.Add(lf.InitialPledgeRequirement, lf.PreCommitDeposits)) } + +func AllCodes() []cid.Cid { + return []cid.Cid{ {{range .versions}} + (&state{{.}}{}).Code(), + {{- end}} + } +} diff --git a/chain/actors/builtin/miner/miner.go b/chain/actors/builtin/miner/miner.go index 3939afdd5..f7e4523be 100644 --- a/chain/actors/builtin/miner/miner.go +++ b/chain/actors/builtin/miner/miner.go @@ -1,6 +1,7 @@ package miner import ( + "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" @@ -114,6 +115,10 @@ func MakeState(store adt.Store, av actors.Version) (State, error) { type State interface { cbor.Marshaler + Code() cid.Cid + ActorKey() string + ActorVersion() actorstypes.Version + // Total available balance to spend. AvailableBalance(abi.TokenAmount) (abi.TokenAmount, error) // Funds that will vest by the given epoch. @@ -291,3 +296,18 @@ type LockedFunds struct { func (lf LockedFunds) TotalLockedFunds() abi.TokenAmount { return big.Add(lf.VestingFunds, big.Add(lf.InitialPledgeRequirement, lf.PreCommitDeposits)) } + +func AllCodes() []cid.Cid { + return []cid.Cid{ + (&state0{}).Code(), + (&state2{}).Code(), + (&state3{}).Code(), + (&state4{}).Code(), + (&state5{}).Code(), + (&state6{}).Code(), + (&state7{}).Code(), + (&state8{}).Code(), + (&state9{}).Code(), + (&state10{}).Code(), + } +} diff --git a/chain/actors/builtin/miner/state.go.template b/chain/actors/builtin/miner/state.go.template index 16c9c75e7..8fae02565 100644 --- a/chain/actors/builtin/miner/state.go.template +++ b/chain/actors/builtin/miner/state.go.template @@ -1,6 +1,7 @@ package miner import ( + "fmt" "bytes" "errors" {{if (le .v 1)}} @@ -15,6 +16,8 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors" + actorstypes "github.com/filecoin-project/go-state-types/actors" minertypes "github.com/filecoin-project/go-state-types/builtin/v{{.latestVersion}}/miner" {{if (le .v 7)}} @@ -602,3 +605,20 @@ func fromV{{.v}}SectorPreCommitOnChainInfo(v{{.v}} miner{{.v}}.SectorPreCommitOn func (s *state{{.v}}) GetState() interface{} { return &s.State } + +func (s *state{{.v}}) ActorKey() string { + return actors.MinerKey +} + +func (s *state{{.v}}) ActorVersion() actorstypes.Version { + return actorstypes.Version{{.v}} +} + +func (s *state{{.v}}) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/miner/v0.go b/chain/actors/builtin/miner/v0.go index 6159961c0..f95ed0049 100644 --- a/chain/actors/builtin/miner/v0.go +++ b/chain/actors/builtin/miner/v0.go @@ -3,6 +3,7 @@ package miner import ( "bytes" "errors" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -11,12 +12,14 @@ import ( "github.com/filecoin-project/go-bitfield" rle "github.com/filecoin-project/go-bitfield/rle" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/go-state-types/big" minertypes "github.com/filecoin-project/go-state-types/builtin/v10/miner" "github.com/filecoin-project/go-state-types/dline" miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -528,3 +531,20 @@ func fromV0SectorPreCommitOnChainInfo(v0 miner0.SectorPreCommitOnChainInfo) mine func (s *state0) GetState() interface{} { return &s.State } + +func (s *state0) ActorKey() string { + return actors.MinerKey +} + +func (s *state0) ActorVersion() actorstypes.Version { + return actorstypes.Version0 +} + +func (s *state0) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/miner/v10.go b/chain/actors/builtin/miner/v10.go index c6cc9f342..dcc06cbdf 100644 --- a/chain/actors/builtin/miner/v10.go +++ b/chain/actors/builtin/miner/v10.go @@ -3,6 +3,7 @@ package miner import ( "bytes" "errors" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -11,12 +12,14 @@ import ( "github.com/filecoin-project/go-bitfield" rle "github.com/filecoin-project/go-bitfield/rle" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" builtin10 "github.com/filecoin-project/go-state-types/builtin" miner10 "github.com/filecoin-project/go-state-types/builtin/v10/miner" minertypes "github.com/filecoin-project/go-state-types/builtin/v10/miner" adt10 "github.com/filecoin-project/go-state-types/builtin/v10/util/adt" "github.com/filecoin-project/go-state-types/dline" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -552,3 +555,20 @@ func fromV10SectorPreCommitOnChainInfo(v10 miner10.SectorPreCommitOnChainInfo) m func (s *state10) GetState() interface{} { return &s.State } + +func (s *state10) ActorKey() string { + return actors.MinerKey +} + +func (s *state10) ActorVersion() actorstypes.Version { + return actorstypes.Version10 +} + +func (s *state10) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/miner/v2.go b/chain/actors/builtin/miner/v2.go index 9d41c5aa5..dec8cbc02 100644 --- a/chain/actors/builtin/miner/v2.go +++ b/chain/actors/builtin/miner/v2.go @@ -3,6 +3,7 @@ package miner import ( "bytes" "errors" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -11,11 +12,13 @@ import ( "github.com/filecoin-project/go-bitfield" rle "github.com/filecoin-project/go-bitfield/rle" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" minertypes "github.com/filecoin-project/go-state-types/builtin/v10/miner" "github.com/filecoin-project/go-state-types/dline" miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -559,3 +562,20 @@ func fromV2SectorPreCommitOnChainInfo(v2 miner2.SectorPreCommitOnChainInfo) mine func (s *state2) GetState() interface{} { return &s.State } + +func (s *state2) ActorKey() string { + return actors.MinerKey +} + +func (s *state2) ActorVersion() actorstypes.Version { + return actorstypes.Version2 +} + +func (s *state2) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/miner/v3.go b/chain/actors/builtin/miner/v3.go index b26fe3784..e5c7288e1 100644 --- a/chain/actors/builtin/miner/v3.go +++ b/chain/actors/builtin/miner/v3.go @@ -3,6 +3,7 @@ package miner import ( "bytes" "errors" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -11,12 +12,14 @@ import ( "github.com/filecoin-project/go-bitfield" rle "github.com/filecoin-project/go-bitfield/rle" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" minertypes "github.com/filecoin-project/go-state-types/builtin/v10/miner" "github.com/filecoin-project/go-state-types/dline" builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" miner3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/miner" adt3 "github.com/filecoin-project/specs-actors/v3/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -559,3 +562,20 @@ func fromV3SectorPreCommitOnChainInfo(v3 miner3.SectorPreCommitOnChainInfo) mine func (s *state3) GetState() interface{} { return &s.State } + +func (s *state3) ActorKey() string { + return actors.MinerKey +} + +func (s *state3) ActorVersion() actorstypes.Version { + return actorstypes.Version3 +} + +func (s *state3) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/miner/v4.go b/chain/actors/builtin/miner/v4.go index ccf82148b..155e16649 100644 --- a/chain/actors/builtin/miner/v4.go +++ b/chain/actors/builtin/miner/v4.go @@ -3,6 +3,7 @@ package miner import ( "bytes" "errors" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -11,12 +12,14 @@ import ( "github.com/filecoin-project/go-bitfield" rle "github.com/filecoin-project/go-bitfield/rle" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" minertypes "github.com/filecoin-project/go-state-types/builtin/v10/miner" "github.com/filecoin-project/go-state-types/dline" builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" miner4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/miner" adt4 "github.com/filecoin-project/specs-actors/v4/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -559,3 +562,20 @@ func fromV4SectorPreCommitOnChainInfo(v4 miner4.SectorPreCommitOnChainInfo) mine func (s *state4) GetState() interface{} { return &s.State } + +func (s *state4) ActorKey() string { + return actors.MinerKey +} + +func (s *state4) ActorVersion() actorstypes.Version { + return actorstypes.Version4 +} + +func (s *state4) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/miner/v5.go b/chain/actors/builtin/miner/v5.go index eb04b1a6f..823a6dd67 100644 --- a/chain/actors/builtin/miner/v5.go +++ b/chain/actors/builtin/miner/v5.go @@ -3,6 +3,7 @@ package miner import ( "bytes" "errors" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -11,12 +12,14 @@ import ( "github.com/filecoin-project/go-bitfield" rle "github.com/filecoin-project/go-bitfield/rle" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" minertypes "github.com/filecoin-project/go-state-types/builtin/v10/miner" "github.com/filecoin-project/go-state-types/dline" builtin5 "github.com/filecoin-project/specs-actors/v5/actors/builtin" miner5 "github.com/filecoin-project/specs-actors/v5/actors/builtin/miner" adt5 "github.com/filecoin-project/specs-actors/v5/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -559,3 +562,20 @@ func fromV5SectorPreCommitOnChainInfo(v5 miner5.SectorPreCommitOnChainInfo) mine func (s *state5) GetState() interface{} { return &s.State } + +func (s *state5) ActorKey() string { + return actors.MinerKey +} + +func (s *state5) ActorVersion() actorstypes.Version { + return actorstypes.Version5 +} + +func (s *state5) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/miner/v6.go b/chain/actors/builtin/miner/v6.go index c659dee9c..c9b7778f1 100644 --- a/chain/actors/builtin/miner/v6.go +++ b/chain/actors/builtin/miner/v6.go @@ -3,6 +3,7 @@ package miner import ( "bytes" "errors" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -11,12 +12,14 @@ import ( "github.com/filecoin-project/go-bitfield" rle "github.com/filecoin-project/go-bitfield/rle" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" minertypes "github.com/filecoin-project/go-state-types/builtin/v10/miner" "github.com/filecoin-project/go-state-types/dline" builtin6 "github.com/filecoin-project/specs-actors/v6/actors/builtin" miner6 "github.com/filecoin-project/specs-actors/v6/actors/builtin/miner" adt6 "github.com/filecoin-project/specs-actors/v6/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -559,3 +562,20 @@ func fromV6SectorPreCommitOnChainInfo(v6 miner6.SectorPreCommitOnChainInfo) mine func (s *state6) GetState() interface{} { return &s.State } + +func (s *state6) ActorKey() string { + return actors.MinerKey +} + +func (s *state6) ActorVersion() actorstypes.Version { + return actorstypes.Version6 +} + +func (s *state6) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/miner/v7.go b/chain/actors/builtin/miner/v7.go index 40c08da14..925002e71 100644 --- a/chain/actors/builtin/miner/v7.go +++ b/chain/actors/builtin/miner/v7.go @@ -3,6 +3,7 @@ package miner import ( "bytes" "errors" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -11,12 +12,14 @@ import ( "github.com/filecoin-project/go-bitfield" rle "github.com/filecoin-project/go-bitfield/rle" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" minertypes "github.com/filecoin-project/go-state-types/builtin/v10/miner" "github.com/filecoin-project/go-state-types/dline" builtin7 "github.com/filecoin-project/specs-actors/v7/actors/builtin" miner7 "github.com/filecoin-project/specs-actors/v7/actors/builtin/miner" adt7 "github.com/filecoin-project/specs-actors/v7/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -560,3 +563,20 @@ func fromV7SectorPreCommitOnChainInfo(v7 miner7.SectorPreCommitOnChainInfo) mine func (s *state7) GetState() interface{} { return &s.State } + +func (s *state7) ActorKey() string { + return actors.MinerKey +} + +func (s *state7) ActorVersion() actorstypes.Version { + return actorstypes.Version7 +} + +func (s *state7) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/miner/v8.go b/chain/actors/builtin/miner/v8.go index 71ec78f5e..7dff2f2bb 100644 --- a/chain/actors/builtin/miner/v8.go +++ b/chain/actors/builtin/miner/v8.go @@ -3,6 +3,7 @@ package miner import ( "bytes" "errors" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -11,12 +12,14 @@ import ( "github.com/filecoin-project/go-bitfield" rle "github.com/filecoin-project/go-bitfield/rle" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" builtin8 "github.com/filecoin-project/go-state-types/builtin" minertypes "github.com/filecoin-project/go-state-types/builtin/v10/miner" miner8 "github.com/filecoin-project/go-state-types/builtin/v8/miner" adt8 "github.com/filecoin-project/go-state-types/builtin/v8/util/adt" "github.com/filecoin-project/go-state-types/dline" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -560,3 +563,20 @@ func fromV8SectorPreCommitOnChainInfo(v8 miner8.SectorPreCommitOnChainInfo) mine func (s *state8) GetState() interface{} { return &s.State } + +func (s *state8) ActorKey() string { + return actors.MinerKey +} + +func (s *state8) ActorVersion() actorstypes.Version { + return actorstypes.Version8 +} + +func (s *state8) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/miner/v9.go b/chain/actors/builtin/miner/v9.go index 9c1fb98a0..4a229b6bb 100644 --- a/chain/actors/builtin/miner/v9.go +++ b/chain/actors/builtin/miner/v9.go @@ -3,6 +3,7 @@ package miner import ( "bytes" "errors" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -11,12 +12,14 @@ import ( "github.com/filecoin-project/go-bitfield" rle "github.com/filecoin-project/go-bitfield/rle" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" builtin9 "github.com/filecoin-project/go-state-types/builtin" minertypes "github.com/filecoin-project/go-state-types/builtin/v10/miner" miner9 "github.com/filecoin-project/go-state-types/builtin/v9/miner" adt9 "github.com/filecoin-project/go-state-types/builtin/v9/util/adt" "github.com/filecoin-project/go-state-types/dline" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -552,3 +555,20 @@ func fromV9SectorPreCommitOnChainInfo(v9 miner9.SectorPreCommitOnChainInfo) mine func (s *state9) GetState() interface{} { return &s.State } + +func (s *state9) ActorKey() string { + return actors.MinerKey +} + +func (s *state9) ActorVersion() actorstypes.Version { + return actorstypes.Version9 +} + +func (s *state9) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/multisig/actor.go.template b/chain/actors/builtin/multisig/actor.go.template index a02a986aa..40e49e702 100644 --- a/chain/actors/builtin/multisig/actor.go.template +++ b/chain/actors/builtin/multisig/actor.go.template @@ -2,6 +2,7 @@ package multisig import ( actorstypes "github.com/filecoin-project/go-state-types/actors" + "github.com/ipfs/go-cid" "fmt" "github.com/minio/blake2b-simd" @@ -67,6 +68,10 @@ func MakeState(store adt.Store, av actorstypes.Version, signers []address.Addres type State interface { cbor.Marshaler + Code() cid.Cid + ActorKey() string + ActorVersion() actorstypes.Version + LockedBalance(epoch abi.ChainEpoch) (abi.TokenAmount, error) StartEpoch() (abi.ChainEpoch, error) UnlockDuration() (abi.ChainEpoch, error) @@ -141,3 +146,10 @@ func txnParams(id uint64, data *ProposalHashData) ([]byte, error) { return actors.SerializeParams(¶ms) } + +func AllCodes() []cid.Cid { + return []cid.Cid{ {{range .versions}} + (&state{{.}}{}).Code(), + {{- end}} + } +} diff --git a/chain/actors/builtin/multisig/multisig.go b/chain/actors/builtin/multisig/multisig.go index 09a37fd6a..adb2fcfa0 100644 --- a/chain/actors/builtin/multisig/multisig.go +++ b/chain/actors/builtin/multisig/multisig.go @@ -3,6 +3,7 @@ package multisig import ( "fmt" + "github.com/ipfs/go-cid" "github.com/minio/blake2b-simd" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" @@ -114,6 +115,10 @@ func MakeState(store adt.Store, av actorstypes.Version, signers []address.Addres type State interface { cbor.Marshaler + Code() cid.Cid + ActorKey() string + ActorVersion() actorstypes.Version + LockedBalance(epoch abi.ChainEpoch) (abi.TokenAmount, error) StartEpoch() (abi.ChainEpoch, error) UnlockDuration() (abi.ChainEpoch, error) @@ -215,3 +220,18 @@ func txnParams(id uint64, data *ProposalHashData) ([]byte, error) { return actors.SerializeParams(¶ms) } + +func AllCodes() []cid.Cid { + return []cid.Cid{ + (&state0{}).Code(), + (&state2{}).Code(), + (&state3{}).Code(), + (&state4{}).Code(), + (&state5{}).Code(), + (&state6{}).Code(), + (&state7{}).Code(), + (&state8{}).Code(), + (&state9{}).Code(), + (&state10{}).Code(), + } +} diff --git a/chain/actors/builtin/multisig/state.go.template b/chain/actors/builtin/multisig/state.go.template index e375becc3..457e8cb4d 100644 --- a/chain/actors/builtin/multisig/state.go.template +++ b/chain/actors/builtin/multisig/state.go.template @@ -1,9 +1,11 @@ package multisig import ( + "fmt" "bytes" "encoding/binary" + actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" @@ -12,6 +14,7 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors" {{if (le .v 7)}} {{if (ge .v 3)}} @@ -131,3 +134,20 @@ func (s *state{{.v}}) decodeTransaction(val *cbg.Deferred) (Transaction, error) func (s *state{{.v}}) GetState() interface{} { return &s.State } + +func (s *state{{.v}}) ActorKey() string { + return actors.MultisigKey +} + +func (s *state{{.v}}) ActorVersion() actorstypes.Version { + return actorstypes.Version{{.v}} +} + +func (s *state{{.v}}) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/multisig/v0.go b/chain/actors/builtin/multisig/v0.go index 9f4d09dc1..38cc76411 100644 --- a/chain/actors/builtin/multisig/v0.go +++ b/chain/actors/builtin/multisig/v0.go @@ -3,6 +3,7 @@ package multisig import ( "bytes" "encoding/binary" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -10,9 +11,11 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -114,3 +117,20 @@ func (s *state0) decodeTransaction(val *cbg.Deferred) (Transaction, error) { func (s *state0) GetState() interface{} { return &s.State } + +func (s *state0) ActorKey() string { + return actors.MultisigKey +} + +func (s *state0) ActorVersion() actorstypes.Version { + return actorstypes.Version0 +} + +func (s *state0) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/multisig/v10.go b/chain/actors/builtin/multisig/v10.go index a90b8ee96..3b9babebe 100644 --- a/chain/actors/builtin/multisig/v10.go +++ b/chain/actors/builtin/multisig/v10.go @@ -3,6 +3,7 @@ package multisig import ( "bytes" "encoding/binary" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -10,10 +11,12 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" builtin10 "github.com/filecoin-project/go-state-types/builtin" msig10 "github.com/filecoin-project/go-state-types/builtin/v10/multisig" adt10 "github.com/filecoin-project/go-state-types/builtin/v10/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -115,3 +118,20 @@ func (s *state10) decodeTransaction(val *cbg.Deferred) (Transaction, error) { func (s *state10) GetState() interface{} { return &s.State } + +func (s *state10) ActorKey() string { + return actors.MultisigKey +} + +func (s *state10) ActorVersion() actorstypes.Version { + return actorstypes.Version10 +} + +func (s *state10) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/multisig/v2.go b/chain/actors/builtin/multisig/v2.go index 14e895680..2d72b3215 100644 --- a/chain/actors/builtin/multisig/v2.go +++ b/chain/actors/builtin/multisig/v2.go @@ -3,6 +3,7 @@ package multisig import ( "bytes" "encoding/binary" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -10,9 +11,11 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" msig2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig" adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -114,3 +117,20 @@ func (s *state2) decodeTransaction(val *cbg.Deferred) (Transaction, error) { func (s *state2) GetState() interface{} { return &s.State } + +func (s *state2) ActorKey() string { + return actors.MultisigKey +} + +func (s *state2) ActorVersion() actorstypes.Version { + return actorstypes.Version2 +} + +func (s *state2) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/multisig/v3.go b/chain/actors/builtin/multisig/v3.go index 5cde148c1..bd45ecdaa 100644 --- a/chain/actors/builtin/multisig/v3.go +++ b/chain/actors/builtin/multisig/v3.go @@ -3,6 +3,7 @@ package multisig import ( "bytes" "encoding/binary" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -10,10 +11,12 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" msig3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/multisig" adt3 "github.com/filecoin-project/specs-actors/v3/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -115,3 +118,20 @@ func (s *state3) decodeTransaction(val *cbg.Deferred) (Transaction, error) { func (s *state3) GetState() interface{} { return &s.State } + +func (s *state3) ActorKey() string { + return actors.MultisigKey +} + +func (s *state3) ActorVersion() actorstypes.Version { + return actorstypes.Version3 +} + +func (s *state3) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/multisig/v4.go b/chain/actors/builtin/multisig/v4.go index 87936661d..1f5f2a9ce 100644 --- a/chain/actors/builtin/multisig/v4.go +++ b/chain/actors/builtin/multisig/v4.go @@ -3,6 +3,7 @@ package multisig import ( "bytes" "encoding/binary" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -10,10 +11,12 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" msig4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/multisig" adt4 "github.com/filecoin-project/specs-actors/v4/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -115,3 +118,20 @@ func (s *state4) decodeTransaction(val *cbg.Deferred) (Transaction, error) { func (s *state4) GetState() interface{} { return &s.State } + +func (s *state4) ActorKey() string { + return actors.MultisigKey +} + +func (s *state4) ActorVersion() actorstypes.Version { + return actorstypes.Version4 +} + +func (s *state4) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/multisig/v5.go b/chain/actors/builtin/multisig/v5.go index d50638ca5..bf4a58cbf 100644 --- a/chain/actors/builtin/multisig/v5.go +++ b/chain/actors/builtin/multisig/v5.go @@ -3,6 +3,7 @@ package multisig import ( "bytes" "encoding/binary" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -10,10 +11,12 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" builtin5 "github.com/filecoin-project/specs-actors/v5/actors/builtin" msig5 "github.com/filecoin-project/specs-actors/v5/actors/builtin/multisig" adt5 "github.com/filecoin-project/specs-actors/v5/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -115,3 +118,20 @@ func (s *state5) decodeTransaction(val *cbg.Deferred) (Transaction, error) { func (s *state5) GetState() interface{} { return &s.State } + +func (s *state5) ActorKey() string { + return actors.MultisigKey +} + +func (s *state5) ActorVersion() actorstypes.Version { + return actorstypes.Version5 +} + +func (s *state5) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/multisig/v6.go b/chain/actors/builtin/multisig/v6.go index 9246eeaa9..f5c6f66bb 100644 --- a/chain/actors/builtin/multisig/v6.go +++ b/chain/actors/builtin/multisig/v6.go @@ -3,6 +3,7 @@ package multisig import ( "bytes" "encoding/binary" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -10,10 +11,12 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" builtin6 "github.com/filecoin-project/specs-actors/v6/actors/builtin" msig6 "github.com/filecoin-project/specs-actors/v6/actors/builtin/multisig" adt6 "github.com/filecoin-project/specs-actors/v6/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -115,3 +118,20 @@ func (s *state6) decodeTransaction(val *cbg.Deferred) (Transaction, error) { func (s *state6) GetState() interface{} { return &s.State } + +func (s *state6) ActorKey() string { + return actors.MultisigKey +} + +func (s *state6) ActorVersion() actorstypes.Version { + return actorstypes.Version6 +} + +func (s *state6) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/multisig/v7.go b/chain/actors/builtin/multisig/v7.go index a6b630179..e75865841 100644 --- a/chain/actors/builtin/multisig/v7.go +++ b/chain/actors/builtin/multisig/v7.go @@ -3,6 +3,7 @@ package multisig import ( "bytes" "encoding/binary" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -10,10 +11,12 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" builtin7 "github.com/filecoin-project/specs-actors/v7/actors/builtin" msig7 "github.com/filecoin-project/specs-actors/v7/actors/builtin/multisig" adt7 "github.com/filecoin-project/specs-actors/v7/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -115,3 +118,20 @@ func (s *state7) decodeTransaction(val *cbg.Deferred) (Transaction, error) { func (s *state7) GetState() interface{} { return &s.State } + +func (s *state7) ActorKey() string { + return actors.MultisigKey +} + +func (s *state7) ActorVersion() actorstypes.Version { + return actorstypes.Version7 +} + +func (s *state7) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/multisig/v8.go b/chain/actors/builtin/multisig/v8.go index 6311583b3..677f4ffe9 100644 --- a/chain/actors/builtin/multisig/v8.go +++ b/chain/actors/builtin/multisig/v8.go @@ -3,6 +3,7 @@ package multisig import ( "bytes" "encoding/binary" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -10,10 +11,12 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" builtin8 "github.com/filecoin-project/go-state-types/builtin" msig8 "github.com/filecoin-project/go-state-types/builtin/v8/multisig" adt8 "github.com/filecoin-project/go-state-types/builtin/v8/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -115,3 +118,20 @@ func (s *state8) decodeTransaction(val *cbg.Deferred) (Transaction, error) { func (s *state8) GetState() interface{} { return &s.State } + +func (s *state8) ActorKey() string { + return actors.MultisigKey +} + +func (s *state8) ActorVersion() actorstypes.Version { + return actorstypes.Version8 +} + +func (s *state8) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/multisig/v9.go b/chain/actors/builtin/multisig/v9.go index ef9a48f28..2700470d3 100644 --- a/chain/actors/builtin/multisig/v9.go +++ b/chain/actors/builtin/multisig/v9.go @@ -3,6 +3,7 @@ package multisig import ( "bytes" "encoding/binary" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -10,10 +11,12 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" builtin9 "github.com/filecoin-project/go-state-types/builtin" msig9 "github.com/filecoin-project/go-state-types/builtin/v9/multisig" adt9 "github.com/filecoin-project/go-state-types/builtin/v9/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -115,3 +118,20 @@ func (s *state9) decodeTransaction(val *cbg.Deferred) (Transaction, error) { func (s *state9) GetState() interface{} { return &s.State } + +func (s *state9) ActorKey() string { + return actors.MultisigKey +} + +func (s *state9) ActorVersion() actorstypes.Version { + return actorstypes.Version9 +} + +func (s *state9) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/paych/actor.go.template b/chain/actors/builtin/paych/actor.go.template index 1308d4ea4..4250b4770 100644 --- a/chain/actors/builtin/paych/actor.go.template +++ b/chain/actors/builtin/paych/actor.go.template @@ -1,7 +1,9 @@ package paych import ( + "github.com/ipfs/go-cid" actorstypes "github.com/filecoin-project/go-state-types/actors" + "github.com/ipfs/go-cid" "encoding/base64" "fmt" @@ -59,6 +61,11 @@ func Load(store adt.Store, act *types.Actor) (State, error) { // versions type State interface { cbor.Marshaler + + Code() cid.Cid + ActorKey() string + ActorVersion() actorstypes.Version + // Channel owner, who has funded the actor From() (address.Address, error) // Recipient of payouts from channel @@ -132,4 +139,11 @@ func toV0SignedVoucher(sv paychtypes.SignedVoucher) paych0.SignedVoucher { Merges: nil, Signature: sv.Signature, } -} \ No newline at end of file +} + +func AllCodes() []cid.Cid { + return []cid.Cid{ {{range .versions}} + (&state{{.}}{}).Code(), + {{- end}} + } +} diff --git a/chain/actors/builtin/paych/mock/mock.go b/chain/actors/builtin/paych/mock/mock.go index 729db5924..8b8624ac8 100644 --- a/chain/actors/builtin/paych/mock/mock.go +++ b/chain/actors/builtin/paych/mock/mock.go @@ -3,10 +3,14 @@ package mock import ( "io" + "github.com/ipfs/go-cid" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/builtin/paych" ) @@ -18,6 +22,18 @@ type mockState struct { lanes map[uint64]paych.LaneState } +func (ms *mockState) Code() cid.Cid { + panic("paych mock does not have CID") +} + +func (ms *mockState) ActorKey() string { + return actors.PaychKey +} + +func (ms *mockState) ActorVersion() actorstypes.Version { + panic("paych mock is unversioned") +} + func (ms *mockState) GetState() interface{} { panic("implement me") } diff --git a/chain/actors/builtin/paych/paych.go b/chain/actors/builtin/paych/paych.go index 17f8dd5e9..537ae8d92 100644 --- a/chain/actors/builtin/paych/paych.go +++ b/chain/actors/builtin/paych/paych.go @@ -4,6 +4,7 @@ import ( "encoding/base64" "fmt" + "github.com/ipfs/go-cid" ipldcbor "github.com/ipfs/go-ipld-cbor" "golang.org/x/xerrors" @@ -80,6 +81,11 @@ func Load(store adt.Store, act *types.Actor) (State, error) { // versions type State interface { cbor.Marshaler + + Code() cid.Cid + ActorKey() string + ActorVersion() actorstypes.Version + // Channel owner, who has funded the actor From() (address.Address, error) // Recipient of payouts from channel @@ -181,3 +187,18 @@ func toV0SignedVoucher(sv paychtypes.SignedVoucher) paych0.SignedVoucher { Signature: sv.Signature, } } + +func AllCodes() []cid.Cid { + return []cid.Cid{ + (&state0{}).Code(), + (&state2{}).Code(), + (&state3{}).Code(), + (&state4{}).Code(), + (&state5{}).Code(), + (&state6{}).Code(), + (&state7{}).Code(), + (&state8{}).Code(), + (&state9{}).Code(), + (&state10{}).Code(), + } +} diff --git a/chain/actors/builtin/paych/state.go.template b/chain/actors/builtin/paych/state.go.template index c3954ce81..c00f7dc56 100644 --- a/chain/actors/builtin/paych/state.go.template +++ b/chain/actors/builtin/paych/state.go.template @@ -1,6 +1,8 @@ package paych import ( + "fmt" + actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/ipfs/go-cid" "github.com/filecoin-project/go-address" @@ -8,6 +10,7 @@ import ( "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors" {{if (le .v 7)}} paych{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/paych" @@ -117,3 +120,20 @@ func (ls *laneState{{.v}}) Redeemed() (big.Int, error) { func (ls *laneState{{.v}}) Nonce() (uint64, error) { return ls.LaneState.Nonce, nil } + +func (s *state{{.v}}) ActorKey() string { + return actors.PaychKey +} + +func (s *state{{.v}}) ActorVersion() actorstypes.Version { + return actorstypes.Version{{.v}} +} + +func (s *state{{.v}}) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/paych/v0.go b/chain/actors/builtin/paych/v0.go index 727525c50..8cdc27c39 100644 --- a/chain/actors/builtin/paych/v0.go +++ b/chain/actors/builtin/paych/v0.go @@ -1,14 +1,18 @@ package paych import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/go-state-types/big" paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych" adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -111,3 +115,20 @@ func (ls *laneState0) Redeemed() (big.Int, error) { func (ls *laneState0) Nonce() (uint64, error) { return ls.LaneState.Nonce, nil } + +func (s *state0) ActorKey() string { + return actors.PaychKey +} + +func (s *state0) ActorVersion() actorstypes.Version { + return actorstypes.Version0 +} + +func (s *state0) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/paych/v10.go b/chain/actors/builtin/paych/v10.go index f3b1996eb..0527c36d1 100644 --- a/chain/actors/builtin/paych/v10.go +++ b/chain/actors/builtin/paych/v10.go @@ -1,14 +1,18 @@ package paych import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/go-state-types/big" paych10 "github.com/filecoin-project/go-state-types/builtin/v10/paych" adt10 "github.com/filecoin-project/go-state-types/builtin/v10/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -111,3 +115,20 @@ func (ls *laneState10) Redeemed() (big.Int, error) { func (ls *laneState10) Nonce() (uint64, error) { return ls.LaneState.Nonce, nil } + +func (s *state10) ActorKey() string { + return actors.PaychKey +} + +func (s *state10) ActorVersion() actorstypes.Version { + return actorstypes.Version10 +} + +func (s *state10) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/paych/v2.go b/chain/actors/builtin/paych/v2.go index 5852c9a64..ae94adc17 100644 --- a/chain/actors/builtin/paych/v2.go +++ b/chain/actors/builtin/paych/v2.go @@ -1,14 +1,18 @@ package paych import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/go-state-types/big" paych2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/paych" adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -111,3 +115,20 @@ func (ls *laneState2) Redeemed() (big.Int, error) { func (ls *laneState2) Nonce() (uint64, error) { return ls.LaneState.Nonce, nil } + +func (s *state2) ActorKey() string { + return actors.PaychKey +} + +func (s *state2) ActorVersion() actorstypes.Version { + return actorstypes.Version2 +} + +func (s *state2) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/paych/v3.go b/chain/actors/builtin/paych/v3.go index 5297e9d10..5c57ea729 100644 --- a/chain/actors/builtin/paych/v3.go +++ b/chain/actors/builtin/paych/v3.go @@ -1,14 +1,18 @@ package paych import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/go-state-types/big" paych3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/paych" adt3 "github.com/filecoin-project/specs-actors/v3/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -111,3 +115,20 @@ func (ls *laneState3) Redeemed() (big.Int, error) { func (ls *laneState3) Nonce() (uint64, error) { return ls.LaneState.Nonce, nil } + +func (s *state3) ActorKey() string { + return actors.PaychKey +} + +func (s *state3) ActorVersion() actorstypes.Version { + return actorstypes.Version3 +} + +func (s *state3) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/paych/v4.go b/chain/actors/builtin/paych/v4.go index be10061bf..b243be2e3 100644 --- a/chain/actors/builtin/paych/v4.go +++ b/chain/actors/builtin/paych/v4.go @@ -1,14 +1,18 @@ package paych import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/go-state-types/big" paych4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/paych" adt4 "github.com/filecoin-project/specs-actors/v4/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -111,3 +115,20 @@ func (ls *laneState4) Redeemed() (big.Int, error) { func (ls *laneState4) Nonce() (uint64, error) { return ls.LaneState.Nonce, nil } + +func (s *state4) ActorKey() string { + return actors.PaychKey +} + +func (s *state4) ActorVersion() actorstypes.Version { + return actorstypes.Version4 +} + +func (s *state4) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/paych/v5.go b/chain/actors/builtin/paych/v5.go index 37a917273..b3b9ad50e 100644 --- a/chain/actors/builtin/paych/v5.go +++ b/chain/actors/builtin/paych/v5.go @@ -1,14 +1,18 @@ package paych import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/go-state-types/big" paych5 "github.com/filecoin-project/specs-actors/v5/actors/builtin/paych" adt5 "github.com/filecoin-project/specs-actors/v5/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -111,3 +115,20 @@ func (ls *laneState5) Redeemed() (big.Int, error) { func (ls *laneState5) Nonce() (uint64, error) { return ls.LaneState.Nonce, nil } + +func (s *state5) ActorKey() string { + return actors.PaychKey +} + +func (s *state5) ActorVersion() actorstypes.Version { + return actorstypes.Version5 +} + +func (s *state5) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/paych/v6.go b/chain/actors/builtin/paych/v6.go index 36676d9de..a3b80c8e1 100644 --- a/chain/actors/builtin/paych/v6.go +++ b/chain/actors/builtin/paych/v6.go @@ -1,14 +1,18 @@ package paych import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/go-state-types/big" paych6 "github.com/filecoin-project/specs-actors/v6/actors/builtin/paych" adt6 "github.com/filecoin-project/specs-actors/v6/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -111,3 +115,20 @@ func (ls *laneState6) Redeemed() (big.Int, error) { func (ls *laneState6) Nonce() (uint64, error) { return ls.LaneState.Nonce, nil } + +func (s *state6) ActorKey() string { + return actors.PaychKey +} + +func (s *state6) ActorVersion() actorstypes.Version { + return actorstypes.Version6 +} + +func (s *state6) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/paych/v7.go b/chain/actors/builtin/paych/v7.go index 88b6f2b84..bb6721b01 100644 --- a/chain/actors/builtin/paych/v7.go +++ b/chain/actors/builtin/paych/v7.go @@ -1,14 +1,18 @@ package paych import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/go-state-types/big" paych7 "github.com/filecoin-project/specs-actors/v7/actors/builtin/paych" adt7 "github.com/filecoin-project/specs-actors/v7/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -111,3 +115,20 @@ func (ls *laneState7) Redeemed() (big.Int, error) { func (ls *laneState7) Nonce() (uint64, error) { return ls.LaneState.Nonce, nil } + +func (s *state7) ActorKey() string { + return actors.PaychKey +} + +func (s *state7) ActorVersion() actorstypes.Version { + return actorstypes.Version7 +} + +func (s *state7) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/paych/v8.go b/chain/actors/builtin/paych/v8.go index 1961e69ec..fc6853cad 100644 --- a/chain/actors/builtin/paych/v8.go +++ b/chain/actors/builtin/paych/v8.go @@ -1,14 +1,18 @@ package paych import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/go-state-types/big" paych8 "github.com/filecoin-project/go-state-types/builtin/v8/paych" adt8 "github.com/filecoin-project/go-state-types/builtin/v8/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -111,3 +115,20 @@ func (ls *laneState8) Redeemed() (big.Int, error) { func (ls *laneState8) Nonce() (uint64, error) { return ls.LaneState.Nonce, nil } + +func (s *state8) ActorKey() string { + return actors.PaychKey +} + +func (s *state8) ActorVersion() actorstypes.Version { + return actorstypes.Version8 +} + +func (s *state8) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/paych/v9.go b/chain/actors/builtin/paych/v9.go index 443fe74ea..817541dfb 100644 --- a/chain/actors/builtin/paych/v9.go +++ b/chain/actors/builtin/paych/v9.go @@ -1,14 +1,18 @@ package paych import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/go-state-types/big" paych9 "github.com/filecoin-project/go-state-types/builtin/v9/paych" adt9 "github.com/filecoin-project/go-state-types/builtin/v9/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -111,3 +115,20 @@ func (ls *laneState9) Redeemed() (big.Int, error) { func (ls *laneState9) Nonce() (uint64, error) { return ls.LaneState.Nonce, nil } + +func (s *state9) ActorKey() string { + return actors.PaychKey +} + +func (s *state9) ActorVersion() actorstypes.Version { + return actorstypes.Version9 +} + +func (s *state9) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/power/actor.go.template b/chain/actors/builtin/power/actor.go.template index 93fe70370..0a4d70f46 100644 --- a/chain/actors/builtin/power/actor.go.template +++ b/chain/actors/builtin/power/actor.go.template @@ -1,6 +1,7 @@ package power import ( + "github.com/ipfs/go-cid" actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/big" @@ -69,6 +70,10 @@ func MakeState(store adt.Store, av actorstypes.Version) (State, error) { type State interface { cbor.Marshaler + Code() cid.Cid + ActorKey() string + ActorVersion() actorstypes.Version + TotalLocked() (abi.TokenAmount, error) TotalPower() (Claim, error) TotalCommitted() (Claim, error) @@ -109,3 +114,10 @@ func AddClaims(a Claim, b Claim) Claim { QualityAdjPower: big.Add(a.QualityAdjPower, b.QualityAdjPower), } } + +func AllCodes() []cid.Cid { + return []cid.Cid{ {{range .versions}} + (&state{{.}}{}).Code(), + {{- end}} + } +} diff --git a/chain/actors/builtin/power/power.go b/chain/actors/builtin/power/power.go index fbea9719b..893a25cd7 100644 --- a/chain/actors/builtin/power/power.go +++ b/chain/actors/builtin/power/power.go @@ -1,6 +1,7 @@ package power import ( + "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" @@ -117,6 +118,10 @@ func MakeState(store adt.Store, av actorstypes.Version) (State, error) { type State interface { cbor.Marshaler + Code() cid.Cid + ActorKey() string + ActorVersion() actorstypes.Version + TotalLocked() (abi.TokenAmount, error) TotalPower() (Claim, error) TotalCommitted() (Claim, error) @@ -157,3 +162,18 @@ func AddClaims(a Claim, b Claim) Claim { QualityAdjPower: big.Add(a.QualityAdjPower, b.QualityAdjPower), } } + +func AllCodes() []cid.Cid { + return []cid.Cid{ + (&state0{}).Code(), + (&state2{}).Code(), + (&state3{}).Code(), + (&state4{}).Code(), + (&state5{}).Code(), + (&state6{}).Code(), + (&state7{}).Code(), + (&state8{}).Code(), + (&state9{}).Code(), + (&state10{}).Code(), + } +} diff --git a/chain/actors/builtin/power/state.go.template b/chain/actors/builtin/power/state.go.template index 08362d2db..8c2a8ce97 100644 --- a/chain/actors/builtin/power/state.go.template +++ b/chain/actors/builtin/power/state.go.template @@ -1,6 +1,8 @@ package power import ( + "fmt" + actorstypes "github.com/filecoin-project/go-state-types/actors" "bytes" "github.com/filecoin-project/go-address" @@ -8,6 +10,7 @@ import ( "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" @@ -205,3 +208,20 @@ func fromV{{.v}}Claim(v{{.v}} power{{.v}}.Claim) Claim { QualityAdjPower: v{{.v}}.QualityAdjPower, } } + +func (s *state{{.v}}) ActorKey() string { + return actors.PowerKey +} + +func (s *state{{.v}}) ActorVersion() actorstypes.Version { + return actorstypes.Version{{.v}} +} + +func (s *state{{.v}}) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/power/v0.go b/chain/actors/builtin/power/v0.go index 5ae42b4df..56982e77b 100644 --- a/chain/actors/builtin/power/v0.go +++ b/chain/actors/builtin/power/v0.go @@ -2,15 +2,18 @@ package power import ( "bytes" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" power0 "github.com/filecoin-project/specs-actors/actors/builtin/power" adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" ) @@ -188,3 +191,20 @@ func fromV0Claim(v0 power0.Claim) Claim { QualityAdjPower: v0.QualityAdjPower, } } + +func (s *state0) ActorKey() string { + return actors.PowerKey +} + +func (s *state0) ActorVersion() actorstypes.Version { + return actorstypes.Version0 +} + +func (s *state0) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/power/v10.go b/chain/actors/builtin/power/v10.go index a37cd1850..7359ca947 100644 --- a/chain/actors/builtin/power/v10.go +++ b/chain/actors/builtin/power/v10.go @@ -2,16 +2,19 @@ package power import ( "bytes" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" builtin10 "github.com/filecoin-project/go-state-types/builtin" power10 "github.com/filecoin-project/go-state-types/builtin/v10/power" adt10 "github.com/filecoin-project/go-state-types/builtin/v10/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" ) @@ -184,3 +187,20 @@ func fromV10Claim(v10 power10.Claim) Claim { QualityAdjPower: v10.QualityAdjPower, } } + +func (s *state10) ActorKey() string { + return actors.PowerKey +} + +func (s *state10) ActorVersion() actorstypes.Version { + return actorstypes.Version10 +} + +func (s *state10) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/power/v2.go b/chain/actors/builtin/power/v2.go index 485819e3e..b4e253024 100644 --- a/chain/actors/builtin/power/v2.go +++ b/chain/actors/builtin/power/v2.go @@ -2,15 +2,18 @@ package power import ( "bytes" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" power2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/power" adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" ) @@ -188,3 +191,20 @@ func fromV2Claim(v2 power2.Claim) Claim { QualityAdjPower: v2.QualityAdjPower, } } + +func (s *state2) ActorKey() string { + return actors.PowerKey +} + +func (s *state2) ActorVersion() actorstypes.Version { + return actorstypes.Version2 +} + +func (s *state2) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/power/v3.go b/chain/actors/builtin/power/v3.go index e33ee2bb5..2b2b75ae7 100644 --- a/chain/actors/builtin/power/v3.go +++ b/chain/actors/builtin/power/v3.go @@ -2,16 +2,19 @@ package power import ( "bytes" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" power3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/power" adt3 "github.com/filecoin-project/specs-actors/v3/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" ) @@ -184,3 +187,20 @@ func fromV3Claim(v3 power3.Claim) Claim { QualityAdjPower: v3.QualityAdjPower, } } + +func (s *state3) ActorKey() string { + return actors.PowerKey +} + +func (s *state3) ActorVersion() actorstypes.Version { + return actorstypes.Version3 +} + +func (s *state3) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/power/v4.go b/chain/actors/builtin/power/v4.go index e5c446f07..c40dad92a 100644 --- a/chain/actors/builtin/power/v4.go +++ b/chain/actors/builtin/power/v4.go @@ -2,16 +2,19 @@ package power import ( "bytes" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" power4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/power" adt4 "github.com/filecoin-project/specs-actors/v4/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" ) @@ -184,3 +187,20 @@ func fromV4Claim(v4 power4.Claim) Claim { QualityAdjPower: v4.QualityAdjPower, } } + +func (s *state4) ActorKey() string { + return actors.PowerKey +} + +func (s *state4) ActorVersion() actorstypes.Version { + return actorstypes.Version4 +} + +func (s *state4) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/power/v5.go b/chain/actors/builtin/power/v5.go index aaf248058..5d740a40b 100644 --- a/chain/actors/builtin/power/v5.go +++ b/chain/actors/builtin/power/v5.go @@ -2,16 +2,19 @@ package power import ( "bytes" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" builtin5 "github.com/filecoin-project/specs-actors/v5/actors/builtin" power5 "github.com/filecoin-project/specs-actors/v5/actors/builtin/power" adt5 "github.com/filecoin-project/specs-actors/v5/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" ) @@ -184,3 +187,20 @@ func fromV5Claim(v5 power5.Claim) Claim { QualityAdjPower: v5.QualityAdjPower, } } + +func (s *state5) ActorKey() string { + return actors.PowerKey +} + +func (s *state5) ActorVersion() actorstypes.Version { + return actorstypes.Version5 +} + +func (s *state5) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/power/v6.go b/chain/actors/builtin/power/v6.go index 072def6e2..45c0db9e8 100644 --- a/chain/actors/builtin/power/v6.go +++ b/chain/actors/builtin/power/v6.go @@ -2,16 +2,19 @@ package power import ( "bytes" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" builtin6 "github.com/filecoin-project/specs-actors/v6/actors/builtin" power6 "github.com/filecoin-project/specs-actors/v6/actors/builtin/power" adt6 "github.com/filecoin-project/specs-actors/v6/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" ) @@ -184,3 +187,20 @@ func fromV6Claim(v6 power6.Claim) Claim { QualityAdjPower: v6.QualityAdjPower, } } + +func (s *state6) ActorKey() string { + return actors.PowerKey +} + +func (s *state6) ActorVersion() actorstypes.Version { + return actorstypes.Version6 +} + +func (s *state6) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/power/v7.go b/chain/actors/builtin/power/v7.go index 0c60b03a0..314318263 100644 --- a/chain/actors/builtin/power/v7.go +++ b/chain/actors/builtin/power/v7.go @@ -2,16 +2,19 @@ package power import ( "bytes" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" builtin7 "github.com/filecoin-project/specs-actors/v7/actors/builtin" power7 "github.com/filecoin-project/specs-actors/v7/actors/builtin/power" adt7 "github.com/filecoin-project/specs-actors/v7/actors/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" ) @@ -184,3 +187,20 @@ func fromV7Claim(v7 power7.Claim) Claim { QualityAdjPower: v7.QualityAdjPower, } } + +func (s *state7) ActorKey() string { + return actors.PowerKey +} + +func (s *state7) ActorVersion() actorstypes.Version { + return actorstypes.Version7 +} + +func (s *state7) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/power/v8.go b/chain/actors/builtin/power/v8.go index c23da6904..a462b2600 100644 --- a/chain/actors/builtin/power/v8.go +++ b/chain/actors/builtin/power/v8.go @@ -2,16 +2,19 @@ package power import ( "bytes" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" builtin8 "github.com/filecoin-project/go-state-types/builtin" power8 "github.com/filecoin-project/go-state-types/builtin/v8/power" adt8 "github.com/filecoin-project/go-state-types/builtin/v8/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" ) @@ -184,3 +187,20 @@ func fromV8Claim(v8 power8.Claim) Claim { QualityAdjPower: v8.QualityAdjPower, } } + +func (s *state8) ActorKey() string { + return actors.PowerKey +} + +func (s *state8) ActorVersion() actorstypes.Version { + return actorstypes.Version8 +} + +func (s *state8) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/power/v9.go b/chain/actors/builtin/power/v9.go index 7614b7c2e..0e8d5b072 100644 --- a/chain/actors/builtin/power/v9.go +++ b/chain/actors/builtin/power/v9.go @@ -2,16 +2,19 @@ package power import ( "bytes" + "fmt" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" builtin9 "github.com/filecoin-project/go-state-types/builtin" power9 "github.com/filecoin-project/go-state-types/builtin/v9/power" adt9 "github.com/filecoin-project/go-state-types/builtin/v9/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" ) @@ -184,3 +187,20 @@ func fromV9Claim(v9 power9.Claim) Claim { QualityAdjPower: v9.QualityAdjPower, } } + +func (s *state9) ActorKey() string { + return actors.PowerKey +} + +func (s *state9) ActorVersion() actorstypes.Version { + return actorstypes.Version9 +} + +func (s *state9) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/reward/actor.go.template b/chain/actors/builtin/reward/actor.go.template index 165f9efdf..4fd317c97 100644 --- a/chain/actors/builtin/reward/actor.go.template +++ b/chain/actors/builtin/reward/actor.go.template @@ -1,6 +1,7 @@ package reward import ( + "github.com/ipfs/go-cid" actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/go-state-types/abi" reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward" @@ -66,6 +67,10 @@ func MakeState(store adt.Store, av actorstypes.Version, currRealizedPower abi.St type State interface { cbor.Marshaler + Code() cid.Cid + ActorKey() string + ActorVersion() actorstypes.Version + ThisEpochBaselinePower() (abi.StoragePower, error) ThisEpochReward() (abi.StoragePower, error) ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) @@ -84,3 +89,10 @@ type State interface { } type AwardBlockRewardParams = reward0.AwardBlockRewardParams + +func AllCodes() []cid.Cid { + return []cid.Cid{ {{range .versions}} + (&state{{.}}{}).Code(), + {{- end}} + } +} diff --git a/chain/actors/builtin/reward/reward.go b/chain/actors/builtin/reward/reward.go index 437e58dc8..0efbdaf79 100644 --- a/chain/actors/builtin/reward/reward.go +++ b/chain/actors/builtin/reward/reward.go @@ -1,6 +1,7 @@ package reward import ( + "github.com/ipfs/go-cid" "golang.org/x/xerrors" "github.com/filecoin-project/go-state-types/abi" @@ -115,6 +116,10 @@ func MakeState(store adt.Store, av actorstypes.Version, currRealizedPower abi.St type State interface { cbor.Marshaler + Code() cid.Cid + ActorKey() string + ActorVersion() actorstypes.Version + ThisEpochBaselinePower() (abi.StoragePower, error) ThisEpochReward() (abi.StoragePower, error) ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) @@ -133,3 +138,18 @@ type State interface { } type AwardBlockRewardParams = reward0.AwardBlockRewardParams + +func AllCodes() []cid.Cid { + return []cid.Cid{ + (&state0{}).Code(), + (&state2{}).Code(), + (&state3{}).Code(), + (&state4{}).Code(), + (&state5{}).Code(), + (&state6{}).Code(), + (&state7{}).Code(), + (&state8{}).Code(), + (&state9{}).Code(), + (&state10{}).Code(), + } +} diff --git a/chain/actors/builtin/reward/state.go.template b/chain/actors/builtin/reward/state.go.template index dac3d82a4..104aefbaf 100644 --- a/chain/actors/builtin/reward/state.go.template +++ b/chain/actors/builtin/reward/state.go.template @@ -1,9 +1,12 @@ package reward import ( + "fmt" + actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/go-state-types/abi" "github.com/ipfs/go-cid" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" @@ -117,3 +120,20 @@ func (s *state{{.v}}) PreCommitDepositForPower(networkQAPower builtin.FilterEsti func (s *state{{.v}}) GetState() interface{} { return &s.State } + +func (s *state{{.v}}) ActorKey() string { + return actors.RewardKey +} + +func (s *state{{.v}}) ActorVersion() actorstypes.Version { + return actorstypes.Version{{.v}} +} + +func (s *state{{.v}}) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/reward/v0.go b/chain/actors/builtin/reward/v0.go index 12bdee054..332e97128 100644 --- a/chain/actors/builtin/reward/v0.go +++ b/chain/actors/builtin/reward/v0.go @@ -1,13 +1,17 @@ package reward import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward" smoothing0 "github.com/filecoin-project/specs-actors/actors/util/smoothing" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" ) @@ -93,3 +97,20 @@ func (s *state0) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, func (s *state0) GetState() interface{} { return &s.State } + +func (s *state0) ActorKey() string { + return actors.RewardKey +} + +func (s *state0) ActorVersion() actorstypes.Version { + return actorstypes.Version0 +} + +func (s *state0) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/reward/v10.go b/chain/actors/builtin/reward/v10.go index 8ef3875f3..75c23e1a6 100644 --- a/chain/actors/builtin/reward/v10.go +++ b/chain/actors/builtin/reward/v10.go @@ -1,13 +1,17 @@ package reward import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" miner10 "github.com/filecoin-project/go-state-types/builtin/v10/miner" reward10 "github.com/filecoin-project/go-state-types/builtin/v10/reward" smoothing10 "github.com/filecoin-project/go-state-types/builtin/v10/util/smoothing" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" ) @@ -96,3 +100,20 @@ func (s *state10) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate func (s *state10) GetState() interface{} { return &s.State } + +func (s *state10) ActorKey() string { + return actors.RewardKey +} + +func (s *state10) ActorVersion() actorstypes.Version { + return actorstypes.Version10 +} + +func (s *state10) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/reward/v2.go b/chain/actors/builtin/reward/v2.go index ed2481635..33f6c120f 100644 --- a/chain/actors/builtin/reward/v2.go +++ b/chain/actors/builtin/reward/v2.go @@ -1,13 +1,17 @@ package reward import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" reward2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/reward" smoothing2 "github.com/filecoin-project/specs-actors/v2/actors/util/smoothing" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" ) @@ -96,3 +100,20 @@ func (s *state2) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, func (s *state2) GetState() interface{} { return &s.State } + +func (s *state2) ActorKey() string { + return actors.RewardKey +} + +func (s *state2) ActorVersion() actorstypes.Version { + return actorstypes.Version2 +} + +func (s *state2) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/reward/v3.go b/chain/actors/builtin/reward/v3.go index d9f4bf369..d727a9861 100644 --- a/chain/actors/builtin/reward/v3.go +++ b/chain/actors/builtin/reward/v3.go @@ -1,13 +1,17 @@ package reward import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" miner3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/miner" reward3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/reward" smoothing3 "github.com/filecoin-project/specs-actors/v3/actors/util/smoothing" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" ) @@ -96,3 +100,20 @@ func (s *state3) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, func (s *state3) GetState() interface{} { return &s.State } + +func (s *state3) ActorKey() string { + return actors.RewardKey +} + +func (s *state3) ActorVersion() actorstypes.Version { + return actorstypes.Version3 +} + +func (s *state3) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/reward/v4.go b/chain/actors/builtin/reward/v4.go index 160c72ce7..94ebc43c4 100644 --- a/chain/actors/builtin/reward/v4.go +++ b/chain/actors/builtin/reward/v4.go @@ -1,13 +1,17 @@ package reward import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" miner4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/miner" reward4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/reward" smoothing4 "github.com/filecoin-project/specs-actors/v4/actors/util/smoothing" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" ) @@ -96,3 +100,20 @@ func (s *state4) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, func (s *state4) GetState() interface{} { return &s.State } + +func (s *state4) ActorKey() string { + return actors.RewardKey +} + +func (s *state4) ActorVersion() actorstypes.Version { + return actorstypes.Version4 +} + +func (s *state4) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/reward/v5.go b/chain/actors/builtin/reward/v5.go index 838ec8f21..563b8f42a 100644 --- a/chain/actors/builtin/reward/v5.go +++ b/chain/actors/builtin/reward/v5.go @@ -1,13 +1,17 @@ package reward import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" miner5 "github.com/filecoin-project/specs-actors/v5/actors/builtin/miner" reward5 "github.com/filecoin-project/specs-actors/v5/actors/builtin/reward" smoothing5 "github.com/filecoin-project/specs-actors/v5/actors/util/smoothing" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" ) @@ -96,3 +100,20 @@ func (s *state5) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, func (s *state5) GetState() interface{} { return &s.State } + +func (s *state5) ActorKey() string { + return actors.RewardKey +} + +func (s *state5) ActorVersion() actorstypes.Version { + return actorstypes.Version5 +} + +func (s *state5) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/reward/v6.go b/chain/actors/builtin/reward/v6.go index e056b22f6..523736766 100644 --- a/chain/actors/builtin/reward/v6.go +++ b/chain/actors/builtin/reward/v6.go @@ -1,13 +1,17 @@ package reward import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" miner6 "github.com/filecoin-project/specs-actors/v6/actors/builtin/miner" reward6 "github.com/filecoin-project/specs-actors/v6/actors/builtin/reward" smoothing6 "github.com/filecoin-project/specs-actors/v6/actors/util/smoothing" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" ) @@ -96,3 +100,20 @@ func (s *state6) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, func (s *state6) GetState() interface{} { return &s.State } + +func (s *state6) ActorKey() string { + return actors.RewardKey +} + +func (s *state6) ActorVersion() actorstypes.Version { + return actorstypes.Version6 +} + +func (s *state6) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/reward/v7.go b/chain/actors/builtin/reward/v7.go index 5fedaa43c..79db860e1 100644 --- a/chain/actors/builtin/reward/v7.go +++ b/chain/actors/builtin/reward/v7.go @@ -1,13 +1,17 @@ package reward import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" miner7 "github.com/filecoin-project/specs-actors/v7/actors/builtin/miner" reward7 "github.com/filecoin-project/specs-actors/v7/actors/builtin/reward" smoothing7 "github.com/filecoin-project/specs-actors/v7/actors/util/smoothing" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" ) @@ -96,3 +100,20 @@ func (s *state7) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, func (s *state7) GetState() interface{} { return &s.State } + +func (s *state7) ActorKey() string { + return actors.RewardKey +} + +func (s *state7) ActorVersion() actorstypes.Version { + return actorstypes.Version7 +} + +func (s *state7) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/reward/v8.go b/chain/actors/builtin/reward/v8.go index ecc5a94ba..a9d6fae69 100644 --- a/chain/actors/builtin/reward/v8.go +++ b/chain/actors/builtin/reward/v8.go @@ -1,13 +1,17 @@ package reward import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" miner8 "github.com/filecoin-project/go-state-types/builtin/v8/miner" reward8 "github.com/filecoin-project/go-state-types/builtin/v8/reward" smoothing8 "github.com/filecoin-project/go-state-types/builtin/v8/util/smoothing" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" ) @@ -96,3 +100,20 @@ func (s *state8) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, func (s *state8) GetState() interface{} { return &s.State } + +func (s *state8) ActorKey() string { + return actors.RewardKey +} + +func (s *state8) ActorVersion() actorstypes.Version { + return actorstypes.Version8 +} + +func (s *state8) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/reward/v9.go b/chain/actors/builtin/reward/v9.go index 04da532d2..34b8a7d34 100644 --- a/chain/actors/builtin/reward/v9.go +++ b/chain/actors/builtin/reward/v9.go @@ -1,13 +1,17 @@ package reward import ( + "fmt" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" miner9 "github.com/filecoin-project/go-state-types/builtin/v9/miner" reward9 "github.com/filecoin-project/go-state-types/builtin/v9/reward" smoothing9 "github.com/filecoin-project/go-state-types/builtin/v9/util/smoothing" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" ) @@ -96,3 +100,20 @@ func (s *state9) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, func (s *state9) GetState() interface{} { return &s.State } + +func (s *state9) ActorKey() string { + return actors.RewardKey +} + +func (s *state9) ActorVersion() actorstypes.Version { + return actorstypes.Version9 +} + +func (s *state9) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/system/actor.go.template b/chain/actors/builtin/system/actor.go.template index 0ef41e775..a6442c6a9 100644 --- a/chain/actors/builtin/system/actor.go.template +++ b/chain/actors/builtin/system/actor.go.template @@ -1,6 +1,7 @@ package system import ( + "github.com/ipfs/go-cid" actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors" @@ -60,7 +61,18 @@ func MakeState(store adt.Store, av actorstypes.Version, builtinActors cid.Cid) ( } type State interface { + Code() cid.Cid + ActorKey() string + ActorVersion() actorstypes.Version + GetState() interface{} GetBuiltinActors() cid.Cid SetBuiltinActors(cid.Cid) error } + +func AllCodes() []cid.Cid { + return []cid.Cid{ {{range .versions}} + (&state{{.}}{}).Code(), + {{- end}} + } +} diff --git a/chain/actors/builtin/system/state.go.template b/chain/actors/builtin/system/state.go.template index f8d9addf7..62dba041a 100644 --- a/chain/actors/builtin/system/state.go.template +++ b/chain/actors/builtin/system/state.go.template @@ -1,9 +1,13 @@ package system import ( + "fmt" + actorstypes "github.com/filecoin-project/go-state-types/actors" + "github.com/ipfs/go-cid" "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors" {{if (le .v 7)}} system{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/system" @@ -56,4 +60,21 @@ func (s *state{{.v}}) SetBuiltinActors(c cid.Cid) error { s.State.BuiltinActors = c return nil {{end}} -} \ No newline at end of file +} + +func (s *state{{.v}}) ActorKey() string { + return actors.SystemKey +} + +func (s *state{{.v}}) ActorVersion() actorstypes.Version { + return actorstypes.Version{{.v}} +} + +func (s *state{{.v}}) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/system/system.go b/chain/actors/builtin/system/system.go index 2fec9e5e5..747563cc0 100644 --- a/chain/actors/builtin/system/system.go +++ b/chain/actors/builtin/system/system.go @@ -109,7 +109,26 @@ func MakeState(store adt.Store, av actorstypes.Version, builtinActors cid.Cid) ( } type State interface { + Code() cid.Cid + ActorKey() string + ActorVersion() actorstypes.Version + GetState() interface{} GetBuiltinActors() cid.Cid SetBuiltinActors(cid.Cid) error } + +func AllCodes() []cid.Cid { + return []cid.Cid{ + (&state0{}).Code(), + (&state2{}).Code(), + (&state3{}).Code(), + (&state4{}).Code(), + (&state5{}).Code(), + (&state6{}).Code(), + (&state7{}).Code(), + (&state8{}).Code(), + (&state9{}).Code(), + (&state10{}).Code(), + } +} diff --git a/chain/actors/builtin/system/v0.go b/chain/actors/builtin/system/v0.go index 78e578896..17fa9e8c7 100644 --- a/chain/actors/builtin/system/v0.go +++ b/chain/actors/builtin/system/v0.go @@ -1,11 +1,15 @@ package system import ( + "fmt" + "github.com/ipfs/go-cid" "golang.org/x/xerrors" + actorstypes "github.com/filecoin-project/go-state-types/actors" system0 "github.com/filecoin-project/specs-actors/actors/builtin/system" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -46,3 +50,20 @@ func (s *state0) SetBuiltinActors(c cid.Cid) error { return xerrors.New("cannot set manifest cid before v8") } + +func (s *state0) ActorKey() string { + return actors.SystemKey +} + +func (s *state0) ActorVersion() actorstypes.Version { + return actorstypes.Version0 +} + +func (s *state0) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/system/v10.go b/chain/actors/builtin/system/v10.go index a90a7f5ac..e6d6fbe96 100644 --- a/chain/actors/builtin/system/v10.go +++ b/chain/actors/builtin/system/v10.go @@ -1,10 +1,14 @@ package system import ( + "fmt" + "github.com/ipfs/go-cid" + actorstypes "github.com/filecoin-project/go-state-types/actors" system10 "github.com/filecoin-project/go-state-types/builtin/v10/system" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -48,3 +52,20 @@ func (s *state10) SetBuiltinActors(c cid.Cid) error { return nil } + +func (s *state10) ActorKey() string { + return actors.SystemKey +} + +func (s *state10) ActorVersion() actorstypes.Version { + return actorstypes.Version10 +} + +func (s *state10) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/system/v2.go b/chain/actors/builtin/system/v2.go index 21dfa5c78..7821bee58 100644 --- a/chain/actors/builtin/system/v2.go +++ b/chain/actors/builtin/system/v2.go @@ -1,11 +1,15 @@ package system import ( + "fmt" + "github.com/ipfs/go-cid" "golang.org/x/xerrors" + actorstypes "github.com/filecoin-project/go-state-types/actors" system2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/system" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -46,3 +50,20 @@ func (s *state2) SetBuiltinActors(c cid.Cid) error { return xerrors.New("cannot set manifest cid before v8") } + +func (s *state2) ActorKey() string { + return actors.SystemKey +} + +func (s *state2) ActorVersion() actorstypes.Version { + return actorstypes.Version2 +} + +func (s *state2) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/system/v3.go b/chain/actors/builtin/system/v3.go index ccf8aa2c3..0c80218c4 100644 --- a/chain/actors/builtin/system/v3.go +++ b/chain/actors/builtin/system/v3.go @@ -1,11 +1,15 @@ package system import ( + "fmt" + "github.com/ipfs/go-cid" "golang.org/x/xerrors" + actorstypes "github.com/filecoin-project/go-state-types/actors" system3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/system" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -46,3 +50,20 @@ func (s *state3) SetBuiltinActors(c cid.Cid) error { return xerrors.New("cannot set manifest cid before v8") } + +func (s *state3) ActorKey() string { + return actors.SystemKey +} + +func (s *state3) ActorVersion() actorstypes.Version { + return actorstypes.Version3 +} + +func (s *state3) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/system/v4.go b/chain/actors/builtin/system/v4.go index bcb120be2..e41792110 100644 --- a/chain/actors/builtin/system/v4.go +++ b/chain/actors/builtin/system/v4.go @@ -1,11 +1,15 @@ package system import ( + "fmt" + "github.com/ipfs/go-cid" "golang.org/x/xerrors" + actorstypes "github.com/filecoin-project/go-state-types/actors" system4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/system" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -46,3 +50,20 @@ func (s *state4) SetBuiltinActors(c cid.Cid) error { return xerrors.New("cannot set manifest cid before v8") } + +func (s *state4) ActorKey() string { + return actors.SystemKey +} + +func (s *state4) ActorVersion() actorstypes.Version { + return actorstypes.Version4 +} + +func (s *state4) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/system/v5.go b/chain/actors/builtin/system/v5.go index 182883398..a2760b096 100644 --- a/chain/actors/builtin/system/v5.go +++ b/chain/actors/builtin/system/v5.go @@ -1,11 +1,15 @@ package system import ( + "fmt" + "github.com/ipfs/go-cid" "golang.org/x/xerrors" + actorstypes "github.com/filecoin-project/go-state-types/actors" system5 "github.com/filecoin-project/specs-actors/v5/actors/builtin/system" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -46,3 +50,20 @@ func (s *state5) SetBuiltinActors(c cid.Cid) error { return xerrors.New("cannot set manifest cid before v8") } + +func (s *state5) ActorKey() string { + return actors.SystemKey +} + +func (s *state5) ActorVersion() actorstypes.Version { + return actorstypes.Version5 +} + +func (s *state5) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/system/v6.go b/chain/actors/builtin/system/v6.go index 9860ce373..0de085a5e 100644 --- a/chain/actors/builtin/system/v6.go +++ b/chain/actors/builtin/system/v6.go @@ -1,11 +1,15 @@ package system import ( + "fmt" + "github.com/ipfs/go-cid" "golang.org/x/xerrors" + actorstypes "github.com/filecoin-project/go-state-types/actors" system6 "github.com/filecoin-project/specs-actors/v6/actors/builtin/system" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -46,3 +50,20 @@ func (s *state6) SetBuiltinActors(c cid.Cid) error { return xerrors.New("cannot set manifest cid before v8") } + +func (s *state6) ActorKey() string { + return actors.SystemKey +} + +func (s *state6) ActorVersion() actorstypes.Version { + return actorstypes.Version6 +} + +func (s *state6) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/system/v7.go b/chain/actors/builtin/system/v7.go index 5984b0b4d..2753251c0 100644 --- a/chain/actors/builtin/system/v7.go +++ b/chain/actors/builtin/system/v7.go @@ -1,11 +1,15 @@ package system import ( + "fmt" + "github.com/ipfs/go-cid" "golang.org/x/xerrors" + actorstypes "github.com/filecoin-project/go-state-types/actors" system7 "github.com/filecoin-project/specs-actors/v7/actors/builtin/system" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -46,3 +50,20 @@ func (s *state7) SetBuiltinActors(c cid.Cid) error { return xerrors.New("cannot set manifest cid before v8") } + +func (s *state7) ActorKey() string { + return actors.SystemKey +} + +func (s *state7) ActorVersion() actorstypes.Version { + return actorstypes.Version7 +} + +func (s *state7) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/system/v8.go b/chain/actors/builtin/system/v8.go index 574df9c44..00cafdfed 100644 --- a/chain/actors/builtin/system/v8.go +++ b/chain/actors/builtin/system/v8.go @@ -1,10 +1,14 @@ package system import ( + "fmt" + "github.com/ipfs/go-cid" + actorstypes "github.com/filecoin-project/go-state-types/actors" system8 "github.com/filecoin-project/go-state-types/builtin/v8/system" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -48,3 +52,20 @@ func (s *state8) SetBuiltinActors(c cid.Cid) error { return nil } + +func (s *state8) ActorKey() string { + return actors.SystemKey +} + +func (s *state8) ActorVersion() actorstypes.Version { + return actorstypes.Version8 +} + +func (s *state8) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/system/v9.go b/chain/actors/builtin/system/v9.go index 40555a921..8bf96a917 100644 --- a/chain/actors/builtin/system/v9.go +++ b/chain/actors/builtin/system/v9.go @@ -1,10 +1,14 @@ package system import ( + "fmt" + "github.com/ipfs/go-cid" + actorstypes "github.com/filecoin-project/go-state-types/actors" system9 "github.com/filecoin-project/go-state-types/builtin/v9/system" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -48,3 +52,20 @@ func (s *state9) SetBuiltinActors(c cid.Cid) error { return nil } + +func (s *state9) ActorKey() string { + return actors.SystemKey +} + +func (s *state9) ActorVersion() actorstypes.Version { + return actorstypes.Version9 +} + +func (s *state9) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/verifreg/actor.go.template b/chain/actors/builtin/verifreg/actor.go.template index 5c7715e3d..fe8eb1849 100644 --- a/chain/actors/builtin/verifreg/actor.go.template +++ b/chain/actors/builtin/verifreg/actor.go.template @@ -1,6 +1,7 @@ package verifreg import ( + "github.com/ipfs/go-cid" actorstypes "github.com/filecoin-project/go-state-types/actors" "golang.org/x/xerrors" @@ -67,6 +68,10 @@ func MakeState(store adt.Store, av actorstypes.Version, rootKeyAddress address.A type State interface { cbor.Marshaler + Code() cid.Cid + ActorKey() string + ActorVersion() actorstypes.Version + RootKey() (address.Address, error) VerifiedClientDataCap(address.Address) (bool, abi.StoragePower, error) VerifierDataCap(address.Address) (bool, abi.StoragePower, error) @@ -79,3 +84,10 @@ type State interface { GetClaims(providerIdAddr address.Address) (map[verifregtypes.ClaimId]verifregtypes.Claim, error) GetState() interface{} } + +func AllCodes() []cid.Cid { + return []cid.Cid{ {{range .versions}} + (&state{{.}}{}).Code(), + {{- end}} + } +} diff --git a/chain/actors/builtin/verifreg/state.go.template b/chain/actors/builtin/verifreg/state.go.template index 6a93c50b6..0d96168d6 100644 --- a/chain/actors/builtin/verifreg/state.go.template +++ b/chain/actors/builtin/verifreg/state.go.template @@ -1,6 +1,8 @@ package verifreg import ( + "fmt" + actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/ipfs/go-cid" @@ -150,3 +152,20 @@ func (s *state{{.v}}) GetClaims(providerIdAddr address.Address) (map[verifreg9.C return s.LoadClaimsToMap(s.store, providerIdAddr) {{end}} } + +func (s *state{{.v}}) ActorKey() string { + return actors.VerifregKey +} + +func (s *state{{.v}}) ActorVersion() actorstypes.Version { + return actorstypes.Version{{.v}} +} + +func (s *state{{.v}}) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/verifreg/v0.go b/chain/actors/builtin/verifreg/v0.go index debe32125..d8d81b4d3 100644 --- a/chain/actors/builtin/verifreg/v0.go +++ b/chain/actors/builtin/verifreg/v0.go @@ -1,11 +1,14 @@ package verifreg import ( + "fmt" + "github.com/ipfs/go-cid" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" verifreg9 "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg" adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" @@ -113,3 +116,20 @@ func (s *state0) GetClaims(providerIdAddr address.Address) (map[verifreg9.ClaimI return nil, xerrors.Errorf("unsupported in actors v0") } + +func (s *state0) ActorKey() string { + return actors.VerifregKey +} + +func (s *state0) ActorVersion() actorstypes.Version { + return actorstypes.Version0 +} + +func (s *state0) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/verifreg/v10.go b/chain/actors/builtin/verifreg/v10.go index 5f7cd559d..497ea4d3a 100644 --- a/chain/actors/builtin/verifreg/v10.go +++ b/chain/actors/builtin/verifreg/v10.go @@ -1,11 +1,14 @@ package verifreg import ( + "fmt" + "github.com/ipfs/go-cid" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/go-state-types/big" builtin10 "github.com/filecoin-project/go-state-types/builtin" adt10 "github.com/filecoin-project/go-state-types/builtin/v10/util/adt" @@ -114,3 +117,20 @@ func (s *state10) GetClaims(providerIdAddr address.Address) (map[verifreg9.Claim return s.LoadClaimsToMap(s.store, providerIdAddr) } + +func (s *state10) ActorKey() string { + return actors.VerifregKey +} + +func (s *state10) ActorVersion() actorstypes.Version { + return actorstypes.Version10 +} + +func (s *state10) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/verifreg/v2.go b/chain/actors/builtin/verifreg/v2.go index a6f07eea2..c12e3a505 100644 --- a/chain/actors/builtin/verifreg/v2.go +++ b/chain/actors/builtin/verifreg/v2.go @@ -1,11 +1,14 @@ package verifreg import ( + "fmt" + "github.com/ipfs/go-cid" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" verifreg9 "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" verifreg2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/verifreg" adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" @@ -113,3 +116,20 @@ func (s *state2) GetClaims(providerIdAddr address.Address) (map[verifreg9.ClaimI return nil, xerrors.Errorf("unsupported in actors v2") } + +func (s *state2) ActorKey() string { + return actors.VerifregKey +} + +func (s *state2) ActorVersion() actorstypes.Version { + return actorstypes.Version2 +} + +func (s *state2) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/verifreg/v3.go b/chain/actors/builtin/verifreg/v3.go index 11e56d8ae..3ac18aa6d 100644 --- a/chain/actors/builtin/verifreg/v3.go +++ b/chain/actors/builtin/verifreg/v3.go @@ -1,11 +1,14 @@ package verifreg import ( + "fmt" + "github.com/ipfs/go-cid" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" verifreg9 "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin" verifreg3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/verifreg" @@ -114,3 +117,20 @@ func (s *state3) GetClaims(providerIdAddr address.Address) (map[verifreg9.ClaimI return nil, xerrors.Errorf("unsupported in actors v3") } + +func (s *state3) ActorKey() string { + return actors.VerifregKey +} + +func (s *state3) ActorVersion() actorstypes.Version { + return actorstypes.Version3 +} + +func (s *state3) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/verifreg/v4.go b/chain/actors/builtin/verifreg/v4.go index da51e78b8..c99e84478 100644 --- a/chain/actors/builtin/verifreg/v4.go +++ b/chain/actors/builtin/verifreg/v4.go @@ -1,11 +1,14 @@ package verifreg import ( + "fmt" + "github.com/ipfs/go-cid" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" verifreg9 "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin" verifreg4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/verifreg" @@ -114,3 +117,20 @@ func (s *state4) GetClaims(providerIdAddr address.Address) (map[verifreg9.ClaimI return nil, xerrors.Errorf("unsupported in actors v4") } + +func (s *state4) ActorKey() string { + return actors.VerifregKey +} + +func (s *state4) ActorVersion() actorstypes.Version { + return actorstypes.Version4 +} + +func (s *state4) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/verifreg/v5.go b/chain/actors/builtin/verifreg/v5.go index 08f8ad706..45e416693 100644 --- a/chain/actors/builtin/verifreg/v5.go +++ b/chain/actors/builtin/verifreg/v5.go @@ -1,11 +1,14 @@ package verifreg import ( + "fmt" + "github.com/ipfs/go-cid" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" verifreg9 "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" builtin5 "github.com/filecoin-project/specs-actors/v5/actors/builtin" verifreg5 "github.com/filecoin-project/specs-actors/v5/actors/builtin/verifreg" @@ -114,3 +117,20 @@ func (s *state5) GetClaims(providerIdAddr address.Address) (map[verifreg9.ClaimI return nil, xerrors.Errorf("unsupported in actors v5") } + +func (s *state5) ActorKey() string { + return actors.VerifregKey +} + +func (s *state5) ActorVersion() actorstypes.Version { + return actorstypes.Version5 +} + +func (s *state5) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/verifreg/v6.go b/chain/actors/builtin/verifreg/v6.go index 8e6fc3603..d181366dc 100644 --- a/chain/actors/builtin/verifreg/v6.go +++ b/chain/actors/builtin/verifreg/v6.go @@ -1,11 +1,14 @@ package verifreg import ( + "fmt" + "github.com/ipfs/go-cid" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" verifreg9 "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" builtin6 "github.com/filecoin-project/specs-actors/v6/actors/builtin" verifreg6 "github.com/filecoin-project/specs-actors/v6/actors/builtin/verifreg" @@ -114,3 +117,20 @@ func (s *state6) GetClaims(providerIdAddr address.Address) (map[verifreg9.ClaimI return nil, xerrors.Errorf("unsupported in actors v6") } + +func (s *state6) ActorKey() string { + return actors.VerifregKey +} + +func (s *state6) ActorVersion() actorstypes.Version { + return actorstypes.Version6 +} + +func (s *state6) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/verifreg/v7.go b/chain/actors/builtin/verifreg/v7.go index c3b49a305..0f9a4301c 100644 --- a/chain/actors/builtin/verifreg/v7.go +++ b/chain/actors/builtin/verifreg/v7.go @@ -1,11 +1,14 @@ package verifreg import ( + "fmt" + "github.com/ipfs/go-cid" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" verifreg9 "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" builtin7 "github.com/filecoin-project/specs-actors/v7/actors/builtin" verifreg7 "github.com/filecoin-project/specs-actors/v7/actors/builtin/verifreg" @@ -113,3 +116,20 @@ func (s *state7) GetClaims(providerIdAddr address.Address) (map[verifreg9.ClaimI return nil, xerrors.Errorf("unsupported in actors v7") } + +func (s *state7) ActorKey() string { + return actors.VerifregKey +} + +func (s *state7) ActorVersion() actorstypes.Version { + return actorstypes.Version7 +} + +func (s *state7) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/verifreg/v8.go b/chain/actors/builtin/verifreg/v8.go index 36d219fa0..8bd524635 100644 --- a/chain/actors/builtin/verifreg/v8.go +++ b/chain/actors/builtin/verifreg/v8.go @@ -1,11 +1,14 @@ package verifreg import ( + "fmt" + "github.com/ipfs/go-cid" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" builtin8 "github.com/filecoin-project/go-state-types/builtin" adt8 "github.com/filecoin-project/go-state-types/builtin/v8/util/adt" verifreg8 "github.com/filecoin-project/go-state-types/builtin/v8/verifreg" @@ -113,3 +116,20 @@ func (s *state8) GetClaims(providerIdAddr address.Address) (map[verifreg9.ClaimI return nil, xerrors.Errorf("unsupported in actors v8") } + +func (s *state8) ActorKey() string { + return actors.VerifregKey +} + +func (s *state8) ActorVersion() actorstypes.Version { + return actorstypes.Version8 +} + +func (s *state8) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/verifreg/v9.go b/chain/actors/builtin/verifreg/v9.go index 5c84c7041..22768b22d 100644 --- a/chain/actors/builtin/verifreg/v9.go +++ b/chain/actors/builtin/verifreg/v9.go @@ -1,11 +1,14 @@ package verifreg import ( + "fmt" + "github.com/ipfs/go-cid" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/go-state-types/big" builtin9 "github.com/filecoin-project/go-state-types/builtin" adt9 "github.com/filecoin-project/go-state-types/builtin/v9/util/adt" @@ -113,3 +116,20 @@ func (s *state9) GetClaims(providerIdAddr address.Address) (map[verifreg9.ClaimI return s.LoadClaimsToMap(s.store, providerIdAddr) } + +func (s *state9) ActorKey() string { + return actors.VerifregKey +} + +func (s *state9) ActorVersion() actorstypes.Version { + return actorstypes.Version9 +} + +func (s *state9) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/verifreg/verifreg.go b/chain/actors/builtin/verifreg/verifreg.go index 9d92751da..135d49d11 100644 --- a/chain/actors/builtin/verifreg/verifreg.go +++ b/chain/actors/builtin/verifreg/verifreg.go @@ -1,6 +1,7 @@ package verifreg import ( + "github.com/ipfs/go-cid" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" @@ -115,6 +116,10 @@ func MakeState(store adt.Store, av actorstypes.Version, rootKeyAddress address.A type State interface { cbor.Marshaler + Code() cid.Cid + ActorKey() string + ActorVersion() actorstypes.Version + RootKey() (address.Address, error) VerifiedClientDataCap(address.Address) (bool, abi.StoragePower, error) VerifierDataCap(address.Address) (bool, abi.StoragePower, error) @@ -127,3 +132,18 @@ type State interface { GetClaims(providerIdAddr address.Address) (map[verifregtypes.ClaimId]verifregtypes.Claim, error) GetState() interface{} } + +func AllCodes() []cid.Cid { + return []cid.Cid{ + (&state0{}).Code(), + (&state2{}).Code(), + (&state3{}).Code(), + (&state4{}).Code(), + (&state5{}).Code(), + (&state6{}).Code(), + (&state7{}).Code(), + (&state8{}).Code(), + (&state9{}).Code(), + (&state10{}).Code(), + } +} diff --git a/chain/beacon/drand/drand.go b/chain/beacon/drand/drand.go index 5b6cc45bd..181fa3046 100644 --- a/chain/beacon/drand/drand.go +++ b/chain/beacon/drand/drand.go @@ -107,7 +107,7 @@ func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config dtypes client, err := dclient.Wrap(clients, opts...) if err != nil { - return nil, xerrors.Errorf("creating drand client") + return nil, xerrors.Errorf("creating drand client: %w", err) } lc, err := lru.New(1024) diff --git a/chain/consensus/filcns/compute_state.go b/chain/consensus/filcns/compute_state.go index 8da5e1051..ece973798 100644 --- a/chain/consensus/filcns/compute_state.go +++ b/chain/consensus/filcns/compute_state.go @@ -101,6 +101,7 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context, NetworkVersion: sm.GetNetworkVersion(ctx, e), BaseFee: baseFee, LookbackState: stmgr.LookbackStateGetterForTipset(sm, ts), + TipSetGetter: stmgr.TipSetGetterForTipset(sm.ChainStore(), ts), Tracing: vmTracing, } diff --git a/chain/messagepool/messagepool.go b/chain/messagepool/messagepool.go index a0872ac90..7016b7242 100644 --- a/chain/messagepool/messagepool.go +++ b/chain/messagepool/messagepool.go @@ -82,6 +82,7 @@ var ( ErrRBFTooLowPremium = errors.New("replace by fee has too low GasPremium") ErrTooManyPendingMessages = errors.New("too many pending messages for actor") ErrNonceGap = errors.New("unfulfilled nonce gap") + ErrExistingNonce = errors.New("message with nonce already exists") ) const ( @@ -276,7 +277,7 @@ func (ms *msgSet) add(m *types.SignedMessage, mp *MessagePool, strict, untrusted } } else { return false, xerrors.Errorf("message from %s with nonce %d already in mpool: %w", - m.Message.From, m.Message.Nonce, ErrSoftValidationFailure) + m.Message.From, m.Message.Nonce, ErrExistingNonce) } ms.requiredFunds.Sub(ms.requiredFunds, exms.Message.RequiredFunds().Int) @@ -667,7 +668,9 @@ func (mp *MessagePool) verifyMsgBeforeAdd(ctx context.Context, m *types.SignedMe return publish, nil } -func (mp *MessagePool) Push(ctx context.Context, m *types.SignedMessage) (cid.Cid, error) { +// Push checks the signed message for any violations, adds the message to the message pool and +// publishes the message if the publish flag is set +func (mp *MessagePool) Push(ctx context.Context, m *types.SignedMessage, publish bool) (cid.Cid, error) { done := metrics.Timer(ctx, metrics.MpoolPushDuration) defer done() @@ -683,14 +686,14 @@ func (mp *MessagePool) Push(ctx context.Context, m *types.SignedMessage) (cid.Ci }() mp.curTsLk.Lock() - publish, err := mp.addTs(ctx, m, mp.curTs, true, false) + ok, err := mp.addTs(ctx, m, mp.curTs, true, false) if err != nil { mp.curTsLk.Unlock() return cid.Undef, err } mp.curTsLk.Unlock() - if publish { + if ok && publish { msgb, err := m.Serialize() if err != nil { return cid.Undef, xerrors.Errorf("error serializing message: %w", err) @@ -1583,3 +1586,8 @@ func getBaseFeeLowerBound(baseFee, factor types.BigInt) types.BigInt { return baseFeeLowerBound } + +type MpoolNonceAPI interface { + GetNonce(context.Context, address.Address, types.TipSetKey) (uint64, error) + GetActor(context.Context, address.Address, types.TipSetKey) (*types.Actor, error) +} diff --git a/chain/messagepool/messagepool_test.go b/chain/messagepool/messagepool_test.go index 5822a68b7..37122492e 100644 --- a/chain/messagepool/messagepool_test.go +++ b/chain/messagepool/messagepool_test.go @@ -545,7 +545,7 @@ func TestLoadLocal(t *testing.T) { for i := 0; i < 10; i++ { m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1)) //stm: @CHAIN_MEMPOOL_PUSH_001 - cid, err := mp.Push(context.TODO(), m) + cid, err := mp.Push(context.TODO(), m, true) if err != nil { t.Fatal(err) } @@ -618,7 +618,7 @@ func TestClearAll(t *testing.T) { for i := 0; i < 10; i++ { m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1)) //stm: @CHAIN_MEMPOOL_PUSH_001 - _, err := mp.Push(context.TODO(), m) + _, err := mp.Push(context.TODO(), m, true) if err != nil { t.Fatal(err) } @@ -676,7 +676,7 @@ func TestClearNonLocal(t *testing.T) { for i := 0; i < 10; i++ { m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1)) //stm: @CHAIN_MEMPOOL_PUSH_001 - _, err := mp.Push(context.TODO(), m) + _, err := mp.Push(context.TODO(), m, true) if err != nil { t.Fatal(err) } @@ -749,7 +749,7 @@ func TestUpdates(t *testing.T) { for i := 0; i < 10; i++ { m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1)) //stm: @CHAIN_MEMPOOL_PUSH_001 - _, err := mp.Push(context.TODO(), m) + _, err := mp.Push(context.TODO(), m, true) if err != nil { t.Fatal(err) } diff --git a/chain/messagepool/provider.go b/chain/messagepool/provider.go index 50a1bf30f..f8bbbc01e 100644 --- a/chain/messagepool/provider.go +++ b/chain/messagepool/provider.go @@ -12,7 +12,6 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/network" - "github.com/filecoin-project/lotus/chain/messagesigner" "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" @@ -42,7 +41,7 @@ type mpoolProvider struct { sm *stmgr.StateManager ps *pubsub.PubSub - lite messagesigner.MpoolNonceAPI + lite MpoolNonceAPI } var _ Provider = (*mpoolProvider)(nil) @@ -51,7 +50,7 @@ func NewProvider(sm *stmgr.StateManager, ps *pubsub.PubSub) Provider { return &mpoolProvider{sm: sm, ps: ps} } -func NewProviderLite(sm *stmgr.StateManager, ps *pubsub.PubSub, noncer messagesigner.MpoolNonceAPI) Provider { +func NewProviderLite(sm *stmgr.StateManager, ps *pubsub.PubSub, noncer MpoolNonceAPI) Provider { return &mpoolProvider{sm: sm, ps: ps, lite: noncer} } diff --git a/chain/messagepool/repub_test.go b/chain/messagepool/repub_test.go index f6130282c..9cdabc02f 100644 --- a/chain/messagepool/repub_test.go +++ b/chain/messagepool/repub_test.go @@ -60,7 +60,7 @@ func TestRepubMessages(t *testing.T) { for i := 0; i < 10; i++ { m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1)) //stm: @CHAIN_MEMPOOL_PUSH_001 - _, err := mp.Push(context.TODO(), m) + _, err := mp.Push(context.TODO(), m, true) if err != nil { t.Fatal(err) } diff --git a/chain/messagesigner/messagesigner.go b/chain/messagesigner/messagesigner.go index 249639d2a..96457e9f8 100644 --- a/chain/messagesigner/messagesigner.go +++ b/chain/messagesigner/messagesigner.go @@ -15,6 +15,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/messagepool" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/node/modules/dtypes" ) @@ -24,9 +25,12 @@ const dsKeyMsgUUIDSet = "MsgUuidSet" var log = logging.Logger("messagesigner") -type MpoolNonceAPI interface { - GetNonce(context.Context, address.Address, types.TipSetKey) (uint64, error) - GetActor(context.Context, address.Address, types.TipSetKey) (*types.Actor, error) +type MsgSigner interface { + SignMessage(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, cb func(*types.SignedMessage) error) (*types.SignedMessage, error) + GetSignedMessage(ctx context.Context, uuid uuid.UUID) (*types.SignedMessage, error) + StoreSignedMessage(ctx context.Context, uuid uuid.UUID, message *types.SignedMessage) error + NextNonce(ctx context.Context, addr address.Address) (uint64, error) + SaveNonce(ctx context.Context, addr address.Address, nonce uint64) error } // MessageSigner keeps track of nonces per address, and increments the nonce @@ -34,11 +38,11 @@ type MpoolNonceAPI interface { type MessageSigner struct { wallet api.Wallet lk sync.Mutex - mpool MpoolNonceAPI + mpool messagepool.MpoolNonceAPI ds datastore.Batching } -func NewMessageSigner(wallet api.Wallet, mpool MpoolNonceAPI, ds dtypes.MetadataDS) *MessageSigner { +func NewMessageSigner(wallet api.Wallet, mpool messagepool.MpoolNonceAPI, ds dtypes.MetadataDS) *MessageSigner { ds = namespace.Wrap(ds, datastore.NewKey("/message-signer/")) return &MessageSigner{ wallet: wallet, @@ -49,12 +53,12 @@ func NewMessageSigner(wallet api.Wallet, mpool MpoolNonceAPI, ds dtypes.Metadata // SignMessage increments the nonce for the message From address, and signs // the message -func (ms *MessageSigner) SignMessage(ctx context.Context, msg *types.Message, cb func(*types.SignedMessage) error) (*types.SignedMessage, error) { +func (ms *MessageSigner) SignMessage(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, cb func(*types.SignedMessage) error) (*types.SignedMessage, error) { ms.lk.Lock() defer ms.lk.Unlock() // Get the next message nonce - nonce, err := ms.nextNonce(ctx, msg.From) + nonce, err := ms.NextNonce(ctx, msg.From) if err != nil { return nil, xerrors.Errorf("failed to create nonce: %w", err) } @@ -72,7 +76,7 @@ func (ms *MessageSigner) SignMessage(ctx context.Context, msg *types.Message, cb Extra: mb.RawData(), }) if err != nil { - return nil, xerrors.Errorf("failed to sign message: %w", err) + return nil, xerrors.Errorf("failed to sign message: %w, addr=%s", err, msg.From) } // Callback with the signed message @@ -80,13 +84,14 @@ func (ms *MessageSigner) SignMessage(ctx context.Context, msg *types.Message, cb Message: *msg, Signature: *sig, } + err = cb(smsg) if err != nil { return nil, err } // If the callback executed successfully, write the nonce to the datastore - if err := ms.saveNonce(ctx, msg.From, nonce); err != nil { + if err := ms.SaveNonce(ctx, msg.From, nonce); err != nil { return nil, xerrors.Errorf("failed to save nonce: %w", err) } @@ -113,9 +118,9 @@ func (ms *MessageSigner) StoreSignedMessage(ctx context.Context, uuid uuid.UUID, return ms.ds.Put(ctx, key, serializedMsg) } -// nextNonce gets the next nonce for the given address. +// NextNonce gets the next nonce for the given address. // If there is no nonce in the datastore, gets the nonce from the message pool. -func (ms *MessageSigner) nextNonce(ctx context.Context, addr address.Address) (uint64, error) { +func (ms *MessageSigner) NextNonce(ctx context.Context, addr address.Address) (uint64, error) { // Nonces used to be created by the mempool and we need to support nodes // that have mempool nonces, so first check the mempool for a nonce for // this address. Note that the mempool returns the actor state's nonce @@ -159,9 +164,9 @@ func (ms *MessageSigner) nextNonce(ctx context.Context, addr address.Address) (u } } -// saveNonce increments the nonce for this address and writes it to the +// SaveNonce increments the nonce for this address and writes it to the // datastore -func (ms *MessageSigner) saveNonce(ctx context.Context, addr address.Address, nonce uint64) error { +func (ms *MessageSigner) SaveNonce(ctx context.Context, addr address.Address, nonce uint64) error { // Increment the nonce nonce++ diff --git a/chain/messagesigner/messagesigner_consensus.go b/chain/messagesigner/messagesigner_consensus.go new file mode 100644 index 000000000..905bb7199 --- /dev/null +++ b/chain/messagesigner/messagesigner_consensus.go @@ -0,0 +1,98 @@ +package messagesigner + +import ( + "context" + + "github.com/google/uuid" + "github.com/ipfs/go-datastore" + "github.com/ipfs/go-datastore/namespace" + "github.com/libp2p/go-libp2p/core/peer" + "golang.org/x/xerrors" + + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/messagepool" + "github.com/filecoin-project/lotus/chain/types" + consensus "github.com/filecoin-project/lotus/lib/consensus/raft" + "github.com/filecoin-project/lotus/node/modules/dtypes" +) + +type MessageSignerConsensus struct { + MsgSigner + Consensus *consensus.Consensus +} + +func NewMessageSignerConsensus( + wallet api.Wallet, + mpool messagepool.MpoolNonceAPI, + ds dtypes.MetadataDS, + consensus *consensus.Consensus) *MessageSignerConsensus { + + ds = namespace.Wrap(ds, datastore.NewKey("/message-signer-consensus/")) + return &MessageSignerConsensus{ + MsgSigner: &MessageSigner{ + wallet: wallet, + mpool: mpool, + ds: ds, + }, + Consensus: consensus, + } +} + +func (ms *MessageSignerConsensus) IsLeader(ctx context.Context) bool { + return ms.Consensus.IsLeader(ctx) +} + +func (ms *MessageSignerConsensus) RedirectToLeader(ctx context.Context, method string, arg interface{}, ret interface{}) (bool, error) { + ok, err := ms.Consensus.RedirectToLeader(method, arg, ret.(*types.SignedMessage)) + if err != nil { + return ok, err + } + return ok, nil +} + +func (ms *MessageSignerConsensus) SignMessage( + ctx context.Context, + msg *types.Message, + spec *api.MessageSendSpec, + cb func(*types.SignedMessage) error) (*types.SignedMessage, error) { + + signedMsg, err := ms.MsgSigner.SignMessage(ctx, msg, spec, cb) + if err != nil { + return nil, err + } + + op := &consensus.ConsensusOp{ + Nonce: signedMsg.Message.Nonce, + Uuid: spec.MsgUuid, + Addr: signedMsg.Message.From, + SignedMsg: signedMsg, + } + err = ms.Consensus.Commit(ctx, op) + if err != nil { + return nil, err + } + + return signedMsg, nil +} + +func (ms *MessageSignerConsensus) GetSignedMessage(ctx context.Context, uuid uuid.UUID) (*types.SignedMessage, error) { + cstate, err := ms.Consensus.State(ctx) + if err != nil { + return nil, err + } + + //cstate := state.(Consensus.RaftState) + msg, ok := cstate.MsgUuids[uuid] + if !ok { + return nil, xerrors.Errorf("Msg with Uuid %s not available", uuid) + } + return msg, nil +} + +func (ms *MessageSignerConsensus) GetRaftState(ctx context.Context) (*consensus.RaftState, error) { + return ms.Consensus.State(ctx) +} + +func (ms *MessageSignerConsensus) Leader(ctx context.Context) (peer.ID, error) { + return ms.Consensus.Leader(ctx) +} diff --git a/chain/messagesigner/messagesigner_test.go b/chain/messagesigner/messagesigner_test.go index 87a5e8615..637f17b46 100644 --- a/chain/messagesigner/messagesigner_test.go +++ b/chain/messagesigner/messagesigner_test.go @@ -13,6 +13,7 @@ import ( "github.com/filecoin-project/go-address" + "github.com/filecoin-project/lotus/chain/messagepool" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/wallet" ) @@ -22,7 +23,7 @@ type mockMpool struct { nonces map[address.Address]uint64 } -var _ MpoolNonceAPI = (*mockMpool)(nil) +var _ messagepool.MpoolNonceAPI = (*mockMpool)(nil) func newMockMpool() *mockMpool { return &mockMpool{nonces: make(map[address.Address]uint64)} @@ -187,7 +188,7 @@ func TestMessageSignerSignMessage(t *testing.T) { mpool.setNonce(m.msg.From, m.mpoolNonce[0]) } merr := m.cbErr - smsg, err := ms.SignMessage(ctx, m.msg, func(message *types.SignedMessage) error { + smsg, err := ms.SignMessage(ctx, m.msg, nil, func(message *types.SignedMessage) error { return merr }) diff --git a/chain/stmgr/call.go b/chain/stmgr/call.go index 92066ca81..c110dd4bd 100644 --- a/chain/stmgr/call.go +++ b/chain/stmgr/call.go @@ -14,6 +14,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/crypto" + "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/blockstore" @@ -29,74 +30,7 @@ var ErrExpensiveFork = errors.New("refusing explicit call due to state fork at e // Call applies the given message to the given tipset's parent state, at the epoch following the // tipset's parent. In the presence of null blocks, the height at which the message is invoked may // be less than the specified tipset. -// -// - If no tipset is specified, the first tipset without an expensive migration is used. -// - If executing a message at a given tipset would trigger an expensive migration, the call will -// fail with ErrExpensiveFork. func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types.TipSet) (*api.InvocResult, error) { - ctx, span := trace.StartSpan(ctx, "statemanager.Call") - defer span.End() - - var pheight abi.ChainEpoch = -1 - - // If no tipset is provided, try to find one without a fork. - if ts == nil { - ts = sm.cs.GetHeaviestTipSet() - // Search back till we find a height with no fork, or we reach the beginning. - for ts.Height() > 0 { - pts, err := sm.cs.GetTipSetFromKey(ctx, ts.Parents()) - if err != nil { - return nil, xerrors.Errorf("failed to find a non-forking epoch: %w", err) - } - if !sm.hasExpensiveFork(pts.Height()) { - pheight = pts.Height() - break - } - ts = pts - } - } else if ts.Height() > 0 { - pts, err := sm.cs.LoadTipSet(ctx, ts.Parents()) - if err != nil { - return nil, xerrors.Errorf("failed to load parent tipset: %w", err) - } - pheight = pts.Height() - if sm.hasExpensiveFork(pheight) { - return nil, ErrExpensiveFork - } - } else { - // We can't get the parent tipset in this case. - pheight = ts.Height() - 1 - } - - // Since we're simulating a future message, pretend we're applying it in the "next" tipset - vmHeight := pheight + 1 - bstate := ts.ParentState() - - // Run the (not expensive) migration. - 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: vmHeight, - Rand: rand.NewStateRand(sm.cs, ts.Cids(), sm.beacon, sm.GetNetworkVersion), - Bstore: sm.cs.StateBlockstore(), - Actors: sm.tsExec.NewActorRegistry(), - Syscalls: sm.Syscalls, - CircSupplyCalc: sm.GetVMCirculatingSupply, - NetworkVersion: sm.GetNetworkVersion(ctx, pheight+1), - BaseFee: types.NewInt(0), - LookbackState: LookbackStateGetterForTipset(sm, ts), - Tracing: true, - } - - vmi, err := sm.newVM(ctx, vmopt) - if err != nil { - return nil, xerrors.Errorf("failed to set up vm: %w", err) - } - if msg.GasLimit == 0 { msg.GasLimit = build.BlockGasLimit } @@ -106,61 +40,43 @@ func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types. if msg.GasPremium == types.EmptyInt { msg.GasPremium = types.NewInt(0) } - if msg.Value == types.EmptyInt { msg.Value = types.NewInt(0) } - if span.IsRecordingEvents() { - span.AddAttributes( - trace.Int64Attribute("gas_limit", msg.GasLimit), - trace.StringAttribute("gas_feecap", msg.GasFeeCap.String()), - trace.StringAttribute("value", msg.Value.String()), - ) - } - - stTree, err := sm.StateTree(bstate) - if err != nil { - return nil, xerrors.Errorf("failed to load state tree: %w", err) - } - - fromActor, err := stTree.GetActor(msg.From) - if err != nil { - return nil, xerrors.Errorf("call raw get actor: %s", err) - } - - msg.Nonce = fromActor.Nonce - - // TODO: maybe just use the invoker directly? - ret, err := vmi.ApplyImplicitMessage(ctx, msg) - if err != nil && ret == nil { - return nil, xerrors.Errorf("apply message failed: %w", err) - } - - var errs string - if ret.ActorErr != nil { - errs = ret.ActorErr.Error() - log.Warnf("chain call failed: %s", ret.ActorErr) - } - - return &api.InvocResult{ - MsgCid: msg.Cid(), - Msg: msg, - MsgRct: &ret.MessageReceipt, - ExecutionTrace: ret.ExecutionTrace, - Error: errs, - Duration: ret.Duration, - }, err + return sm.callInternal(ctx, msg, nil, ts, cid.Undef, sm.GetNetworkVersion, false) } +// CallWithGas calculates the state for a given tipset, and then applies the given message on top of that state. func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, priorMsgs []types.ChainMsg, ts *types.TipSet) (*api.InvocResult, error) { - ctx, span := trace.StartSpan(ctx, "statemanager.CallWithGas") + return sm.callInternal(ctx, msg, priorMsgs, ts, cid.Undef, sm.GetNetworkVersion, true) +} + +// CallAtStateAndVersion allows you to specify a message to execute on the given stateCid and network version. +// This should mostly be used for gas modelling on a migrated state. +// Tipset here is not needed because stateCid and network version fully describe execution we want. The internal function +// will get the heaviest tipset for use for things like basefee, which we don't really care about here. +func (sm *StateManager) CallAtStateAndVersion(ctx context.Context, msg *types.Message, stateCid cid.Cid, v network.Version) (*api.InvocResult, error) { + nvGetter := func(context.Context, abi.ChainEpoch) network.Version { + return v + } + + return sm.callInternal(ctx, msg, nil, nil, stateCid, nvGetter, true) +} + +// - If no tipset is specified, the first tipset without an expensive migration or one in its parent is used. +// - If executing a message at a given tipset or its parent would trigger an expensive migration, the call will +// fail with ErrExpensiveFork. +func (sm *StateManager) callInternal(ctx context.Context, msg *types.Message, priorMsgs []types.ChainMsg, ts *types.TipSet, stateCid cid.Cid, nvGetter rand.NetworkVersionGetter, checkGas bool) (*api.InvocResult, error) { + ctx, span := trace.StartSpan(ctx, "statemanager.callInternal") defer span.End() // Copy the message as we'll be modifying the nonce. msgCopy := *msg msg = &msgCopy + var err error + var pts *types.TipSet if ts == nil { ts = sm.cs.GetHeaviestTipSet() @@ -170,10 +86,11 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri // height to have no fork, because we'll run it inside this // function before executing the given message. for ts.Height() > 0 { - pts, err := sm.cs.GetTipSetFromKey(ctx, ts.Parents()) + pts, err = sm.cs.GetTipSetFromKey(ctx, ts.Parents()) if err != nil { return nil, xerrors.Errorf("failed to find a non-forking epoch: %w", err) } + // Checks for expensive forks from the parents to the tipset, including nil tipsets if !sm.hasExpensiveForkBetween(pts.Height(), ts.Height()+1) { break } @@ -181,7 +98,7 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri ts = pts } } else if ts.Height() > 0 { - pts, err := sm.cs.GetTipSetFromKey(ctx, ts.Parents()) + pts, err = sm.cs.GetTipSetFromKey(ctx, ts.Parents()) if err != nil { return nil, xerrors.Errorf("failed to find a non-forking epoch: %w", err) } @@ -190,12 +107,22 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri } } - // Since we're simulating a future message, pretend we're applying it in the "next" tipset - vmHeight := ts.Height() + 1 - - stateCid, _, err := sm.TipSetState(ctx, ts) - if err != nil { - return nil, xerrors.Errorf("computing tipset state: %w", err) + var vmHeight abi.ChainEpoch + if checkGas { + // Since we're simulating a future message, pretend we're applying it in the "next" tipset + vmHeight = ts.Height() + 1 + if stateCid == cid.Undef { + stateCid, _, err = sm.TipSetState(ctx, ts) + if err != nil { + return nil, xerrors.Errorf("computing tipset state: %w", err) + } + } + } else { + // If we're not checking gas, we don't want to have to execute the tipset like above. This saves a lot of computation time + vmHeight = pts.Height() + 1 + if stateCid == cid.Undef { + stateCid = ts.ParentState() + } } // Technically, the tipset we're passing in here should be ts+1, but that may not exist. @@ -204,8 +131,6 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri return nil, fmt.Errorf("failed to handle fork: %w", err) } - r := rand.NewStateRand(sm.cs, ts.Cids(), sm.beacon, sm.GetNetworkVersion) - if span.IsRecordingEvents() { span.AddAttributes( trace.Int64Attribute("gas_limit", msg.GasLimit), @@ -218,14 +143,15 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri vmopt := &vm.VMOpts{ StateBase: stateCid, Epoch: vmHeight, - Rand: r, + Rand: rand.NewStateRand(sm.cs, ts.Cids(), sm.beacon, nvGetter), Bstore: buffStore, Actors: sm.tsExec.NewActorRegistry(), Syscalls: sm.Syscalls, CircSupplyCalc: sm.GetVMCirculatingSupply, - NetworkVersion: sm.GetNetworkVersion(ctx, ts.Height()+1), + NetworkVersion: nvGetter(ctx, vmHeight), BaseFee: ts.Blocks()[0].ParentBaseFee, LookbackState: LookbackStateGetterForTipset(sm, ts), + TipSetGetter: TipSetGetterForTipset(sm.cs, ts), Tracing: true, } vmi, err := sm.newVM(ctx, vmopt) @@ -233,7 +159,7 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri return nil, xerrors.Errorf("failed to set up vm: %w", err) } for i, m := range priorMsgs { - _, err := vmi.ApplyMessage(ctx, m) + _, err = vmi.ApplyMessage(ctx, m) if err != nil { return nil, xerrors.Errorf("applying prior message (%d, %s): %w", i, m.Cid(), err) } @@ -258,27 +184,6 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri msg.Nonce = fromActor.Nonce - fromKey, err := sm.ResolveToKeyAddress(ctx, msg.From, ts) - if err != nil { - return nil, xerrors.Errorf("could not resolve key: %w", err) - } - - var msgApply types.ChainMsg - - switch fromKey.Protocol() { - case address.BLS: - msgApply = msg - case address.SECP256K1: - msgApply = &types.SignedMessage{ - Message: *msg, - Signature: crypto.Signature{ - Type: crypto.SigTypeSecp256k1, - Data: make([]byte, 65), - }, - } - - } - // If the fee cap is set to zero, make gas free. if msg.GasFeeCap.NilOrZero() { // Now estimate with a new VM with no base fee. @@ -291,9 +196,39 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri } } - ret, err := vmi.ApplyMessage(ctx, msgApply) - if err != nil { - return nil, xerrors.Errorf("gas estimation failed: %w", err) + var ret *vm.ApplyRet + var gasInfo api.MsgGasCost + if checkGas { + fromKey, err := sm.ResolveToKeyAddress(ctx, msg.From, ts) + if err != nil { + return nil, xerrors.Errorf("could not resolve key: %w", err) + } + + var msgApply types.ChainMsg + + switch fromKey.Protocol() { + case address.BLS: + msgApply = msg + case address.SECP256K1: + msgApply = &types.SignedMessage{ + Message: *msg, + Signature: crypto.Signature{ + Type: crypto.SigTypeSecp256k1, + Data: make([]byte, 65), + }, + } + } + + ret, err = vmi.ApplyMessage(ctx, msgApply) + if err != nil { + return nil, xerrors.Errorf("gas estimation failed: %w", err) + } + gasInfo = MakeMsgGasCost(msg, ret) + } else { + ret, err = vmi.ApplyImplicitMessage(ctx, msg) + if err != nil && ret == nil { + return nil, xerrors.Errorf("apply message failed: %w", err) + } } var errs string @@ -305,11 +240,11 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri MsgCid: msg.Cid(), Msg: msg, MsgRct: &ret.MessageReceipt, - GasCost: MakeMsgGasCost(msg, ret), + GasCost: gasInfo, ExecutionTrace: ret.ExecutionTrace, Error: errs, Duration: ret.Duration, - }, nil + }, err } var errHaltExecution = fmt.Errorf("halt") diff --git a/chain/stmgr/forks_test.go b/chain/stmgr/forks_test.go index 3c774a790..98ab647c9 100644 --- a/chain/stmgr/forks_test.go +++ b/chain/stmgr/forks_test.go @@ -335,7 +335,7 @@ func testForkRefuseCall(t *testing.T, nullsBefore, nullsAfter int) { parentHeight := pts.Height() currentHeight := ts.TipSet.TipSet().Height() - // CallWithGas calls _at_ the current tipset. + // CallWithGas calls on top of the given tipset. ret, err := sm.CallWithGas(ctx, m, nil, ts.TipSet.TipSet()) if parentHeight <= testForkHeight && currentHeight >= testForkHeight { // If I had a fork, or I _will_ have a fork, it should fail. @@ -347,7 +347,7 @@ func testForkRefuseCall(t *testing.T, nullsBefore, nullsAfter int) { // Call always applies the message to the "next block" after the tipset's parent state. ret, err = sm.Call(ctx, m, ts.TipSet.TipSet()) - if parentHeight == testForkHeight { + if parentHeight <= testForkHeight && currentHeight >= testForkHeight { require.Equal(t, ErrExpensiveFork, err) } else { require.NoError(t, err) diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index a466029ce..af4a0cd9e 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -95,6 +95,7 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch, NetworkVersion: sm.GetNetworkVersion(ctx, height), BaseFee: ts.Blocks()[0].ParentBaseFee, LookbackState: LookbackStateGetterForTipset(sm, ts), + TipSetGetter: TipSetGetterForTipset(sm.cs, ts), Tracing: true, } vmi, err := sm.newVM(ctx, vmopt) @@ -131,6 +132,16 @@ func LookbackStateGetterForTipset(sm *StateManager, ts *types.TipSet) vm.Lookbac } } +func TipSetGetterForTipset(cs *store.ChainStore, ts *types.TipSet) vm.TipSetGetter { + return func(ctx context.Context, round abi.ChainEpoch) (types.TipSetKey, error) { + ts, err := cs.GetTipsetByHeight(ctx, round, ts, true) + if err != nil { + return types.EmptyTSK, err + } + return ts.Key(), nil + } +} + func GetLookbackTipSetForRound(ctx context.Context, sm *StateManager, ts *types.TipSet, round abi.ChainEpoch) (*types.TipSet, cid.Cid, error) { var lbr abi.ChainEpoch lb := policy.GetWinningPoStSectorSetLookback(sm.GetNetworkVersion(ctx, round)) diff --git a/chain/types/execresult.go b/chain/types/execresult.go index 917b84a92..98d06a390 100644 --- a/chain/types/execresult.go +++ b/chain/types/execresult.go @@ -42,6 +42,25 @@ type Loc struct { Function string } +func (et ExecutionTrace) SumGas() GasTrace { + return SumGas(et.GasCharges) +} + +func SumGas(charges []*GasTrace) GasTrace { + var out GasTrace + for _, gc := range charges { + out.TotalGas += gc.TotalGas + out.ComputeGas += gc.ComputeGas + out.StorageGas += gc.StorageGas + + out.TotalVirtualGas += gc.TotalVirtualGas + out.VirtualComputeGas += gc.VirtualComputeGas + out.VirtualStorageGas += gc.VirtualStorageGas + } + + return out +} + func (l Loc) Show() bool { ignorePrefix := []string{ "reflect.", diff --git a/chain/types/message.go b/chain/types/message.go index 547d4c353..352548d0c 100644 --- a/chain/types/message.go +++ b/chain/types/message.go @@ -159,10 +159,18 @@ func (m *Message) ValidForBlockInclusion(minGas int64, version network.Version) return xerrors.New("invalid 'To' address") } + if !abi.AddressValidForNetworkVersion(m.To, version) { + return xerrors.New("'To' address protocol unsupported for network version") + } + if m.From == address.Undef { return xerrors.New("'From' address cannot be empty") } + if !abi.AddressValidForNetworkVersion(m.From, version) { + return xerrors.New("'From' address protocol unsupported for network version") + } + if m.Value.Int == nil { return xerrors.New("'Value' cannot be nil") } diff --git a/chain/types/tipset_key.go b/chain/types/tipset_key.go index 59514a792..15e655da7 100644 --- a/chain/types/tipset_key.go +++ b/chain/types/tipset_key.go @@ -7,6 +7,7 @@ import ( "io" "strings" + block "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" typegen "github.com/whyrusleeping/cbor-gen" @@ -98,6 +99,28 @@ func (k *TipSetKey) UnmarshalJSON(b []byte) error { return nil } +func (k TipSetKey) Cid() (cid.Cid, error) { + blk, err := k.ToStorageBlock() + if err != nil { + return cid.Cid{}, err + } + return blk.Cid(), nil +} + +func (k TipSetKey) ToStorageBlock() (block.Block, error) { + buf := new(bytes.Buffer) + if err := k.MarshalCBOR(buf); err != nil { + log.Errorf("failed to marshal ts key as CBOR: %s", k) + } + + cid, err := abi.CidBuilder.Sum(buf.Bytes()) + if err != nil { + return nil, err + } + + return block.NewBlockWithCid(buf.Bytes(), cid) +} + func (k TipSetKey) MarshalCBOR(writer io.Writer) error { if err := typegen.WriteMajorTypeHeader(writer, typegen.MajByteString, uint64(len(k.Bytes()))); err != nil { return err diff --git a/chain/vm/fvm.go b/chain/vm/fvm.go index 440470761..b229c826c 100644 --- a/chain/vm/fvm.go +++ b/chain/vm/fvm.go @@ -45,6 +45,7 @@ type FvmExtern struct { blockstore.Blockstore epoch abi.ChainEpoch lbState LookbackStateGetter + tsGet TipSetGetter base cid.Cid } @@ -99,6 +100,14 @@ func (t *FvmExecutionTrace) ToExecutionTrace() types.ExecutionTrace { return ret } +func (x *FvmExtern) TipsetCid(ctx context.Context, epoch abi.ChainEpoch) (cid.Cid, error) { + tsk, err := x.tsGet(ctx, epoch) + if err != nil { + return cid.Undef, err + } + return tsk.Cid() +} + // VerifyConsensusFault is similar to the one in syscalls.go used by the Lotus VM, except it never errors // Errors are logged and "no fault" is returned, which is functionally what go-actors does anyway func (x *FvmExtern) VerifyConsensusFault(ctx context.Context, a, b, extra []byte) (*ffi_cgo.ConsensusFault, int64) { @@ -294,6 +303,7 @@ func defaultFVMOpts(ctx context.Context, opts *VMOpts) (*ffi.FVMOpts, error) { Rand: opts.Rand, Blockstore: opts.Bstore, lbState: opts.LookbackState, + tsGet: opts.TipSetGetter, base: opts.StateBase, epoch: opts.Epoch, }, diff --git a/chain/vm/syscalls.go b/chain/vm/syscalls.go index 757453887..f6adc8940 100644 --- a/chain/vm/syscalls.go +++ b/chain/vm/syscalls.go @@ -105,10 +105,20 @@ func (ss *syscallShim) VerifyConsensusFault(a, b, extra []byte) (*runtime7.Conse return nil, xerrors.Errorf("cannot decode first block header: %w", decodeErr) } + // A _valid_ block must use an ID address, but that's not what we're checking here. We're + // just making sure that adding additional address protocols won't lead to consensus issues. + if !abi.AddressValidForNetworkVersion(blockA.Miner, ss.networkVersion) { + return nil, xerrors.Errorf("address protocol unsupported in current network version: %d", blockA.Miner.Protocol()) + } + if decodeErr := blockB.UnmarshalCBOR(bytes.NewReader(b)); decodeErr != nil { return nil, xerrors.Errorf("cannot decode second block header: %f", decodeErr) } + if !abi.AddressValidForNetworkVersion(blockB.Miner, ss.networkVersion) { + return nil, xerrors.Errorf("address protocol unsupported in current network version: %d", blockB.Miner.Protocol()) + } + // workaround chain halt if build.IsNearUpgrade(blockA.Height, build.UpgradeOrangeHeight) { return nil, xerrors.Errorf("consensus reporting disabled around Upgrade Orange") @@ -170,6 +180,10 @@ func (ss *syscallShim) VerifyConsensusFault(a, b, extra []byte) (*runtime7.Conse return nil, xerrors.Errorf("cannot decode extra: %w", decodeErr) } + if !abi.AddressValidForNetworkVersion(blockC.Miner, ss.networkVersion) { + return nil, xerrors.Errorf("address protocol unsupported in current network version: %d", blockC.Miner.Protocol()) + } + if types.CidArrsEqual(blockA.Parents, blockC.Parents) && blockA.Height == blockC.Height && types.CidArrsContains(blockB.Parents, blockC.Cid()) && !types.CidArrsContains(blockB.Parents, blockA.Cid()) { consensusFault = &runtime7.ConsensusFault{ diff --git a/chain/vm/vm.go b/chain/vm/vm.go index c5b47fd10..ecd87caf0 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -192,6 +192,7 @@ type ( CircSupplyCalculator func(context.Context, abi.ChainEpoch, *state.StateTree) (abi.TokenAmount, error) NtwkVersionGetter func(context.Context, abi.ChainEpoch) network.Version LookbackStateGetter func(context.Context, abi.ChainEpoch) (*state.StateTree, error) + TipSetGetter func(context.Context, abi.ChainEpoch) (types.TipSetKey, error) ) var _ Interface = (*LegacyVM)(nil) @@ -223,10 +224,15 @@ type VMOpts struct { NetworkVersion network.Version BaseFee abi.TokenAmount LookbackState LookbackStateGetter + TipSetGetter TipSetGetter Tracing bool } func NewLegacyVM(ctx context.Context, opts *VMOpts) (*LegacyVM, error) { + if opts.NetworkVersion >= network.Version16 { + return nil, xerrors.Errorf("the legacy VM does not support network versions 16+") + } + buf := blockstore.NewBuffered(opts.Bstore) cst := cbor.NewCborStore(buf) state, err := state.LoadStateTree(cst, opts.StateBase) diff --git a/cli/client_retr.go b/cli/client_retr.go index 23acf1f08..b619a2871 100644 --- a/cli/client_retr.go +++ b/cli/client_retr.go @@ -3,14 +3,9 @@ package cli import ( "bytes" "context" - "encoding/json" "fmt" "io" - "io/ioutil" - "net/http" - "net/url" "os" - "path" "sort" "strings" "time" @@ -29,8 +24,6 @@ import ( "github.com/ipld/go-ipld-prime/traversal/selector/builder" selectorparse "github.com/ipld/go-ipld-prime/traversal/selector/parse" textselector "github.com/ipld/go-ipld-selector-text-lite" - "github.com/multiformats/go-multiaddr" - manet "github.com/multiformats/go-multiaddr/net" "github.com/urfave/cli/v2" "golang.org/x/xerrors" @@ -40,6 +33,7 @@ import ( lapi "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/types" + cliutil "github.com/filecoin-project/lotus/cli/util" "github.com/filecoin-project/lotus/markets/utils" "github.com/filecoin-project/lotus/node/repo" ) @@ -337,60 +331,6 @@ Examples: }, } -func ClientExportStream(apiAddr string, apiAuth http.Header, eref lapi.ExportRef, car bool) (io.ReadCloser, error) { - rj, err := json.Marshal(eref) - if err != nil { - return nil, xerrors.Errorf("marshaling export ref: %w", err) - } - - ma, err := multiaddr.NewMultiaddr(apiAddr) - if err == nil { - _, addr, err := manet.DialArgs(ma) - if err != nil { - return nil, err - } - - // todo: make cliutil helpers for this - apiAddr = "http://" + addr - } - - aa, err := url.Parse(apiAddr) - if err != nil { - return nil, xerrors.Errorf("parsing api address: %w", err) - } - switch aa.Scheme { - case "ws": - aa.Scheme = "http" - case "wss": - aa.Scheme = "https" - } - - aa.Path = path.Join(aa.Path, "rest/v0/export") - req, err := http.NewRequest("GET", fmt.Sprintf("%s?car=%t&export=%s", aa, car, url.QueryEscape(string(rj))), nil) - if err != nil { - return nil, err - } - - req.Header = apiAuth - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return nil, err - } - - if resp.StatusCode != http.StatusOK { - em, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, xerrors.Errorf("reading error body: %w", err) - } - - resp.Body.Close() // nolint - return nil, xerrors.Errorf("getting root car: http %d: %s", resp.StatusCode, string(em)) - } - - return resp.Body, nil -} - var clientRetrieveCatCmd = &cli.Command{ Name: "cat", Usage: "Show data from network", @@ -440,7 +380,7 @@ var clientRetrieveCatCmd = &cli.Command{ eref.DAGs = append(eref.DAGs, lapi.DagSpec{DataSelector: &sel}) } - rc, err := ClientExportStream(ainfo.Addr, ainfo.AuthHeader(), *eref, false) + rc, err := cliutil.ClientExportStream(ainfo.Addr, ainfo.AuthHeader(), *eref, false) if err != nil { return err } @@ -528,7 +468,7 @@ var clientRetrieveLsCmd = &cli.Command{ DataSelector: &dataSelector, }) - rc, err := ClientExportStream(ainfo.Addr, ainfo.AuthHeader(), *eref, true) + rc, err := cliutil.ClientExportStream(ainfo.Addr, ainfo.AuthHeader(), *eref, true) if err != nil { return xerrors.Errorf("export: %w", err) } @@ -583,6 +523,7 @@ var clientRetrieveLsCmd = &cli.Command{ dserv, roots[0], sel, + nil, func(p traversal.Progress, n ipld.Node, r traversal.VisitReason) error { if r == traversal.VisitReason_SelectionMatch { fmt.Println(p.Path) diff --git a/cli/state.go b/cli/state.go index 8fb7ddf61..434fb1a1c 100644 --- a/cli/state.go +++ b/cli/state.go @@ -46,6 +46,7 @@ import ( "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" + cliutil "github.com/filecoin-project/lotus/cli/util" ) var StateCmd = &cli.Command{ @@ -230,7 +231,7 @@ var StateMinerInfo = &cli.Command{ return xerrors.Errorf("getting miner info: %w", err) } - fmt.Printf("Proving Period Start:\t%s\n", EpochTime(cd.CurrentEpoch, cd.PeriodStart)) + fmt.Printf("Proving Period Start:\t%s\n", cliutil.EpochTime(cd.CurrentEpoch, cd.PeriodStart)) return nil }, @@ -1320,7 +1321,7 @@ var compStateMsg = ` {{end}} {{end}} - {{with SumGas .GasCharges}} + {{with sumGas .GasCharges}} Sum {{template "gasC" .}} {{if PrintTiming}}{{.TimeTaken}}{{end}} @@ -1354,7 +1355,7 @@ func ComputeStateHTMLTempl(w io.Writer, ts *types.TipSet, o *api.ComputeStateOut "IsSlow": isSlow, "IsVerySlow": isVerySlow, "IntExit": func(i exitcode.ExitCode) int64 { return int64(i) }, - "SumGas": sumGas, + "sumGas": types.SumGas, "CodeStr": codeStr, "Call": call, "PrintTiming": func() bool { return printTiming }, @@ -1422,21 +1423,6 @@ func isVerySlow(t time.Duration) bool { return t > 50*time.Millisecond } -func sumGas(changes []*types.GasTrace) types.GasTrace { - var out types.GasTrace - for _, gc := range changes { - out.TotalGas += gc.TotalGas - out.ComputeGas += gc.ComputeGas - out.StorageGas += gc.StorageGas - - out.TotalVirtualGas += gc.TotalVirtualGas - out.VirtualComputeGas += gc.VirtualComputeGas - out.VirtualStorageGas += gc.VirtualStorageGas - } - - return out -} - func JsonParams(code cid.Cid, method abi.MethodNum, params []byte) (string, error) { p, err := stmgr.GetParamType(filcns.NewActorRegistry(), code, method) // todo use api for correct actor registry if err != nil { @@ -1816,8 +1802,8 @@ var StateSectorCmd = &cli.Command{ } fmt.Println("DealIDs: ", si.DealIDs) fmt.Println() - fmt.Println("Activation: ", EpochTimeTs(ts.Height(), si.Activation, ts)) - fmt.Println("Expiration: ", EpochTimeTs(ts.Height(), si.Expiration, ts)) + fmt.Println("Activation: ", cliutil.EpochTimeTs(ts.Height(), si.Activation, ts)) + fmt.Println("Expiration: ", cliutil.EpochTimeTs(ts.Height(), si.Expiration, ts)) fmt.Println() fmt.Println("DealWeight: ", si.DealWeight) fmt.Println("VerifiedDealWeight: ", si.VerifiedDealWeight) diff --git a/cli/util.go b/cli/util.go index 69c45b382..03de817f9 100644 --- a/cli/util.go +++ b/cli/util.go @@ -2,19 +2,13 @@ package cli import ( "context" - "fmt" "os" - "time" "github.com/fatih/color" - "github.com/hako/durafmt" "github.com/ipfs/go-cid" "github.com/mattn/go-isatty" - "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/lotus/api/v0api" - "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" ) @@ -43,36 +37,3 @@ func parseTipSet(ctx context.Context, api v0api.FullNode, vals []string) (*types return types.NewTipSet(headers) } - -func EpochTime(curr, e abi.ChainEpoch) string { - switch { - case curr > e: - return fmt.Sprintf("%d (%s ago)", e, durafmt.Parse(time.Second*time.Duration(int64(build.BlockDelaySecs)*int64(curr-e))).LimitFirstN(2)) - case curr == e: - return fmt.Sprintf("%d (now)", e) - case curr < e: - return fmt.Sprintf("%d (in %s)", e, durafmt.Parse(time.Second*time.Duration(int64(build.BlockDelaySecs)*int64(e-curr))).LimitFirstN(2)) - } - - panic("math broke") -} - -// EpochTimeTs is like EpochTime, but also outputs absolute time. `ts` is only -// used to provide a timestamp at some epoch to calculate time from. It can be -// a genesis tipset. -// -// Example output: `1944975 (01 Jul 22 08:07 CEST, 10 hours 29 minutes ago)` -func EpochTimeTs(curr, e abi.ChainEpoch, ts *types.TipSet) string { - timeStr := time.Unix(int64(ts.MinTimestamp()+(uint64(e-ts.Height())*build.BlockDelaySecs)), 0).Format(time.RFC822) - - switch { - case curr > e: - return fmt.Sprintf("%d (%s, %s ago)", e, timeStr, durafmt.Parse(time.Second*time.Duration(int64(build.BlockDelaySecs)*int64(curr-e))).LimitFirstN(2)) - case curr == e: - return fmt.Sprintf("%d (%s, now)", e, timeStr) - case curr < e: - return fmt.Sprintf("%d (%s, in %s)", e, timeStr, durafmt.Parse(time.Second*time.Duration(int64(build.BlockDelaySecs)*int64(e-curr))).LimitFirstN(2)) - } - - panic("math broke") -} diff --git a/cli/util/api.go b/cli/util/api.go index 6c673d91f..596322ab8 100644 --- a/cli/util/api.go +++ b/cli/util/api.go @@ -8,8 +8,10 @@ import ( "net/url" "os" "os/signal" + "reflect" "strings" "syscall" + "time" "github.com/mitchellh/go-homedir" "github.com/urfave/cli/v2" @@ -21,6 +23,7 @@ import ( "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/lib/retry" "github.com/filecoin-project/lotus/node/repo" ) @@ -36,7 +39,7 @@ const ( // 2. *_API_INFO environment variables // 3. deprecated *_API_INFO environment variables // 4. *-repo command line flags. -func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { +func GetAPIInfoMulti(ctx *cli.Context, t repo.RepoType) ([]APIInfo, error) { // Check if there was a flag passed with the listen address of the API // server (only used by the tests) for _, f := range t.APIFlags() { @@ -46,7 +49,7 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { strma := ctx.String(f) strma = strings.TrimSpace(strma) - return APIInfo{Addr: strma}, nil + return []APIInfo{{Addr: strma}}, nil } // @@ -56,14 +59,14 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { primaryEnv, fallbacksEnvs, deprecatedEnvs := t.APIInfoEnvVars() env, ok := os.LookupEnv(primaryEnv) if ok { - return ParseApiInfo(env), nil + return ParseApiInfoMulti(env), nil } for _, env := range deprecatedEnvs { env, ok := os.LookupEnv(env) if ok { log.Warnf("Using deprecated env(%s) value, please use env(%s) instead.", env, primaryEnv) - return ParseApiInfo(env), nil + return ParseApiInfoMulti(env), nil } } @@ -76,26 +79,26 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { p, err := homedir.Expand(path) if err != nil { - return APIInfo{}, xerrors.Errorf("could not expand home dir (%s): %w", f, err) + return []APIInfo{}, xerrors.Errorf("could not expand home dir (%s): %w", f, err) } r, err := repo.NewFS(p) if err != nil { - return APIInfo{}, xerrors.Errorf("could not open repo at path: %s; %w", p, err) + return []APIInfo{}, xerrors.Errorf("could not open repo at path: %s; %w", p, err) } exists, err := r.Exists() if err != nil { - return APIInfo{}, xerrors.Errorf("repo.Exists returned an error: %w", err) + return []APIInfo{}, xerrors.Errorf("repo.Exists returned an error: %w", err) } if !exists { - return APIInfo{}, errors.New("repo directory does not exist. Make sure your configuration is correct") + return []APIInfo{}, errors.New("repo directory does not exist. Make sure your configuration is correct") } ma, err := r.APIEndpoint() if err != nil { - return APIInfo{}, xerrors.Errorf("could not get api endpoint: %w", err) + return []APIInfo{}, xerrors.Errorf("could not get api endpoint: %w", err) } token, err := r.APIToken() @@ -103,38 +106,75 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { log.Warnf("Couldn't load CLI token, capabilities may be limited: %v", err) } - return APIInfo{ + return []APIInfo{{ Addr: ma.String(), Token: token, - }, nil + }}, nil } for _, env := range fallbacksEnvs { env, ok := os.LookupEnv(env) if ok { - return ParseApiInfo(env), nil + return ParseApiInfoMulti(env), nil } } - return APIInfo{}, fmt.Errorf("could not determine API endpoint for node type: %v", t.Type()) + return []APIInfo{}, fmt.Errorf("could not determine API endpoint for node type: %v", t.Type()) } -func GetRawAPI(ctx *cli.Context, t repo.RepoType, version string) (string, http.Header, error) { - ainfo, err := GetAPIInfo(ctx, t) - if err != nil { - return "", nil, xerrors.Errorf("could not get API info for %s: %w", t.Type(), err) +func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { + ainfos, err := GetAPIInfoMulti(ctx, t) + if err != nil || len(ainfos) == 0 { + return APIInfo{}, err } - addr, err := ainfo.DialArgs(version) - if err != nil { - return "", nil, xerrors.Errorf("could not get DialArgs: %w", err) + if len(ainfos) > 1 { + log.Warn("multiple API infos received when only one was expected") + } + + return ainfos[0], nil + +} + +type HttpHead struct { + addr string + header http.Header +} + +func GetRawAPIMulti(ctx *cli.Context, t repo.RepoType, version string) ([]HttpHead, error) { + + var httpHeads []HttpHead + ainfos, err := GetAPIInfoMulti(ctx, t) + if err != nil || len(ainfos) == 0 { + return httpHeads, xerrors.Errorf("could not get API info for %s: %w", t.Type(), err) + } + + for _, ainfo := range ainfos { + addr, err := ainfo.DialArgs(version) + if err != nil { + return httpHeads, xerrors.Errorf("could not get DialArgs: %w", err) + } + httpHeads = append(httpHeads, HttpHead{addr: addr, header: ainfo.AuthHeader()}) } if IsVeryVerbose { - _, _ = fmt.Fprintf(ctx.App.Writer, "using raw API %s endpoint: %s\n", version, addr) + _, _ = fmt.Fprintf(ctx.App.Writer, "using raw API %s endpoint: %s\n", version, httpHeads[0].addr) } - return addr, ainfo.AuthHeader(), nil + return httpHeads, nil +} + +func GetRawAPI(ctx *cli.Context, t repo.RepoType, version string) (string, http.Header, error) { + heads, err := GetRawAPIMulti(ctx, t, version) + if err != nil { + return "", nil, err + } + + if len(heads) > 1 { + log.Warnf("More than 1 header received when expecting only one") + } + + return heads[0].addr, heads[0].header, nil } func GetCommonAPI(ctx *cli.Context) (api.CommonNet, jsonrpc.ClientCloser, error) { @@ -185,7 +225,72 @@ func GetFullNodeAPI(ctx *cli.Context) (v0api.FullNode, jsonrpc.ClientCloser, err return client.NewFullNodeRPCV0(ctx.Context, addr, headers) } -func GetFullNodeAPIV1(ctx *cli.Context) (v1api.FullNode, jsonrpc.ClientCloser, error) { +type contextKey string + +// Not thread safe +func OnSingleNode(ctx context.Context) context.Context { + return context.WithValue(ctx, contextKey("retry-node"), new(*int)) +} + +func FullNodeProxy[T api.FullNode](ins []T, outstr *api.FullNodeStruct) { + outs := api.GetInternalStructs(outstr) + + var rins []reflect.Value + for _, in := range ins { + rins = append(rins, reflect.ValueOf(in)) + } + + for _, out := range outs { + rProxyInternal := reflect.ValueOf(out).Elem() + + for f := 0; f < rProxyInternal.NumField(); f++ { + field := rProxyInternal.Type().Field(f) + + var fns []reflect.Value + for _, rin := range rins { + fns = append(fns, rin.MethodByName(field.Name)) + } + + rProxyInternal.Field(f).Set(reflect.MakeFunc(field.Type, func(args []reflect.Value) (results []reflect.Value) { + errorsToRetry := []error{&jsonrpc.RPCConnectionError{}, &jsonrpc.ErrClient{}} + initialBackoff, err := time.ParseDuration("1s") + if err != nil { + return nil + } + + ctx := args[0].Interface().(context.Context) + + curr := -1 + + // for calls that need to be performed on the same node + // primarily for miner when calling create block and submit block subsequently + key := contextKey("retry-node") + if ctx.Value(key) != nil { + if (*ctx.Value(key).(**int)) == nil { + *ctx.Value(key).(**int) = &curr + } else { + curr = **ctx.Value(key).(**int) - 1 + } + } + + total := len(rins) + result, err := retry.Retry(ctx, 5, initialBackoff, errorsToRetry, func() (results []reflect.Value, err2 error) { + curr = (curr + 1) % total + + result := fns[curr].Call(args) + if result[len(result)-1].IsNil() { + return result, nil + } + e := result[len(result)-1].Interface().(error) + return result, e + }) + return result + })) + } + } +} + +func GetFullNodeAPIV1Single(ctx *cli.Context) (v1api.FullNode, jsonrpc.ClientCloser, error) { if tn, ok := ctx.App.Metadata["testnode-full"]; ok { return tn.(v1api.FullNode), func() {}, nil } @@ -214,6 +319,58 @@ func GetFullNodeAPIV1(ctx *cli.Context) (v1api.FullNode, jsonrpc.ClientCloser, e return v1API, closer, nil } +func GetFullNodeAPIV1(ctx *cli.Context) (v1api.FullNode, jsonrpc.ClientCloser, error) { + if tn, ok := ctx.App.Metadata["testnode-full"]; ok { + return tn.(v1api.FullNode), func() {}, nil + } + + heads, err := GetRawAPIMulti(ctx, repo.FullNode, "v1") + if err != nil { + return nil, nil, err + } + + if IsVeryVerbose { + _, _ = fmt.Fprintln(ctx.App.Writer, "using full node API v1 endpoint:", heads[0].addr) + } + + var fullNodes []api.FullNode + var closers []jsonrpc.ClientCloser + + for _, head := range heads { + v1api, closer, err := client.NewFullNodeRPCV1(ctx.Context, head.addr, head.header) + if err != nil { + log.Warnf("Not able to establish connection to node with addr: ", head.addr) + continue + } + fullNodes = append(fullNodes, v1api) + closers = append(closers, closer) + } + + // When running in cluster mode and trying to establish connections to multiple nodes, fail + // if less than 2 lotus nodes are actually running + if len(heads) > 1 && len(fullNodes) < 2 { + return nil, nil, xerrors.Errorf("Not able to establish connection to more than a single node") + } + + finalCloser := func() { + for _, c := range closers { + c() + } + } + + var v1API api.FullNodeStruct + FullNodeProxy(fullNodes, &v1API) + + v, err := v1API.Version(ctx.Context) + if err != nil { + return nil, nil, err + } + if !v.APIVersion.EqMajorMinor(api.FullAPIVersion1) { + return nil, nil, xerrors.Errorf("Remote API version didn't match (expected %s, remote %s)", api.FullAPIVersion1, v.APIVersion) + } + return &v1API, finalCloser, nil +} + type GetStorageMinerOptions struct { PreferHttp bool } diff --git a/cli/util/apiinfo.go b/cli/util/apiinfo.go index 41ca18c61..68befdb55 100644 --- a/cli/util/apiinfo.go +++ b/cli/util/apiinfo.go @@ -24,6 +24,7 @@ type APIInfo struct { func ParseApiInfo(s string) APIInfo { var tok []byte + if infoWithToken.Match([]byte(s)) { sp := strings.SplitN(s, ":", 2) tok = []byte(sp[0]) @@ -36,6 +37,24 @@ func ParseApiInfo(s string) APIInfo { } } +func ParseApiInfoMulti(s string) []APIInfo { + var apiInfos []APIInfo + + allAddrs := strings.SplitN(s, ",", -1) + + for _, addr := range allAddrs { + if infoWithToken.Match([]byte(addr)) { + sp := strings.SplitN(addr, ":", 2) + apiInfos = append(apiInfos, APIInfo{ + Addr: sp[1], + Token: []byte(sp[0]), + }) + } + } + + return apiInfos +} + func (a APIInfo) DialArgs(version string) (string, error) { ma, err := multiaddr.NewMultiaddr(a.Addr) if err == nil { diff --git a/cli/util/epoch.go b/cli/util/epoch.go new file mode 100644 index 000000000..81c92a7e3 --- /dev/null +++ b/cli/util/epoch.go @@ -0,0 +1,46 @@ +package cliutil + +import ( + "fmt" + "time" + + "github.com/hako/durafmt" + + "github.com/filecoin-project/go-state-types/abi" + + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/types" +) + +func EpochTime(curr, e abi.ChainEpoch) string { + switch { + case curr > e: + return fmt.Sprintf("%d (%s ago)", e, durafmt.Parse(time.Second*time.Duration(int64(build.BlockDelaySecs)*int64(curr-e))).LimitFirstN(2)) + case curr == e: + return fmt.Sprintf("%d (now)", e) + case curr < e: + return fmt.Sprintf("%d (in %s)", e, durafmt.Parse(time.Second*time.Duration(int64(build.BlockDelaySecs)*int64(e-curr))).LimitFirstN(2)) + } + + panic("math broke") +} + +// EpochTimeTs is like EpochTime, but also outputs absolute time. `ts` is only +// used to provide a timestamp at some epoch to calculate time from. It can be +// a genesis tipset. +// +// Example output: `1944975 (01 Jul 22 08:07 CEST, 10 hours 29 minutes ago)` +func EpochTimeTs(curr, e abi.ChainEpoch, ts *types.TipSet) string { + timeStr := time.Unix(int64(ts.MinTimestamp()+(uint64(e-ts.Height())*build.BlockDelaySecs)), 0).Format(time.RFC822) + + switch { + case curr > e: + return fmt.Sprintf("%d (%s, %s ago)", e, timeStr, durafmt.Parse(time.Second*time.Duration(int64(build.BlockDelaySecs)*int64(curr-e))).LimitFirstN(2)) + case curr == e: + return fmt.Sprintf("%d (%s, now)", e, timeStr) + case curr < e: + return fmt.Sprintf("%d (%s, in %s)", e, timeStr, durafmt.Parse(time.Second*time.Duration(int64(build.BlockDelaySecs)*int64(e-curr))).LimitFirstN(2)) + } + + panic("math broke") +} diff --git a/cli/util/retrieval.go b/cli/util/retrieval.go new file mode 100644 index 000000000..3a2ef6077 --- /dev/null +++ b/cli/util/retrieval.go @@ -0,0 +1,78 @@ +package cliutil + +import ( + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "path" + + "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr/net" + "golang.org/x/xerrors" + + "github.com/filecoin-project/lotus/api" +) + +func ApiAddrToUrl(apiAddr string) (*url.URL, error) { + ma, err := multiaddr.NewMultiaddr(apiAddr) + if err == nil { + _, addr, err := manet.DialArgs(ma) + if err != nil { + return nil, err + } + // todo: make cliutil helpers for this + apiAddr = "http://" + addr + } + aa, err := url.Parse(apiAddr) + if err != nil { + return nil, xerrors.Errorf("parsing api address: %w", err) + } + switch aa.Scheme { + case "ws": + aa.Scheme = "http" + case "wss": + aa.Scheme = "https" + } + + return aa, nil +} + +func ClientExportStream(apiAddr string, apiAuth http.Header, eref api.ExportRef, car bool) (io.ReadCloser, error) { + rj, err := json.Marshal(eref) + if err != nil { + return nil, xerrors.Errorf("marshaling export ref: %w", err) + } + + aa, err := ApiAddrToUrl(apiAddr) + if err != nil { + return nil, err + } + + aa.Path = path.Join(aa.Path, "rest/v0/export") + req, err := http.NewRequest("GET", fmt.Sprintf("%s?car=%t&export=%s", aa, car, url.QueryEscape(string(rj))), nil) + if err != nil { + return nil, err + } + + req.Header = apiAuth + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, err + } + + if resp.StatusCode != http.StatusOK { + em, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, xerrors.Errorf("reading error body: %w", err) + } + + resp.Body.Close() // nolint + return nil, xerrors.Errorf("getting root car: http %d: %s", resp.StatusCode, string(em)) + } + + return resp.Body, nil +} diff --git a/cmd/lotus-miner/actor.go b/cmd/lotus-miner/actor.go index 476467282..843862d92 100644 --- a/cmd/lotus-miner/actor.go +++ b/cmd/lotus-miner/actor.go @@ -595,6 +595,7 @@ var actorControlList = &cli.Command{ printKey("owner", mi.Owner) printKey("worker", mi.Worker) + printKey("beneficiary", mi.Beneficiary) for i, ca := range mi.ControlAddresses { printKey(fmt.Sprintf("control-%d", i), ca) } diff --git a/cmd/lotus-miner/info.go b/cmd/lotus-miner/info.go index 312d86600..b1075be37 100644 --- a/cmd/lotus-miner/info.go +++ b/cmd/lotus-miner/info.go @@ -33,6 +33,7 @@ import ( "github.com/filecoin-project/lotus/chain/actors/builtin/reward" "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/journal/alerting" sealing "github.com/filecoin-project/lotus/storage/pipeline" "github.com/filecoin-project/lotus/storage/sealer/sealtasks" @@ -534,6 +535,7 @@ var stateList = []stateMeta{ {col: color.FgYellow, state: sealing.ProveReplicaUpdate}, {col: color.FgYellow, state: sealing.SubmitReplicaUpdate}, {col: color.FgYellow, state: sealing.ReplicaUpdateWait}, + {col: color.FgYellow, state: sealing.WaitMutable}, {col: color.FgYellow, state: sealing.FinalizeReplicaUpdate}, {col: color.FgYellow, state: sealing.ReleaseSectorKey}, @@ -664,7 +666,7 @@ func producedBlocks(ctx context.Context, count int, maddr address.Address, napi fmt.Printf("%8d | %s | %s\n", ts.Height(), bh.Cid(), types.FIL(minerReward)) count-- } else if tty && bh.Height%120 == 0 { - _, _ = fmt.Fprintf(os.Stderr, "\r\x1b[0KChecking epoch %s", lcli.EpochTime(head.Height(), bh.Height)) + _, _ = fmt.Fprintf(os.Stderr, "\r\x1b[0KChecking epoch %s", cliutil.EpochTime(head.Height(), bh.Height)) } } tsk = ts.Parents() diff --git a/cmd/lotus-miner/init.go b/cmd/lotus-miner/init.go index 2d094b55a..66a6691af 100644 --- a/cmd/lotus-miner/init.go +++ b/cmd/lotus-miner/init.go @@ -49,6 +49,7 @@ import ( "github.com/filecoin-project/lotus/journal" "github.com/filecoin-project/lotus/journal/fsjournal" storageminer "github.com/filecoin-project/lotus/miner" + "github.com/filecoin-project/lotus/node/config" "github.com/filecoin-project/lotus/node/modules" "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/node/repo" @@ -218,7 +219,7 @@ var initCmd = &cli.Command{ return err } - var localPaths []paths.LocalPath + var localPaths []storiface.LocalPath if pssb := cctx.StringSlice("pre-sealed-sectors"); len(pssb) != 0 { log.Infof("Setting up storage config with presealed sectors: %v", pssb) @@ -228,14 +229,14 @@ var initCmd = &cli.Command{ if err != nil { return err } - localPaths = append(localPaths, paths.LocalPath{ + localPaths = append(localPaths, storiface.LocalPath{ Path: psp, }) } } if !cctx.Bool("no-local-storage") { - b, err := json.MarshalIndent(&paths.LocalStorageMeta{ + b, err := json.MarshalIndent(&storiface.LocalStorageMeta{ ID: storiface.ID(uuid.New().String()), Weight: 10, CanSeal: true, @@ -249,12 +250,12 @@ var initCmd = &cli.Command{ return xerrors.Errorf("persisting storage metadata (%s): %w", filepath.Join(lr.Path(), "sectorstore.json"), err) } - localPaths = append(localPaths, paths.LocalPath{ + localPaths = append(localPaths, storiface.LocalPath{ Path: lr.Path(), }) } - if err := lr.SetStorage(func(sc *paths.StorageConfig) { + if err := lr.SetStorage(func(sc *storiface.StorageConfig) { sc.StoragePaths = append(sc.StoragePaths, localPaths...) }); err != nil { return xerrors.Errorf("set storage config: %w", err) @@ -471,7 +472,7 @@ func storageMinerInit(ctx context.Context, cctx *cli.Context, api v1api.FullNode } stor := paths.NewRemote(lstor, si, http.Header(sa), 10, &paths.DefaultPartialFileHandler{}) - smgr, err := sealer.New(ctx, lstor, stor, lr, si, sealer.Config{ + smgr, err := sealer.New(ctx, lstor, stor, lr, si, config.SealerConfig{ ParallelFetchLimit: 10, AllowAddPiece: true, AllowPreCommit1: true, @@ -481,7 +482,7 @@ func storageMinerInit(ctx context.Context, cctx *cli.Context, api v1api.FullNode AllowReplicaUpdate: true, AllowProveReplicaUpdate2: true, AllowRegenSectorKey: true, - }, wsts, smsts) + }, config.ProvingConfig{}, wsts, smsts) if err != nil { return err } diff --git a/cmd/lotus-miner/init_restore.go b/cmd/lotus-miner/init_restore.go index 3d179f3ba..618825a27 100644 --- a/cmd/lotus-miner/init_restore.go +++ b/cmd/lotus-miner/init_restore.go @@ -27,7 +27,7 @@ import ( "github.com/filecoin-project/lotus/lib/backupds" "github.com/filecoin-project/lotus/node/config" "github.com/filecoin-project/lotus/node/repo" - "github.com/filecoin-project/lotus/storage/paths" + "github.com/filecoin-project/lotus/storage/sealer/storiface" ) var restoreCmd = &cli.Command{ @@ -52,7 +52,7 @@ var restoreCmd = &cli.Command{ ctx := lcli.ReqContext(cctx) log.Info("Initializing lotus miner using a backup") - var storageCfg *paths.StorageConfig + var storageCfg *storiface.StorageConfig if cctx.IsSet("storage-config") { cf, err := homedir.Expand(cctx.String("storage-config")) if err != nil { @@ -64,7 +64,7 @@ var restoreCmd = &cli.Command{ return xerrors.Errorf("reading storage config: %w", err) } - storageCfg = &paths.StorageConfig{} + storageCfg = &storiface.StorageConfig{} err = json.Unmarshal(cfb, storageCfg) if err != nil { return xerrors.Errorf("cannot unmarshal json for storage config: %w", err) @@ -95,7 +95,7 @@ var restoreCmd = &cli.Command{ }, } -func restore(ctx context.Context, cctx *cli.Context, targetPath string, strConfig *paths.StorageConfig, manageConfig func(*config.StorageMiner) error, after func(api lapi.FullNode, addr address.Address, peerid peer.ID, mi api.MinerInfo) error) error { +func restore(ctx context.Context, cctx *cli.Context, targetPath string, strConfig *storiface.StorageConfig, manageConfig func(*config.StorageMiner) error, after func(api lapi.FullNode, addr address.Address, peerid peer.ID, mi api.MinerInfo) error) error { if cctx.NArg() != 1 { return lcli.IncorrectNumArgs(cctx) } @@ -214,7 +214,7 @@ func restore(ctx context.Context, cctx *cli.Context, targetPath string, strConfi if strConfig != nil { log.Info("Restoring storage path config") - err = lr.SetStorage(func(scfg *paths.StorageConfig) { + err = lr.SetStorage(func(scfg *storiface.StorageConfig) { *scfg = *strConfig }) if err != nil { @@ -223,8 +223,8 @@ func restore(ctx context.Context, cctx *cli.Context, targetPath string, strConfi } else { log.Warn("--storage-config NOT SET. NO SECTOR PATHS WILL BE CONFIGURED") // setting empty config to allow miner to be started - if err := lr.SetStorage(func(sc *paths.StorageConfig) { - sc.StoragePaths = append(sc.StoragePaths, paths.LocalPath{}) + if err := lr.SetStorage(func(sc *storiface.StorageConfig) { + sc.StoragePaths = append(sc.StoragePaths, storiface.LocalPath{}) }); err != nil { return xerrors.Errorf("set storage config: %w", err) } diff --git a/cmd/lotus-miner/init_service.go b/cmd/lotus-miner/init_service.go index 41838965a..235e4e4c8 100644 --- a/cmd/lotus-miner/init_service.go +++ b/cmd/lotus-miner/init_service.go @@ -17,7 +17,7 @@ import ( lcli "github.com/filecoin-project/lotus/cli" cliutil "github.com/filecoin-project/lotus/cli/util" "github.com/filecoin-project/lotus/node/config" - "github.com/filecoin-project/lotus/storage/paths" + "github.com/filecoin-project/lotus/storage/sealer/storiface" ) const ( @@ -78,7 +78,7 @@ var serviceCmd = &cli.Command{ return xerrors.Errorf("please provide Lotus markets repo path via flag %s", FlagMarketsRepo) } - if err := restore(ctx, cctx, repoPath, &paths.StorageConfig{}, func(cfg *config.StorageMiner) error { + if err := restore(ctx, cctx, repoPath, &storiface.StorageConfig{}, func(cfg *config.StorageMiner) error { cfg.Subsystems.EnableMarkets = es.Contains(MarketsService) cfg.Subsystems.EnableMining = false cfg.Subsystems.EnableSealing = false diff --git a/cmd/lotus-miner/proving.go b/cmd/lotus-miner/proving.go index 6f6fd6635..9ae8bdd48 100644 --- a/cmd/lotus-miner/proving.go +++ b/cmd/lotus-miner/proving.go @@ -26,6 +26,7 @@ import ( "github.com/filecoin-project/lotus/chain/store" "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/storage/sealer/storiface" ) @@ -185,18 +186,18 @@ var provingInfoCmd = &cli.Command{ fmt.Printf("Current Epoch: %d\n", cd.CurrentEpoch) fmt.Printf("Proving Period Boundary: %d\n", cd.PeriodStart%cd.WPoStProvingPeriod) - fmt.Printf("Proving Period Start: %s\n", lcli.EpochTimeTs(cd.CurrentEpoch, cd.PeriodStart, head)) - fmt.Printf("Next Period Start: %s\n\n", lcli.EpochTimeTs(cd.CurrentEpoch, cd.PeriodStart+cd.WPoStProvingPeriod, head)) + fmt.Printf("Proving Period Start: %s\n", cliutil.EpochTimeTs(cd.CurrentEpoch, cd.PeriodStart, head)) + fmt.Printf("Next Period Start: %s\n\n", cliutil.EpochTimeTs(cd.CurrentEpoch, cd.PeriodStart+cd.WPoStProvingPeriod, head)) fmt.Printf("Faults: %d (%.2f%%)\n", faults, faultPerc) fmt.Printf("Recovering: %d\n", recovering) fmt.Printf("Deadline Index: %d\n", cd.Index) fmt.Printf("Deadline Sectors: %d\n", curDeadlineSectors) - fmt.Printf("Deadline Open: %s\n", lcli.EpochTime(cd.CurrentEpoch, cd.Open)) - fmt.Printf("Deadline Close: %s\n", lcli.EpochTime(cd.CurrentEpoch, cd.Close)) - fmt.Printf("Deadline Challenge: %s\n", lcli.EpochTime(cd.CurrentEpoch, cd.Challenge)) - fmt.Printf("Deadline FaultCutoff: %s\n", lcli.EpochTime(cd.CurrentEpoch, cd.FaultCutoff)) + fmt.Printf("Deadline Open: %s\n", cliutil.EpochTime(cd.CurrentEpoch, cd.Open)) + fmt.Printf("Deadline Close: %s\n", cliutil.EpochTime(cd.CurrentEpoch, cd.Close)) + fmt.Printf("Deadline Challenge: %s\n", cliutil.EpochTime(cd.CurrentEpoch, cd.Challenge)) + fmt.Printf("Deadline FaultCutoff: %s\n", cliutil.EpochTime(cd.CurrentEpoch, cd.FaultCutoff)) return nil }, } @@ -582,7 +583,7 @@ var provingCheckProvableCmd = &cli.Command{ }) } - bad, err := minerApi.CheckProvable(ctx, info.WindowPoStProofType, tocheck, cctx.Bool("slow")) + bad, err := minerApi.CheckProvable(ctx, info.WindowPoStProofType, tocheck) if err != nil { return err } diff --git a/cmd/lotus-miner/sectors.go b/cmd/lotus-miner/sectors.go index 44bce55bc..f17346821 100644 --- a/cmd/lotus-miner/sectors.go +++ b/cmd/lotus-miner/sectors.go @@ -32,6 +32,7 @@ import ( "github.com/filecoin-project/lotus/chain/actors/policy" "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/lib/strle" "github.com/filecoin-project/lotus/lib/tablewriter" sealing "github.com/filecoin-project/lotus/storage/pipeline" @@ -485,9 +486,9 @@ var sectorsListCmd = &cli.Command{ if !inSSet { m["Expiration"] = "n/a" } else { - m["Expiration"] = lcli.EpochTime(head.Height(), exp) + m["Expiration"] = cliutil.EpochTime(head.Height(), exp) if st.Early > 0 { - m["RecoveryTimeout"] = color.YellowString(lcli.EpochTime(head.Height(), st.Early)) + m["RecoveryTimeout"] = color.YellowString(cliutil.EpochTime(head.Height(), st.Early)) } } if inSSet && cctx.Bool("initial-pledge") { @@ -666,10 +667,10 @@ var sectorsCheckExpireCmd = &cli.Command{ "ID": sector.SectorNumber, "SealProof": sector.SealProof, "InitialPledge": types.FIL(sector.InitialPledge).Short(), - "Activation": lcli.EpochTime(currEpoch, sector.Activation), - "Expiration": lcli.EpochTime(currEpoch, sector.Expiration), - "MaxExpiration": lcli.EpochTime(currEpoch, MaxExpiration), - "MaxExtendNow": lcli.EpochTime(currEpoch, MaxExtendNow), + "Activation": cliutil.EpochTime(currEpoch, sector.Activation), + "Expiration": cliutil.EpochTime(currEpoch, sector.Expiration), + "MaxExpiration": cliutil.EpochTime(currEpoch, MaxExpiration), + "MaxExtendNow": cliutil.EpochTime(currEpoch, MaxExtendNow), }) } @@ -1909,7 +1910,7 @@ var sectorsExpiredCmd = &cli.Command{ toRemove = append(toRemove, s) } - fmt.Printf("%d%s\t%s\t%s\n", s, rmMsg, st.State, lcli.EpochTime(head.Height(), st.Expiration)) + fmt.Printf("%d%s\t%s\t%s\n", s, rmMsg, st.State, cliutil.EpochTime(head.Height(), st.Expiration)) return nil }) diff --git a/cmd/lotus-miner/storage.go b/cmd/lotus-miner/storage.go index 290d128e4..b5bfb730d 100644 --- a/cmd/lotus-miner/storage.go +++ b/cmd/lotus-miner/storage.go @@ -29,7 +29,6 @@ import ( "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" "github.com/filecoin-project/lotus/lib/tablewriter" - "github.com/filecoin-project/lotus/storage/paths" sealing "github.com/filecoin-project/lotus/storage/pipeline" "github.com/filecoin-project/lotus/storage/sealer/fsutil" "github.com/filecoin-project/lotus/storage/sealer/storiface" @@ -148,7 +147,7 @@ over time } } - cfg := &paths.LocalStorageMeta{ + cfg := &storiface.LocalStorageMeta{ ID: storiface.ID(uuid.New().String()), Weight: cctx.Uint64("weight"), CanSeal: cctx.Bool("seal"), diff --git a/cmd/lotus-seed/seed/seed.go b/cmd/lotus-seed/seed/seed.go index 70ee77921..3b6359e0f 100644 --- a/cmd/lotus-seed/seed/seed.go +++ b/cmd/lotus-seed/seed/seed.go @@ -27,7 +27,6 @@ import ( "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/wallet/key" "github.com/filecoin-project/lotus/genesis" - "github.com/filecoin-project/lotus/storage/paths" "github.com/filecoin-project/lotus/storage/sealer/ffiwrapper" "github.com/filecoin-project/lotus/storage/sealer/ffiwrapper/basicfs" "github.com/filecoin-project/lotus/storage/sealer/storiface" @@ -126,7 +125,7 @@ func PreSeal(maddr address.Address, spt abi.RegisteredSealProof, offset abi.Sect } { - b, err := json.MarshalIndent(&paths.LocalStorageMeta{ + b, err := json.MarshalIndent(&storiface.LocalStorageMeta{ ID: storiface.ID(uuid.New().String()), Weight: 0, // read-only CanSeal: false, diff --git a/cmd/lotus-shed/gas-estimation.go b/cmd/lotus-shed/gas-estimation.go new file mode 100644 index 000000000..b05380535 --- /dev/null +++ b/cmd/lotus-shed/gas-estimation.go @@ -0,0 +1,277 @@ +package main + +import ( + "context" + "fmt" + "io" + "os" + "strconv" + "text/tabwriter" + + "github.com/ipfs/go-cid" + "github.com/urfave/cli/v2" + "golang.org/x/xerrors" + + "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/chain/beacon" + "github.com/filecoin-project/lotus/chain/beacon/drand" + "github.com/filecoin-project/lotus/chain/consensus/filcns" + "github.com/filecoin-project/lotus/chain/stmgr" + "github.com/filecoin-project/lotus/chain/store" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/chain/vm" + lcli "github.com/filecoin-project/lotus/cli" + "github.com/filecoin-project/lotus/node/repo" + "github.com/filecoin-project/lotus/storage/sealer/ffiwrapper" +) + +const MAINNET_GENESIS_TIME = 1598306400 + +// USAGE: Sync a node, then call migrate-nv17 on some old state. Pass in the cid of the migrated state root, +// the epoch you migrated at, the network version you migrated to, and a message CID. You will be able to replay any +// message from between the migration epoch, and where your node originally synced to. Note: You may run into issues +// with state that changed between the epoch you migrated at, and when the message was originally processed. +// This can be avoided by replaying messages from close to the migration epoch, or circumvented by using a custom +// FVM bundle. +var gasTraceCmd = &cli.Command{ + Name: "trace-gas", + Description: "replay a message on the specified stateRoot and network version to get an execution trace", + ArgsUsage: "[migratedStateRootCid networkVersion messageCid]", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "repo", + Value: "~/.lotus", + }, + }, + Action: func(cctx *cli.Context) error { + ctx := context.TODO() + + if cctx.NArg() != 3 { + return lcli.IncorrectNumArgs(cctx) + } + + stateRootCid, err := cid.Decode(cctx.Args().Get(0)) + if err != nil { + return fmt.Errorf("failed to parse input: %w", err) + } + + nv, err := strconv.ParseInt(cctx.Args().Get(1), 10, 32) + if err != nil { + return fmt.Errorf("failed to parse input: %w", err) + } + + messageCid, err := cid.Decode(cctx.Args().Get(2)) + if err != nil { + return fmt.Errorf("failed to parse input: %w", err) + } + + fsrepo, err := repo.NewFS(cctx.String("repo")) + if err != nil { + return err + } + + lkrepo, err := fsrepo.Lock(repo.FullNode) + if err != nil { + return err + } + + defer lkrepo.Close() //nolint:errcheck + + bs, err := lkrepo.Blockstore(ctx, repo.UniversalBlockstore) + if err != nil { + return fmt.Errorf("failed to open blockstore: %w", err) + } + + defer func() { + if c, ok := bs.(io.Closer); ok { + if err := c.Close(); err != nil { + log.Warnf("failed to close blockstore: %s", err) + } + } + }() + + mds, err := lkrepo.Datastore(context.Background(), "/metadata") + if err != nil { + return err + } + + dcs := build.DrandConfigSchedule() + shd := beacon.Schedule{} + for _, dc := range dcs { + bc, err := drand.NewDrandBeacon(MAINNET_GENESIS_TIME, build.BlockDelaySecs, nil, dc.Config) + if err != nil { + return xerrors.Errorf("creating drand beacon: %w", err) + } + shd = append(shd, beacon.BeaconPoint{Start: dc.Start, Beacon: bc}) + } + cs := store.NewChainStore(bs, bs, mds, filcns.Weight, nil) + defer cs.Close() //nolint:errcheck + + sm, err := stmgr.NewStateManager(cs, filcns.NewTipSetExecutor(), vm.Syscalls(ffiwrapper.ProofVerifier), filcns.DefaultUpgradeSchedule(), shd) + if err != nil { + return err + } + + msg, err := cs.GetMessage(ctx, messageCid) + if err != nil { + return err + } + + // Set to block limit so message will not run out of gas + msg.GasLimit = build.BlockGasLimit + + err = cs.Load(ctx) + if err != nil { + return err + } + + tw := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', tabwriter.AlignRight) + res, err := sm.CallAtStateAndVersion(ctx, msg, stateRootCid, network.Version(nv)) + if err != nil { + return err + } + fmt.Println("Total gas used: ", res.MsgRct.GasUsed) + printInternalExecutions(0, []types.ExecutionTrace{res.ExecutionTrace}, tw) + + return tw.Flush() + }, +} + +var replayOfflineCmd = &cli.Command{ + Name: "replay-offline", + Description: "replay a message to get a gas trace", + ArgsUsage: "[messageCid]", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "repo", + Value: "~/.lotus", + }, + &cli.Int64Flag{ + Name: "lookback-limit", + Value: 10000, + }, + }, + Action: func(cctx *cli.Context) error { + ctx := context.TODO() + + if cctx.NArg() != 1 { + return lcli.IncorrectNumArgs(cctx) + } + + messageCid, err := cid.Decode(cctx.Args().Get(0)) + if err != nil { + return fmt.Errorf("failed to parse input: %w", err) + } + + lookbackLimit := cctx.Int("lookback-limit") + + fsrepo, err := repo.NewFS(cctx.String("repo")) + if err != nil { + return err + } + + lkrepo, err := fsrepo.Lock(repo.FullNode) + if err != nil { + return err + } + + defer lkrepo.Close() //nolint:errcheck + + bs, err := lkrepo.Blockstore(ctx, repo.UniversalBlockstore) + if err != nil { + return fmt.Errorf("failed to open blockstore: %w", err) + } + + defer func() { + if c, ok := bs.(io.Closer); ok { + if err := c.Close(); err != nil { + log.Warnf("failed to close blockstore: %s", err) + } + } + }() + + mds, err := lkrepo.Datastore(context.Background(), "/metadata") + if err != nil { + return err + } + + dcs := build.DrandConfigSchedule() + shd := beacon.Schedule{} + for _, dc := range dcs { + bc, err := drand.NewDrandBeacon(MAINNET_GENESIS_TIME, build.BlockDelaySecs, nil, dc.Config) + if err != nil { + return xerrors.Errorf("creating drand beacon: %w", err) + } + shd = append(shd, beacon.BeaconPoint{Start: dc.Start, Beacon: bc}) + } + + cs := store.NewChainStore(bs, bs, mds, filcns.Weight, nil) + defer cs.Close() //nolint:errcheck + + sm, err := stmgr.NewStateManager(cs, filcns.NewTipSetExecutor(), vm.Syscalls(ffiwrapper.ProofVerifier), filcns.DefaultUpgradeSchedule(), shd) + if err != nil { + return err + } + + msg, err := cs.GetMessage(ctx, messageCid) + if err != nil { + return err + } + + err = cs.Load(ctx) + if err != nil { + return err + } + + ts, _, _, err := sm.SearchForMessage(ctx, cs.GetHeaviestTipSet(), messageCid, abi.ChainEpoch(lookbackLimit), true) + if err != nil { + return err + } + if ts == nil { + return xerrors.Errorf("could not find message within the last %d epochs", lookbackLimit) + } + executionTs, err := cs.GetTipsetByHeight(ctx, ts.Height()-2, ts, true) + + tw := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', tabwriter.AlignRight) + res, err := sm.CallWithGas(ctx, msg, []types.ChainMsg{}, executionTs) + if err != nil { + return err + } + fmt.Println("Total gas used: ", res.MsgRct.GasUsed) + printInternalExecutions(0, []types.ExecutionTrace{res.ExecutionTrace}, tw) + + return tw.Flush() + }, +} + +func printInternalExecutions(depth int, trace []types.ExecutionTrace, tw *tabwriter.Writer) { + if depth == 0 { + _, _ = fmt.Fprintf(tw, "Depth\tFrom\tTo\tMethod\tTotalGas\tComputeGas\tStorageGas\t\tExitCode\n") + } + for _, im := range trace { + sumGas := im.SumGas() + _, _ = fmt.Fprintf(tw, "%d\t%s\t%s\t%d\t%d\t%d\t%d\t\t%d\n", depth, truncateString(im.Msg.From.String(), 10), truncateString(im.Msg.To.String(), 10), im.Msg.Method, sumGas.TotalGas, sumGas.ComputeGas, sumGas.StorageGas, im.MsgRct.ExitCode) + printInternalExecutions(depth+1, im.Subcalls, tw) + } +} + +func truncateString(str string, length int) string { + if len(str) <= length { + return str + } + + truncated := "" + count := 0 + for _, char := range str { + truncated += string(char) + count++ + if count >= length { + break + } + } + truncated += "..." + return truncated +} diff --git a/cmd/lotus-shed/main.go b/cmd/lotus-shed/main.go index 3972a625b..623afb55e 100644 --- a/cmd/lotus-shed/main.go +++ b/cmd/lotus-shed/main.go @@ -13,7 +13,10 @@ import ( var log = logging.Logger("lotus-shed") func main() { - logging.SetLogLevel("*", "INFO") + _ = logging.SetLogLevel("*", "INFO") + _ = logging.SetLogLevelRegex("badger*", "ERROR") + _ = logging.SetLogLevel("drand", "ERROR") + _ = logging.SetLogLevel("chainstore", "ERROR") local := []*cli.Command{ addressCmd, @@ -76,6 +79,8 @@ func main() { msigCmd, fip36PollCmd, invariantsCmd, + gasTraceCmd, + replayOfflineCmd, } app := &cli.App{ @@ -108,7 +113,7 @@ func main() { } if err := app.Run(os.Args); err != nil { - log.Warnf("%+v", err) + log.Errorf("%+v", err) os.Exit(1) return } diff --git a/cmd/lotus-shed/migrations.go b/cmd/lotus-shed/migrations.go index 415faa16d..c4e9af397 100644 --- a/cmd/lotus-shed/migrations.go +++ b/cmd/lotus-shed/migrations.go @@ -7,6 +7,7 @@ import ( "time" "github.com/ipfs/go-cid" + logging "github.com/ipfs/go-log/v2" "github.com/urfave/cli/v2" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" @@ -53,6 +54,9 @@ var migrationsCmd = &cli.Command{ Name: "repo", Value: "~/.lotus", }, + &cli.BoolFlag{ + Name: "skip-pre-migration", + }, &cli.BoolFlag{ Name: "check-invariants", }, @@ -60,6 +64,11 @@ var migrationsCmd = &cli.Command{ Action: func(cctx *cli.Context) error { ctx := context.TODO() + err := logging.SetLogLevelRegex("badger*", "ERROR") + if err != nil { + return err + } + if cctx.NArg() != 1 { return lcli.IncorrectNumArgs(cctx) } @@ -107,8 +116,6 @@ var migrationsCmd = &cli.Command{ return err } - cache := nv15.NewMemMigrationCache() - blk, err := cs.GetBlock(ctx, blkCid) if err != nil { return err @@ -119,45 +126,8 @@ var migrationsCmd = &cli.Command{ return err } - ts1, err := cs.GetTipsetByHeight(ctx, blk.Height-240, migrationTs, false) - if err != nil { - return err - } - startTime := time.Now() - err = filcns.PreUpgradeActorsV9(ctx, sm, cache, ts1.ParentState(), ts1.Height()-1, ts1) - if err != nil { - return err - } - - preMigration1Time := time.Since(startTime) - - ts2, err := cs.GetTipsetByHeight(ctx, blk.Height-15, migrationTs, false) - if err != nil { - return err - } - - startTime = time.Now() - - err = filcns.PreUpgradeActorsV9(ctx, sm, cache, ts2.ParentState(), ts2.Height()-1, ts2) - if err != nil { - return err - } - - preMigration2Time := time.Since(startTime) - - startTime = time.Now() - - newCid1, err := filcns.UpgradeActorsV9(ctx, sm, cache, nil, blk.ParentStateRoot, blk.Height-1, migrationTs) - if err != nil { - return err - } - - cachedMigrationTime := time.Since(startTime) - - startTime = time.Now() - newCid2, err := filcns.UpgradeActorsV9(ctx, sm, nv15.NewMemMigrationCache(), nil, blk.ParentStateRoot, blk.Height-1, migrationTs) if err != nil { return err @@ -165,18 +135,60 @@ var migrationsCmd = &cli.Command{ uncachedMigrationTime := time.Since(startTime) - if newCid1 != newCid2 { - return xerrors.Errorf("got different results with and without the cache: %s, %s", newCid1, - newCid2) - } - fmt.Println("migration height ", blk.Height-1) + fmt.Println("old cid ", blk.ParentStateRoot) fmt.Println("new cid ", newCid2) - fmt.Println("completed premigration 1, took ", preMigration1Time) - fmt.Println("completed premigration 2, took ", preMigration2Time) - fmt.Println("completed round actual (with cache), took ", cachedMigrationTime) fmt.Println("completed round actual (without cache), took ", uncachedMigrationTime) + if !cctx.IsSet("skip-pre-migration") { + cache := nv15.NewMemMigrationCache() + + ts1, err := cs.GetTipsetByHeight(ctx, blk.Height-240, migrationTs, false) + if err != nil { + return err + } + + startTime = time.Now() + + err = filcns.PreUpgradeActorsV9(ctx, sm, cache, ts1.ParentState(), ts1.Height()-1, ts1) + if err != nil { + return err + } + + preMigration1Time := time.Since(startTime) + + ts2, err := cs.GetTipsetByHeight(ctx, blk.Height-15, migrationTs, false) + if err != nil { + return err + } + + startTime = time.Now() + + err = filcns.PreUpgradeActorsV9(ctx, sm, cache, ts2.ParentState(), ts2.Height()-1, ts2) + if err != nil { + return err + } + + preMigration2Time := time.Since(startTime) + + startTime = time.Now() + + newCid1, err := filcns.UpgradeActorsV9(ctx, sm, cache, nil, blk.ParentStateRoot, blk.Height-1, migrationTs) + if err != nil { + return err + } + + cachedMigrationTime := time.Since(startTime) + + if newCid1 != newCid2 { + return xerrors.Errorf("got different results with and without the cache: %s, %s", newCid1, + newCid2) + } + fmt.Println("completed premigration 1, took ", preMigration1Time) + fmt.Println("completed premigration 2, took ", preMigration2Time) + fmt.Println("completed round actual (with cache), took ", cachedMigrationTime) + } + if cctx.Bool("check-invariants") { err = checkMigrationInvariants(ctx, blk.ParentStateRoot, newCid2, bs, blk.Height-1) if err != nil { diff --git a/cmd/lotus-worker/main.go b/cmd/lotus-worker/main.go index 8b8db5aa7..afee6f1e1 100644 --- a/cmd/lotus-worker/main.go +++ b/cmd/lotus-worker/main.go @@ -447,10 +447,10 @@ var runCmd = &cli.Command{ return err } - var localPaths []paths.LocalPath + var localPaths []storiface.LocalPath if !cctx.Bool("no-local-storage") { - b, err := json.MarshalIndent(&paths.LocalStorageMeta{ + b, err := json.MarshalIndent(&storiface.LocalStorageMeta{ ID: storiface.ID(uuid.New().String()), Weight: 10, CanSeal: true, @@ -464,12 +464,12 @@ var runCmd = &cli.Command{ return xerrors.Errorf("persisting storage metadata (%s): %w", filepath.Join(lr.Path(), "sectorstore.json"), err) } - localPaths = append(localPaths, paths.LocalPath{ + localPaths = append(localPaths, storiface.LocalPath{ Path: lr.Path(), }) } - if err := lr.SetStorage(func(sc *paths.StorageConfig) { + if err := lr.SetStorage(func(sc *storiface.StorageConfig) { sc.StoragePaths = append(sc.StoragePaths, localPaths...) }); err != nil { return xerrors.Errorf("set storage config: %w", err) diff --git a/cmd/lotus-worker/sealworker/rpc.go b/cmd/lotus-worker/sealworker/rpc.go index 7d84b5c8b..97f78942e 100644 --- a/cmd/lotus-worker/sealworker/rpc.go +++ b/cmd/lotus-worker/sealworker/rpc.go @@ -92,8 +92,8 @@ func (w *Worker) StorageAddLocal(ctx context.Context, path string) error { return xerrors.Errorf("opening local path: %w", err) } - if err := w.Storage.SetStorage(func(sc *paths.StorageConfig) { - sc.StoragePaths = append(sc.StoragePaths, paths.LocalPath{Path: path}) + if err := w.Storage.SetStorage(func(sc *storiface.StorageConfig) { + sc.StoragePaths = append(sc.StoragePaths, storiface.LocalPath{Path: path}) }); err != nil { return xerrors.Errorf("get storage config: %w", err) } @@ -127,8 +127,8 @@ func (w *Worker) StorageDetachLocal(ctx context.Context, path string) error { // drop from the persisted storage.json var found bool - if err := w.Storage.SetStorage(func(sc *paths.StorageConfig) { - out := make([]paths.LocalPath, 0, len(sc.StoragePaths)) + if err := w.Storage.SetStorage(func(sc *storiface.StorageConfig) { + out := make([]storiface.LocalPath, 0, len(sc.StoragePaths)) for _, storagePath := range sc.StoragePaths { if storagePath.Path != path { out = append(out, storagePath) diff --git a/cmd/lotus-worker/storage.go b/cmd/lotus-worker/storage.go index 0736ffbfb..6b5994c17 100644 --- a/cmd/lotus-worker/storage.go +++ b/cmd/lotus-worker/storage.go @@ -13,7 +13,6 @@ import ( "golang.org/x/xerrors" lcli "github.com/filecoin-project/lotus/cli" - "github.com/filecoin-project/lotus/storage/paths" "github.com/filecoin-project/lotus/storage/sealer/storiface" ) @@ -103,7 +102,7 @@ var storageAttachCmd = &cli.Command{ } } - cfg := &paths.LocalStorageMeta{ + cfg := &storiface.LocalStorageMeta{ ID: storiface.ID(uuid.New().String()), Weight: cctx.Uint64("weight"), CanSeal: cctx.Bool("seal"), diff --git a/cmd/tvx/extract_message.go b/cmd/tvx/extract_message.go index db6b5322c..8ff8a2b79 100644 --- a/cmd/tvx/extract_message.go +++ b/cmd/tvx/extract_message.go @@ -417,10 +417,10 @@ func findMsgAndPrecursors(ctx context.Context, mode string, msgCid cid.Cid, send case mode == PrecursorSelectAll: fallthrough case mode == PrecursorSelectParticipants && - msgSenderID == senderID || - msgRecipientID == recipientID || - msgSenderID == recipientID || - msgRecipientID == senderID: + (msgSenderID == senderID || + msgRecipientID == recipientID || + msgSenderID == recipientID || + msgRecipientID == senderID): related = append(related, m.Message) } diff --git a/cmd/tvx/stores.go b/cmd/tvx/stores.go index 0f4f81397..9035c482a 100644 --- a/cmd/tvx/stores.go +++ b/cmd/tvx/stores.go @@ -16,6 +16,7 @@ import ( cbor "github.com/ipfs/go-ipld-cbor" format "github.com/ipfs/go-ipld-format" "github.com/ipfs/go-merkledag" + "golang.org/x/xerrors" "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/blockstore" @@ -158,3 +159,12 @@ func (pb *proxyingBlockstore) PutMany(ctx context.Context, blocks []blocks.Block pb.lk.Unlock() return pb.Blockstore.PutMany(ctx, blocks) } + +func (pb *proxyingBlockstore) View(ctx context.Context, c cid.Cid, callback func([]byte) error) error { + blk, err := pb.Get(ctx, c) + if err != nil { + return xerrors.Errorf("failed to Get cid %s: %w", c, err) + } + + return callback(blk.RawData()) +} diff --git a/conformance/driver.go b/conformance/driver.go index ba9f49176..fc03a48d8 100644 --- a/conformance/driver.go +++ b/conformance/driver.go @@ -160,7 +160,7 @@ func (d *Driver) ExecuteTipset(bs blockstore.Blockstore, ds ds.Batching, params return big.Zero(), nil } - return vm.NewLegacyVM(ctx, vmopt) + return vm.NewVM(ctx, vmopt) }) postcid, receiptsroot, err := tse.ApplyBlocks(context.Background(), @@ -203,6 +203,9 @@ type ExecuteMessageParams struct { // Lookback is the LookbackStateGetter; returns the state tree at a given epoch. Lookback vm.LookbackStateGetter + + // TipSetGetter returns the tipset key at any given epoch. + TipSetGetter vm.TipSetGetter } // ExecuteMessage executes a conformance test vector message in a temporary VM. @@ -217,15 +220,26 @@ func (d *Driver) ExecuteMessage(bs blockstore.Blockstore, params ExecuteMessageP params.Rand = NewFixedRand() } - // TODO: This lookback state returns the supplied precondition state tree, unconditionally. - // This is obviously not correct, but the lookback state tree is only used to validate the - // worker key when verifying a consensus fault. If the worker key hasn't changed in the - // current finality window, this workaround is enough. - // The correct solutions are documented in https://github.com/filecoin-project/ref-fvm/issues/381, - // but they're much harder to implement, and the tradeoffs aren't clear. - var lookback vm.LookbackStateGetter = func(ctx context.Context, epoch abi.ChainEpoch) (*state.StateTree, error) { - cst := cbor.NewCborStore(bs) - return state.LoadStateTree(cst, params.Preroot) + if params.TipSetGetter == nil { + // TODO: If/when we start writing conformance tests against the EVM, we'll need to + // actually implement this and (unfortunately) capture any tipsets looked up by + // messages. + params.TipSetGetter = func(context.Context, abi.ChainEpoch) (types.TipSetKey, error) { + return types.EmptyTSK, nil + } + } + + if params.Lookback == nil { + // TODO: This lookback state returns the supplied precondition state tree, unconditionally. + // This is obviously not correct, but the lookback state tree is only used to validate the + // worker key when verifying a consensus fault. If the worker key hasn't changed in the + // current finality window, this workaround is enough. + // The correct solutions are documented in https://github.com/filecoin-project/ref-fvm/issues/381, + // but they're much harder to implement, and the tradeoffs aren't clear. + params.Lookback = func(ctx context.Context, epoch abi.ChainEpoch) (*state.StateTree, error) { + cst := cbor.NewCborStore(bs) + return state.LoadStateTree(cst, params.Preroot) + } } vmOpts := &vm.VMOpts{ @@ -239,26 +253,42 @@ func (d *Driver) ExecuteMessage(bs blockstore.Blockstore, params ExecuteMessageP Rand: params.Rand, BaseFee: params.BaseFee, NetworkVersion: params.NetworkVersion, - LookbackState: lookback, + LookbackState: params.Lookback, + TipSetGetter: params.TipSetGetter, } - lvm, err := vm.NewLegacyVM(context.TODO(), vmOpts) - if err != nil { - return nil, cid.Undef, err - } - - invoker := filcns.NewActorRegistry() - - // register the chaos actor if required by the vector. + var vmi vm.Interface if chaosOn, ok := d.selector["chaos_actor"]; ok && chaosOn == "true" { + lvm, err := vm.NewLegacyVM(context.TODO(), vmOpts) + if err != nil { + return nil, cid.Undef, err + } + + invoker := filcns.NewActorRegistry() av, _ := actorstypes.VersionForNetwork(params.NetworkVersion) registry := builtin.MakeRegistryLegacy([]rtt.VMActor{chaos.Actor{}}) invoker.Register(av, nil, registry) + lvm.SetInvoker(invoker) + vmi = lvm + } else { + if vmOpts.NetworkVersion >= network.Version16 { + fvm, err := vm.NewFVM(context.TODO(), vmOpts) + if err != nil { + return nil, cid.Undef, err + } + vmi = fvm + } else { + lvm, err := vm.NewLegacyVM(context.TODO(), vmOpts) + if err != nil { + return nil, cid.Undef, err + } + invoker := filcns.NewActorRegistry() + lvm.SetInvoker(invoker) + vmi = lvm + } } - lvm.SetInvoker(invoker) - - ret, err := lvm.ApplyMessage(d.ctx, toChainMsg(params.Message)) + ret, err := vmi.ApplyMessage(d.ctx, toChainMsg(params.Message)) if err != nil { return nil, cid.Undef, err } @@ -266,10 +296,10 @@ func (d *Driver) ExecuteMessage(bs blockstore.Blockstore, params ExecuteMessageP var root cid.Cid if d.vmFlush { // flush the VM, committing the state tree changes and forcing a - // recursive copoy from the temporary blcokstore to the real blockstore. - root, err = lvm.Flush(d.ctx) + // recursive copy from the temporary blockstore to the real blockstore. + root, err = vmi.Flush(d.ctx) } else { - root, err = lvm.StateTree().(*state.StateTree).Flush(d.ctx) + root, err = vmi.(*vm.LegacyVM).StateTree().(*state.StateTree).Flush(d.ctx) } return ret, root, err diff --git a/documentation/en/api-v0-methods-miner.md b/documentation/en/api-v0-methods-miner.md index d85a98ae7..cb94cf3f7 100644 --- a/documentation/en/api-v0-methods-miner.md +++ b/documentation/en/api-v0-methods-miner.md @@ -415,8 +415,7 @@ Inputs: }, "ProofType": 8 } - ], - true + ] ] ``` diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index d2dc7e1f3..24fd88c95 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -164,6 +164,9 @@ * [PaychVoucherCreate](#PaychVoucherCreate) * [PaychVoucherList](#PaychVoucherList) * [PaychVoucherSubmit](#PaychVoucherSubmit) +* [Raft](#Raft) + * [RaftLeader](#RaftLeader) + * [RaftState](#RaftState) * [Start](#Start) * [StartTime](#StartTime) * [State](#State) @@ -1992,7 +1995,8 @@ Inputs: "Address": "f01234", "ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf", "PieceCID": null - } + }, + "RemoteStore": "00000000-0000-0000-0000-000000000000" } ] ``` @@ -5054,6 +5058,33 @@ Response: } ``` +## Raft + + +### RaftLeader + + +Perms: read + +Inputs: `null` + +Response: `"12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf"` + +### RaftState + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "NonceMap": {}, + "MsgUuids": {} +} +``` + ## Start diff --git a/documentation/en/cli-lotus-miner.md b/documentation/en/cli-lotus-miner.md index 845f657a8..707fc8a15 100644 --- a/documentation/en/cli-lotus-miner.md +++ b/documentation/en/cli-lotus-miner.md @@ -7,7 +7,7 @@ USAGE: lotus-miner [global options] command [command options] [arguments...] VERSION: - 1.19.0-dev + 1.19.1-dev COMMANDS: init Initialize a lotus miner repo diff --git a/documentation/en/cli-lotus-worker.md b/documentation/en/cli-lotus-worker.md index bfbdc5bc7..dda7c17e8 100644 --- a/documentation/en/cli-lotus-worker.md +++ b/documentation/en/cli-lotus-worker.md @@ -7,7 +7,7 @@ USAGE: lotus-worker [global options] command [command options] [arguments...] VERSION: - 1.19.0-dev + 1.19.1-dev COMMANDS: run Start lotus worker diff --git a/documentation/en/cli-lotus.md b/documentation/en/cli-lotus.md index f95e1473e..733971c94 100644 --- a/documentation/en/cli-lotus.md +++ b/documentation/en/cli-lotus.md @@ -7,7 +7,7 @@ USAGE: lotus [global options] command [command options] [arguments...] VERSION: - 1.19.0-dev + 1.19.1-dev COMMANDS: daemon Start a lotus daemon process diff --git a/documentation/en/default-lotus-config.toml b/documentation/en/default-lotus-config.toml index bfb1aa228..889b87e4e 100644 --- a/documentation/en/default-lotus-config.toml +++ b/documentation/en/default-lotus-config.toml @@ -202,3 +202,65 @@ #HotStoreFullGCFrequency = 20 +[Cluster] + # EXPERIMENTAL. config to enabled node cluster with raft consensus + # + # type: bool + # env var: LOTUS_CLUSTER_CLUSTERMODEENABLED + #ClusterModeEnabled = false + + # A folder to store Raft's data. + # + # type: string + # env var: LOTUS_CLUSTER_DATAFOLDER + #DataFolder = "" + + # InitPeersetMultiAddr provides the list of initial cluster peers for new Raft + # peers (with no prior state). It is ignored when Raft was already + # initialized or when starting in staging mode. + # + # type: []string + # env var: LOTUS_CLUSTER_INITPEERSETMULTIADDR + #InitPeersetMultiAddr = [] + + # LeaderTimeout specifies how long to wait for a leader before + # failing an operation. + # + # type: Duration + # env var: LOTUS_CLUSTER_WAITFORLEADERTIMEOUT + #WaitForLeaderTimeout = "15s" + + # NetworkTimeout specifies how long before a Raft network + # operation is timed out + # + # type: Duration + # env var: LOTUS_CLUSTER_NETWORKTIMEOUT + #NetworkTimeout = "1m40s" + + # CommitRetries specifies how many times we retry a failed commit until + # we give up. + # + # type: int + # env var: LOTUS_CLUSTER_COMMITRETRIES + #CommitRetries = 1 + + # How long to wait between retries + # + # type: Duration + # env var: LOTUS_CLUSTER_COMMITRETRYDELAY + #CommitRetryDelay = "200ms" + + # BackupsRotate specifies the maximum number of Raft's DataFolder + # copies that we keep as backups (renaming) after cleanup. + # + # type: int + # env var: LOTUS_CLUSTER_BACKUPSROTATE + #BackupsRotate = 6 + + # Tracing enables propagation of contexts across binary boundaries. + # + # type: bool + # env var: LOTUS_CLUSTER_TRACING + #Tracing = false + + diff --git a/documentation/en/default-lotus-miner-config.toml b/documentation/en/default-lotus-miner-config.toml index b51e325e8..939bac0cc 100644 --- a/documentation/en/default-lotus-miner-config.toml +++ b/documentation/en/default-lotus-miner-config.toml @@ -325,6 +325,29 @@ # env var: LOTUS_PROVING_PARALLELCHECKLIMIT #ParallelCheckLimit = 128 + # Maximum amount of time a proving pre-check can take for a sector. If the check times out the sector will be skipped + # + # WARNING: Setting this value too low risks in sectors being skipped even though they are accessible, just reading the + # test challenge took longer than this timeout + # WARNING: Setting this value too high risks missing PoSt deadline in case IO operations related to this sector are + # blocked (e.g. in case of disconnected NFS mount) + # + # type: Duration + # env var: LOTUS_PROVING_SINGLECHECKTIMEOUT + #SingleCheckTimeout = "10m0s" + + # Maximum amount of time a proving pre-check can take for an entire partition. If the check times out, sectors in + # the partition which didn't get checked on time will be skipped + # + # WARNING: Setting this value too low risks in sectors being skipped even though they are accessible, just reading the + # test challenge took longer than this timeout + # WARNING: Setting this value too high risks missing PoSt deadline in case IO operations related to this partition are + # blocked or slow + # + # type: Duration + # env var: LOTUS_PROVING_PARTITIONCHECKTIMEOUT + #PartitionCheckTimeout = "20m0s" + # Disable Window PoSt computation on the lotus-miner process even if no window PoSt workers are present. # # WARNING: If no windowPoSt workers are connected, window PoSt WILL FAIL resulting in faulty sectors which will need @@ -694,7 +717,7 @@ # to use when evaluating tasks against this worker. An empty value defaults # to "hardware". # - # type: sealer.ResourceFilteringStrategy + # type: ResourceFilteringStrategy # env var: LOTUS_STORAGE_RESOURCEFILTERING #ResourceFiltering = "hardware" diff --git a/documentation/misc/RELEASE_ISSUE_TEMPLATE.md b/documentation/misc/RELEASE_ISSUE_TEMPLATE.md index 8c3cce944..9ae46fe57 100644 --- a/documentation/misc/RELEASE_ISSUE_TEMPLATE.md +++ b/documentation/misc/RELEASE_ISSUE_TEMPLATE.md @@ -21,12 +21,14 @@ 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. - - [ ] Bump the version in `build/version.go` in the `master` branch to `vX.Y.(Z+1)-dev` (bump from feature release) or `vX.(Y+1).0-dev` (bump from mandatory release) + - [ ] Bump the version in `build/version.go` in the `master` branch to `vX.Y.(Z+1)-dev` (bump from feature release) or `vX.(Y+1).0-dev` (bump from mandatory release). Run make gen and make docsgen-cli before committing changes Prepping an RC: -- [ ] version string in `build/version.go` has been updated (in the `release/vX.Y.Z` branch). +- [ ] version string in `build/version.go` has been updated (in the `release/vX.Y.Z` branch) - [ ] run `make gen && make docsgen-cli` +- [ ] Generate changelog using the script at scripts/mkreleaselog +- [ ] Add contents of generated text to lotus/CHANGELOG.md in addition to other details - [ ] tag commit with `vX.Y.Z-rcN` - [ ] cut a pre-release [here](https://github.com/filecoin-project/lotus/releases/new?prerelease=true) diff --git a/extern/filecoin-ffi b/extern/filecoin-ffi index 6c58e21db..6bde8568a 160000 --- a/extern/filecoin-ffi +++ b/extern/filecoin-ffi @@ -1 +1 @@ -Subproject commit 6c58e21db3f813afce5e1240401036b53be0a33e +Subproject commit 6bde8568a206ee28ed0344341026ff97af4fe824 diff --git a/gen/main.go b/gen/main.go index 95b2d43e3..38ec5935d 100644 --- a/gen/main.go +++ b/gen/main.go @@ -7,6 +7,7 @@ import ( gen "github.com/whyrusleeping/cbor-gen" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/chain/exchange" "github.com/filecoin-project/lotus/chain/market" "github.com/filecoin-project/lotus/chain/types" @@ -128,4 +129,13 @@ func main() { fmt.Println(err) os.Exit(1) } + err = gen.WriteTupleEncodersToFile("./blockstore/cbor_gen.go", "blockstore", + blockstore.NetRpcReq{}, + blockstore.NetRpcResp{}, + blockstore.NetRpcErr{}, + ) + if err != nil { + fmt.Println(err) + os.Exit(1) + } } diff --git a/go.mod b/go.mod index 728899e4c..5cb6a6399 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( contrib.go.opencensus.io/exporter/prometheus v0.4.0 github.com/BurntSushi/toml v1.1.0 github.com/DataDog/zstd v1.4.1 - github.com/GeertJohan/go.rice v1.0.2 + github.com/GeertJohan/go.rice v1.0.3 github.com/Gurpartap/async v0.0.0-20180927173644-4f7f499dd9ee github.com/Kubuxu/imtui v0.0.0-20210401140320-41663d68d0fa github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d @@ -37,7 +37,7 @@ require ( github.com/filecoin-project/go-data-transfer v1.15.2 github.com/filecoin-project/go-fil-commcid v0.1.0 github.com/filecoin-project/go-fil-commp-hashhash v0.1.0 - github.com/filecoin-project/go-fil-markets v1.24.0-v17 + github.com/filecoin-project/go-fil-markets v1.25.0 github.com/filecoin-project/go-jsonrpc v0.1.8 github.com/filecoin-project/go-legs v0.4.4 github.com/filecoin-project/go-padreader v0.0.1 @@ -63,10 +63,13 @@ require ( github.com/golang/mock v1.6.0 github.com/google/uuid v1.3.0 github.com/gorilla/mux v1.7.4 + github.com/gorilla/websocket v1.5.0 github.com/hako/durafmt v0.0.0-20200710122514-c0fb7b4da026 github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/golang-lru v0.5.4 + github.com/hashicorp/raft v1.1.1 + github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea github.com/icza/backscanner v0.0.0-20210726202459-ac2ffc679f94 github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab github.com/ipfs/bbloom v0.0.4 @@ -101,7 +104,7 @@ require ( github.com/ipfs/go-unixfsnode v1.4.0 github.com/ipfs/interface-go-ipfs-core v0.7.0 github.com/ipld/go-car v0.4.0 - github.com/ipld/go-car/v2 v2.4.1 + github.com/ipld/go-car/v2 v2.5.0 github.com/ipld/go-codec-dagpb v1.3.2 github.com/ipld/go-ipld-prime v0.17.0 github.com/ipld/go-ipld-selector-text-lite v0.0.1 @@ -109,12 +112,16 @@ require ( github.com/koalacxr/quantile v0.0.1 github.com/libp2p/go-buffer-pool v0.1.0 github.com/libp2p/go-libp2p v0.22.0 + github.com/libp2p/go-libp2p-consensus v0.0.1 + github.com/libp2p/go-libp2p-gorpc v0.4.0 github.com/libp2p/go-libp2p-kad-dht v0.18.0 github.com/libp2p/go-libp2p-peerstore v0.8.0 github.com/libp2p/go-libp2p-pubsub v0.8.0 + github.com/libp2p/go-libp2p-raft v0.1.8 github.com/libp2p/go-libp2p-record v0.2.0 github.com/libp2p/go-libp2p-routing-helpers v0.2.3 github.com/libp2p/go-maddr-filter v0.1.0 + github.com/libp2p/go-msgio v0.2.0 github.com/mattn/go-isatty v0.0.16 github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 github.com/mitchellh/go-homedir v1.1.0 @@ -145,6 +152,7 @@ require ( go.uber.org/fx v1.15.0 go.uber.org/multierr v1.8.0 go.uber.org/zap v1.22.0 + golang.org/x/exp v0.0.0-20220426173459-3bcf042a4bf5 golang.org/x/net v0.0.0-20220812174116-3211cb980234 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab @@ -163,9 +171,11 @@ require ( github.com/Stebalien/go-bitfield v0.0.1 // indirect github.com/akavel/rsrc v0.8.0 // indirect github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a // indirect + github.com/armon/go-metrics v0.3.9 // indirect github.com/benbjohnson/clock v1.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bep/debounce v1.2.0 // indirect + github.com/boltdb/bolt v1.3.1 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/cheekybits/genny v1.0.0 // indirect @@ -173,7 +183,7 @@ require ( github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 // indirect github.com/cskr/pubsub v1.0.2 // indirect - github.com/daaku/go.zipexe v1.0.0 // indirect + github.com/daaku/go.zipexe v1.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect @@ -213,9 +223,11 @@ require ( github.com/golang/snappy v0.0.4 // indirect github.com/google/go-cmp v0.5.8 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/gorilla/websocket v1.5.0 // indirect github.com/hannahhoward/cbor-gen-for v0.0.0-20200817222906-ea96cece81f1 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-hclog v0.16.2 // indirect + github.com/hashicorp/go-immutable-radix v1.3.1 // indirect + github.com/hashicorp/go-msgpack v0.5.5 // indirect github.com/huin/goupnp v1.0.3 // indirect github.com/iancoleman/orderedmap v0.1.0 // indirect github.com/ipfs/go-bitfield v1.0.0 // indirect @@ -254,7 +266,6 @@ require ( github.com/libp2p/go-libp2p-kbucket v0.5.0 // indirect github.com/libp2p/go-libp2p-noise v0.5.0 // indirect github.com/libp2p/go-libp2p-tls v0.5.0 // indirect - github.com/libp2p/go-msgio v0.2.0 // indirect github.com/libp2p/go-nat v0.1.0 // indirect github.com/libp2p/go-netroute v0.2.0 // indirect github.com/libp2p/go-openssl v0.1.0 // indirect @@ -304,6 +315,7 @@ require ( github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/uber/jaeger-client-go v2.25.0+incompatible // indirect + github.com/ugorji/go/codec v1.2.6 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.0.1 // indirect github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 // indirect @@ -311,7 +323,7 @@ require ( github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect - github.com/zondax/hid v0.9.1-0.20220302062450-5552068d2266 // indirect + github.com/zondax/hid v0.9.1 // indirect github.com/zondax/ledger-go v0.12.1 // indirect go.opentelemetry.io/otel/metric v0.25.0 // indirect go.opentelemetry.io/otel/sdk/export/metric v0.25.0 // indirect @@ -320,7 +332,6 @@ require ( go.uber.org/dig v1.12.0 // indirect go4.org v0.0.0-20200411211856-f5505b9728dd // indirect golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect - golang.org/x/exp v0.0.0-20220426173459-3bcf042a4bf5 // indirect golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect golang.org/x/text v0.3.7 // indirect diff --git a/go.sum b/go.sum index 7275bd3ac..6d33d0b5e 100644 --- a/go.sum +++ b/go.sum @@ -49,12 +49,14 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I= github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/zstd v1.4.1 h1:3oxKN3wbHibqx897utPC2LTQU4J+IHWWJO+glkAkpFM= github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/GeertJohan/go.incremental v1.0.0 h1:7AH+pY1XUgQE4Y1HcXYaMqAI0m9yrFqo/jt0CW30vsg= github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= -github.com/GeertJohan/go.rice v1.0.2 h1:PtRw+Tg3oa3HYwiDBZyvOJ8LdIyf6lAovJJtr7YOAYk= -github.com/GeertJohan/go.rice v1.0.2/go.mod h1:af5vUNlDNkCjOZeSGFgIJxDje9qdjsO6hshx0gTmZt4= +github.com/GeertJohan/go.rice v1.0.3 h1:k5viR+xGtIhF61125vCE1cmJ5957RQGXG6dmbaWZSmI= +github.com/GeertJohan/go.rice v1.0.3/go.mod h1:XVdrU4pW00M4ikZed5q56tPf1v2KwnIKeIdc9CBYNt4= github.com/Gurpartap/async v0.0.0-20180927173644-4f7f499dd9ee h1:8doiS7ib3zi6/K172oDhSKU0dJ/miJramo9NITOMyZQ= github.com/Gurpartap/async v0.0.0-20180927173644-4f7f499dd9ee/go.mod h1:W0GbEAA4uFNYOGG2cJpmFJ04E6SD1NLELPYZB57/7AY= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= @@ -99,6 +101,9 @@ github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= +github.com/armon/go-metrics v0.3.9 h1:O2sNqxBdvq8Eq5xmzljcYzAORli6RWCvEym4cJf9m18= +github.com/armon/go-metrics v0.3.9/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= @@ -120,6 +125,8 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r github.com/bep/debounce v1.2.0 h1:wXds8Kq8qRfwAOpAxHrJDbCXgC5aHSzgQb/0gKsHQqo= github.com/bep/debounce v1.2.0/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= +github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/briandowns/spinner v1.11.1/go.mod h1:QOuQk7x+EaDASo80FEXwlwiA+j/PPIcX3FScO+3/ZPQ= github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= @@ -164,6 +171,8 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= github.com/cilium/ebpf v0.4.0 h1:QlHdikaxALkqWasW8hAC1mfR0jdmvbfaBdBPFmRSglA= github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= @@ -204,8 +213,8 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= -github.com/daaku/go.zipexe v1.0.0 h1:VSOgZtH418pH9L16hC/JrgSNJbbAL26pj7lmD1+CGdY= -github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E= +github.com/daaku/go.zipexe v1.0.2 h1:Zg55YLYTr7M9wjKn8SY/WcpuuEi+kR2u4E8RhvpyXmk= +github.com/daaku/go.zipexe v1.0.2/go.mod h1:5xWogtqlYnfBXkSB1o9xysukNP9GTvaNkqzUZbt3Bw8= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -318,8 +327,8 @@ github.com/filecoin-project/go-fil-commcid v0.1.0 h1:3R4ds1A9r6cr8mvZBfMYxTS88Oq github.com/filecoin-project/go-fil-commcid v0.1.0/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= github.com/filecoin-project/go-fil-commp-hashhash v0.1.0 h1:imrrpZWEHRnNqqv0tN7LXep5bFEVOVmQWHJvl2mgsGo= github.com/filecoin-project/go-fil-commp-hashhash v0.1.0/go.mod h1:73S8WSEWh9vr0fDJVnKADhfIv/d6dCbAGaAGWbdJEI8= -github.com/filecoin-project/go-fil-markets v1.24.0-v17 h1:YjT0usMeR6kdAo3RBfftTPe5bNIgNmBbo5YzJHF1iLk= -github.com/filecoin-project/go-fil-markets v1.24.0-v17/go.mod h1:JW/UHkHDqP4MikCIIWNY5IHvTTsdv/zNMk9jJXKzhIU= +github.com/filecoin-project/go-fil-markets v1.25.0 h1:zWkc1v84JL9KttiqOy2IIZB0jksIdAt1WLCdOP/KvAg= +github.com/filecoin-project/go-fil-markets v1.25.0/go.mod h1:3lzXZt5mRHTHAmZ10sUviiutaLVL57B99FgBU1MYqWY= 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= @@ -380,6 +389,7 @@ github.com/filecoin-project/storetheindex v0.4.17/go.mod h1:y2dL8C5D3PXi183hdxgG 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/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= @@ -593,17 +603,27 @@ github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyN github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v0.16.2 h1:K4ev2ib4LdQETX5cSZBG0DVLk1jwGqSPXBjdah3veNs= +github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= +github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= @@ -615,6 +635,10 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/raft v1.1.1 h1:HJr7UE1x/JrJSc9Oy6aDBHtNHUUBHjcQjTgvUVihoZs= +github.com/hashicorp/raft v1.1.1/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8= +github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea h1:xykPFhrBAS2J0VBzVa5e80b5ZtYuNQtgXjN40qBZlD4= +github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea/go.mod h1:pNv7Wc3ycL6F5oOWn+tPGo2gWD4a5X+yp/ntwdKLjRk= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hodgesds/perf-utils v0.0.8/go.mod h1:F6TfvsbtrF88i++hou29dTXlI2sfsJv+gRZDtmTJkAs= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -837,8 +861,8 @@ github.com/ipld/go-car v0.1.0/go.mod h1:RCWzaUh2i4mOEkB3W45Vc+9jnS/M6Qay5ooytiBH github.com/ipld/go-car v0.4.0 h1:U6W7F1aKF/OJMHovnOVdst2cpQE5GhmHibQkAixgNcQ= github.com/ipld/go-car v0.4.0/go.mod h1:Uslcn4O9cBKK9wqHm/cLTFacg6RAPv6LZx2mxd2Ypl4= github.com/ipld/go-car/v2 v2.1.1/go.mod h1:+2Yvf0Z3wzkv7NeI69i8tuZ+ft7jyjPYIWZzeVNeFcI= -github.com/ipld/go-car/v2 v2.4.1 h1:9S+FYbQzQJ/XzsdiOV13W5Iu/i+gUnr6csbSD9laFEg= -github.com/ipld/go-car/v2 v2.4.1/go.mod h1:zjpRf0Jew9gHqSvjsKVyoq9OY9SWoEKdYCQUKVaaPT0= +github.com/ipld/go-car/v2 v2.5.0 h1:S9h7A6qBAJ+B1M1jIKtau+HPDe30UbM71vsyBzwvRIE= +github.com/ipld/go-car/v2 v2.5.0/go.mod h1:jKjGOqoCj5zn6KjnabD6JbnCsMntqU2hLiU6baZVO3E= github.com/ipld/go-codec-dagpb v1.2.0/go.mod h1:6nBN7X7h8EOsEejZGqC7tej5drsdBAXbMHyBT+Fne5s= github.com/ipld/go-codec-dagpb v1.3.0/go.mod h1:ga4JTU3abYApDC3pZ00BC2RSvC3qfBb9MSJkMLSwnhA= github.com/ipld/go-codec-dagpb v1.3.1/go.mod h1:ErNNglIi5KMur/MfFE/svtgQthzVvf+43MrzLbpcIZY= @@ -979,7 +1003,9 @@ github.com/libp2p/go-libp2p v0.6.1/go.mod h1:CTFnWXogryAHjXAKEbOf1OWY+VeAP3lDMZk github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xSU1ivxn0k= github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= +github.com/libp2p/go-libp2p v0.13.0/go.mod h1:pM0beYdACRfHO1WcJlp65WXyG2A6NqYM+t2DTVAJxMo= github.com/libp2p/go-libp2p v0.14.3/go.mod h1:d12V4PdKbpL0T1/gsUNN8DfgMuRPDX8bS2QxCZlwRH0= +github.com/libp2p/go-libp2p v0.14.4/go.mod h1:EIRU0Of4J5S8rkockZM7eJp2S0UrCyi55m2kJVru3rM= github.com/libp2p/go-libp2p v0.16.0/go.mod h1:ump42BsirwAWxKzsCiFnTtN1Yc+DuPu76fyMX364/O4= github.com/libp2p/go-libp2p v0.17.0/go.mod h1:Fkin50rsGdv5mm5BshBUtPRZknt9esfmYXBOYcwOTgw= github.com/libp2p/go-libp2p v0.22.0 h1:2Tce0kHOp5zASFKJbNzRElvh0iZwdtG5uZheNW8chIw= @@ -993,6 +1019,7 @@ github.com/libp2p/go-libp2p-autonat v0.1.1/go.mod h1:OXqkeGOY2xJVWKAGV2inNF5aKN/ github.com/libp2p/go-libp2p-autonat v0.2.0/go.mod h1:DX+9teU4pEEoZUqR1PiMlqliONQdNbfzE1C718tcViI= 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.4.0/go.mod h1:YxaJlpr81FhdOv3W3BTconZPfhaYivRdf53g+S2wobk= github.com/libp2p/go-libp2p-autonat v0.4.2/go.mod h1:YxaJlpr81FhdOv3W3BTconZPfhaYivRdf53g+S2wobk= github.com/libp2p/go-libp2p-autonat v0.6.0/go.mod h1:bFC6kY8jwzNNWoqc8iGE57vsfwyJ/lP4O4DOV1e0B2o= github.com/libp2p/go-libp2p-autonat v0.7.0/go.mod h1:uPvPn6J7cN+LCfFwW5tpOYvAz5NvPTc4iBamTV/WDMg= @@ -1010,6 +1037,8 @@ github.com/libp2p/go-libp2p-connmgr v0.2.4/go.mod h1:YV0b/RIm8NGPnnNWM7hG9Q38OeQ github.com/libp2p/go-libp2p-connmgr v0.3.0/go.mod h1:RVoyPjJm0J9Vd1m6qUN2Tn7kJm4rL1Ml20pFsFgPGik= github.com/libp2p/go-libp2p-connmgr v0.4.0 h1:q/KZUS1iMDIQckMZarMYwhQisJqiFPHAVC1c4DR3hDE= github.com/libp2p/go-libp2p-connmgr v0.4.0/go.mod h1:exFQQm19PFAx+QuJmBPw4MM58QejzPJRFFFYnNmgi2w= +github.com/libp2p/go-libp2p-consensus v0.0.1 h1:jcVbHRZLwTXU9iT/mPi+Lx4/OrIzq3bU1TbZNhYFCV8= +github.com/libp2p/go-libp2p-consensus v0.0.1/go.mod h1:+9Wrfhc5QOqWB0gXI0m6ARlkHfdJpcFXmRU0WoHz4Mo= github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= github.com/libp2p/go-libp2p-core v0.0.2/go.mod h1:9dAcntw/n46XycV4RnlBq3BpgrmyUi9LuoTNdPrbUco= github.com/libp2p/go-libp2p-core v0.0.3/go.mod h1:j+YQMNz9WNSkNezXOsahp9kwZBKBvxLpKD316QWSJXE= @@ -1052,6 +1081,9 @@ github.com/libp2p/go-libp2p-discovery v0.2.0/go.mod h1:s4VGaxYMbw4+4+tsoQTqh7wfx github.com/libp2p/go-libp2p-discovery v0.3.0/go.mod h1:o03drFnz9BVAZdzC/QUQ+NeQOu38Fu7LJGEOK2gQltw= github.com/libp2p/go-libp2p-discovery v0.5.0/go.mod h1:+srtPIU9gDaBNu//UHvcdliKBIcr4SfDcm0/PfPJLug= github.com/libp2p/go-libp2p-discovery v0.6.0/go.mod h1:/u1voHt0tKIe5oIA1RHBKQLVCWPna2dXmPNHc2zR9S8= +github.com/libp2p/go-libp2p-gorpc v0.4.0 h1:kxHg5C3IuXeOq5FHPGbMHwQzKDlTVeB/NDr0ndc8J/g= +github.com/libp2p/go-libp2p-gorpc v0.4.0/go.mod h1:jux2Mb6BfUE1n58KbVCmWtqvpiZo0DDaKobKInf4s5o= +github.com/libp2p/go-libp2p-gostream v0.3.1/go.mod h1:1V3b+u4Zhaq407UUY9JLCpboaeufAeVQbnvAt12LRsI= github.com/libp2p/go-libp2p-gostream v0.4.0 h1:heduMMEB78yBqeEQv+P7Fn5X926MHC2jDIC7/7yLpYA= github.com/libp2p/go-libp2p-gostream v0.4.0/go.mod h1:21DVGBcCQwRfEXZpCnZ2kG24QiEkBpEQvG53gYXE4u0= github.com/libp2p/go-libp2p-host v0.0.1/go.mod h1:qWd+H1yuU0m5CwzAkvbSjqKairayEHdR5MMl7Cwa7Go= @@ -1082,6 +1114,7 @@ github.com/libp2p/go-libp2p-net v0.0.1/go.mod h1:Yt3zgmlsHOgUWSXmt5V/Jpz9upuJBE8 github.com/libp2p/go-libp2p-net v0.0.2/go.mod h1:Yt3zgmlsHOgUWSXmt5V/Jpz9upuJBE8EgNU9DrCcR8c= github.com/libp2p/go-libp2p-netutil v0.0.1/go.mod h1:GdusFvujWZI9Vt0X5BKqwWWmZFxecf9Gt03cKxm2f/Q= 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.2.0/go.mod h1:IEbYhBBzGyvdLBoxxULL/SGbJARhUeqlO8lVSREYu2Q= github.com/libp2p/go-libp2p-noise v0.3.0/go.mod h1:JNjHbociDJKHD64KTkzGnzqJ0FEV5gHJa6AB00kbCNQ= github.com/libp2p/go-libp2p-noise v0.5.0 h1:gwJZ/3iH3MRnBrLIyr/YLdCOnmqfJMptlsFFUIc3j0Y= @@ -1112,6 +1145,8 @@ github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqU github.com/libp2p/go-libp2p-quic-transport v0.13.0/go.mod h1:39/ZWJ1TW/jx1iFkKzzUg00W6tDJh73FC0xYudjr7Hc= github.com/libp2p/go-libp2p-quic-transport v0.15.0/go.mod h1:wv4uGwjcqe8Mhjj7N/Ic0aKjA+/10UnMlSzLO0yRpYQ= github.com/libp2p/go-libp2p-quic-transport v0.15.2/go.mod h1:wv4uGwjcqe8Mhjj7N/Ic0aKjA+/10UnMlSzLO0yRpYQ= +github.com/libp2p/go-libp2p-raft v0.1.8 h1:Fq0aWHbbhi6WJXf+yaOQeMzV+9UgkbHIIGyaJbH3vpo= +github.com/libp2p/go-libp2p-raft v0.1.8/go.mod h1:+YDisn3uszb7vxshLgKoDdRGs79WSbHRgrOdrYqDPk4= 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.2/go.mod h1:pal0eNcT5nqZaTV7UGhqeGqxFgGdsU/9W//C8dqjQDk= @@ -1131,6 +1166,7 @@ github.com/libp2p/go-libp2p-swarm v0.2.2/go.mod h1:fvmtQ0T1nErXym1/aa1uJEyN7JzaT github.com/libp2p/go-libp2p-swarm v0.2.3/go.mod h1:P2VO/EpxRyDxtChXz/VPVXyTnszHvokHKRhfkEgFKNM= 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.4.0/go.mod h1:XVFcO52VoLoo0eitSxNQWYq4D6sydGOweTOAjJNraCw= github.com/libp2p/go-libp2p-swarm v0.5.0/go.mod h1:sU9i6BoHE0Ve5SKz3y9WfKrh8dUat6JknzUehFx8xW4= github.com/libp2p/go-libp2p-swarm v0.8.0/go.mod h1:sOMp6dPuqco0r0GHTzfVheVBh6UEL0L1lXUZ5ot2Fvc= github.com/libp2p/go-libp2p-swarm v0.9.0/go.mod h1:2f8d8uxTJmpeqHF/1ujjdXZp+98nNIbujVOMEZxCbZ8= @@ -1158,6 +1194,7 @@ 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/go.mod h1:J4ko0ObtZSmgn5BX5AmegP+dK3CSnU2lMCKsSq/EY0s= github.com/libp2p/go-libp2p-transport-upgrader v0.4.2/go.mod h1:NR8ne1VwfreD5VIWIU62Agt/J18ekORFU/j1i2y8zvk= github.com/libp2p/go-libp2p-transport-upgrader v0.4.3/go.mod h1:bpkldbOWXMrXhpZbSV1mQxTrefOg2Fi+k1ClDSA4ppw= github.com/libp2p/go-libp2p-transport-upgrader v0.5.0/go.mod h1:Rc+XODlB3yce7dvFV4q/RmyJGsFcCZRkeZMu/Zdg0mo= @@ -1172,6 +1209,7 @@ 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/go.mod h1:dowuvDu8CRWmr0iqySMiSxK+W0iL5cMVO9S94Y6gkv4= github.com/libp2p/go-libp2p-yamux v0.5.4/go.mod h1:tfrXbyaTqqSU654GTvK3ocnSZL3BuHoeTSqhcel1wsE= github.com/libp2p/go-libp2p-yamux v0.6.0/go.mod h1:MRhd6mAYnFRnSISp4M8i0ClV/j+mWHo2mYLifWGw33k= github.com/libp2p/go-libp2p-yamux v0.7.0/go.mod h1:fMyA0CsPfHkIuBU0wjRGrCjTBFiXTXxG0k5M4ETv+08= @@ -1233,7 +1271,9 @@ github.com/libp2p/go-tcp-transport v0.0.4/go.mod h1:+E8HvC8ezEVOxIo3V5vCK9l1y/19 github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc= github.com/libp2p/go-tcp-transport v0.1.1/go.mod h1:3HzGvLbx6etZjnFlERyakbaYPdfjg2pWP97dFZworkY= github.com/libp2p/go-tcp-transport v0.2.0/go.mod h1:vX2U0CnWimU4h0SGSEsg++AzvBcroCGYw28kh94oLe0= +github.com/libp2p/go-tcp-transport v0.2.1/go.mod h1:zskiJ70MEfWz2MKxvFB/Pv+tPIB1PpPUrHIWQ8aFw7M= github.com/libp2p/go-tcp-transport v0.2.3/go.mod h1:9dvr03yqrPyYGIEN6Dy5UvdJZjyPFvl1S/igQ5QD1SU= +github.com/libp2p/go-tcp-transport v0.2.4/go.mod h1:9dvr03yqrPyYGIEN6Dy5UvdJZjyPFvl1S/igQ5QD1SU= github.com/libp2p/go-tcp-transport v0.4.0/go.mod h1:0y52Rwrn4076xdJYu/51/qJIdxz+EWDAOG2S45sV3VI= github.com/libp2p/go-testutil v0.0.1/go.mod h1:iAcJc/DKJQanJ5ws2V+u5ywdL2n12X1WbbEG+Jjy69I= github.com/libp2p/go-testutil v0.1.0/go.mod h1:81b2n5HypcVyrCg/MJx4Wgfp/VHojytjVe/gLzZ2Ehc= @@ -1252,6 +1292,7 @@ github.com/libp2p/go-yamux v1.3.5/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZ github.com/libp2p/go-yamux v1.3.7/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= github.com/libp2p/go-yamux v1.4.0/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= github.com/libp2p/go-yamux v1.4.1/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= +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/go.mod h1:3So6P6TV6r75R9jiBpiIKgU/66lOarCZjqROGxzPpPQ= github.com/libp2p/go-yamux/v2 v2.3.0/go.mod h1:iTU+lOIn/2h0AgKcL49clNTwfEw+WSfDYrXe05EyKIs= github.com/libp2p/go-yamux/v3 v3.1.2 h1:lNEy28MBk1HavUAlzKgShp+F6mn/ea1nDYWftZhFW9Q= @@ -1306,6 +1347,7 @@ github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= @@ -1331,6 +1373,7 @@ github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00v github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= 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/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= @@ -1429,6 +1472,7 @@ 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/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= github.com/multiformats/go-multistream v0.2.1/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= github.com/multiformats/go-multistream v0.2.2/go.mod h1:UIcnm7Zuo8HKG+HkWgfQsGL+/MIEhyTqbODbIUwSXKs= github.com/multiformats/go-multistream v0.3.3 h1:d5PZpjwRgVlbwfdTDjife7XszfZd8KYWfROYFlGcR8o= @@ -1502,6 +1546,8 @@ github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= @@ -1531,6 +1577,7 @@ github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4 github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= +github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.4.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU= @@ -1697,6 +1744,7 @@ github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0 github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/uber/jaeger-client-go v2.15.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-client-go v2.23.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-client-go v2.25.0+incompatible h1:IxcNZ7WRY1Y3G4poYlx24szfsn/3LvK9QHCq9oQw8+U= @@ -1704,7 +1752,12 @@ github.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMW github.com/uber/jaeger-lib v1.5.1-0.20181102163054-1fc5c315e03c/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= github.com/uber/jaeger-lib v2.2.0+incompatible h1:MxZXOiR2JuoANZ3J6DE/U0kSFv/eJ/GfSYVCjK7dyaw= github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/ugorji/go v1.1.13/go.mod h1:jxau1n+/wyTGLQoCkjok9r5zFa/FxT6eI5HiHKQszjc= +github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn0= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.13/go.mod h1:oNVt3Dq+FO91WNQ/9JnHKQP2QJxTzoN7wCBFCq1OeuU= +github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ= +github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= @@ -1778,8 +1831,8 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zondax/hid v0.9.0/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= -github.com/zondax/hid v0.9.1-0.20220302062450-5552068d2266 h1:O9XLFXGkVswDFmH9LaYpqu+r/AAFWqr0DL6V00KEVFg= -github.com/zondax/hid v0.9.1-0.20220302062450-5552068d2266/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= +github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= +github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= github.com/zondax/ledger-go v0.12.1 h1:hYRcyznPRJp+5mzF2sazTLP2nGvGjYDD2VzhHhFomLU= github.com/zondax/ledger-go v0.12.1/go.mod h1:KatxXrVDzgWwbssUWsF5+cOJHXPvzQ09YSlzGNuhOEo= go.dedis.ch/fixbuf v1.0.3 h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs= @@ -1897,6 +1950,7 @@ golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/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= @@ -2071,6 +2125,7 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190523142557-0e01d883c5c5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190524122548-abf6ff778158/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190524152521-dbbf3f1254d4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190526052359-791d8a0f4d09/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/itests/deals_remote_retrieval_test.go b/itests/deals_remote_retrieval_test.go new file mode 100644 index 000000000..c0a37e69e --- /dev/null +++ b/itests/deals_remote_retrieval_test.go @@ -0,0 +1,104 @@ +package itests + +import ( + "bytes" + "context" + "fmt" + "io" + "net/url" + "os" + "path" + "testing" + "time" + + "github.com/google/uuid" + "github.com/gorilla/websocket" + "github.com/ipld/go-car" + "github.com/stretchr/testify/require" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + + "github.com/filecoin-project/lotus/api" + bstore "github.com/filecoin-project/lotus/blockstore" + "github.com/filecoin-project/lotus/itests/kit" +) + +func TestNetStoreRetrieval(t *testing.T) { + kit.QuietMiningLogs() + + blocktime := 5 * time.Millisecond + ctx := context.Background() + + full, miner, ens := kit.EnsembleMinimal(t, kit.MockProofs(), kit.ThroughRPC()) + ens.InterconnectAll().BeginMining(blocktime) + + time.Sleep(5 * time.Second) + + // 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) + + rseed := 7 + + dh := kit.NewDealHarness(t, full, miner, miner) + dealCid, res, _ := dh.MakeOnlineDeal(context.Background(), kit.MakeFullDealParams{ + Rseed: rseed, + StartEpoch: dealStartEpoch, + UseCARFileForStorageDeal: true, + }) + + // create deal store + id := uuid.New() + rstore := bstore.NewMemorySync() + + au, err := url.Parse(full.ListenURL) + require.NoError(t, err) + + switch au.Scheme { + case "http": + au.Scheme = "ws" + case "https": + au.Scheme = "wss" + } + + au.Path = path.Join(au.Path, "/rest/v0/store/"+id.String()) + + conn, _, err := websocket.DefaultDialer.Dial(au.String(), nil) + require.NoError(t, err) + + _ = bstore.HandleNetBstoreWS(ctx, rstore, conn) + + dh.PerformRetrievalWithOrder(ctx, dealCid, res.Root, false, func(offer api.QueryOffer, address address.Address) api.RetrievalOrder { + order := offer.Order(address) + + order.RemoteStore = &id + + return order + }) + + // check blockstore blocks + carv1FilePath, _ := kit.CreateRandomCARv1(t, rseed, 200) + cb, err := os.ReadFile(carv1FilePath) + require.NoError(t, err) + + cr, err := car.NewCarReader(bytes.NewReader(cb)) + require.NoError(t, err) + + var blocks int + for { + cb, err := cr.Next() + if err == io.EOF { + fmt.Println("blocks: ", blocks) + return + } + require.NoError(t, err) + + sb, err := rstore.Get(ctx, cb.Cid()) + require.NoError(t, err) + require.EqualValues(t, cb.RawData(), sb.RawData()) + + blocks++ + } +} diff --git a/itests/gateway_test.go b/itests/gateway_test.go index a7d9d353b..b9c861bf3 100644 --- a/itests/gateway_test.go +++ b/itests/gateway_test.go @@ -297,7 +297,7 @@ func startNodes( l, err := net.Listen("tcp", "127.0.0.1:0") require.NoError(t, err) - srv, _ := kit.CreateRPCServer(t, handler, l) + srv, _, _ := kit.CreateRPCServer(t, handler, l) // Create a gateway client API that connects to the gateway server var gapi api.Gateway diff --git a/itests/kit/deals.go b/itests/kit/deals.go index 794a63803..1f3a7dfb5 100644 --- a/itests/kit/deals.go +++ b/itests/kit/deals.go @@ -19,6 +19,7 @@ import ( "github.com/stretchr/testify/require" "golang.org/x/sync/errgroup" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-fil-markets/retrievalmarket" "github.com/filecoin-project/go-fil-markets/shared_testutil" "github.com/filecoin-project/go-fil-markets/storagemarket" @@ -308,6 +309,12 @@ func (dh *DealHarness) StartSealingWaiting(ctx context.Context) { } func (dh *DealHarness) PerformRetrieval(ctx context.Context, deal *cid.Cid, root cid.Cid, carExport bool, offers ...api.QueryOffer) (path string) { + return dh.PerformRetrievalWithOrder(ctx, deal, root, carExport, func(offer api.QueryOffer, a address.Address) api.RetrievalOrder { + return offer.Order(a) + }, offers...) +} + +func (dh *DealHarness) PerformRetrievalWithOrder(ctx context.Context, deal *cid.Cid, root cid.Cid, carExport bool, makeOrder func(api.QueryOffer, address.Address) api.RetrievalOrder, offers ...api.QueryOffer) (path string) { var offer api.QueryOffer if len(offers) == 0 { // perform retrieval. @@ -331,7 +338,9 @@ func (dh *DealHarness) PerformRetrieval(ctx context.Context, deal *cid.Cid, root updates, err := dh.client.ClientGetRetrievalUpdates(updatesCtx) require.NoError(dh.t, err) - retrievalRes, err := dh.client.ClientRetrieve(ctx, offer.Order(caddr)) + order := makeOrder(offer, caddr) + + retrievalRes, err := dh.client.ClientRetrieve(ctx, order) require.NoError(dh.t, err) consumeEvents: for { @@ -357,6 +366,11 @@ consumeEvents: } cancel() + if order.RemoteStore != nil { + // if we're retrieving into a remote store, skip export + return "" + } + require.NoError(dh.t, dh.client.ClientExport(ctx, api.ExportRef{ Root: root, diff --git a/itests/kit/ensemble.go b/itests/kit/ensemble.go index 8fa781e65..956d243a3 100644 --- a/itests/kit/ensemble.go +++ b/itests/kit/ensemble.go @@ -13,6 +13,7 @@ import ( "testing" "time" + "github.com/google/uuid" "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/namespace" libp2pcrypto "github.com/libp2p/go-libp2p/core/crypto" @@ -175,6 +176,16 @@ func (n *Ensemble) Mocknet() mocknet.Mocknet { return n.mn } +func (n *Ensemble) NewPrivKey() (libp2pcrypto.PrivKey, peer.ID) { + privkey, _, err := libp2pcrypto.GenerateEd25519Key(rand.Reader) + require.NoError(n.t, err) + + peerId, err := peer.IDFromPrivateKey(privkey) + require.NoError(n.t, err) + + return privkey, peerId +} + // FullNode enrolls a new full node. func (n *Ensemble) FullNode(full *TestFullNode, opts ...NodeOpt) *Ensemble { options := DefaultNodeOpts @@ -200,13 +211,14 @@ func (n *Ensemble) FullNode(full *TestFullNode, opts ...NodeOpt) *Ensemble { } *full = TestFullNode{t: n.t, options: options, DefaultKey: key} + n.inactive.fullnodes = append(n.inactive.fullnodes, full) return n } // Miner enrolls a new miner, using the provided full node for chain // interactions. -func (n *Ensemble) Miner(minerNode *TestMiner, full *TestFullNode, opts ...NodeOpt) *Ensemble { +func (n *Ensemble) MinerEnroll(minerNode *TestMiner, full *TestFullNode, opts ...NodeOpt) *Ensemble { require.NotNil(n.t, full, "full node required when instantiating miner") options := DefaultNodeOpts @@ -291,8 +303,16 @@ func (n *Ensemble) Miner(minerNode *TestMiner, full *TestFullNode, opts ...NodeO minerNode.Libp2p.PeerID = peerId minerNode.Libp2p.PrivKey = privkey - n.inactive.miners = append(n.inactive.miners, minerNode) + return n +} +func (n *Ensemble) AddInactiveMiner(m *TestMiner) { + n.inactive.miners = append(n.inactive.miners, m) +} + +func (n *Ensemble) Miner(minerNode *TestMiner, full *TestFullNode, opts ...NodeOpt) *Ensemble { + n.MinerEnroll(minerNode, full, opts...) + n.AddInactiveMiner(minerNode) return n } @@ -358,6 +378,21 @@ func (n *Ensemble) Start() *Ensemble { lr, err := r.Lock(repo.FullNode) require.NoError(n.t, err) + ks, err := lr.KeyStore() + require.NoError(n.t, err) + + if full.Pkey != nil { + pk, err := libp2pcrypto.MarshalPrivateKey(full.Pkey.PrivKey) + require.NoError(n.t, err) + + err = ks.Put("libp2p-host", types.KeyInfo{ + Type: "libp2p-host", + PrivateKey: pk, + }) + require.NoError(n.t, err) + + } + c, err := lr.Config() require.NoError(n.t, err) @@ -416,6 +451,7 @@ func (n *Ensemble) Start() *Ensemble { // Construct the full node. stop, err := node.New(ctx, opts...) + full.Stop = stop require.NoError(n.t, err) @@ -425,15 +461,31 @@ func (n *Ensemble) Start() *Ensemble { err = full.WalletSetDefault(context.Background(), addr) require.NoError(n.t, err) + var rpcShutdownOnce sync.Once + var stopOnce sync.Once + var stopErr error + + stopFunc := stop + stop = func(ctx context.Context) error { + stopOnce.Do(func() { + stopErr = stopFunc(ctx) + }) + return stopErr + } + // Are we hitting this node through its RPC? if full.options.rpc { - withRPC := fullRpc(n.t, full) + withRPC, rpcCloser := fullRpc(n.t, full) n.inactive.fullnodes[i] = withRPC + full.Stop = func(ctx2 context.Context) error { + rpcShutdownOnce.Do(rpcCloser) + return stop(ctx) + } + n.t.Cleanup(func() { rpcShutdownOnce.Do(rpcCloser) }) } n.t.Cleanup(func() { _ = stop(context.Background()) - }) n.active.fullnodes = append(n.active.fullnodes, full) @@ -477,7 +529,9 @@ func (n *Ensemble) Start() *Ensemble { Method: power.Methods.CreateMiner, Params: params, } - signed, err := m.FullNode.FullNode.MpoolPushMessage(ctx, createStorageMinerMsg, nil) + signed, err := m.FullNode.FullNode.MpoolPushMessage(ctx, createStorageMinerMsg, &api.MessageSendSpec{ + MsgUuid: uuid.New(), + }) require.NoError(n.t, err) mw, err := m.FullNode.FullNode.StateWaitMsg(ctx, signed.Cid(), build.MessageConfidence, api.LookbackNoLimit, true) @@ -501,7 +555,9 @@ func (n *Ensemble) Start() *Ensemble { Value: types.NewInt(0), } - signed, err2 := m.FullNode.FullNode.MpoolPushMessage(ctx, msg, nil) + signed, err2 := m.FullNode.FullNode.MpoolPushMessage(ctx, msg, &api.MessageSendSpec{ + MsgUuid: uuid.New(), + }) require.NoError(n.t, err2) mw, err2 := m.FullNode.FullNode.StateWaitMsg(ctx, signed.Cid(), build.MessageConfidence, api.LookbackNoLimit, true) @@ -586,11 +642,11 @@ func (n *Ensemble) Start() *Ensemble { psd := m.PresealDir noPaths := m.options.noStorage - err := lr.SetStorage(func(sc *paths.StorageConfig) { + err := lr.SetStorage(func(sc *storiface.StorageConfig) { if noPaths { - sc.StoragePaths = []paths.LocalPath{} + sc.StoragePaths = []storiface.LocalPath{} } - sc.StoragePaths = append(sc.StoragePaths, paths.LocalPath{Path: psd}) + sc.StoragePaths = append(sc.StoragePaths, storiface.LocalPath{Path: psd}) }) require.NoError(n.t, err) @@ -611,7 +667,9 @@ func (n *Ensemble) Start() *Ensemble { Value: types.NewInt(0), } - _, err2 := m.FullNode.MpoolPushMessage(ctx, msg, nil) + _, err2 := m.FullNode.MpoolPushMessage(ctx, msg, &api.MessageSendSpec{ + MsgUuid: uuid.New(), + }) require.NoError(n.t, err2) } @@ -620,6 +678,13 @@ func (n *Ensemble) Start() *Ensemble { disallowRemoteFinalize := m.options.disallowRemoteFinalize var mineBlock = make(chan lotusminer.MineReq) + + copy := *m.FullNode + copy.FullNode = modules.MakeUuidWrapper(copy.FullNode) + m.FullNode = © + + //m.FullNode.FullNode = modules.MakeUuidWrapper(fn.FullNode) + opts := []node.Option{ node.StorageMiner(&m.StorageMiner, cfg.Subsystems), node.Base(), @@ -627,12 +692,14 @@ func (n *Ensemble) Start() *Ensemble { node.Test(), node.If(m.options.disableLibp2p, node.MockHost(n.mn)), - node.Override(new(v1api.RawFullNodeAPI), m.FullNode.FullNode), + //node.Override(new(v1api.RawFullNodeAPI), func() api.FullNode { return modules.MakeUuidWrapper(m.FullNode) }), + //node.Override(new(v1api.RawFullNodeAPI), modules.MakeUuidWrapper), + node.Override(new(v1api.RawFullNodeAPI), m.FullNode), node.Override(new(*lotusminer.Miner), lotusminer.NewTestMiner(mineBlock, m.ActorAddr)), // disable resource filtering so that local worker gets assigned tasks // regardless of system pressure. - node.Override(new(sectorstorage.Config), func() sectorstorage.Config { + node.Override(new(config.SealerConfig), func() config.SealerConfig { scfg := config.DefaultStorageMiner() if noLocal { @@ -645,8 +712,8 @@ func (n *Ensemble) Start() *Ensemble { scfg.Storage.Assigner = assigner scfg.Storage.DisallowRemoteFinalize = disallowRemoteFinalize - scfg.Storage.ResourceFiltering = sectorstorage.ResourceFilteringDisabled - return scfg.StorageManager() + scfg.Storage.ResourceFiltering = config.ResourceFilteringDisabled + return scfg.Storage }), // upgrades @@ -737,8 +804,8 @@ func (n *Ensemble) Start() *Ensemble { require.NoError(n.t, err) if m.options.noStorage { - err := lr.SetStorage(func(sc *paths.StorageConfig) { - sc.StoragePaths = []paths.LocalPath{} + err := lr.SetStorage(func(sc *storiface.StorageConfig) { + sc.StoragePaths = []storiface.LocalPath{} }) require.NoError(n.t, err) } @@ -814,9 +881,9 @@ func (n *Ensemble) Start() *Ensemble { wait.Unlock() }) wait.Lock() + n.bootstrapped = true } - n.bootstrapped = true return n } diff --git a/itests/kit/node_full.go b/itests/kit/node_full.go index 710962e6a..12db91c68 100644 --- a/itests/kit/node_full.go +++ b/itests/kit/node_full.go @@ -6,6 +6,8 @@ import ( "testing" "time" + libp2pcrypto "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" "github.com/multiformats/go-multiaddr" "github.com/stretchr/testify/require" @@ -16,8 +18,15 @@ import ( "github.com/filecoin-project/lotus/api/v1api" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/wallet/key" + cliutil "github.com/filecoin-project/lotus/cli/util" + "github.com/filecoin-project/lotus/node" ) +type Libp2p struct { + PeerID peer.ID + PrivKey libp2pcrypto.PrivKey +} + // TestFullNode represents a full node enrolled in an Ensemble. type TestFullNode struct { v1api.FullNode @@ -27,11 +36,36 @@ type TestFullNode struct { // ListenAddr is the address on which an API server is listening, if an // API server is created for this Node. ListenAddr multiaddr.Multiaddr + ListenURL string DefaultKey *key.Key + Pkey *Libp2p + + Stop node.StopFunc + options nodeOpts } +func MergeFullNodes(fullNodes []*TestFullNode) *TestFullNode { + var wrappedFullNode TestFullNode + var fns api.FullNodeStruct + wrappedFullNode.FullNode = &fns + + cliutil.FullNodeProxy(fullNodes, &fns) + + wrappedFullNode.t = fullNodes[0].t + wrappedFullNode.ListenAddr = fullNodes[0].ListenAddr + wrappedFullNode.DefaultKey = fullNodes[0].DefaultKey + wrappedFullNode.Stop = fullNodes[0].Stop + wrappedFullNode.options = fullNodes[0].options + + return &wrappedFullNode +} + +func (f TestFullNode) Shutdown(ctx context.Context) error { + return f.Stop(ctx) +} + func (f *TestFullNode) ClientImportCARFile(ctx context.Context, rseed int, size int) (res *api.ImportRes, carv1FilePath string, origFilePath string) { carv1FilePath, origFilePath = CreateRandomCARv1(f.t, rseed, size) res, err := f.ClientImport(ctx, api.FileRef{Path: carv1FilePath, IsCAR: true}) @@ -86,6 +120,10 @@ func (f *TestFullNode) WaitForSectorActive(ctx context.Context, t *testing.T, sn } } +func (f *TestFullNode) AssignPrivKey(pkey *Libp2p) { + f.Pkey = pkey +} + // ChainPredicate encapsulates a chain condition. type ChainPredicate func(set *types.TipSet) bool diff --git a/itests/kit/node_miner.go b/itests/kit/node_miner.go index 83f6178f7..032cef87c 100644 --- a/itests/kit/node_miner.go +++ b/itests/kit/node_miner.go @@ -26,7 +26,6 @@ import ( "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/wallet/key" "github.com/filecoin-project/lotus/miner" - "github.com/filecoin-project/lotus/storage/paths" sealing "github.com/filecoin-project/lotus/storage/pipeline" "github.com/filecoin-project/lotus/storage/sealer/storiface" ) @@ -175,7 +174,7 @@ func (tm *TestMiner) FlushSealingBatches(ctx context.Context) { const metaFile = "sectorstore.json" -func (tm *TestMiner) AddStorage(ctx context.Context, t *testing.T, conf func(*paths.LocalStorageMeta)) storiface.ID { +func (tm *TestMiner) AddStorage(ctx context.Context, t *testing.T, conf func(*storiface.LocalStorageMeta)) storiface.ID { p := t.TempDir() if err := os.MkdirAll(p, 0755); err != nil { @@ -189,7 +188,7 @@ func (tm *TestMiner) AddStorage(ctx context.Context, t *testing.T, conf func(*pa require.NoError(t, err) } - cfg := &paths.LocalStorageMeta{ + cfg := &storiface.LocalStorageMeta{ ID: storiface.ID(uuid.New().String()), Weight: 10, CanSeal: false, diff --git a/itests/kit/node_worker.go b/itests/kit/node_worker.go index 3a6a55c55..ac200fb0f 100644 --- a/itests/kit/node_worker.go +++ b/itests/kit/node_worker.go @@ -15,7 +15,6 @@ import ( "github.com/stretchr/testify/require" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/storage/paths" "github.com/filecoin-project/lotus/storage/sealer/storiface" ) @@ -38,7 +37,7 @@ type TestWorker struct { options nodeOpts } -func (tm *TestWorker) AddStorage(ctx context.Context, t *testing.T, conf func(*paths.LocalStorageMeta)) storiface.ID { +func (tm *TestWorker) AddStorage(ctx context.Context, t *testing.T, conf func(*storiface.LocalStorageMeta)) storiface.ID { p := t.TempDir() if err := os.MkdirAll(p, 0755); err != nil { @@ -52,7 +51,7 @@ func (tm *TestWorker) AddStorage(ctx context.Context, t *testing.T, conf func(*p require.NoError(t, err) } - cfg := &paths.LocalStorageMeta{ + cfg := &storiface.LocalStorageMeta{ ID: storiface.ID(uuid.New().String()), Weight: 10, CanSeal: false, diff --git a/itests/kit/rpc.go b/itests/kit/rpc.go index 45fb095d5..684742ad3 100644 --- a/itests/kit/rpc.go +++ b/itests/kit/rpc.go @@ -7,7 +7,6 @@ import ( "net/http" "net/http/httptest" "testing" - "time" "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" @@ -18,63 +17,49 @@ import ( "github.com/filecoin-project/lotus/node" ) -func CreateRPCServer(t *testing.T, handler http.Handler, listener net.Listener) (*httptest.Server, multiaddr.Multiaddr) { +type Closer func() + +func CreateRPCServer(t *testing.T, handler http.Handler, listener net.Listener) (*httptest.Server, multiaddr.Multiaddr, Closer) { testServ := &httptest.Server{ Listener: listener, Config: &http.Server{Handler: handler}, } testServ.Start() - t.Cleanup(func() { - waitUpTo(testServ.Close, time.Second, "Gave up waiting for RPC server to close after 1s") - }) - t.Cleanup(testServ.CloseClientConnections) - addr := testServ.Listener.Addr() maddr, err := manet.FromNetAddr(addr) require.NoError(t, err) - return testServ, maddr -} - -func waitUpTo(fn func(), waitTime time.Duration, errMsg string) { - ch := make(chan struct{}) - go func() { - fn() - close(ch) - }() - - select { - case <-ch: - case <-time.After(waitTime): - fmt.Println(errMsg) - return + closer := func() { + testServ.CloseClientConnections() + testServ.Close() } + + return testServ, maddr, closer } -func fullRpc(t *testing.T, f *TestFullNode) *TestFullNode { +func fullRpc(t *testing.T, f *TestFullNode) (*TestFullNode, Closer) { handler, err := node.FullNodeHandler(f.FullNode, false) require.NoError(t, err) l, err := net.Listen("tcp", "127.0.0.1:0") require.NoError(t, err) - srv, maddr := CreateRPCServer(t, handler, l) + srv, maddr, rpcCloser := CreateRPCServer(t, handler, l) fmt.Printf("FULLNODE RPC ENV FOR CLI DEBUGGING `export FULLNODE_API_INFO=%s`\n", "ws://"+srv.Listener.Addr().String()) sendItestdNotif("FULLNODE_API_INFO", t.Name(), "ws://"+srv.Listener.Addr().String()) cl, stop, err := client.NewFullNodeRPCV1(context.Background(), "ws://"+srv.Listener.Addr().String()+"/rpc/v1", nil) require.NoError(t, err) - t.Cleanup(stop) - f.ListenAddr, f.FullNode = maddr, cl + f.ListenAddr, f.ListenURL, f.FullNode = maddr, srv.URL, cl - return f + return f, func() { stop(); rpcCloser() } } func minerRpc(t *testing.T, m *TestMiner) *TestMiner { handler, err := node.MinerHandler(m.StorageMiner, false) require.NoError(t, err) - srv, maddr := CreateRPCServer(t, handler, m.RemoteListener) + srv, maddr, _ := CreateRPCServer(t, handler, m.RemoteListener) fmt.Printf("creating RPC server for %s at %s\n", m.ActorAddr, srv.Listener.Addr().String()) fmt.Printf("SP RPC ENV FOR CLI DEBUGGING `export MINER_API_INFO=%s`\n", "ws://"+srv.Listener.Addr().String()) @@ -92,7 +77,7 @@ func minerRpc(t *testing.T, m *TestMiner) *TestMiner { func workerRpc(t *testing.T, m *TestWorker) *TestWorker { handler := sealworker.WorkerHandler(m.MinerNode.AuthVerify, m.FetchHandler, m.Worker, false) - srv, maddr := CreateRPCServer(t, handler, m.RemoteListener) + srv, maddr, _ := CreateRPCServer(t, handler, m.RemoteListener) fmt.Println("creating RPC server for a worker at: ", srv.Listener.Addr().String()) url := "ws://" + srv.Listener.Addr().String() + "/rpc/v0" diff --git a/itests/mpool_push_with_uuid_test.go b/itests/mpool_push_with_uuid_test.go new file mode 100644 index 000000000..6b94dbad1 --- /dev/null +++ b/itests/mpool_push_with_uuid_test.go @@ -0,0 +1,54 @@ +package itests + +import ( + "context" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/go-state-types/exitcode" + + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/itests/kit" + "github.com/filecoin-project/lotus/node/config" +) + +func TestMpoolPushWithoutUuidWithMaxFee(t *testing.T) { + //stm: @TOKEN_WALLET_SIGN_001, @CHAIN_MEMPOOL_PUSH_001 + ctx := context.Background() + + kit.QuietMiningLogs() + + client15, _, ens := kit.EnsembleMinimal(t, kit.MockProofs()) + ens.InterconnectAll().BeginMining(10 * time.Millisecond) + + bal, err := client15.WalletBalance(ctx, client15.DefaultKey.Address) + require.NoError(t, err) + + // send self half of account balance + msgHalfBal := &types.Message{ + From: client15.DefaultKey.Address, + To: client15.DefaultKey.Address, + Value: big.Div(bal, big.NewInt(2)), + } + smHalfBal, err := client15.MpoolPushMessage(ctx, msgHalfBal, &api.MessageSendSpec{MaxFee: abi.TokenAmount(config.DefaultDefaultMaxFee)}) + require.NoError(t, err) + mLookup, err := client15.StateWaitMsg(ctx, smHalfBal.Cid(), 3, api.LookbackNoLimit, true) + require.NoError(t, err) + require.Equal(t, exitcode.Ok, mLookup.Receipt.ExitCode) + + msgQuarterBal := &types.Message{ + From: client15.DefaultKey.Address, + To: client15.DefaultKey.Address, + Value: big.Div(bal, big.NewInt(4)), + } + smcid, err := client15.MpoolPushMessage(ctx, msgQuarterBal, &api.MessageSendSpec{MaxFee: abi.TokenAmount(config.DefaultDefaultMaxFee)}) + require.NoError(t, err) + mLookup, err = client15.StateWaitMsg(ctx, smcid.Cid(), 3, api.LookbackNoLimit, true) + require.NoError(t, err) + require.Equal(t, exitcode.Ok, mLookup.Receipt.ExitCode) +} diff --git a/itests/path_detach_redeclare_test.go b/itests/path_detach_redeclare_test.go index 124266b7d..10774d012 100644 --- a/itests/path_detach_redeclare_test.go +++ b/itests/path_detach_redeclare_test.go @@ -15,7 +15,6 @@ import ( "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/itests/kit" - "github.com/filecoin-project/lotus/storage/paths" "github.com/filecoin-project/lotus/storage/sealer/sealtasks" "github.com/filecoin-project/lotus/storage/sealer/storiface" ) @@ -74,7 +73,7 @@ func TestPathDetachRedeclare(t *testing.T) { checkSectors(ctx, t, client, miner, 2, 2) // attach a new path - newId := miner.AddStorage(ctx, t, func(cfg *paths.LocalStorageMeta) { + newId := miner.AddStorage(ctx, t, func(cfg *storiface.LocalStorageMeta) { cfg.CanStore = true }) @@ -194,7 +193,7 @@ func TestPathDetachRedeclareWorker(t *testing.T) { checkSectors(ctx, t, client, miner, 2, 2) // attach a new path - newId := sealw.AddStorage(ctx, t, func(cfg *paths.LocalStorageMeta) { + newId := sealw.AddStorage(ctx, t, func(cfg *storiface.LocalStorageMeta) { cfg.CanStore = true }) @@ -239,7 +238,7 @@ func TestPathDetachRedeclareWorker(t *testing.T) { require.Len(t, local, 0) // add a new one again, and move the sectors there - newId = sealw.AddStorage(ctx, t, func(cfg *paths.LocalStorageMeta) { + newId = sealw.AddStorage(ctx, t, func(cfg *storiface.LocalStorageMeta) { cfg.CanStore = true }) @@ -407,7 +406,7 @@ func checkSectors(ctx context.Context, t *testing.T, api kit.TestFullNode, miner require.Len(t, tocheck, expectChecked) - bad, err := miner.CheckProvable(ctx, info.WindowPoStProofType, tocheck, true) + bad, err := miner.CheckProvable(ctx, info.WindowPoStProofType, tocheck) require.NoError(t, err) require.Len(t, bad, expectBad) } diff --git a/itests/path_type_filters_test.go b/itests/path_type_filters_test.go index 03dd5ea16..d41e2c215 100644 --- a/itests/path_type_filters_test.go +++ b/itests/path_type_filters_test.go @@ -10,7 +10,6 @@ import ( "github.com/stretchr/testify/require" "github.com/filecoin-project/lotus/itests/kit" - "github.com/filecoin-project/lotus/storage/paths" "github.com/filecoin-project/lotus/storage/sealer/sealtasks" "github.com/filecoin-project/lotus/storage/sealer/storiface" ) @@ -45,7 +44,7 @@ func TestPathTypeFilters(t *testing.T) { } runTest(t, "invalid-type-alert", func(t *testing.T, ctx context.Context, miner *kit.TestMiner, run func()) { - slU := miner.AddStorage(ctx, t, func(meta *paths.LocalStorageMeta) { + slU := miner.AddStorage(ctx, t, func(meta *storiface.LocalStorageMeta) { meta.CanSeal = true meta.AllowTypes = []string{"unsealed", "seeled"} }) @@ -79,18 +78,18 @@ func TestPathTypeFilters(t *testing.T) { runTest(t, "seal-to-stor-unseal-allowdeny", func(t *testing.T, ctx context.Context, miner *kit.TestMiner, run func()) { // allow all types in the sealing path - sealScratch := miner.AddStorage(ctx, t, func(meta *paths.LocalStorageMeta) { + sealScratch := miner.AddStorage(ctx, t, func(meta *storiface.LocalStorageMeta) { meta.CanSeal = true }) // unsealed storage - unsStor := miner.AddStorage(ctx, t, func(meta *paths.LocalStorageMeta) { + unsStor := miner.AddStorage(ctx, t, func(meta *storiface.LocalStorageMeta) { meta.CanStore = true meta.AllowTypes = []string{"unsealed"} }) // other storage - sealStor := miner.AddStorage(ctx, t, func(meta *paths.LocalStorageMeta) { + sealStor := miner.AddStorage(ctx, t, func(meta *storiface.LocalStorageMeta) { meta.CanStore = true meta.DenyTypes = []string{"unsealed"} }) @@ -115,14 +114,14 @@ func TestPathTypeFilters(t *testing.T) { runTest(t, "sealstor-unseal-allowdeny", func(t *testing.T, ctx context.Context, miner *kit.TestMiner, run func()) { // unsealed storage - unsStor := miner.AddStorage(ctx, t, func(meta *paths.LocalStorageMeta) { + unsStor := miner.AddStorage(ctx, t, func(meta *storiface.LocalStorageMeta) { meta.CanStore = true meta.CanSeal = true meta.AllowTypes = []string{"unsealed"} }) // other storage - sealStor := miner.AddStorage(ctx, t, func(meta *paths.LocalStorageMeta) { + sealStor := miner.AddStorage(ctx, t, func(meta *storiface.LocalStorageMeta) { meta.CanStore = true meta.CanSeal = true meta.DenyTypes = []string{"unsealed"} @@ -147,29 +146,29 @@ func TestPathTypeFilters(t *testing.T) { runTest(t, "seal-store-allseparate", func(t *testing.T, ctx context.Context, miner *kit.TestMiner, run func()) { // sealing stores - slU := miner.AddStorage(ctx, t, func(meta *paths.LocalStorageMeta) { + slU := miner.AddStorage(ctx, t, func(meta *storiface.LocalStorageMeta) { meta.CanSeal = true meta.AllowTypes = []string{"unsealed"} }) - slS := miner.AddStorage(ctx, t, func(meta *paths.LocalStorageMeta) { + slS := miner.AddStorage(ctx, t, func(meta *storiface.LocalStorageMeta) { meta.CanSeal = true meta.AllowTypes = []string{"sealed"} }) - slC := miner.AddStorage(ctx, t, func(meta *paths.LocalStorageMeta) { + slC := miner.AddStorage(ctx, t, func(meta *storiface.LocalStorageMeta) { meta.CanSeal = true meta.AllowTypes = []string{"cache"} }) // storage stores - stU := miner.AddStorage(ctx, t, func(meta *paths.LocalStorageMeta) { + stU := miner.AddStorage(ctx, t, func(meta *storiface.LocalStorageMeta) { meta.CanStore = true meta.AllowTypes = []string{"unsealed"} }) - stS := miner.AddStorage(ctx, t, func(meta *paths.LocalStorageMeta) { + stS := miner.AddStorage(ctx, t, func(meta *storiface.LocalStorageMeta) { meta.CanStore = true meta.AllowTypes = []string{"sealed"} }) - stC := miner.AddStorage(ctx, t, func(meta *paths.LocalStorageMeta) { + stC := miner.AddStorage(ctx, t, func(meta *storiface.LocalStorageMeta) { meta.CanStore = true meta.AllowTypes = []string{"cache"} }) diff --git a/itests/raft_messagesigner_test.go b/itests/raft_messagesigner_test.go new file mode 100644 index 000000000..f94095b90 --- /dev/null +++ b/itests/raft_messagesigner_test.go @@ -0,0 +1,577 @@ +package itests + +import ( + "context" + "crypto/rand" + "fmt" + "reflect" + "testing" + "time" + + "github.com/google/uuid" + gorpc "github.com/libp2p/go-libp2p-gorpc" + libp2pcrypto "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/stretchr/testify/require" + + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/go-state-types/exitcode" + + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/messagesigner" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/itests/kit" + consensus "github.com/filecoin-project/lotus/lib/consensus/raft" + "github.com/filecoin-project/lotus/node" + "github.com/filecoin-project/lotus/node/config" + "github.com/filecoin-project/lotus/node/impl" + "github.com/filecoin-project/lotus/node/modules" +) + +func generatePrivKey() (*kit.Libp2p, error) { + privkey, _, err := libp2pcrypto.GenerateEd25519Key(rand.Reader) + if err != nil { + return nil, err + } + + peerId, err := peer.IDFromPrivateKey(privkey) + if err != nil { + return nil, err + } + + return &kit.Libp2p{PeerID: peerId, PrivKey: privkey}, nil +} + +func getRaftState(ctx context.Context, t *testing.T, node *kit.TestFullNode) *api.RaftStateData { + raftState, err := node.RaftState(ctx) + require.NoError(t, err) + return raftState +} + +func setup(ctx context.Context, t *testing.T, node0 *kit.TestFullNode, node1 *kit.TestFullNode, node2 *kit.TestFullNode, miner *kit.TestMiner) *kit.Ensemble { + + blockTime := 1 * time.Second + + pkey0, _ := generatePrivKey() + pkey1, _ := generatePrivKey() + pkey2, _ := generatePrivKey() + + pkeys := []*kit.Libp2p{pkey0, pkey1, pkey2} + initPeerSet := []string{} + for _, pkey := range pkeys { + initPeerSet = append(initPeerSet, "/p2p/"+pkey.PeerID.String()) + } + + //initPeerSet := []peer.ID{pkey0.PeerID, pkey1.PeerID, pkey2.PeerID} + + raftOps := kit.ConstructorOpts( + node.Override(new(*gorpc.Client), modules.NewRPCClient), + node.Override(new(*consensus.ClusterRaftConfig), func() *consensus.ClusterRaftConfig { + cfg := consensus.DefaultClusterRaftConfig() + cfg.InitPeerset = initPeerSet + return cfg + }), + node.Override(new(*consensus.Consensus), consensus.NewConsensusWithRPCClient(false)), + node.Override(new(*messagesigner.MessageSignerConsensus), messagesigner.NewMessageSignerConsensus), + node.Override(new(messagesigner.MsgSigner), func(ms *messagesigner.MessageSignerConsensus) *messagesigner.MessageSignerConsensus { return ms }), + node.Override(new(*modules.RPCHandler), modules.NewRPCHandler), + node.Override(node.GoRPCServer, modules.NewRPCServer), + ) + //raftOps := kit.ConstructorOpts() + kit.ThroughRPC() + + ens := kit.NewEnsemble(t).FullNode(node0, raftOps, kit.ThroughRPC()).FullNode(node1, raftOps, kit.ThroughRPC()).FullNode(node2, raftOps, kit.ThroughRPC()) + node0.AssignPrivKey(pkey0) + node1.AssignPrivKey(pkey1) + node2.AssignPrivKey(pkey2) + + nodes := []*kit.TestFullNode{node0, node1, node2} + wrappedFullNode := kit.MergeFullNodes(nodes) + + ens.MinerEnroll(miner, wrappedFullNode, kit.WithAllSubsystems(), kit.ThroughRPC()) + ens.Start() + + // Import miner wallet to all nodes + addr0, err := node0.WalletImport(ctx, &miner.OwnerKey.KeyInfo) + require.NoError(t, err) + addr1, err := node1.WalletImport(ctx, &miner.OwnerKey.KeyInfo) + require.NoError(t, err) + addr2, err := node2.WalletImport(ctx, &miner.OwnerKey.KeyInfo) + require.NoError(t, err) + + fmt.Println(addr0, addr1, addr2) + + ens.InterconnectAll() + + ens.AddInactiveMiner(miner) + ens.Start() + + ens.InterconnectAll().BeginMining(blockTime) + + return ens +} + +func TestRaftState(t *testing.T) { + + kit.QuietMiningLogs() + ctx := context.Background() + + var ( + node0 kit.TestFullNode + node1 kit.TestFullNode + node2 kit.TestFullNode + miner kit.TestMiner + ) + + setup(ctx, t, &node0, &node1, &node2, &miner) + + fmt.Println(node0.WalletList(context.Background())) + fmt.Println(node1.WalletList(context.Background())) + fmt.Println(node2.WalletList(context.Background())) + + bal, err := node0.WalletBalance(ctx, node0.DefaultKey.Address) + require.NoError(t, err) + + msgHalfBal := &types.Message{ + From: miner.OwnerKey.Address, + To: node0.DefaultKey.Address, + Value: big.Div(bal, big.NewInt(2)), + } + + mu := uuid.New() + smHalfBal, err := node0.MpoolPushMessage(ctx, msgHalfBal, &api.MessageSendSpec{ + MsgUuid: mu, + }) + require.NoError(t, err) + mLookup, err := node0.StateWaitMsg(ctx, smHalfBal.Cid(), 3, api.LookbackNoLimit, true) + require.NoError(t, err) + require.Equal(t, exitcode.Ok, mLookup.Receipt.ExitCode) + + rstate0 := getRaftState(ctx, t, &node0) + rstate1 := getRaftState(ctx, t, &node1) + rstate2 := getRaftState(ctx, t, &node2) + + require.EqualValues(t, rstate0, rstate1) + require.EqualValues(t, rstate0, rstate2) +} + +func TestRaftStateLeaderDisconnects(t *testing.T) { + + kit.QuietMiningLogs() + ctx := context.Background() + + var ( + node0 kit.TestFullNode + node1 kit.TestFullNode + node2 kit.TestFullNode + miner kit.TestMiner + ) + + nodes := []*kit.TestFullNode{&node0, &node1, &node2} + + setup(ctx, t, &node0, &node1, &node2, &miner) + + peerToNode := make(map[peer.ID]*kit.TestFullNode) + for _, n := range nodes { + peerToNode[n.Pkey.PeerID] = n + } + + bal, err := node0.WalletBalance(ctx, node0.DefaultKey.Address) + require.NoError(t, err) + + msgHalfBal := &types.Message{ + From: miner.OwnerKey.Address, + To: node0.DefaultKey.Address, + Value: big.Div(bal, big.NewInt(2)), + } + mu := uuid.New() + smHalfBal, err := node0.MpoolPushMessage(ctx, msgHalfBal, &api.MessageSendSpec{ + MsgUuid: mu, + }) + require.NoError(t, err) + mLookup, err := node0.StateWaitMsg(ctx, smHalfBal.Cid(), 3, api.LookbackNoLimit, true) + require.NoError(t, err) + require.Equal(t, exitcode.Ok, mLookup.Receipt.ExitCode) + + rstate0 := getRaftState(ctx, t, &node0) + rstate1 := getRaftState(ctx, t, &node1) + rstate2 := getRaftState(ctx, t, &node2) + + require.True(t, reflect.DeepEqual(rstate0, rstate1)) + require.True(t, reflect.DeepEqual(rstate0, rstate2)) + + leader, err := node1.RaftLeader(ctx) + require.NoError(t, err) + leaderNode := peerToNode[leader] + + err = leaderNode.Stop(ctx) + require.NoError(t, err) + oldLeaderNode := leaderNode + + time.Sleep(5 * time.Second) + + newLeader := leader + for _, n := range nodes { + if n != leaderNode { + newLeader, err = n.RaftLeader(ctx) + require.NoError(t, err) + require.NotEqual(t, newLeader, leader) + } + } + + require.NotEqual(t, newLeader, leader) + leaderNode = peerToNode[newLeader] + + msg2 := &types.Message{ + From: miner.OwnerKey.Address, + To: leaderNode.DefaultKey.Address, + Value: big.NewInt(100000), + } + mu2 := uuid.New() + signedMsg2, err := leaderNode.MpoolPushMessage(ctx, msg2, &api.MessageSendSpec{ + MsgUuid: mu2, + }) + require.NoError(t, err) + mLookup, err = leaderNode.StateWaitMsg(ctx, signedMsg2.Cid(), 3, api.LookbackNoLimit, true) + require.NoError(t, err) + require.Equal(t, exitcode.Ok, mLookup.Receipt.ExitCode) + + rstate := getRaftState(ctx, t, leaderNode) + + for _, n := range nodes { + if n != oldLeaderNode { + rs := getRaftState(ctx, t, n) + require.True(t, reflect.DeepEqual(rs, rstate)) + } + } +} + +func TestRaftStateMiner(t *testing.T) { + + kit.QuietMiningLogs() + ctx := context.Background() + + var ( + node0 kit.TestFullNode + node1 kit.TestFullNode + node2 kit.TestFullNode + miner kit.TestMiner + ) + + setup(ctx, t, &node0, &node1, &node2, &miner) + + fmt.Println(node0.WalletList(context.Background())) + fmt.Println(node1.WalletList(context.Background())) + fmt.Println(node2.WalletList(context.Background())) + + bal, err := node0.WalletBalance(ctx, node0.DefaultKey.Address) + require.NoError(t, err) + + msgHalfBal := &types.Message{ + From: miner.OwnerKey.Address, + To: node0.DefaultKey.Address, + Value: big.Div(bal, big.NewInt(2)), + } + mu := uuid.New() + smHalfBal, err := miner.FullNode.MpoolPushMessage(ctx, msgHalfBal, &api.MessageSendSpec{ + MsgUuid: mu, + }) + require.NoError(t, err) + mLookup, err := node0.StateWaitMsg(ctx, smHalfBal.Cid(), 3, api.LookbackNoLimit, true) + require.NoError(t, err) + require.Equal(t, exitcode.Ok, mLookup.Receipt.ExitCode) + + rstate0 := getRaftState(ctx, t, &node0) + rstate1 := getRaftState(ctx, t, &node1) + rstate2 := getRaftState(ctx, t, &node2) + + require.EqualValues(t, rstate0, rstate1) + require.EqualValues(t, rstate0, rstate2) +} + +func TestRaftStateLeaderDisconnectsMiner(t *testing.T) { + + kit.QuietMiningLogs() + ctx := context.Background() + + var ( + node0 kit.TestFullNode + node1 kit.TestFullNode + node2 kit.TestFullNode + miner kit.TestMiner + ) + + nodes := []*kit.TestFullNode{&node0, &node1, &node2} + + setup(ctx, t, &node0, &node1, &node2, &miner) + + peerToNode := make(map[peer.ID]*kit.TestFullNode) + for _, n := range nodes { + peerToNode[n.Pkey.PeerID] = n + } + + leader, err := node0.RaftLeader(ctx) + require.NoError(t, err) + leaderNode := peerToNode[leader] + + // Take leader node down + err = leaderNode.Stop(ctx) + require.NoError(t, err) + oldLeaderNode := leaderNode + + time.Sleep(5 * time.Second) + + newLeader := leader + for _, n := range nodes { + if n != leaderNode { + newLeader, err = n.RaftLeader(ctx) + require.NoError(t, err) + require.NotEqual(t, newLeader, leader) + } + } + + require.NotEqual(t, newLeader, leader) + leaderNode = peerToNode[newLeader] + + msg2 := &types.Message{ + From: miner.OwnerKey.Address, + To: node0.DefaultKey.Address, + Value: big.NewInt(100000), + } + mu2 := uuid.New() + + signedMsg2, err := miner.FullNode.MpoolPushMessage(ctx, msg2, &api.MessageSendSpec{ + MaxFee: abi.TokenAmount(config.DefaultDefaultMaxFee), + MsgUuid: mu2, + }) + require.NoError(t, err) + + mLookup, err := leaderNode.StateWaitMsg(ctx, signedMsg2.Cid(), 3, api.LookbackNoLimit, true) + require.NoError(t, err) + require.Equal(t, exitcode.Ok, mLookup.Receipt.ExitCode) + + rstate := getRaftState(ctx, t, leaderNode) + + for _, n := range nodes { + if n != oldLeaderNode { + rs := getRaftState(ctx, t, n) + require.True(t, reflect.DeepEqual(rs, rstate)) + } + } +} + +// Miner sends message on leader +// Leader disconnects +// Call StateWaitMsg on new leader +func TestLeaderDisconnectsCheckMsgStateOnNewLeader(t *testing.T) { + + kit.QuietMiningLogs() + ctx := context.Background() + + var ( + node0 kit.TestFullNode + node1 kit.TestFullNode + node2 kit.TestFullNode + miner kit.TestMiner + ) + + nodes := []*kit.TestFullNode{&node0, &node1, &node2} + + setup(ctx, t, &node0, &node1, &node2, &miner) + + peerToNode := make(map[peer.ID]*kit.TestFullNode) + for _, n := range nodes { + peerToNode[n.Pkey.PeerID] = n + } + + bal, err := node0.WalletBalance(ctx, node0.DefaultKey.Address) + require.NoError(t, err) + + msgHalfBal := &types.Message{ + From: miner.OwnerKey.Address, + To: node0.DefaultKey.Address, + Value: big.Div(bal, big.NewInt(2)), + } + mu := uuid.New() + smHalfBal, err := miner.FullNode.MpoolPushMessage(ctx, msgHalfBal, &api.MessageSendSpec{ + MsgUuid: mu, + }) + require.NoError(t, err) + + leader, err := node0.RaftLeader(ctx) + require.NoError(t, err) + leaderNode := peerToNode[leader] + + // Take leader node down + err = leaderNode.Stop(ctx) + require.NoError(t, err) + oldLeaderNode := leaderNode + + time.Sleep(5 * time.Second) + + // Check if all active nodes update their leader + newLeader := leader + for _, n := range nodes { + if n != leaderNode { + newLeader, err = n.RaftLeader(ctx) + require.NoError(t, err) + require.NotEqual(t, newLeader, leader) + } + } + + require.NotEqual(t, newLeader, leader) + leaderNode = peerToNode[newLeader] + + mLookup, err := leaderNode.StateWaitMsg(ctx, smHalfBal.Cid(), 3, api.LookbackNoLimit, true) + require.NoError(t, err) + require.Equal(t, exitcode.Ok, mLookup.Receipt.ExitCode) + + rstate := getRaftState(ctx, t, leaderNode) + + // Check if Raft state is consistent on all active nodes + for _, n := range nodes { + if n != oldLeaderNode { + rs := getRaftState(ctx, t, n) + require.True(t, reflect.DeepEqual(rs, rstate)) + } + } +} + +func TestChainStoreSync(t *testing.T) { + + kit.QuietMiningLogs() + ctx := context.Background() + + var ( + node0 kit.TestFullNode + node1 kit.TestFullNode + node2 kit.TestFullNode + miner kit.TestMiner + ) + + nodes := []*kit.TestFullNode{&node0, &node1, &node2} + + setup(ctx, t, &node0, &node1, &node2, &miner) + + peerToNode := make(map[peer.ID]*kit.TestFullNode) + for _, n := range nodes { + peerToNode[n.Pkey.PeerID] = n + } + + bal, err := node0.WalletBalance(ctx, node0.DefaultKey.Address) + require.NoError(t, err) + + leader, err := node0.RaftLeader(ctx) + require.NoError(t, err) + leaderNode := peerToNode[leader] + + msgHalfBal := &types.Message{ + From: miner.OwnerKey.Address, + To: node0.DefaultKey.Address, + Value: big.Div(bal, big.NewInt(2)), + } + mu := uuid.New() + smHalfBal, err := miner.FullNode.MpoolPushMessage(ctx, msgHalfBal, &api.MessageSendSpec{ + MsgUuid: mu, + }) + require.NoError(t, err) + + for _, n := range nodes { + fmt.Println(n != leaderNode) + if n != leaderNode { + mLookup, err := n.StateWaitMsg(ctx, smHalfBal.Cid(), 3, api.LookbackNoLimit, true) + require.NoError(t, err) + require.Equal(t, exitcode.Ok, mLookup.Receipt.ExitCode) + //break + } + } +} + +func TestGoRPCAuth(t *testing.T) { + + blockTime := 1 * time.Second + + kit.QuietMiningLogs() + ctx := context.Background() + + var ( + node0 kit.TestFullNode + node1 kit.TestFullNode + node2 kit.TestFullNode + node3 kit.TestFullNode + miner kit.TestMiner + ) + + pkey0, _ := generatePrivKey() + pkey1, _ := generatePrivKey() + pkey2, _ := generatePrivKey() + + pkeys := []*kit.Libp2p{pkey0, pkey1, pkey2} + initPeerSet := []string{} + for _, pkey := range pkeys { + initPeerSet = append(initPeerSet, "/p2p/"+pkey.PeerID.String()) + } + + raftOps := kit.ConstructorOpts( + node.Override(new(*gorpc.Client), modules.NewRPCClient), + node.Override(new(*consensus.ClusterRaftConfig), func() *consensus.ClusterRaftConfig { + cfg := consensus.DefaultClusterRaftConfig() + cfg.InitPeerset = initPeerSet + return cfg + }), + node.Override(new(*consensus.Consensus), consensus.NewConsensusWithRPCClient(false)), + node.Override(new(*messagesigner.MessageSignerConsensus), messagesigner.NewMessageSignerConsensus), + node.Override(new(messagesigner.MsgSigner), func(ms *messagesigner.MessageSignerConsensus) *messagesigner.MessageSignerConsensus { return ms }), + node.Override(new(*modules.RPCHandler), modules.NewRPCHandler), + node.Override(node.GoRPCServer, modules.NewRPCServer), + ) + //raftOps := kit.ConstructorOpts() + kit.ThroughRPC() + + ens := kit.NewEnsemble(t).FullNode(&node0, raftOps, kit.ThroughRPC()).FullNode(&node1, raftOps, kit.ThroughRPC()).FullNode(&node2, raftOps, kit.ThroughRPC()).FullNode(&node3, raftOps) + node0.AssignPrivKey(pkey0) + node1.AssignPrivKey(pkey1) + node2.AssignPrivKey(pkey2) + + nodes := []*kit.TestFullNode{&node0, &node1, &node2} + wrappedFullNode := kit.MergeFullNodes(nodes) + + ens.MinerEnroll(&miner, wrappedFullNode, kit.WithAllSubsystems(), kit.ThroughRPC()) + ens.Start() + + // Import miner wallet to all nodes + addr0, err := node0.WalletImport(ctx, &miner.OwnerKey.KeyInfo) + require.NoError(t, err) + addr1, err := node1.WalletImport(ctx, &miner.OwnerKey.KeyInfo) + require.NoError(t, err) + addr2, err := node2.WalletImport(ctx, &miner.OwnerKey.KeyInfo) + require.NoError(t, err) + + fmt.Println(addr0, addr1, addr2) + + ens.InterconnectAll() + + ens.AddInactiveMiner(&miner) + ens.Start() + + ens.InterconnectAll().BeginMining(blockTime) + + leader, err := node0.RaftLeader(ctx) + require.NoError(t, err) + + client := node3.FullNode.(*impl.FullNodeAPI).RaftAPI.MessageSigner.Consensus.RpcClient + method := "MpoolPushMessage" + + msg := &types.Message{ + From: miner.OwnerKey.Address, + To: node0.DefaultKey.Address, + Value: big.NewInt(100000), + } + msgWhole := &api.MpoolMessageWhole{Msg: msg} + var ret types.SignedMessage + + err = client.CallContext(ctx, leader, "Consensus", method, msgWhole, &ret) + require.True(t, gorpc.IsAuthorizationError(err)) + +} diff --git a/itests/sector_finalize_early_test.go b/itests/sector_finalize_early_test.go index 8678e6a28..fb7d9d94d 100644 --- a/itests/sector_finalize_early_test.go +++ b/itests/sector_finalize_early_test.go @@ -11,7 +11,7 @@ import ( "github.com/filecoin-project/lotus/itests/kit" "github.com/filecoin-project/lotus/node/config" - "github.com/filecoin-project/lotus/storage/paths" + "github.com/filecoin-project/lotus/storage/sealer/storiface" ) func TestDealsWithFinalizeEarly(t *testing.T) { @@ -36,11 +36,11 @@ func TestDealsWithFinalizeEarly(t *testing.T) { ctx := context.Background() - miner.AddStorage(ctx, t, func(meta *paths.LocalStorageMeta) { + miner.AddStorage(ctx, t, func(meta *storiface.LocalStorageMeta) { meta.Weight = 1000000000 meta.CanSeal = true }) - miner.AddStorage(ctx, t, func(meta *paths.LocalStorageMeta) { + miner.AddStorage(ctx, t, func(meta *storiface.LocalStorageMeta) { meta.Weight = 1000000000 meta.CanStore = true }) diff --git a/itests/wdpost_worker_config_test.go b/itests/wdpost_worker_config_test.go index a84896eae..d1672c20f 100644 --- a/itests/wdpost_worker_config_test.go +++ b/itests/wdpost_worker_config_test.go @@ -17,7 +17,6 @@ import ( "github.com/filecoin-project/lotus/node/config" "github.com/filecoin-project/lotus/node/impl" "github.com/filecoin-project/lotus/node/modules" - "github.com/filecoin-project/lotus/storage/sealer" "github.com/filecoin-project/lotus/storage/sealer/sealtasks" "github.com/filecoin-project/lotus/storage/sealer/storiface" "github.com/filecoin-project/lotus/storage/wdpost" @@ -35,10 +34,10 @@ func TestWindowPostNoBuiltinWindow(t *testing.T) { kit.PresealSectors(sectors), // 2 sectors per partition, 2 partitions in all 48 deadlines kit.LatestActorsAt(-1), kit.ConstructorOpts( - node.Override(new(sealer.Config), func() sealer.Config { - c := config.DefaultStorageMiner().StorageManager() - c.DisableBuiltinWindowPoSt = true - return c + node.Override(new(config.ProvingConfig), func() config.ProvingConfig { + c := config.DefaultStorageMiner() + c.Proving.DisableBuiltinWindowPoSt = true + return c.Proving }), node.Override(new(*wdpost.WindowPoStScheduler), modules.WindowPostScheduler( config.DefaultStorageMiner().Fees, @@ -92,10 +91,10 @@ func TestWindowPostNoBuiltinWindowWithWorker(t *testing.T) { kit.PresealSectors(sectors), // 2 sectors per partition, 2 partitions in all 48 deadlines kit.LatestActorsAt(-1), kit.ConstructorOpts( - node.Override(new(sealer.Config), func() sealer.Config { - c := config.DefaultStorageMiner().StorageManager() - c.DisableBuiltinWindowPoSt = true - return c + node.Override(new(config.ProvingConfig), func() config.ProvingConfig { + c := config.DefaultStorageMiner() + c.Proving.DisableBuiltinWindowPoSt = true + return c.Proving }), node.Override(new(*wdpost.WindowPoStScheduler), modules.WindowPostScheduler( config.DefaultStorageMiner().Fees, diff --git a/itests/worker_test.go b/itests/worker_test.go index 5b26f481c..2e3722884 100644 --- a/itests/worker_test.go +++ b/itests/worker_test.go @@ -408,10 +408,10 @@ func TestWindowPostWorkerManualPoSt(t *testing.T) { func TestSchedulerRemoveRequest(t *testing.T) { ctx := context.Background() - _, miner, worker, ens := kit.EnsembleWorker(t, kit.WithAllSubsystems(), kit.ThroughRPC(), kit.WithNoLocalSealing(true), + _, miner, worker, _ := kit.EnsembleWorker(t, kit.WithAllSubsystems(), kit.ThroughRPC(), kit.WithNoLocalSealing(true), kit.WithTaskTypes([]sealtasks.TaskType{sealtasks.TTFetch, sealtasks.TTCommit1, sealtasks.TTFinalize, sealtasks.TTDataCid, sealtasks.TTAddPiece, sealtasks.TTPreCommit1, sealtasks.TTCommit2, sealtasks.TTUnseal})) // no mock proofs - ens.InterconnectAll().BeginMining(50 * time.Millisecond) + //ens.InterconnectAll().BeginMining(50 * time.Millisecond) e, err := worker.Enabled(ctx) require.NoError(t, err) diff --git a/lib/consensus/raft/config.go b/lib/consensus/raft/config.go new file mode 100644 index 000000000..983e4cc4d --- /dev/null +++ b/lib/consensus/raft/config.go @@ -0,0 +1,135 @@ +package consensus + +import ( + "io/ioutil" + "path/filepath" + "time" + + hraft "github.com/hashicorp/raft" + "golang.org/x/xerrors" + + "github.com/filecoin-project/lotus/node/config" + "github.com/filecoin-project/lotus/node/repo" +) + +// Configuration defaults +var ( + DefaultDataSubFolder = "raft-cluster" + DefaultWaitForLeaderTimeout = 15 * time.Second + DefaultCommitRetries = 1 + DefaultNetworkTimeout = 100 * time.Second + DefaultCommitRetryDelay = 200 * time.Millisecond + DefaultBackupsRotate = 6 +) + +// ClusterRaftConfig allows to configure the Raft Consensus component for the node cluster. +type ClusterRaftConfig struct { + // config to enabled node cluster with raft consensus + ClusterModeEnabled bool + // A folder to store Raft's data. + DataFolder string + // InitPeerset provides the list of initial cluster peers for new Raft + // peers (with no prior state). It is ignored when Raft was already + // initialized or when starting in staging mode. + InitPeerset []string + // LeaderTimeout specifies how long to wait for a leader before + // failing an operation. + WaitForLeaderTimeout time.Duration + // NetworkTimeout specifies how long before a Raft network + // operation is timed out + NetworkTimeout time.Duration + // CommitRetries specifies how many times we retry a failed commit until + // we give up. + CommitRetries int + // How long to wait between retries + CommitRetryDelay time.Duration + // BackupsRotate specifies the maximum number of Raft's DataFolder + // copies that we keep as backups (renaming) after cleanup. + BackupsRotate int + // A Hashicorp Raft's configuration object. + RaftConfig *hraft.Config + + // Tracing enables propagation of contexts across binary boundaries. + Tracing bool +} + +func DefaultClusterRaftConfig() *ClusterRaftConfig { + var cfg ClusterRaftConfig + cfg.DataFolder = "" // empty so it gets omitted + cfg.InitPeerset = []string{} + cfg.WaitForLeaderTimeout = DefaultWaitForLeaderTimeout + cfg.NetworkTimeout = DefaultNetworkTimeout + cfg.CommitRetries = DefaultCommitRetries + cfg.CommitRetryDelay = DefaultCommitRetryDelay + cfg.BackupsRotate = DefaultBackupsRotate + cfg.RaftConfig = hraft.DefaultConfig() + + // These options are imposed over any Default Raft Config. + cfg.RaftConfig.ShutdownOnRemove = false + cfg.RaftConfig.LocalID = "will_be_set_automatically" + + // Set up logging + cfg.RaftConfig.LogOutput = ioutil.Discard + return &cfg +} + +func NewClusterRaftConfig(userRaftConfig *config.UserRaftConfig) *ClusterRaftConfig { + var cfg ClusterRaftConfig + cfg.DataFolder = userRaftConfig.DataFolder + cfg.InitPeerset = userRaftConfig.InitPeersetMultiAddr + cfg.WaitForLeaderTimeout = time.Duration(userRaftConfig.WaitForLeaderTimeout) + cfg.NetworkTimeout = time.Duration(userRaftConfig.NetworkTimeout) + cfg.CommitRetries = userRaftConfig.CommitRetries + cfg.CommitRetryDelay = time.Duration(userRaftConfig.CommitRetryDelay) + cfg.BackupsRotate = userRaftConfig.BackupsRotate + + // Keep this to be default hraft config for now + cfg.RaftConfig = hraft.DefaultConfig() + + // These options are imposed over any Default Raft Config. + cfg.RaftConfig.ShutdownOnRemove = false + cfg.RaftConfig.LocalID = "will_be_set_automatically" + + // Set up logging + cfg.RaftConfig.LogOutput = ioutil.Discard + + return &cfg + +} + +// // Validate checks that this configuration has working values, +// // at least in appearance. +func ValidateConfig(cfg *ClusterRaftConfig) error { + if cfg.RaftConfig == nil { + return xerrors.Errorf("no hashicorp/raft.Config") + } + if cfg.WaitForLeaderTimeout <= 0 { + return xerrors.Errorf("wait_for_leader_timeout <= 0") + } + + if cfg.NetworkTimeout <= 0 { + return xerrors.Errorf("network_timeout <= 0") + } + + if cfg.CommitRetries < 0 { + return xerrors.Errorf("commit_retries is invalid") + } + + if cfg.CommitRetryDelay <= 0 { + return xerrors.Errorf("commit_retry_delay is invalid") + } + + if cfg.BackupsRotate <= 0 { + return xerrors.Errorf("backups_rotate should be larger than 0") + } + + return hraft.ValidateConfig(cfg.RaftConfig) +} + +// GetDataFolder returns the Raft data folder that we are using. +func (cfg *ClusterRaftConfig) GetDataFolder(repo repo.LockedRepo) string { + if cfg.DataFolder == "" { + return filepath.Join(repo.Path(), DefaultDataSubFolder) + } + return filepath.Join(repo.Path(), cfg.DataFolder) +} diff --git a/lib/consensus/raft/consensus.go b/lib/consensus/raft/consensus.go new file mode 100644 index 000000000..085f94c72 --- /dev/null +++ b/lib/consensus/raft/consensus.go @@ -0,0 +1,506 @@ +// Package raft implements a Consensus component for IPFS Cluster which uses +// Raft (go-libp2p-raft). +package consensus + +import ( + "bytes" + "context" + "errors" + "fmt" + "sort" + "time" + + "github.com/google/uuid" + "golang.org/x/exp/slices" + + addr "github.com/filecoin-project/go-address" + + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/messagepool" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/lib/addrutil" + "github.com/filecoin-project/lotus/node/repo" + + //ds "github.com/ipfs/go-datastore" + logging "github.com/ipfs/go-log/v2" + consensus "github.com/libp2p/go-libp2p-consensus" + rpc "github.com/libp2p/go-libp2p-gorpc" + libp2praft "github.com/libp2p/go-libp2p-raft" + host "github.com/libp2p/go-libp2p/core/host" + peer "github.com/libp2p/go-libp2p/core/peer" +) + +var logger = logging.Logger("raft") + +type RaftState struct { + NonceMap api.NonceMapType + MsgUuids api.MsgUuidMapType + + // TODO: add comment explaining why this is needed + // We need a reference to the messagepool in the raft state in order to + // sync messages that have been sent by the leader node + // Miner calls StateWaitMsg after MpoolPushMessage to check if the message has + // landed on chain. This check requires the message be stored in the local chainstore + // If a leadernode goes down after sending a message to the chain and is replaced by + // another node, the other node needs to have this message in its chainstore for the + // above check to succeed. + + // This is because the miner only stores signed CIDs but the message received from in a + // block will be unsigned (for BLS). Hence, the process relies on the node to store the + // signed message which holds a copy of the unsigned message to properly perform all the + // needed checks + Mpool *messagepool.MessagePool +} + +func newRaftState(mpool *messagepool.MessagePool) *RaftState { + return &RaftState{ + NonceMap: make(map[addr.Address]uint64), + MsgUuids: make(map[uuid.UUID]*types.SignedMessage), + Mpool: mpool, + } +} + +type ConsensusOp struct { + Nonce uint64 `codec:"nonce,omitempty"` + Uuid uuid.UUID `codec:"uuid,omitempty"` + Addr addr.Address `codec:"addr,omitempty"` + SignedMsg *types.SignedMessage `codec:"signedMsg,omitempty"` +} + +func (c ConsensusOp) ApplyTo(state consensus.State) (consensus.State, error) { + s := state.(*RaftState) + s.NonceMap[c.Addr] = c.Nonce + if c.SignedMsg != nil { + + // Deep copy to tmp + var buffer bytes.Buffer + err := c.SignedMsg.MarshalCBOR(&buffer) + if err != nil { + return nil, err + } + tmp, err := types.DecodeSignedMessage(buffer.Bytes()) + if err != nil { + return nil, err + } + s.MsgUuids[c.Uuid] = tmp + + _, err = s.Mpool.Push(context.TODO(), tmp, false) + // Since this is only meant to keep messages in sync, ignore any error which + // shows the message already exists in the mpool + if err != nil && !api.ErrorIsIn(err, []error{messagepool.ErrExistingNonce}) { + return nil, err + } + } + + return s, nil +} + +var _ consensus.Op = &ConsensusOp{} + +// Consensus handles the work of keeping a shared-state between +// the peers of a Lotus Cluster, as well as modifying that state and +// applying any updates in a thread-safe manner. +type Consensus struct { + ctx context.Context + cancel func() + config *ClusterRaftConfig + + host host.Host + + consensus consensus.OpLogConsensus + actor consensus.Actor + raft *raftWrapper + state *RaftState + + RpcClient *rpc.Client + rpcReady chan struct{} + readyCh chan struct{} + + peerSet []peer.ID + repo repo.LockedRepo +} + +// NewConsensus builds a new ClusterConsensus component using Raft. +// +// Raft saves state snapshots regularly and persists log data in a bolt +// datastore. Therefore, unless memory usage is a concern, it is recommended +// to use an in-memory go-datastore as store parameter. +// +// The staging parameter controls if the Raft peer should start in +// staging mode (used when joining a new Raft peerset with other peers). +func NewConsensus(host host.Host, cfg *ClusterRaftConfig, mpool *messagepool.MessagePool, repo repo.LockedRepo, staging bool) (*Consensus, error) { + err := ValidateConfig(cfg) + if err != nil { + return nil, err + } + + ctx, cancel := context.WithCancel(context.Background()) + + logger.Debug("starting Consensus and waiting for a leader...") + state := newRaftState(mpool) + + consensus := libp2praft.NewOpLog(state, &ConsensusOp{}) + + raft, err := newRaftWrapper(host, cfg, consensus.FSM(), repo, staging) + if err != nil { + logger.Error("error creating raft: ", err) + cancel() + return nil, err + } + actor := libp2praft.NewActor(raft.raft) + consensus.SetActor(actor) + + peers := []peer.ID{} + addrInfos, err := addrutil.ParseAddresses(ctx, cfg.InitPeerset) + for _, addrInfo := range addrInfos { + peers = append(peers, addrInfo.ID) + + // Add peer to address book + host.Peerstore().AddAddrs(addrInfo.ID, addrInfo.Addrs, time.Hour*100) + } + + cc := &Consensus{ + ctx: ctx, + cancel: cancel, + config: cfg, + host: host, + consensus: consensus, + actor: actor, + state: state, + raft: raft, + peerSet: peers, + rpcReady: make(chan struct{}, 1), + readyCh: make(chan struct{}, 1), + repo: repo, + } + + go cc.finishBootstrap() + return cc, nil + +} + +// TODO: Merge with NewConsensus and remove the rpcReady chan +func NewConsensusWithRPCClient(staging bool) func(host host.Host, + cfg *ClusterRaftConfig, + rpcClient *rpc.Client, + mpool *messagepool.MessagePool, + repo repo.LockedRepo, +) (*Consensus, error) { + + return func(host host.Host, cfg *ClusterRaftConfig, rpcClient *rpc.Client, mpool *messagepool.MessagePool, repo repo.LockedRepo) (*Consensus, error) { + cc, err := NewConsensus(host, cfg, mpool, repo, staging) + if err != nil { + return nil, err + } + cc.RpcClient = rpcClient + cc.rpcReady <- struct{}{} + return cc, nil + } +} + +// WaitForSync waits for a leader and for the state to be up to date, then returns. +func (cc *Consensus) WaitForSync(ctx context.Context) error { + + leaderCtx, cancel := context.WithTimeout(ctx, cc.config.WaitForLeaderTimeout) + defer cancel() + + // 1 - wait for leader + // 2 - wait until we are a Voter + // 3 - wait until last index is applied + + // From raft docs: + + // once a staging server receives enough log entries to be sufficiently + // caught up to the leader's log, the leader will invoke a membership + // change to change the Staging server to a Voter + + // Thus, waiting to be a Voter is a guarantee that we have a reasonable + // up to date state. Otherwise, we might return too early (see + // https://github.com/ipfs-cluster/ipfs-cluster/issues/378) + + _, err := cc.raft.WaitForLeader(leaderCtx) + if err != nil { + return errors.New("error waiting for leader: " + err.Error()) + } + + err = cc.raft.WaitForVoter(ctx) + if err != nil { + return errors.New("error waiting to become a Voter: " + err.Error()) + } + + err = cc.raft.WaitForUpdates(ctx) + if err != nil { + return errors.New("error waiting for consensus updates: " + err.Error()) + } + return nil +} + +// waits until there is a consensus leader and syncs the state +// to the tracker. If errors happen, this will return and never +// signal the component as Ready. +func (cc *Consensus) finishBootstrap() { + // wait until we have RPC to perform any actions. + select { + case <-cc.ctx.Done(): + return + case <-cc.rpcReady: + } + + // Sometimes bootstrap is a no-Op. It only applies when + // no state exists and staging=false. + _, err := cc.raft.Bootstrap() + if err != nil { + return + } + + logger.Debugf("Bootstrap finished") + err = cc.WaitForSync(cc.ctx) + if err != nil { + return + } + logger.Debug("Raft state is now up to date") + logger.Debug("consensus ready") + cc.readyCh <- struct{}{} +} + +// Shutdown stops the component so it will not process any +// more updates. The underlying consensus is permanently +// shutdown, along with the libp2p transport. +func (cc *Consensus) Shutdown(ctx context.Context) error { + + logger.Info("stopping Consensus component") + + // Raft Shutdown + err := cc.raft.Shutdown(ctx) + if err != nil { + logger.Error(err) + } + + cc.cancel() + close(cc.rpcReady) + return nil +} + +// Ready returns a channel which is signaled when the Consensus +// algorithm has finished bootstrapping and is ready to use +func (cc *Consensus) Ready(ctx context.Context) <-chan struct{} { + return cc.readyCh +} + +// IsTrustedPeer returns true. In Raft we trust all peers. +func (cc *Consensus) IsTrustedPeer(ctx context.Context, p peer.ID) bool { + return slices.Contains(cc.peerSet, p) +} + +// Trust is a no-Op. +func (cc *Consensus) Trust(ctx context.Context, pid peer.ID) error { return nil } + +// Distrust is a no-Op. +func (cc *Consensus) Distrust(ctx context.Context, pid peer.ID) error { return nil } + +// returns true if the operation was redirected to the leader +// note that if the leader just dissappeared, the rpc call will +// fail because we haven't heard that it's gone. +func (cc *Consensus) RedirectToLeader(method string, arg interface{}, ret interface{}) (bool, error) { + ctx := cc.ctx + + var finalErr error + + // Retry redirects + for i := 0; i <= cc.config.CommitRetries; i++ { + logger.Debugf("redirect try %d", i) + leader, err := cc.Leader(ctx) + + // No leader, wait for one + if err != nil { + logger.Warn("there seems to be no leader. Waiting for one") + rctx, cancel := context.WithTimeout(ctx, cc.config.WaitForLeaderTimeout) + defer cancel() + pidstr, err := cc.raft.WaitForLeader(rctx) + + // means we timed out waiting for a leader + // we don't retry in this case + if err != nil { + return false, fmt.Errorf("timed out waiting for leader: %s", err) + } + leader, err = peer.Decode(pidstr) + if err != nil { + return false, err + } + } + + logger.Infof("leader: %s, curr host: %s, peerSet: %s", leader, cc.host.ID(), cc.peerSet) + + // We are the leader. Do not redirect + if leader == cc.host.ID() { + return false, nil + } + + logger.Debugf("redirecting %s to leader: %s", method, leader.Pretty()) + finalErr = cc.RpcClient.CallContext( + ctx, + leader, + "Consensus", + method, + arg, + ret, + ) + if finalErr != nil { + logger.Errorf("retrying to redirect request to leader: %s", finalErr) + time.Sleep(2 * cc.config.RaftConfig.HeartbeatTimeout) + continue + } + break + } + + // We tried to redirect, but something happened + return true, finalErr +} + +// commit submits a cc.consensus commit. It retries upon failures. +func (cc *Consensus) Commit(ctx context.Context, op *ConsensusOp) error { + + var finalErr error + for i := 0; i <= cc.config.CommitRetries; i++ { + logger.Debugf("attempt #%d: committing %+v", i, op) + + // this means we are retrying + if finalErr != nil { + logger.Errorf("retrying upon failed commit (retry %d): %s ", + i, finalErr) + } + + // Being here means we are the LEADER. We can commit. + // now commit the changes to our state + _, finalErr = cc.consensus.CommitOp(op) + if finalErr != nil { + goto RETRY + } + + RETRY: + time.Sleep(cc.config.CommitRetryDelay) + } + return finalErr +} + +// AddPeer adds a new peer to participate in this consensus. It will +// forward the operation to the leader if this is not it. +func (cc *Consensus) AddPeer(ctx context.Context, pid peer.ID) error { + var finalErr error + for i := 0; i <= cc.config.CommitRetries; i++ { + logger.Debugf("attempt #%d: AddPeer %s", i, pid.Pretty()) + if finalErr != nil { + logger.Errorf("retrying to add peer. Attempt #%d failed: %s", i, finalErr) + } + ok, err := cc.RedirectToLeader("AddPeer", pid, struct{}{}) + if err != nil || ok { + return err + } + // Being here means we are the leader and can commit + finalErr = cc.raft.AddPeer(ctx, pid) + if finalErr != nil { + time.Sleep(cc.config.CommitRetryDelay) + continue + } + logger.Infof("peer added to Raft: %s", pid.Pretty()) + break + } + return finalErr +} + +// RmPeer removes a peer from this consensus. It will +// forward the operation to the leader if this is not it. +func (cc *Consensus) RmPeer(ctx context.Context, pid peer.ID) error { + var finalErr error + for i := 0; i <= cc.config.CommitRetries; i++ { + logger.Debugf("attempt #%d: RmPeer %s", i, pid.Pretty()) + if finalErr != nil { + logger.Errorf("retrying to remove peer. Attempt #%d failed: %s", i, finalErr) + } + ok, err := cc.RedirectToLeader("RmPeer", pid, struct{}{}) + if err != nil || ok { + return err + } + // Being here means we are the leader and can commit + finalErr = cc.raft.RemovePeer(ctx, peer.Encode(pid)) + if finalErr != nil { + time.Sleep(cc.config.CommitRetryDelay) + continue + } + logger.Infof("peer removed from Raft: %s", pid.Pretty()) + break + } + return finalErr +} + +// RaftState retrieves the current consensus RaftState. It may error if no RaftState has +// been agreed upon or the state is not consistent. The returned RaftState is the +// last agreed-upon RaftState known by this node. No writes are allowed, as all +// writes to the shared state should happen through the Consensus component +// methods. +func (cc *Consensus) State(ctx context.Context) (*RaftState, error) { + st, err := cc.consensus.GetLogHead() + if err == libp2praft.ErrNoState { + return newRaftState(nil), nil + } + + if err != nil { + return nil, err + } + state, ok := st.(*RaftState) + if !ok { + return nil, errors.New("wrong state type") + } + return state, nil +} + +// Leader returns the peerID of the Leader of the +// cluster. It returns an error when there is no leader. +func (cc *Consensus) Leader(ctx context.Context) (peer.ID, error) { + // Note the hard-dependency on raft here... + raftactor := cc.actor.(*libp2praft.Actor) + return raftactor.Leader() +} + +// Clean removes the Raft persisted state. +func (cc *Consensus) Clean(ctx context.Context) error { + //return CleanupRaft(cc.config) + return nil +} + +//Rollback replaces the current agreed-upon +//state with the state provided. Only the consensus leader +//can perform this operation. +//func (cc *Consensus) Rollback(state RaftState) error { +// // This is unused. It *might* be used for upgrades. +// // There is rather untested magic in libp2p-raft's FSM() +// // to make this possible. +// return cc.consensus.Rollback(state) +//} + +// Peers return the current list of peers in the consensus. +// The list will be sorted alphabetically. +func (cc *Consensus) Peers(ctx context.Context) ([]peer.ID, error) { + + peers := []peer.ID{} + raftPeers, err := cc.raft.Peers(ctx) + if err != nil { + return nil, fmt.Errorf("cannot retrieve list of peers: %s", err) + } + + sort.Strings(raftPeers) + + for _, p := range raftPeers { + id, err := peer.Decode(p) + if err != nil { + panic("could not decode peer") + } + peers = append(peers, id) + } + return peers, nil +} + +func (cc *Consensus) IsLeader(ctx context.Context) bool { + leader, _ := cc.Leader(ctx) + return leader == cc.host.ID() +} diff --git a/lib/consensus/raft/interfaces.go b/lib/consensus/raft/interfaces.go new file mode 100644 index 000000000..2b77d1ebe --- /dev/null +++ b/lib/consensus/raft/interfaces.go @@ -0,0 +1,41 @@ +package consensus + +import ( + "context" + + consensus "github.com/libp2p/go-libp2p-consensus" + "github.com/libp2p/go-libp2p/core/peer" +) + +type ConsensusAPI interface { + // Returns a channel to signal that the consensus layer is ready + // allowing the main component to wait for it during start. + Ready(context.Context) <-chan struct{} + + AddPeer(context.Context, peer.ID) error + RmPeer(context.Context, peer.ID) error + State(context.Context) (consensus.State, error) + // Provide a node which is responsible to perform + // specific tasks which must only run in 1 cluster peer. + Leader(context.Context) (peer.ID, error) + // Only returns when the consensus state has all log + // updates applied to it. + WaitForSync(context.Context) error + // Clean removes all consensus data. + Clean(context.Context) error + // Peers returns the peerset participating in the Consensus. + Peers(context.Context) ([]peer.ID, error) + // IsTrustedPeer returns true if the given peer is "trusted". + // This will grant access to more rpc endpoints and a + // non-trusted one. This should be fast as it will be + // called repeatedly for every remote RPC request. + IsTrustedPeer(context.Context, peer.ID) bool + // Trust marks a peer as "trusted". + Trust(context.Context, peer.ID) error + // Distrust removes a peer from the "trusted" set. + Distrust(context.Context, peer.ID) error + // Returns true if current node is the cluster leader + IsLeader(ctx context.Context) bool + + Shutdown(context.Context) error +} diff --git a/lib/consensus/raft/raft.go b/lib/consensus/raft/raft.go new file mode 100644 index 000000000..76c23a6d1 --- /dev/null +++ b/lib/consensus/raft/raft.go @@ -0,0 +1,592 @@ +package consensus + +import ( + "context" + "errors" + "fmt" + "os" + "path/filepath" + "time" + + hraft "github.com/hashicorp/raft" + raftboltdb "github.com/hashicorp/raft-boltdb" + "github.com/ipfs/go-log/v2" + p2praft "github.com/libp2p/go-libp2p-raft" + host "github.com/libp2p/go-libp2p/core/host" + peer "github.com/libp2p/go-libp2p/core/peer" + "go.uber.org/multierr" + "go.uber.org/zap" + + "github.com/filecoin-project/lotus/lib/addrutil" + "github.com/filecoin-project/lotus/node/repo" +) + +var raftLogger = log.Logger("raft-cluster") + +// ErrWaitingForSelf is returned when we are waiting for ourselves to depart +// the peer set, which won't happen +var errWaitingForSelf = errors.New("waiting for ourselves to depart") + +// RaftMaxSnapshots indicates how many snapshots to keep in the consensus data +// folder. +// TODO: Maybe include this in Config. Not sure how useful it is to touch +// this anyways. +var RaftMaxSnapshots = 5 + +// RaftLogCacheSize is the maximum number of logs to cache in-memory. +// This is used to reduce disk I/O for the recently committed entries. +var RaftLogCacheSize = 512 + +// How long we wait for updates during shutdown before snapshotting +var waitForUpdatesShutdownTimeout = 5 * time.Second +var waitForUpdatesInterval = 400 * time.Millisecond + +// How many times to retry snapshotting when shutting down +var maxShutdownSnapshotRetries = 5 + +// raftWrapper wraps the hraft.Raft object and related things like the +// different stores used or the hraft.Configuration. +// Its methods provide functionality for working with Raft. +type raftWrapper struct { + ctx context.Context + cancel context.CancelFunc + raft *hraft.Raft + config *ClusterRaftConfig + host host.Host + serverConfig hraft.Configuration + transport *hraft.NetworkTransport + snapshotStore hraft.SnapshotStore + logStore hraft.LogStore + stableStore hraft.StableStore + boltdb *raftboltdb.BoltStore + repo repo.LockedRepo + staging bool +} + +// newRaftWrapper creates a Raft instance and initializes +// everything leaving it ready to use. Note, that Bootstrap() should be called +// to make sure the raft instance is usable. +func newRaftWrapper( + host host.Host, + cfg *ClusterRaftConfig, + fsm hraft.FSM, + repo repo.LockedRepo, + staging bool, +) (*raftWrapper, error) { + + raftW := &raftWrapper{} + raftW.config = cfg + raftW.host = host + raftW.staging = staging + raftW.repo = repo + // Set correct LocalID + cfg.RaftConfig.LocalID = hraft.ServerID(peer.Encode(host.ID())) + + df := cfg.GetDataFolder(repo) + err := makeDataFolder(df) + if err != nil { + return nil, err + } + + err = raftW.makeServerConfig() + if err != nil { + return nil, err + } + + err = raftW.makeTransport() + if err != nil { + return nil, err + } + + err = raftW.makeStores() + if err != nil { + return nil, err + } + + raftLogger.Debug("creating Raft") + raftW.raft, err = hraft.NewRaft( + cfg.RaftConfig, + fsm, + raftW.logStore, + raftW.stableStore, + raftW.snapshotStore, + raftW.transport, + ) + if err != nil { + raftLogger.Error("initializing raft: ", err) + return nil, err + } + + raftW.ctx, raftW.cancel = context.WithCancel(context.Background()) + + return raftW, nil +} + +// makeDataFolder creates the folder that is meant to store Raft data. Ensures +// we always set 0700 mode. +func makeDataFolder(folder string) error { + return os.MkdirAll(folder, 0700) +} + +func (rw *raftWrapper) makeTransport() (err error) { + raftLogger.Debug("creating libp2p Raft transport") + rw.transport, err = p2praft.NewLibp2pTransport( + rw.host, + rw.config.NetworkTimeout, + ) + return err +} + +func (rw *raftWrapper) makeStores() error { + raftLogger.Debug("creating BoltDB store") + df := rw.config.GetDataFolder(rw.repo) + store, err := raftboltdb.NewBoltStore(filepath.Join(df, "raft.db")) + if err != nil { + return err + } + + // wraps the store in a LogCache to improve performance. + // See consul/agent/consul/server.go + cacheStore, err := hraft.NewLogCache(RaftLogCacheSize, store) + if err != nil { + return err + } + + raftLogger.Debug("creating raft snapshot store") + snapstore, err := hraft.NewFileSnapshotStoreWithLogger( + df, + RaftMaxSnapshots, + zap.NewStdLog(log.Logger("raft-snapshot").SugaredLogger.Desugar()), + ) + if err != nil { + return err + } + + rw.logStore = cacheStore + rw.stableStore = store + rw.snapshotStore = snapstore + rw.boltdb = store + return nil +} + +// Bootstrap calls BootstrapCluster on the Raft instance with a valid +// Configuration (generated from InitPeerset) when Raft has no state +// and we are not setting up a staging peer. It returns if Raft +// was boostrapped (true) and an error. +func (rw *raftWrapper) Bootstrap() (bool, error) { + logger.Debug("checking for existing raft states") + hasState, err := hraft.HasExistingState( + rw.logStore, + rw.stableStore, + rw.snapshotStore, + ) + if err != nil { + return false, err + } + + if hasState { + logger.Debug("raft cluster is already initialized") + + // Inform the user that we are working with a pre-existing peerset + logger.Info("existing Raft state found! raft.InitPeerset will be ignored") + cf := rw.raft.GetConfiguration() + if err := cf.Error(); err != nil { + logger.Debug(err) + return false, err + } + currentCfg := cf.Configuration() + srvs := "" + for _, s := range currentCfg.Servers { + srvs += fmt.Sprintf(" %s\n", s.ID) + } + + logger.Debugf("Current Raft Peerset:\n%s\n", srvs) + return false, nil + } + + if rw.staging { + logger.Debug("staging servers do not need initialization") + logger.Info("peer is ready to join a cluster") + return false, nil + } + + voters := "" + for _, s := range rw.serverConfig.Servers { + voters += fmt.Sprintf(" %s\n", s.ID) + } + + logger.Infof("initializing raft cluster with the following voters:\n%s\n", voters) + + future := rw.raft.BootstrapCluster(rw.serverConfig) + if err := future.Error(); err != nil { + logger.Error("bootstrapping cluster: ", err) + return true, err + } + return true, nil +} + +// create Raft servers configuration. The result is used +// by Bootstrap() when it proceeds to Bootstrap. +func (rw *raftWrapper) makeServerConfig() error { + peers := []peer.ID{} + addrInfos, err := addrutil.ParseAddresses(context.Background(), rw.config.InitPeerset) + if err != nil { + return err + } + for _, addrInfo := range addrInfos { + peers = append(peers, addrInfo.ID) + } + rw.serverConfig = makeServerConf(append(peers, rw.host.ID())) + return nil +} + +// creates a server configuration with all peers as Voters. +func makeServerConf(peers []peer.ID) hraft.Configuration { + sm := make(map[string]struct{}) + + servers := make([]hraft.Server, 0) + + // Servers are peers + self. We avoid duplicate entries below + for _, pid := range peers { + p := peer.Encode(pid) + _, ok := sm[p] + if !ok { // avoid dups + sm[p] = struct{}{} + servers = append(servers, hraft.Server{ + Suffrage: hraft.Voter, + ID: hraft.ServerID(p), + Address: hraft.ServerAddress(p), + }) + } + } + return hraft.Configuration{Servers: servers} +} + +// WaitForLeader holds until Raft says we have a leader. +// Returns if ctx is canceled. +func (rw *raftWrapper) WaitForLeader(ctx context.Context) (string, error) { + ticker := time.NewTicker(time.Second / 2) + for { + select { + case <-ticker.C: + if l := rw.raft.Leader(); l != "" { + logger.Debug("waitForleaderTimer") + logger.Infof("Current Raft Leader: %s", l) + ticker.Stop() + return string(l), nil + } + case <-ctx.Done(): + return "", ctx.Err() + } + } +} + +func (rw *raftWrapper) WaitForVoter(ctx context.Context) error { + logger.Debug("waiting until we are promoted to a voter") + + pid := hraft.ServerID(peer.Encode(rw.host.ID())) + for { + select { + case <-ctx.Done(): + return ctx.Err() + default: + logger.Debugf("%s: get configuration", pid) + configFuture := rw.raft.GetConfiguration() + if err := configFuture.Error(); err != nil { + return err + } + + if isVoter(pid, configFuture.Configuration()) { + return nil + } + logger.Debugf("%s: not voter yet", pid) + + time.Sleep(waitForUpdatesInterval) + } + } +} + +func isVoter(srvID hraft.ServerID, cfg hraft.Configuration) bool { + for _, server := range cfg.Servers { + if server.ID == srvID && server.Suffrage == hraft.Voter { + return true + } + } + return false +} + +// WaitForUpdates holds until Raft has synced to the last index in the log +func (rw *raftWrapper) WaitForUpdates(ctx context.Context) error { + + logger.Debug("Raft state is catching up to the latest known version. Please wait...") + for { + select { + case <-ctx.Done(): + return ctx.Err() + default: + lai := rw.raft.AppliedIndex() + li := rw.raft.LastIndex() + logger.Debugf("current Raft index: %d/%d", + lai, li) + if lai == li { + return nil + } + time.Sleep(waitForUpdatesInterval) + } + } +} + +func (rw *raftWrapper) WaitForPeer(ctx context.Context, pid string, depart bool) error { + + for { + select { + case <-ctx.Done(): + return ctx.Err() + default: + peers, err := rw.Peers(ctx) + if err != nil { + return err + } + + if len(peers) == 1 && pid == peers[0] && depart { + return errWaitingForSelf + } + + found := find(peers, pid) + + // departing + if depart && !found { + return nil + } + + // joining + if !depart && found { + return nil + } + + time.Sleep(50 * time.Millisecond) + } + } +} + +// Snapshot tells Raft to take a snapshot. +func (rw *raftWrapper) Snapshot() error { + future := rw.raft.Snapshot() + err := future.Error() + if err != nil && err.Error() != hraft.ErrNothingNewToSnapshot.Error() { + return err + } + return nil +} + +// snapshotOnShutdown attempts to take a snapshot before a shutdown. +// Snapshotting might fail if the raft applied index is not the last index. +// This waits for the updates and tries to take a snapshot when the +// applied index is up to date. +// It will retry if the snapshot still fails, in case more updates have arrived. +// If waiting for updates times-out, it will not try anymore, since something +// is wrong. This is a best-effort solution as there is no way to tell Raft +// to stop processing entries because we want to take a snapshot before +// shutting down. +func (rw *raftWrapper) snapshotOnShutdown() error { + var err error + for i := 0; i < maxShutdownSnapshotRetries; i++ { + ctx, cancel := context.WithTimeout(context.Background(), waitForUpdatesShutdownTimeout) + err = rw.WaitForUpdates(ctx) + cancel() + if err != nil { + logger.Warn("timed out waiting for state updates before shutdown. Snapshotting may fail") + return rw.Snapshot() + } + + err = rw.Snapshot() + if err == nil { + return nil // things worked + } + + // There was an error + err = errors.New("could not snapshot raft: " + err.Error()) + logger.Warnf("retrying to snapshot (%d/%d)...", i+1, maxShutdownSnapshotRetries) + } + return err +} + +// Shutdown shutdown Raft and closes the BoltDB. +func (rw *raftWrapper) Shutdown(ctx context.Context) error { + + rw.cancel() + + var finalErr error + + err := rw.snapshotOnShutdown() + if err != nil { + finalErr = multierr.Append(finalErr, err) + } + + future := rw.raft.Shutdown() + err = future.Error() + if err != nil { + finalErr = multierr.Append(finalErr, err) + } + + err = rw.boltdb.Close() // important! + if err != nil { + finalErr = multierr.Append(finalErr, err) + } + + return finalErr +} + +// AddPeer adds a peer to Raft +func (rw *raftWrapper) AddPeer(ctx context.Context, peerId peer.ID) error { + + // Check that we don't have it to not waste + // log entries if so. + peers, err := rw.Peers(ctx) + if err != nil { + return err + } + if find(peers, peerId.String()) { + logger.Infof("%s is already a raft peerStr", peerId.String()) + return nil + } + + err = rw.host.Connect(ctx, peer.AddrInfo{ID: peerId}) + if err != nil { + return err + } + + future := rw.raft.AddVoter( + hraft.ServerID(peerId.String()), + hraft.ServerAddress(peerId.String()), + 0, + 0, + ) // TODO: Extra cfg value? + err = future.Error() + if err != nil { + logger.Error("raft cannot add peer: ", err) + } + return err +} + +// RemovePeer removes a peer from Raft +func (rw *raftWrapper) RemovePeer(ctx context.Context, peer string) error { + // Check that we have it to not waste + // log entries if we don't. + peers, err := rw.Peers(ctx) + if err != nil { + return err + } + if !find(peers, peer) { + logger.Infof("%s is not among raft peers", peer) + return nil + } + + if len(peers) == 1 && peers[0] == peer { + return errors.New("cannot remove ourselves from a 1-peer cluster") + } + + rmFuture := rw.raft.RemoveServer( + hraft.ServerID(peer), + 0, + 0, + ) + err = rmFuture.Error() + if err != nil { + logger.Error("raft cannot remove peer: ", err) + return err + } + + return nil +} + +// Leader returns Raft's leader. It may be an empty string if +// there is no leader or it is unknown. +func (rw *raftWrapper) Leader(ctx context.Context) string { + return string(rw.raft.Leader()) +} + +func (rw *raftWrapper) Peers(ctx context.Context) ([]string, error) { + ids := make([]string, 0) + + configFuture := rw.raft.GetConfiguration() + if err := configFuture.Error(); err != nil { + return nil, err + } + + for _, server := range configFuture.Configuration().Servers { + ids = append(ids, string(server.ID)) + } + + return ids, nil +} + +// CleanupRaft moves the current data folder to a backup location +//func CleanupRaft(cfg *Config) error { +// dataFolder := cfg.GetDataFolder() +// keep := cfg.BackupsRotate +// +// meta, _, err := latestSnapshot(dataFolder) +// if meta == nil && err == nil { +// // no snapshots at all. Avoid creating backups +// // from empty state folders. +// logger.Infof("cleaning empty Raft data folder (%s)", dataFolder) +// os.RemoveAll(dataFolder) +// return nil +// } +// +// logger.Infof("cleaning and backing up Raft data folder (%s)", dataFolder) +// dbh := newDataBackupHelper(dataFolder, keep) +// err = dbh.makeBackup() +// if err != nil { +// logger.Warn(err) +// logger.Warn("the state could not be cleaned properly") +// logger.Warn("manual intervention may be needed before starting cluster again") +// } +// return nil +//} + +// only call when Raft is shutdown +func (rw *raftWrapper) Clean() error { + //return CleanupRaft(rw.config) + return nil +} + +func find(s []string, elem string) bool { + for _, selem := range s { + if selem == elem { + return true + } + } + return false +} + +func (rw *raftWrapper) observePeers() { + obsCh := make(chan hraft.Observation, 1) + defer close(obsCh) + + observer := hraft.NewObserver(obsCh, true, func(o *hraft.Observation) bool { + po, ok := o.Data.(hraft.PeerObservation) + return ok && po.Removed + }) + + rw.raft.RegisterObserver(observer) + defer rw.raft.DeregisterObserver(observer) + + for { + select { + case obs := <-obsCh: + pObs := obs.Data.(hraft.PeerObservation) + logger.Info("raft peer departed. Removing from peerstore: ", pObs.Peer.ID) + pID, err := peer.Decode(string(pObs.Peer.ID)) + if err != nil { + logger.Error(err) + continue + } + rw.host.Peerstore().ClearAddrs(pID) + case <-rw.ctx.Done(): + logger.Debug("stopped observing raft peers") + return + } + } +} diff --git a/lib/result/result.go b/lib/result/result.go new file mode 100644 index 000000000..bec839d7a --- /dev/null +++ b/lib/result/result.go @@ -0,0 +1,35 @@ +package result + +// Result is a small wrapper type encapsulating Value/Error tuples, mostly for +// use when sending values across channels +// NOTE: Avoid adding any functionality to this, any "nice" things added here will +// make it more difficult to switch to a more standardised Result-like type when +// one gets into the stdlib, or when we will want to switch to a library providing +// those types. +type Result[T any] struct { + Value T + Error error +} + +func Ok[T any](value T) Result[T] { + return Result[T]{ + Value: value, + } +} + +func Err[T any](err error) Result[T] { + return Result[T]{ + Error: err, + } +} + +func Wrap[T any](value T, err error) Result[T] { + return Result[T]{ + Value: value, + Error: err, + } +} + +func (r *Result[T]) Unwrap() (T, error) { + return r.Value, r.Error +} diff --git a/lib/retry/retry.go b/lib/retry/retry.go index e69d1ef35..897dbb06c 100644 --- a/lib/retry/retry.go +++ b/lib/retry/retry.go @@ -1,6 +1,7 @@ package retry import ( + "context" "time" logging "github.com/ipfs/go-log/v2" @@ -10,7 +11,7 @@ import ( var log = logging.Logger("retry") -func Retry[T any](attempts int, initialBackoff time.Duration, errorTypes []error, f func() (T, error)) (result T, err error) { +func Retry[T any](ctx context.Context, attempts int, initialBackoff time.Duration, errorTypes []error, f func() (T, error)) (result T, err error) { for i := 0; i < attempts; i++ { if i > 0 { log.Info("Retrying after error:", err) @@ -21,6 +22,9 @@ func Retry[T any](attempts int, initialBackoff time.Duration, errorTypes []error if err == nil || !api.ErrorIsIn(err, errorTypes) { return result, err } + if ctx.Err() != nil { + return result, ctx.Err() + } } log.Errorf("Failed after %d attempts, last error: %s", attempts, err) return result, err diff --git a/markets/retrievaladapter/client_blockstore.go b/markets/retrievaladapter/client_blockstore.go index 84c75fdbd..37a80013a 100644 --- a/markets/retrievaladapter/client_blockstore.go +++ b/markets/retrievaladapter/client_blockstore.go @@ -8,8 +8,12 @@ import ( "github.com/ipfs/go-cid" bstore "github.com/ipfs/go-ipfs-blockstore" "github.com/ipld/go-car/v2/blockstore" + "golang.org/x/xerrors" "github.com/filecoin-project/go-fil-markets/retrievalmarket" + + "github.com/filecoin-project/lotus/api" + lbstore "github.com/filecoin-project/lotus/blockstore" ) // ProxyBlockstoreAccessor is an accessor that returns a fixed blockstore. @@ -32,6 +36,85 @@ func (p *ProxyBlockstoreAccessor) Done(_ retrievalmarket.DealID) error { return nil } +func NewAPIBlockstoreAdapter(sub retrievalmarket.BlockstoreAccessor) *APIBlockstoreAccessor { + return &APIBlockstoreAccessor{ + sub: sub, + retrStores: map[retrievalmarket.DealID]api.RemoteStoreID{}, + remoteStores: map[api.RemoteStoreID]bstore.Blockstore{}, + } +} + +// APIBlockstoreAccessor adds support to API-specified remote blockstores +type APIBlockstoreAccessor struct { + sub retrievalmarket.BlockstoreAccessor + + retrStores map[retrievalmarket.DealID]api.RemoteStoreID + remoteStores map[api.RemoteStoreID]bstore.Blockstore + + accessLk sync.Mutex +} + +func (a *APIBlockstoreAccessor) Get(id retrievalmarket.DealID, payloadCID retrievalmarket.PayloadCID) (bstore.Blockstore, error) { + a.accessLk.Lock() + defer a.accessLk.Unlock() + + as, has := a.retrStores[id] + if !has { + return a.sub.Get(id, payloadCID) + } + + return a.remoteStores[as], nil +} + +func (a *APIBlockstoreAccessor) Done(id retrievalmarket.DealID) error { + a.accessLk.Lock() + defer a.accessLk.Unlock() + + if _, has := a.retrStores[id]; has { + delete(a.retrStores, id) + return nil + } + return a.sub.Done(id) +} + +func (a *APIBlockstoreAccessor) RegisterDealToRetrievalStore(id retrievalmarket.DealID, sid api.RemoteStoreID) error { + a.accessLk.Lock() + defer a.accessLk.Unlock() + + if _, has := a.retrStores[id]; has { + return xerrors.Errorf("apistore for deal %d already registered", id) + } + if _, has := a.remoteStores[sid]; !has { + return xerrors.Errorf("remote store not found") + } + + a.retrStores[id] = sid + return nil +} + +func (a *APIBlockstoreAccessor) RegisterApiStore(sid api.RemoteStoreID, st *lbstore.NetworkStore) error { + a.accessLk.Lock() + defer a.accessLk.Unlock() + + if _, has := a.remoteStores[sid]; has { + return xerrors.Errorf("remote store already registered with this uuid") + } + + a.remoteStores[sid] = st + + st.OnClose(func() { + a.accessLk.Lock() + defer a.accessLk.Unlock() + + if _, has := a.remoteStores[sid]; has { + delete(a.remoteStores, sid) + } + }) + return nil +} + +var _ retrievalmarket.BlockstoreAccessor = &APIBlockstoreAccessor{} + type CARBlockstoreAccessor struct { rootdir string lk sync.Mutex diff --git a/markets/utils/selectors.go b/markets/utils/selectors.go index e1009d1ff..1b8a62401 100644 --- a/markets/utils/selectors.go +++ b/markets/utils/selectors.go @@ -26,6 +26,7 @@ func TraverseDag( ds mdagipld.DAGService, startFrom cid.Cid, optionalSelector ipld.Node, + onOpen func(node mdagipld.Node) error, visitCallback traversal.AdvVisitFn, ) error { @@ -61,6 +62,12 @@ func TraverseDag( return nil, err } + if onOpen != nil { + if err := onOpen(node); err != nil { + return nil, err + } + } + return bytes.NewBuffer(node.RawData()), nil } unixfsnode.AddUnixFSReificationToLinkSystem(&linkSystem) diff --git a/miner/miner.go b/miner/miner.go index 4952f95fb..f954352ae 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -30,6 +30,7 @@ import ( "github.com/filecoin-project/lotus/chain/gen/slashfilter" lrand "github.com/filecoin-project/lotus/chain/rand" "github.com/filecoin-project/lotus/chain/types" + cliutil "github.com/filecoin-project/lotus/cli/util" "github.com/filecoin-project/lotus/journal" ) @@ -208,6 +209,8 @@ func (m *Miner) mine(ctx context.Context) { var lastBase MiningBase minerLoop: for { + ctx := cliutil.OnSingleNode(ctx) + select { case <-m.stop: stopping := m.stopping diff --git a/node/builder.go b/node/builder.go index 9690b7f7c..eaf932e2e 100644 --- a/node/builder.go +++ b/node/builder.go @@ -121,6 +121,7 @@ const ( SettlePaymentChannelsKey RunPeerTaggerKey SetupFallbackBlockstoresKey + GoRPCServer SetApiEndpointKey diff --git a/node/builder_chain.go b/node/builder_chain.go index 7a96e163c..2201be2e6 100644 --- a/node/builder_chain.go +++ b/node/builder_chain.go @@ -3,6 +3,7 @@ package node import ( "os" + gorpc "github.com/libp2p/go-libp2p-gorpc" "go.uber.org/fx" "golang.org/x/xerrors" @@ -28,7 +29,9 @@ import ( "github.com/filecoin-project/lotus/chain/wallet" ledgerwallet "github.com/filecoin-project/lotus/chain/wallet/ledger" "github.com/filecoin-project/lotus/chain/wallet/remotewallet" + raftcns "github.com/filecoin-project/lotus/lib/consensus/raft" "github.com/filecoin-project/lotus/lib/peermgr" + "github.com/filecoin-project/lotus/markets/retrievaladapter" "github.com/filecoin-project/lotus/markets/storageadapter" "github.com/filecoin-project/lotus/node/config" "github.com/filecoin-project/lotus/node/hello" @@ -105,6 +108,7 @@ var ChainNode = Options( // Service: Wallet Override(new(*messagesigner.MessageSigner), messagesigner.NewMessageSigner), + Override(new(messagesigner.MsgSigner), func(ms *messagesigner.MessageSigner) *messagesigner.MessageSigner { return ms }), Override(new(*wallet.LocalWallet), wallet.NewWallet), Override(new(wallet.Default), From(new(*wallet.LocalWallet))), Override(new(api.Wallet), From(new(wallet.MultiWallet))), @@ -129,6 +133,7 @@ var ChainNode = Options( Override(new(*market.FundManager), market.NewFundManager), Override(new(dtypes.ClientDatastore), modules.NewClientDatastore), Override(new(storagemarket.BlockstoreAccessor), modules.StorageBlockstoreAccessor), + Override(new(*retrievaladapter.APIBlockstoreAccessor), retrievaladapter.NewAPIBlockstoreAdapter), Override(new(storagemarket.StorageClient), modules.StorageClient), Override(new(storagemarket.StorageClientNode), storageadapter.NewClientNodeAdapter), Override(HandleMigrateClientFundsKey, modules.HandleMigrateClientFunds), @@ -140,7 +145,7 @@ var ChainNode = Options( // Lite node API ApplyIf(isLiteNode, Override(new(messagepool.Provider), messagepool.NewProviderLite), - Override(new(messagesigner.MpoolNonceAPI), From(new(modules.MpoolNonceAPI))), + Override(new(messagepool.MpoolNonceAPI), From(new(modules.MpoolNonceAPI))), Override(new(full.ChainModuleAPI), From(new(api.Gateway))), Override(new(full.GasModuleAPI), From(new(api.Gateway))), Override(new(full.MpoolModuleAPI), From(new(api.Gateway))), @@ -151,7 +156,7 @@ var ChainNode = Options( // Full node API / service startup ApplyIf(isFullNode, Override(new(messagepool.Provider), messagepool.NewProvider), - Override(new(messagesigner.MpoolNonceAPI), From(new(*messagepool.MessagePool))), + Override(new(messagepool.MpoolNonceAPI), From(new(*messagepool.MessagePool))), Override(new(full.ChainModuleAPI), From(new(full.ChainModule))), Override(new(full.GasModuleAPI), From(new(full.GasModule))), Override(new(full.MpoolModuleAPI), From(new(full.MpoolModule))), @@ -236,6 +241,16 @@ func ConfigFullNode(c interface{}) Option { Unset(new(*wallet.LocalWallet)), Override(new(wallet.Default), wallet.NilDefault), ), + // Chain node cluster enabled + If(cfg.Cluster.ClusterModeEnabled, + Override(new(*gorpc.Client), modules.NewRPCClient), + Override(new(*raftcns.ClusterRaftConfig), raftcns.NewClusterRaftConfig(&cfg.Cluster)), + Override(new(*raftcns.Consensus), raftcns.NewConsensusWithRPCClient(false)), + Override(new(*messagesigner.MessageSignerConsensus), messagesigner.NewMessageSignerConsensus), + Override(new(messagesigner.MsgSigner), From(new(*messagesigner.MessageSignerConsensus))), + Override(new(*modules.RPCHandler), modules.NewRPCHandler), + Override(GoRPCServer, modules.NewRPCServer), + ), ) } diff --git a/node/builder_miner.go b/node/builder_miner.go index cd7b4ec8d..2d33727f8 100644 --- a/node/builder_miner.go +++ b/node/builder_miner.go @@ -224,7 +224,8 @@ func ConfigStorageMiner(c interface{}) Option { Override(new(storagemarket.StorageProviderNode), storageadapter.NewProviderNodeAdapter(&cfg.Fees, &cfg.Dealmaking)), ), - Override(new(sectorstorage.Config), cfg.StorageManager()), + Override(new(config.SealerConfig), cfg.Storage), + Override(new(config.ProvingConfig), cfg.Proving), Override(new(*ctladdr.AddressSelector), modules.AddressSelector(&cfg.Addresses)), ) } diff --git a/node/config/def.go b/node/config/def.go index a6e6fc66a..dc26f1661 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -15,7 +15,6 @@ import ( "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/storage/sealer" ) const ( @@ -98,6 +97,7 @@ func DefaultFullNode() *FullNode { HotStoreFullGCFrequency: 20, }, }, + Cluster: *DefaultUserRaftConfig(), } } @@ -141,7 +141,9 @@ func DefaultStorageMiner() *StorageMiner { }, Proving: ProvingConfig{ - ParallelCheckLimit: 128, + ParallelCheckLimit: 128, + PartitionCheckTimeout: Duration(20 * time.Minute), + SingleCheckTimeout: Duration(10 * time.Minute), }, Storage: SealerConfig{ @@ -162,7 +164,7 @@ func DefaultStorageMiner() *StorageMiner { Assigner: "utilization", // By default use the hardware resource filtering strategy. - ResourceFiltering: sealer.ResourceFilteringHardware, + ResourceFiltering: ResourceFilteringHardware, }, Dealmaking: DealmakingConfig{ @@ -274,3 +276,39 @@ func (dur Duration) MarshalText() ([]byte, error) { d := time.Duration(dur) return []byte(d.String()), nil } + +// 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") +) + +var ( + DefaultDataSubFolder = "raft" + DefaultWaitForLeaderTimeout = 15 * time.Second + DefaultCommitRetries = 1 + DefaultNetworkTimeout = 100 * time.Second + DefaultCommitRetryDelay = 200 * time.Millisecond + DefaultBackupsRotate = 6 +) + +func DefaultUserRaftConfig() *UserRaftConfig { + var cfg UserRaftConfig + cfg.DataFolder = "" // empty so it gets omitted + cfg.InitPeersetMultiAddr = []string{} + cfg.WaitForLeaderTimeout = Duration(DefaultWaitForLeaderTimeout) + cfg.NetworkTimeout = Duration(DefaultNetworkTimeout) + cfg.CommitRetries = DefaultCommitRetries + cfg.CommitRetryDelay = Duration(DefaultCommitRetryDelay) + cfg.BackupsRotate = DefaultBackupsRotate + + return &cfg +} diff --git a/node/config/dep_test.go b/node/config/dep_test.go new file mode 100644 index 000000000..91167e690 --- /dev/null +++ b/node/config/dep_test.go @@ -0,0 +1,34 @@ +package config + +import ( + "os" + "os/exec" + "path/filepath" + "runtime" + "strings" + "testing" +) + +func goCmd() string { + var exeSuffix string + if runtime.GOOS == "windows" { + exeSuffix = ".exe" + } + path := filepath.Join(runtime.GOROOT(), "bin", "go"+exeSuffix) + if _, err := os.Stat(path); err == nil { + return path + } + return "go" +} + +func TestDoesntDependOnFFI(t *testing.T) { + deps, err := exec.Command(goCmd(), "list", "-deps", "github.com/filecoin-project/lotus/node/config").Output() + if err != nil { + t.Fatal(err) + } + for _, pkg := range strings.Fields(string(deps)) { + if pkg == "github.com/filecoin-project/filecoin-ffi" { + t.Fatal("config depends on filecoin-ffi") + } + } +} diff --git a/node/config/doc_gen.go b/node/config/doc_gen.go index 902cb1a05..ecf533137 100644 --- a/node/config/doc_gen.go +++ b/node/config/doc_gen.go @@ -372,6 +372,12 @@ see https://lotus.filecoin.io/storage-providers/advanced-configurations/market/# Name: "Chainstore", Type: "Chainstore", + Comment: ``, + }, + { + Name: "Cluster", + Type: "UserRaftConfig", + Comment: ``, }, }, @@ -638,6 +644,29 @@ to late submission. After changing this option, confirm that the new value works in your setup by invoking 'lotus-miner proving compute window-post 0'`, + }, + { + Name: "SingleCheckTimeout", + Type: "Duration", + + Comment: `Maximum amount of time a proving pre-check can take for a sector. If the check times out the sector will be skipped + +WARNING: Setting this value too low risks in sectors being skipped even though they are accessible, just reading the +test challenge took longer than this timeout +WARNING: Setting this value too high risks missing PoSt deadline in case IO operations related to this sector are +blocked (e.g. in case of disconnected NFS mount)`, + }, + { + Name: "PartitionCheckTimeout", + Type: "Duration", + + Comment: `Maximum amount of time a proving pre-check can take for an entire partition. If the check times out, sectors in +the partition which didn't get checked on time will be skipped + +WARNING: Setting this value too low risks in sectors being skipped even though they are accessible, just reading the +test challenge took longer than this timeout +WARNING: Setting this value too high risks missing PoSt deadline in case IO operations related to this partition are +blocked or slow`, }, { Name: "DisableBuiltinWindowPoSt", @@ -894,7 +923,7 @@ If you see stuck Finalize tasks after enabling this setting, check }, { Name: "ResourceFiltering", - Type: "sealer.ResourceFilteringStrategy", + Type: "ResourceFilteringStrategy", Comment: `ResourceFiltering instructs the system which resource filtering strategy to use when evaluating tasks against this worker. An empty value defaults @@ -1204,6 +1233,68 @@ Default is 20 (about once a week).`, Comment: ``, }, }, + "UserRaftConfig": []DocField{ + { + Name: "ClusterModeEnabled", + Type: "bool", + + Comment: `EXPERIMENTAL. config to enabled node cluster with raft consensus`, + }, + { + Name: "DataFolder", + Type: "string", + + Comment: `A folder to store Raft's data.`, + }, + { + Name: "InitPeersetMultiAddr", + Type: "[]string", + + Comment: `InitPeersetMultiAddr provides the list of initial cluster peers for new Raft +peers (with no prior state). It is ignored when Raft was already +initialized or when starting in staging mode.`, + }, + { + Name: "WaitForLeaderTimeout", + Type: "Duration", + + Comment: `LeaderTimeout specifies how long to wait for a leader before +failing an operation.`, + }, + { + Name: "NetworkTimeout", + Type: "Duration", + + Comment: `NetworkTimeout specifies how long before a Raft network +operation is timed out`, + }, + { + Name: "CommitRetries", + Type: "int", + + Comment: `CommitRetries specifies how many times we retry a failed commit until +we give up.`, + }, + { + Name: "CommitRetryDelay", + Type: "Duration", + + Comment: `How long to wait between retries`, + }, + { + Name: "BackupsRotate", + Type: "int", + + Comment: `BackupsRotate specifies the maximum number of Raft's DataFolder +copies that we keep as backups (renaming) after cleanup.`, + }, + { + Name: "Tracing", + Type: "bool", + + Comment: `Tracing enables propagation of contexts across binary boundaries.`, + }, + }, "Wallet": []DocField{ { Name: "RemoteBackend", diff --git a/node/config/storage.go b/node/config/storage.go index 0c72eabd1..2c9d880f9 100644 --- a/node/config/storage.go +++ b/node/config/storage.go @@ -8,11 +8,10 @@ import ( "golang.org/x/xerrors" - "github.com/filecoin-project/lotus/storage/paths" - "github.com/filecoin-project/lotus/storage/sealer" + "github.com/filecoin-project/lotus/storage/sealer/storiface" ) -func StorageFromFile(path string, def *paths.StorageConfig) (*paths.StorageConfig, error) { +func StorageFromFile(path string, def *storiface.StorageConfig) (*storiface.StorageConfig, error) { file, err := os.Open(path) switch { case os.IsNotExist(err): @@ -28,8 +27,8 @@ func StorageFromFile(path string, def *paths.StorageConfig) (*paths.StorageConfi return StorageFromReader(file) } -func StorageFromReader(reader io.Reader) (*paths.StorageConfig, error) { - var cfg paths.StorageConfig +func StorageFromReader(reader io.Reader) (*storiface.StorageConfig, error) { + var cfg storiface.StorageConfig err := json.NewDecoder(reader).Decode(&cfg) if err != nil { return nil, err @@ -38,7 +37,7 @@ func StorageFromReader(reader io.Reader) (*paths.StorageConfig, error) { return &cfg, nil } -func WriteStorageFile(path string, config paths.StorageConfig) error { +func WriteStorageFile(path string, config storiface.StorageConfig) error { b, err := json.MarshalIndent(config, "", " ") if err != nil { return xerrors.Errorf("marshaling storage config: %w", err) @@ -50,28 +49,3 @@ func WriteStorageFile(path string, config paths.StorageConfig) error { return nil } - -func (c *StorageMiner) StorageManager() sealer.Config { - return sealer.Config{ - ParallelFetchLimit: c.Storage.ParallelFetchLimit, - AllowSectorDownload: c.Storage.AllowSectorDownload, - AllowAddPiece: c.Storage.AllowAddPiece, - AllowPreCommit1: c.Storage.AllowPreCommit1, - AllowPreCommit2: c.Storage.AllowPreCommit2, - AllowCommit: c.Storage.AllowCommit, - AllowUnseal: c.Storage.AllowUnseal, - AllowReplicaUpdate: c.Storage.AllowReplicaUpdate, - AllowProveReplicaUpdate2: c.Storage.AllowProveReplicaUpdate2, - AllowRegenSectorKey: c.Storage.AllowRegenSectorKey, - ResourceFiltering: c.Storage.ResourceFiltering, - DisallowRemoteFinalize: c.Storage.DisallowRemoteFinalize, - - LocalWorkerName: c.Storage.LocalWorkerName, - - Assigner: c.Storage.Assigner, - - ParallelCheckLimit: c.Proving.ParallelCheckLimit, - DisableBuiltinWindowPoSt: c.Proving.DisableBuiltinWindowPoSt, - DisableBuiltinWinningPoSt: c.Proving.DisableBuiltinWinningPoSt, - } -} diff --git a/node/config/types.go b/node/config/types.go index dbfa2e432..90d878b7e 100644 --- a/node/config/types.go +++ b/node/config/types.go @@ -4,7 +4,6 @@ import ( "github.com/ipfs/go-cid" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/storage/sealer" ) // // NOTE: ONLY PUT STRUCT DEFINITIONS IN THIS FILE @@ -27,6 +26,7 @@ type FullNode struct { Wallet Wallet Fees FeeConfig Chainstore Chainstore + Cluster UserRaftConfig } // // Common @@ -230,6 +230,23 @@ type ProvingConfig struct { // 'lotus-miner proving compute window-post 0' ParallelCheckLimit int + // Maximum amount of time a proving pre-check can take for a sector. If the check times out the sector will be skipped + // + // WARNING: Setting this value too low risks in sectors being skipped even though they are accessible, just reading the + // test challenge took longer than this timeout + // WARNING: Setting this value too high risks missing PoSt deadline in case IO operations related to this sector are + // blocked (e.g. in case of disconnected NFS mount) + SingleCheckTimeout Duration + + // Maximum amount of time a proving pre-check can take for an entire partition. If the check times out, sectors in + // the partition which didn't get checked on time will be skipped + // + // WARNING: Setting this value too low risks in sectors being skipped even though they are accessible, just reading the + // test challenge took longer than this timeout + // WARNING: Setting this value too high risks missing PoSt deadline in case IO operations related to this partition are + // blocked or slow + PartitionCheckTimeout Duration + // Disable Window PoSt computation on the lotus-miner process even if no window PoSt workers are present. // // WARNING: If no windowPoSt workers are connected, window PoSt WILL FAIL resulting in faulty sectors which will need @@ -452,7 +469,7 @@ type SealerConfig struct { // ResourceFiltering instructs the system which resource filtering strategy // to use when evaluating tasks against this worker. An empty value defaults // to "hardware". - ResourceFiltering sealer.ResourceFilteringStrategy + ResourceFiltering ResourceFilteringStrategy } type BatchFeeConfig struct { @@ -601,3 +618,30 @@ type Wallet struct { type FeeConfig struct { DefaultMaxFee types.FIL } + +type UserRaftConfig struct { + // EXPERIMENTAL. config to enabled node cluster with raft consensus + ClusterModeEnabled bool + // A folder to store Raft's data. + DataFolder string + // InitPeersetMultiAddr provides the list of initial cluster peers for new Raft + // peers (with no prior state). It is ignored when Raft was already + // initialized or when starting in staging mode. + InitPeersetMultiAddr []string + // LeaderTimeout specifies how long to wait for a leader before + // failing an operation. + WaitForLeaderTimeout Duration + // NetworkTimeout specifies how long before a Raft network + // operation is timed out + NetworkTimeout Duration + // CommitRetries specifies how many times we retry a failed commit until + // we give up. + CommitRetries int + // How long to wait between retries + CommitRetryDelay Duration + // BackupsRotate specifies the maximum number of Raft's DataFolder + // copies that we keep as backups (renaming) after cleanup. + BackupsRotate int + // Tracing enables propagation of contexts across binary boundaries. + Tracing bool +} diff --git a/node/impl/client/client.go b/node/impl/client/client.go index f69691e41..fef4d91e3 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -10,6 +10,7 @@ import ( "os" "sort" "strings" + "sync" "time" "github.com/ipfs/go-blockservice" @@ -97,6 +98,7 @@ type API struct { Imports dtypes.ClientImportMgr StorageBlockstoreAccessor storagemarket.BlockstoreAccessor RtvlBlockstoreAccessor rm.BlockstoreAccessor + ApiBlockstoreAccessor *retrievaladapter.APIBlockstoreAccessor DataTransfer dtypes.ClientDataTransfer Host host.Host @@ -845,6 +847,13 @@ func (a *API) doRetrieval(ctx context.Context, order api.RetrievalOrder, sel dat } id := a.Retrieval.NextID() + + if order.RemoteStore != nil { + if err := a.ApiBlockstoreAccessor.RegisterDealToRetrievalStore(id, *order.RemoteStore); err != nil { + return 0, xerrors.Errorf("registering api store: %w", err) + } + } + id, err = a.Retrieval.Retrieve( ctx, id, @@ -999,6 +1008,8 @@ func (a *API) outputCAR(ctx context.Context, ds format.DAGService, bs bstore.Blo roots[i] = dag.root } + var lk sync.Mutex + return dest.doWrite(func(w io.Writer) error { if err := car.WriteHeader(&car.CarHeader{ @@ -1011,13 +1022,29 @@ func (a *API) outputCAR(ctx context.Context, ds format.DAGService, bs bstore.Blo cs := cid.NewSet() for _, dagSpec := range dags { + dagSpec := dagSpec + if err := utils.TraverseDag( ctx, ds, root, dagSpec.selector, + func(node format.Node) error { + // if we're exporting merkle proofs for this dag, export all nodes read by the traversal + if dagSpec.exportAll { + lk.Lock() + defer lk.Unlock() + if cs.Visit(node.Cid()) { + err := util.LdWrite(w, node.Cid().Bytes(), node.RawData()) + if err != nil { + return xerrors.Errorf("writing block data: %w", err) + } + } + } + return nil + }, func(p traversal.Progress, n ipld.Node, r traversal.VisitReason) error { - if r == traversal.VisitReason_SelectionMatch { + if !dagSpec.exportAll && r == traversal.VisitReason_SelectionMatch { var c cid.Cid if p.LastBlock.Link == nil { c = root @@ -1082,8 +1109,9 @@ func (a *API) outputUnixFS(ctx context.Context, root cid.Cid, ds format.DAGServi } type dagSpec struct { - root cid.Cid - selector ipld.Node + root cid.Cid + selector ipld.Node + exportAll bool } func parseDagSpec(ctx context.Context, root cid.Cid, dsp []api.DagSpec, ds format.DAGService, car bool) ([]dagSpec, error) { @@ -1098,6 +1126,7 @@ func parseDagSpec(ctx context.Context, root cid.Cid, dsp []api.DagSpec, ds forma out := make([]dagSpec, len(dsp)) for i, spec := range dsp { + out[i].exportAll = spec.ExportMerkleProof if spec.DataSelector == nil { return nil, xerrors.Errorf("invalid DagSpec at position %d: `DataSelector` can not be nil", i) @@ -1131,6 +1160,7 @@ func parseDagSpec(ctx context.Context, root cid.Cid, dsp []api.DagSpec, ds forma ds, root, rsn, + nil, func(p traversal.Progress, n ipld.Node, r traversal.VisitReason) error { if r == traversal.VisitReason_SelectionMatch { if !car && p.LastBlock.Path.String() != p.Path.String() { diff --git a/node/impl/full.go b/node/impl/full.go index e1e7ac7a0..03a28eb75 100644 --- a/node/impl/full.go +++ b/node/impl/full.go @@ -34,6 +34,7 @@ type FullNodeAPI struct { full.MsigAPI full.WalletAPI full.SyncAPI + full.RaftAPI DS dtypes.MetadataDS NetworkName dtypes.NetworkName @@ -117,4 +118,12 @@ func (n *FullNodeAPI) NodeStatus(ctx context.Context, inclChainStatus bool) (sta return status, nil } +func (n *FullNodeAPI) RaftState(ctx context.Context) (*api.RaftStateData, error) { + return n.RaftAPI.GetRaftState(ctx) +} + +func (n *FullNodeAPI) RaftLeader(ctx context.Context) (peer.ID, error) { + return n.RaftAPI.Leader(ctx) +} + var _ api.FullNode = &FullNodeAPI{} diff --git a/node/impl/full/mpool.go b/node/impl/full/mpool.go index a2dbf0a86..31d134dac 100644 --- a/node/impl/full/mpool.go +++ b/node/impl/full/mpool.go @@ -44,7 +44,9 @@ type MpoolAPI struct { WalletAPI GasAPI - MessageSigner *messagesigner.MessageSigner + RaftAPI + + MessageSigner messagesigner.MsgSigner PushLocks *dtypes.MpoolLocker } @@ -131,7 +133,7 @@ func (a *MpoolAPI) MpoolClear(ctx context.Context, local bool) error { } func (m *MpoolModule) MpoolPush(ctx context.Context, smsg *types.SignedMessage) (cid.Cid, error) { - return m.Mpool.Push(ctx, smsg) + return m.Mpool.Push(ctx, smsg, true) } func (a *MpoolAPI) MpoolPushUntrusted(ctx context.Context, smsg *types.SignedMessage) (cid.Cid, error) { @@ -143,8 +145,29 @@ func (a *MpoolAPI) MpoolPushMessage(ctx context.Context, msg *types.Message, spe msg = &cp inMsg := *msg - // Check if this uuid has already been processed. Ignore if uuid is not populated - if (spec != nil) && (spec.MsgUuid != uuid.UUID{}) { + // Redirect to leader if current node is not leader. A single non raft based node is always the leader + if !a.RaftAPI.IsLeader(ctx) { + var signedMsg types.SignedMessage + redirected, err := a.RaftAPI.RedirectToLeader(ctx, "MpoolPushMessage", api.MpoolMessageWhole{Msg: msg, Spec: spec}, &signedMsg) + if err != nil { + return nil, err + } + // It's possible that the current node became the leader between the check and the redirect + // In that case, continue with rest of execution and only return signedMsg if something was redirected + if redirected { + return &signedMsg, nil + } + } + + // Generate spec and uuid if not available in the message + if spec == nil { + spec = &api.MessageSendSpec{ + MsgUuid: uuid.New(), + } + } else if (spec.MsgUuid == uuid.UUID{}) { + spec.MsgUuid = uuid.New() + } else { + // Check if this uuid has already been processed. Ignore if uuid is not populated signedMessage, err := a.MessageSigner.GetSignedMessage(ctx, spec.MsgUuid) if err == nil { log.Warnf("Message already processed. cid=%s", signedMessage.Cid()) @@ -196,7 +219,7 @@ func (a *MpoolAPI) MpoolPushMessage(ctx context.Context, msg *types.Message, spe } // Sign and push the message - signedMsg, err := a.MessageSigner.SignMessage(ctx, msg, func(smsg *types.SignedMessage) error { + signedMsg, err := a.MessageSigner.SignMessage(ctx, msg, spec, func(smsg *types.SignedMessage) error { if _, err := a.MpoolModuleAPI.MpoolPush(ctx, smsg); err != nil { return xerrors.Errorf("mpool push: failed to push message: %w", err) } @@ -207,11 +230,9 @@ func (a *MpoolAPI) MpoolPushMessage(ctx context.Context, msg *types.Message, spe } // Store uuid->signed message in datastore - if (spec != nil) && (spec.MsgUuid != uuid.UUID{}) { - err = a.MessageSigner.StoreSignedMessage(ctx, spec.MsgUuid, signedMsg) - if err != nil { - return nil, err - } + err = a.MessageSigner.StoreSignedMessage(ctx, spec.MsgUuid, signedMsg) + if err != nil { + return nil, err } return signedMsg, nil @@ -220,7 +241,7 @@ func (a *MpoolAPI) MpoolPushMessage(ctx context.Context, msg *types.Message, spe func (a *MpoolAPI) MpoolBatchPush(ctx context.Context, smsgs []*types.SignedMessage) ([]cid.Cid, error) { var messageCids []cid.Cid for _, smsg := range smsgs { - smsgCid, err := a.Mpool.Push(ctx, smsg) + smsgCid, err := a.Mpool.Push(ctx, smsg, true) if err != nil { return messageCids, err } diff --git a/node/impl/full/raft.go b/node/impl/full/raft.go new file mode 100644 index 000000000..8d665ddd5 --- /dev/null +++ b/node/impl/full/raft.go @@ -0,0 +1,50 @@ +package full + +import ( + "context" + + "github.com/libp2p/go-libp2p/core/peer" + "go.uber.org/fx" + "golang.org/x/xerrors" + + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/messagesigner" +) + +type RaftAPI struct { + fx.In + + MessageSigner *messagesigner.MessageSignerConsensus `optional:"true"` +} + +func (r *RaftAPI) GetRaftState(ctx context.Context) (*api.RaftStateData, error) { + if r.MessageSigner == nil { + return nil, xerrors.Errorf("raft consensus not enabled. Please check your configuration") + } + raftState, err := r.MessageSigner.GetRaftState(ctx) + if err != nil { + return nil, err + } + return &api.RaftStateData{NonceMap: raftState.NonceMap, MsgUuids: raftState.MsgUuids}, nil +} + +func (r *RaftAPI) Leader(ctx context.Context) (peer.ID, error) { + if r.MessageSigner == nil { + return "", xerrors.Errorf("raft consensus not enabled. Please check your configuration") + } + return r.MessageSigner.Leader(ctx) +} + +func (r *RaftAPI) IsLeader(ctx context.Context) bool { + if r.MessageSigner == nil { + return true + } + return r.MessageSigner.IsLeader(ctx) +} + +func (r *RaftAPI) RedirectToLeader(ctx context.Context, method string, arg interface{}, ret interface{}) (bool, error) { + if r.MessageSigner == nil { + return false, xerrors.Errorf("raft consensus not enabled. Please check your configuration") + } + return r.MessageSigner.RedirectToLeader(ctx, method, arg, ret) +} diff --git a/node/impl/full/sync.go b/node/impl/full/sync.go index 2809d41dc..fda55def1 100644 --- a/node/impl/full/sync.go +++ b/node/impl/full/sync.go @@ -2,6 +2,7 @@ package full import ( "context" + "os" "sync/atomic" "github.com/ipfs/go-cid" @@ -56,7 +57,7 @@ func (a *SyncAPI) SyncSubmitBlock(ctx context.Context, blk *types.BlockMsg) erro return xerrors.Errorf("loading parent block: %w", err) } - if a.SlashFilter != nil { + if a.SlashFilter != nil && os.Getenv("LOTUS_NO_SLASHFILTER") != "_yes_i_know_i_can_and_probably_will_lose_all_my_fil_and_power_" { if err := a.SlashFilter.MinedBlock(ctx, blk.Header, parent.Height); err != nil { log.Errorf(" SLASH FILTER ERROR: %s", err) return xerrors.Errorf(" SLASH FILTER ERROR: %w", err) diff --git a/node/impl/storminer.go b/node/impl/storminer.go index c26d50410..56aa7afde 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -1295,20 +1295,17 @@ func (sm *StorageMinerAPI) CreateBackup(ctx context.Context, fpath string) error return backup(ctx, sm.DS, fpath) } -func (sm *StorageMinerAPI) CheckProvable(ctx context.Context, pp abi.RegisteredPoStProof, sectors []storiface.SectorRef, expensive bool) (map[abi.SectorNumber]string, error) { - var rg storiface.RGetter - if expensive { - rg = func(ctx context.Context, id abi.SectorID) (cid.Cid, bool, error) { - si, err := sm.Miner.SectorsStatus(ctx, id.Number, false) - if err != nil { - return cid.Undef, false, err - } - if si.CommR == nil { - return cid.Undef, false, xerrors.Errorf("commr is nil") - } - - return *si.CommR, si.ReplicaUpdateMessage != nil, nil +func (sm *StorageMinerAPI) CheckProvable(ctx context.Context, pp abi.RegisteredPoStProof, sectors []storiface.SectorRef) (map[abi.SectorNumber]string, error) { + rg := func(ctx context.Context, id abi.SectorID) (cid.Cid, bool, error) { + si, err := sm.Miner.SectorsStatus(ctx, id.Number, false) + if err != nil { + return cid.Undef, false, err } + if si.CommR == nil { + return cid.Undef, false, xerrors.Errorf("commr is nil") + } + + return *si.CommR, si.ReplicaUpdateMessage != nil, nil } bad, err := sm.StorageMgr.CheckProvable(ctx, pp, sectors, rg) diff --git a/node/modules/client.go b/node/modules/client.go index 22fcbb00d..69f8db559 100644 --- a/node/modules/client.go +++ b/node/modules/client.go @@ -202,9 +202,9 @@ func StorageClient(lc fx.Lifecycle, h host.Host, dataTransfer dtypes.ClientDataT // RetrievalClient creates a new retrieval client attached to the client blockstore func RetrievalClient(forceOffChain bool) func(lc fx.Lifecycle, h host.Host, r repo.LockedRepo, dt dtypes.ClientDataTransfer, payAPI payapi.PaychAPI, resolver discovery.PeerResolver, - ds dtypes.MetadataDS, chainAPI full.ChainAPI, stateAPI full.StateAPI, accessor retrievalmarket.BlockstoreAccessor, j journal.Journal) (retrievalmarket.RetrievalClient, error) { + ds dtypes.MetadataDS, chainAPI full.ChainAPI, stateAPI full.StateAPI, accessor *retrievaladapter.APIBlockstoreAccessor, j journal.Journal) (retrievalmarket.RetrievalClient, error) { return func(lc fx.Lifecycle, h host.Host, r repo.LockedRepo, dt dtypes.ClientDataTransfer, payAPI payapi.PaychAPI, resolver discovery.PeerResolver, - ds dtypes.MetadataDS, chainAPI full.ChainAPI, stateAPI full.StateAPI, accessor retrievalmarket.BlockstoreAccessor, j journal.Journal) (retrievalmarket.RetrievalClient, error) { + ds dtypes.MetadataDS, chainAPI full.ChainAPI, stateAPI full.StateAPI, accessor *retrievaladapter.APIBlockstoreAccessor, j journal.Journal) (retrievalmarket.RetrievalClient, error) { adapter := retrievaladapter.NewRetrievalClientNode(forceOffChain, payAPI, chainAPI, stateAPI) network := rmnet.NewFromLibp2pHost(h) ds = namespace.Wrap(ds, datastore.NewKey("/retrievals/client")) diff --git a/node/modules/mpoolnonceapi.go b/node/modules/mpoolnonceapi.go index 00e704727..393bee32f 100644 --- a/node/modules/mpoolnonceapi.go +++ b/node/modules/mpoolnonceapi.go @@ -9,7 +9,7 @@ import ( "github.com/filecoin-project/go-address" - "github.com/filecoin-project/lotus/chain/messagesigner" + "github.com/filecoin-project/lotus/chain/messagepool" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/node/impl/full" ) @@ -104,4 +104,4 @@ func (a *MpoolNonceAPI) GetActor(ctx context.Context, addr address.Address, tsk return act, nil } -var _ messagesigner.MpoolNonceAPI = (*MpoolNonceAPI)(nil) +var _ messagepool.MpoolNonceAPI = (*MpoolNonceAPI)(nil) diff --git a/node/modules/rpc.go b/node/modules/rpc.go new file mode 100644 index 000000000..d76949737 --- /dev/null +++ b/node/modules/rpc.go @@ -0,0 +1,55 @@ +package modules + +import ( + "context" + + rpc "github.com/libp2p/go-libp2p-gorpc" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" + + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/types" + consensus "github.com/filecoin-project/lotus/lib/consensus/raft" + "github.com/filecoin-project/lotus/node/impl/full" +) + +type RPCHandler struct { + mpoolAPI full.MpoolAPI + cons *consensus.Consensus +} + +func NewRPCHandler(mpoolAPI full.MpoolAPI, cons *consensus.Consensus) *RPCHandler { + return &RPCHandler{mpoolAPI, cons} +} + +func (h *RPCHandler) MpoolPushMessage(ctx context.Context, msgWhole *api.MpoolMessageWhole, ret *types.SignedMessage) error { + signedMsg, err := h.mpoolAPI.MpoolPushMessage(ctx, msgWhole.Msg, msgWhole.Spec) + if err != nil { + return err + } + *ret = *signedMsg + return nil +} + +func (h *RPCHandler) AddPeer(ctx context.Context, pid peer.ID, ret *struct{}) error { + return h.cons.AddPeer(ctx, pid) +} + +// Add other consensus RPC calls here + +func NewRPCClient(host host.Host) *rpc.Client { + protocolID := protocol.ID("/rpc/lotus-chain/v0") + return rpc.NewClient(host, protocolID) +} + +func NewRPCServer(ctx context.Context, host host.Host, rpcHandler *RPCHandler) error { + + authF := func(pid peer.ID, svc, method string) bool { + return rpcHandler.cons.IsTrustedPeer(ctx, pid) + } + + protocolID := protocol.ID("/rpc/lotus-chain/v0") + rpcServer := rpc.NewServer(host, protocolID, rpc.WithAuthorizeFunc(authF)) + return rpcServer.RegisterName("Consensus", rpcHandler) +} diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index 4497271ed..04814ffdc 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -37,7 +37,6 @@ import ( storageimpl "github.com/filecoin-project/go-fil-markets/storagemarket/impl" "github.com/filecoin-project/go-fil-markets/storagemarket/impl/storedask" smnet "github.com/filecoin-project/go-fil-markets/storagemarket/network" - "github.com/filecoin-project/go-jsonrpc" "github.com/filecoin-project/go-jsonrpc/auth" "github.com/filecoin-project/go-paramfetch" "github.com/filecoin-project/go-state-types/abi" @@ -56,7 +55,6 @@ import ( "github.com/filecoin-project/lotus/chain/gen/slashfilter" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/journal" - "github.com/filecoin-project/lotus/lib/retry" "github.com/filecoin-project/lotus/markets" "github.com/filecoin-project/lotus/markets/dagstore" "github.com/filecoin-project/lotus/markets/idxprov" @@ -89,12 +87,7 @@ func (a *UuidWrapper) MpoolPushMessage(ctx context.Context, msg *types.Message, spec = new(api.MessageSendSpec) } spec.MsgUuid = uuid.New() - errorsToRetry := []error{&jsonrpc.RPCConnectionError{}} - initialBackoff, err := time.ParseDuration("1s") - if err != nil { - return nil, err - } - return retry.Retry(5, initialBackoff, errorsToRetry, func() (*types.SignedMessage, error) { return a.FullNode.MpoolPushMessage(ctx, msg, spec) }) + return a.FullNode.MpoolPushMessage(ctx, msg, spec) } func MakeUuidWrapper(a v1api.RawFullNodeAPI) v1api.FullNode { @@ -794,17 +787,17 @@ func LocalStorage(mctx helpers.MetricsCtx, lc fx.Lifecycle, ls paths.LocalStorag return paths.NewLocal(ctx, ls, si, urls) } -func RemoteStorage(lstor *paths.Local, si paths.SectorIndex, sa sealer.StorageAuth, sc sealer.Config) *paths.Remote { +func RemoteStorage(lstor *paths.Local, si paths.SectorIndex, sa sealer.StorageAuth, sc config.SealerConfig) *paths.Remote { return paths.NewRemote(lstor, si, http.Header(sa), sc.ParallelFetchLimit, &paths.DefaultPartialFileHandler{}) } -func SectorStorage(mctx helpers.MetricsCtx, lc fx.Lifecycle, lstor *paths.Local, stor paths.Store, ls paths.LocalStorage, si paths.SectorIndex, sc sealer.Config, ds dtypes.MetadataDS) (*sealer.Manager, error) { +func SectorStorage(mctx helpers.MetricsCtx, lc fx.Lifecycle, lstor *paths.Local, stor paths.Store, ls paths.LocalStorage, si paths.SectorIndex, sc config.SealerConfig, pc config.ProvingConfig, ds dtypes.MetadataDS) (*sealer.Manager, error) { ctx := helpers.LifecycleCtx(mctx, lc) wsts := statestore.New(namespace.Wrap(ds, WorkerCallsPrefix)) smsts := statestore.New(namespace.Wrap(ds, ManagerWorkPrefix)) - sst, err := sealer.New(ctx, lstor, stor, ls, si, sc, wsts, smsts) + sst, err := sealer.New(ctx, lstor, stor, ls, si, sc, pc, wsts, smsts) if err != nil { return nil, err } diff --git a/node/repo/fsrepo.go b/node/repo/fsrepo.go index 9327575dd..68550e389 100644 --- a/node/repo/fsrepo.go +++ b/node/repo/fsrepo.go @@ -25,8 +25,8 @@ import ( badgerbs "github.com/filecoin-project/lotus/blockstore/badger" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/node/config" - "github.com/filecoin-project/lotus/storage/paths" "github.com/filecoin-project/lotus/storage/sealer/fsutil" + "github.com/filecoin-project/lotus/storage/sealer/storiface" ) const ( @@ -572,26 +572,26 @@ func (fsr *fsLockedRepo) SetConfig(c func(interface{})) error { return nil } -func (fsr *fsLockedRepo) GetStorage() (paths.StorageConfig, error) { +func (fsr *fsLockedRepo) GetStorage() (storiface.StorageConfig, error) { fsr.storageLk.Lock() defer fsr.storageLk.Unlock() return fsr.getStorage(nil) } -func (fsr *fsLockedRepo) getStorage(def *paths.StorageConfig) (paths.StorageConfig, error) { +func (fsr *fsLockedRepo) getStorage(def *storiface.StorageConfig) (storiface.StorageConfig, error) { c, err := config.StorageFromFile(fsr.join(fsStorageConfig), def) if err != nil { - return paths.StorageConfig{}, err + return storiface.StorageConfig{}, err } return *c, nil } -func (fsr *fsLockedRepo) SetStorage(c func(*paths.StorageConfig)) error { +func (fsr *fsLockedRepo) SetStorage(c func(*storiface.StorageConfig)) error { fsr.storageLk.Lock() defer fsr.storageLk.Unlock() - sc, err := fsr.getStorage(&paths.StorageConfig{}) + sc, err := fsr.getStorage(&storiface.StorageConfig{}) if err != nil { return xerrors.Errorf("get storage: %w", err) } diff --git a/node/repo/interface.go b/node/repo/interface.go index 4f0294713..dd0839559 100644 --- a/node/repo/interface.go +++ b/node/repo/interface.go @@ -9,8 +9,8 @@ import ( "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/storage/paths" "github.com/filecoin-project/lotus/storage/sealer/fsutil" + "github.com/filecoin-project/lotus/storage/sealer/storiface" ) // BlockstoreDomain represents the domain of a blockstore. @@ -73,8 +73,8 @@ type LockedRepo interface { Config() (interface{}, error) SetConfig(func(interface{})) error - GetStorage() (paths.StorageConfig, error) - SetStorage(func(*paths.StorageConfig)) error + GetStorage() (storiface.StorageConfig, error) + SetStorage(func(*storiface.StorageConfig)) error Stat(path string) (fsutil.FsStat, error) DiskUsage(path string) (int64, error) diff --git a/node/repo/memrepo.go b/node/repo/memrepo.go index 53fd1eeee..61d960872 100644 --- a/node/repo/memrepo.go +++ b/node/repo/memrepo.go @@ -18,7 +18,6 @@ import ( "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/node/config" - "github.com/filecoin-project/lotus/storage/paths" "github.com/filecoin-project/lotus/storage/sealer/fsutil" "github.com/filecoin-project/lotus/storage/sealer/storiface" ) @@ -37,7 +36,7 @@ type MemRepo struct { keystore map[string]types.KeyInfo blockstore blockstore.Blockstore - sc *paths.StorageConfig + sc *storiface.StorageConfig tempDir string // holds the current config value @@ -59,13 +58,13 @@ func (lmem *lockedMemRepo) RepoType() RepoType { return lmem.t } -func (lmem *lockedMemRepo) GetStorage() (paths.StorageConfig, error) { +func (lmem *lockedMemRepo) GetStorage() (storiface.StorageConfig, error) { if err := lmem.checkToken(); err != nil { - return paths.StorageConfig{}, err + return storiface.StorageConfig{}, err } if lmem.mem.sc == nil { - lmem.mem.sc = &paths.StorageConfig{StoragePaths: []paths.LocalPath{ + lmem.mem.sc = &storiface.StorageConfig{StoragePaths: []storiface.LocalPath{ {Path: lmem.Path()}, }} } @@ -73,7 +72,7 @@ func (lmem *lockedMemRepo) GetStorage() (paths.StorageConfig, error) { return *lmem.mem.sc, nil } -func (lmem *lockedMemRepo) SetStorage(c func(*paths.StorageConfig)) error { +func (lmem *lockedMemRepo) SetStorage(c func(*storiface.StorageConfig)) error { if err := lmem.checkToken(); err != nil { return err } @@ -126,14 +125,14 @@ func (lmem *lockedMemRepo) Path() string { } func (lmem *lockedMemRepo) initSectorStore(t string) { - if err := config.WriteStorageFile(filepath.Join(t, fsStorageConfig), paths.StorageConfig{ - StoragePaths: []paths.LocalPath{ + if err := config.WriteStorageFile(filepath.Join(t, fsStorageConfig), storiface.StorageConfig{ + StoragePaths: []storiface.LocalPath{ {Path: t}, }}); err != nil { panic(err) } - b, err := json.MarshalIndent(&paths.LocalStorageMeta{ + b, err := json.MarshalIndent(&storiface.LocalStorageMeta{ ID: storiface.ID(uuid.New().String()), Weight: 10, CanSeal: true, diff --git a/node/rpc.go b/node/rpc.go index 2c85c71be..96a81a383 100644 --- a/node/rpc.go +++ b/node/rpc.go @@ -3,13 +3,16 @@ package node import ( "context" "encoding/json" + "fmt" "net" "net/http" _ "net/http/pprof" "runtime" "strconv" + "github.com/google/uuid" "github.com/gorilla/mux" + "github.com/gorilla/websocket" "github.com/ipfs/go-cid" logging "github.com/ipfs/go-log/v2" "github.com/multiformats/go-multiaddr" @@ -23,6 +26,7 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/api/v1api" + bstore "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/lib/rpcenc" "github.com/filecoin-project/lotus/metrics" "github.com/filecoin-project/lotus/metrics/proxy" @@ -92,6 +96,7 @@ func FullNodeHandler(a v1api.FullNode, permissioned bool, opts ...jsonrpc.Server // Import handler handleImportFunc := handleImport(a.(*impl.FullNodeAPI)) handleExportFunc := handleExport(a.(*impl.FullNodeAPI)) + handleRemoteStoreFunc := handleRemoteStore(a.(*impl.FullNodeAPI)) if permissioned { importAH := &auth.Handler{ Verify: a.AuthVerify, @@ -104,9 +109,16 @@ func FullNodeHandler(a v1api.FullNode, permissioned bool, opts ...jsonrpc.Server Next: handleExportFunc, } m.Handle("/rest/v0/export", exportAH) + + storeAH := &auth.Handler{ + Verify: a.AuthVerify, + Next: handleRemoteStoreFunc, + } + m.Handle("/rest/v0/store/{uuid}", storeAH) } else { m.HandleFunc("/rest/v0/import", handleImportFunc) m.HandleFunc("/rest/v0/export", handleExportFunc) + m.HandleFunc("/rest/v0/store/{uuid}", handleRemoteStoreFunc) } // debugging @@ -256,3 +268,34 @@ func handleFractionOpt(name string, setter func(int)) http.HandlerFunc { setter(fr) } } + +var upgrader = websocket.Upgrader{ + CheckOrigin: func(r *http.Request) bool { + return true + }, +} + +func handleRemoteStore(a *impl.FullNodeAPI) func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + id, err := uuid.Parse(vars["uuid"]) + if err != nil { + http.Error(w, fmt.Sprintf("parse uuid: %s", err), http.StatusBadRequest) + return + } + + c, err := upgrader.Upgrade(w, r, nil) + if err != nil { + log.Error(err) + w.WriteHeader(500) + return + } + + nstore := bstore.NewNetworkStoreWS(c) + if err := a.ApiBlockstoreAccessor.RegisterApiStore(id, nstore); err != nil { + log.Errorw("registering api bstore", "error", err) + _ = c.Close() + return + } + } +} diff --git a/scripts/build-appimage-bundle.sh b/scripts/build-appimage-bundle.sh index d99b459b9..d4ce6de77 100755 --- a/scripts/build-appimage-bundle.sh +++ b/scripts/build-appimage-bundle.sh @@ -20,7 +20,7 @@ PID="$!" trap "kill -9 ${PID}" EXIT sleep 30 -cp "../appimage/Lotus-${CIRCLE_TAG}-x86_64.AppImage" . +cp "/tmp/workspace/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/storage/paths/local.go b/storage/paths/local.go index ec146ba5a..2182f24ef 100644 --- a/storage/paths/local.go +++ b/storage/paths/local.go @@ -17,71 +17,14 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/proof" + "github.com/filecoin-project/lotus/lib/result" "github.com/filecoin-project/lotus/storage/sealer/fsutil" "github.com/filecoin-project/lotus/storage/sealer/storiface" ) -// LocalStorageMeta [path]/sectorstore.json -type LocalStorageMeta struct { - ID storiface.ID - - // A high weight means data is more likely to be stored in this path - Weight uint64 // 0 = readonly - - // Intermediate data for the sealing process will be stored here - CanSeal bool - - // Finalized sectors that will be proved over time will be stored here - CanStore bool - - // MaxStorage specifies the maximum number of bytes to use for sector storage - // (0 = unlimited) - MaxStorage uint64 - - // List of storage groups this path belongs to - Groups []string - - // List of storage groups to which data from this path can be moved. If none - // are specified, allow to all - AllowTo []string - - // AllowTypes lists sector file types which are allowed to be put into this - // path. If empty, all file types are allowed. - // - // Valid values: - // - "unsealed" - // - "sealed" - // - "cache" - // - "update" - // - "update-cache" - // Any other value will generate a warning and be ignored. - AllowTypes []string - - // DenyTypes lists sector file types which aren't allowed to be put into this - // path. - // - // Valid values: - // - "unsealed" - // - "sealed" - // - "cache" - // - "update" - // - "update-cache" - // Any other value will generate a warning and be ignored. - DenyTypes []string -} - -// StorageConfig .lotusstorage/storage.json -type StorageConfig struct { - StoragePaths []LocalPath -} - -type LocalPath struct { - Path string -} - type LocalStorage interface { - GetStorage() (StorageConfig, error) - SetStorage(func(*StorageConfig)) error + GetStorage() (storiface.StorageConfig, error) + SetStorage(func(*storiface.StorageConfig)) error Stat(path string) (fsutil.FsStat, error) @@ -213,7 +156,7 @@ func (st *Local) OpenPath(ctx context.Context, p string) error { return xerrors.Errorf("reading storage metadata for %s: %w", p, err) } - var meta LocalStorageMeta + var meta storiface.LocalStorageMeta if err := json.Unmarshal(mb, &meta); err != nil { return xerrors.Errorf("unmarshalling storage metadata for %s: %w", p, err) } @@ -309,7 +252,7 @@ func (st *Local) Redeclare(ctx context.Context, filterId *storiface.ID, dropMiss return xerrors.Errorf("reading storage metadata for %s: %w", p.local, err) } - var meta LocalStorageMeta + var meta storiface.LocalStorageMeta if err := json.Unmarshal(mb, &meta); err != nil { return xerrors.Errorf("unmarshalling storage metadata for %s: %w", p.local, err) } @@ -816,20 +759,22 @@ func (st *Local) GenerateSingleVanillaProof(ctx context.Context, minerID abi.Act ProofType: si.SealProof, } - var cache string - var sealed string + var cache, sealed, cacheID, sealedID string + if si.Update { - src, _, err := st.AcquireSector(ctx, sr, storiface.FTUpdate|storiface.FTUpdateCache, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove) + src, si, err := st.AcquireSector(ctx, sr, storiface.FTUpdate|storiface.FTUpdateCache, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove) if err != nil { return nil, xerrors.Errorf("acquire sector: %w", err) } cache, sealed = src.UpdateCache, src.Update + cacheID, sealedID = si.UpdateCache, si.Update } else { - src, _, err := st.AcquireSector(ctx, sr, storiface.FTSealed|storiface.FTCache, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove) + src, si, err := st.AcquireSector(ctx, sr, storiface.FTSealed|storiface.FTCache, storiface.FTNone, storiface.PathStorage, storiface.AcquireMove) if err != nil { return nil, xerrors.Errorf("acquire sector: %w", err) } cache, sealed = src.Cache, src.Sealed + cacheID, sealedID = si.Cache, si.Sealed } if sealed == "" || cache == "" { @@ -847,7 +792,22 @@ func (st *Local) GenerateSingleVanillaProof(ctx context.Context, minerID abi.Act SealedSectorPath: sealed, } - return ffi.GenerateSingleVanillaProof(psi, si.Challenge) + start := time.Now() + + resCh := make(chan result.Result[[]byte], 1) + go func() { + resCh <- result.Wrap(ffi.GenerateSingleVanillaProof(psi, si.Challenge)) + }() + + select { + case r := <-resCh: + return r.Unwrap() + case <-ctx.Done(): + log.Errorw("failed to generate valilla PoSt proof before context cancellation", "err", ctx.Err(), "duration", time.Now().Sub(start), "cache-id", cacheID, "sealed-id", sealedID, "cache", cache, "sealed", sealed) + + // this will leave the GenerateSingleVanillaProof goroutine hanging, but that's still less bad than failing PoSt + return nil, xerrors.Errorf("failed to generate vanilla proof before context cancellation: %w", ctx.Err()) + } } var _ Store = &Local{} diff --git a/storage/paths/local_test.go b/storage/paths/local_test.go index 83e8e27fd..6b9f4a545 100644 --- a/storage/paths/local_test.go +++ b/storage/paths/local_test.go @@ -19,18 +19,18 @@ const pathSize = 16 << 20 type TestingLocalStorage struct { root string - c StorageConfig + c storiface.StorageConfig } func (t *TestingLocalStorage) DiskUsage(path string) (int64, error) { return 1, nil } -func (t *TestingLocalStorage) GetStorage() (StorageConfig, error) { +func (t *TestingLocalStorage) GetStorage() (storiface.StorageConfig, error) { return t.c, nil } -func (t *TestingLocalStorage) SetStorage(f func(*StorageConfig)) error { +func (t *TestingLocalStorage) SetStorage(f func(*storiface.StorageConfig)) error { f(&t.c) return nil } @@ -51,7 +51,7 @@ func (t *TestingLocalStorage) init(subpath string) error { metaFile := filepath.Join(path, MetaFile) - meta := &LocalStorageMeta{ + meta := &storiface.LocalStorageMeta{ ID: storiface.ID(uuid.New().String()), Weight: 1, CanSeal: true, diff --git a/storage/paths/localstorage_cached.go b/storage/paths/localstorage_cached.go index 4ccabb15e..cac0a44b6 100644 --- a/storage/paths/localstorage_cached.go +++ b/storage/paths/localstorage_cached.go @@ -7,6 +7,7 @@ import ( lru "github.com/hashicorp/golang-lru" "github.com/filecoin-project/lotus/storage/sealer/fsutil" + "github.com/filecoin-project/lotus/storage/sealer/storiface" ) var StatTimeout = 5 * time.Second @@ -47,11 +48,11 @@ type diskUsageResult struct { time time.Time } -func (c *cachedLocalStorage) GetStorage() (StorageConfig, error) { +func (c *cachedLocalStorage) GetStorage() (storiface.StorageConfig, error) { return c.base.GetStorage() } -func (c *cachedLocalStorage) SetStorage(f func(*StorageConfig)) error { +func (c *cachedLocalStorage) SetStorage(f func(*storiface.StorageConfig)) error { return c.base.SetStorage(f) } diff --git a/storage/paths/remote_test.go b/storage/paths/remote_test.go index a7bd6bf40..2d7fe2c73 100644 --- a/storage/paths/remote_test.go +++ b/storage/paths/remote_test.go @@ -38,7 +38,7 @@ func createTestStorage(t *testing.T, p string, seal bool, att ...*paths.Local) s } } - cfg := &paths.LocalStorageMeta{ + cfg := &storiface.LocalStorageMeta{ ID: storiface.ID(uuid.New().String()), Weight: 10, CanSeal: seal, @@ -77,8 +77,8 @@ func TestMoveShared(t *testing.T) { _ = lr.Close() }) - err = lr.SetStorage(func(config *paths.StorageConfig) { - *config = paths.StorageConfig{} + err = lr.SetStorage(func(config *storiface.StorageConfig) { + *config = storiface.StorageConfig{} }) require.NoError(t, err) diff --git a/storage/pipeline/fsm.go b/storage/pipeline/fsm.go index 0a75d88c8..25fd6fcef 100644 --- a/storage/pipeline/fsm.go +++ b/storage/pipeline/fsm.go @@ -188,6 +188,11 @@ var fsmPlanners = map[SectorState]func(events []statemachine.Event, state *Secto SubmitReplicaUpdate: planOne( on(SectorReplicaUpdateSubmitted{}, ReplicaUpdateWait), on(SectorSubmitReplicaUpdateFailed{}, ReplicaUpdateFailed), + on(SectorDeadlineImmutable{}, WaitMutable), + ), + WaitMutable: planOne( + on(SectorDeadlineMutable{}, SubmitReplicaUpdate), + on(SectorAbortUpgrade{}, AbortUpgrade), ), ReplicaUpdateWait: planOne( on(SectorReplicaUpdateLanded{}, UpdateActivating), @@ -525,6 +530,8 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta return m.handleProveReplicaUpdate, processed, nil case SubmitReplicaUpdate: return m.handleSubmitReplicaUpdate, processed, nil + case WaitMutable: + return m.handleWaitMutable, processed, nil case ReplicaUpdateWait: return m.handleReplicaUpdateWait, processed, nil case FinalizeReplicaUpdate: diff --git a/storage/pipeline/fsm_events.go b/storage/pipeline/fsm_events.go index f92f527ad..122691ca3 100644 --- a/storage/pipeline/fsm_events.go +++ b/storage/pipeline/fsm_events.go @@ -323,6 +323,9 @@ func (evt SectorStartCCUpdate) apply(state *SectorInfo) { // Clear filler piece but remember in case of abort state.CCPieces = state.Pieces state.Pieces = nil + + // Clear CreationTime in case this sector was accepting piece data previously + state.CreationTime = 0 } type SectorReplicaUpdate struct { @@ -458,6 +461,7 @@ func (evt SectorRevertUpgradeToProving) apply(state *SectorInfo) { state.ReplicaUpdateMessage = nil state.Pieces = state.CCPieces state.CCPieces = nil + state.CreationTime = 0 } type SectorRetrySubmitReplicaUpdateWait struct{} @@ -472,6 +476,14 @@ type SectorSubmitReplicaUpdateFailed struct{} func (evt SectorSubmitReplicaUpdateFailed) apply(state *SectorInfo) {} +type SectorDeadlineImmutable struct{} + +func (evt SectorDeadlineImmutable) apply(state *SectorInfo) {} + +type SectorDeadlineMutable struct{} + +func (evt SectorDeadlineMutable) apply(state *SectorInfo) {} + type SectorReleaseKeyFailed struct{ error } func (evt SectorReleaseKeyFailed) FormatError(xerrors.Printer) (next error) { diff --git a/storage/pipeline/fsm_test.go b/storage/pipeline/fsm_test.go index 53f85d1dc..f12b66f93 100644 --- a/storage/pipeline/fsm_test.go +++ b/storage/pipeline/fsm_test.go @@ -390,3 +390,64 @@ func TestTicketExpired(t *testing.T) { } } } + +func TestCreationTimeCleared(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]SectorState{}, + byState: map[SectorState]int64{}, + }, + notifee: func(before, after SectorInfo) { + notif = append(notif, struct{ before, after SectorInfo }{before, after}) + }, + }, + t: t, + state: &SectorInfo{State: Available}, + } + + // sector starts with zero CreationTime + m.planSingle(SectorStartCCUpdate{}) + require.Equal(m.t, m.state.State, SnapDealsWaitDeals) + + require.Equal(t, int64(0), m.state.CreationTime) + + // First AddPiece will set CreationTime + m.planSingle(SectorAddPiece{}) + require.Equal(m.t, m.state.State, SnapDealsAddPiece) + + require.NotEqual(t, int64(0), m.state.CreationTime) + + m.planSingle(SectorPieceAdded{}) + require.Equal(m.t, m.state.State, SnapDealsWaitDeals) + + // abort shoult clean up CreationTime + m.planSingle(SectorAbortUpgrade{}) + require.Equal(m.t, m.state.State, AbortUpgrade) + + require.NotEqual(t, int64(0), m.state.CreationTime) + + m.planSingle(SectorRevertUpgradeToProving{}) + require.Equal(m.t, m.state.State, Proving) + + require.Equal(t, int64(0), m.state.CreationTime) + + m.planSingle(SectorMarkForUpdate{}) + + // in case CreationTime was set for whatever reason (lotus bug / manual sector state change) + // make sure we clean it up when starting upgrade + m.state.CreationTime = 325 + m.planSingle(SectorStartCCUpdate{}) + require.Equal(m.t, m.state.State, SnapDealsWaitDeals) + + require.Equal(t, int64(0), m.state.CreationTime) + + // "First" AddPiece will set CreationTime + m.planSingle(SectorAddPiece{}) + require.Equal(m.t, m.state.State, SnapDealsAddPiece) + + require.NotEqual(t, int64(0), m.state.CreationTime) +} diff --git a/storage/pipeline/input.go b/storage/pipeline/input.go index 631e84455..3499c855c 100644 --- a/storage/pipeline/input.go +++ b/storage/pipeline/input.go @@ -6,6 +6,7 @@ import ( "time" "github.com/ipfs/go-cid" + "go.uber.org/zap" "golang.org/x/xerrors" "github.com/filecoin-project/go-commp-utils/zerocomm" @@ -91,12 +92,17 @@ func (m *Sealing) handleWaitDeals(ctx statemachine.Context, sector SectorInfo) e } func (m *Sealing) maybeStartSealing(ctx statemachine.Context, sector SectorInfo, used abi.UnpaddedPieceSize) (bool, error) { + log := log.WithOptions(zap.Fields( + zap.Uint64("sector", uint64(sector.SectorNumber)), + zap.Int("deals", len(sector.dealIDs())), + )) + now := time.Now() st := m.sectorTimers[m.minerSectorID(sector.SectorNumber)] if st != nil { if !st.Stop() { // timer expired, SectorStartPacking was/is being sent // we send another SectorStartPacking in case one was sent in the handleAddPiece state - log.Infow("starting to seal deal sector", "sector", sector.SectorNumber, "trigger", "wait-timeout") + log.Infow("starting to seal deal sector", "trigger", "wait-timeout") return true, ctx.Send(SectorStartPacking{}) } } @@ -113,13 +119,13 @@ func (m *Sealing) maybeStartSealing(ctx statemachine.Context, sector SectorInfo, if len(sector.dealIDs()) >= maxDeals { // can't accept more deals - log.Infow("starting to seal deal sector", "sector", sector.SectorNumber, "trigger", "maxdeals") + log.Infow("starting to seal deal sector", "trigger", "maxdeals") return true, ctx.Send(SectorStartPacking{}) } if used.Padded() == abi.PaddedPieceSize(ssize) { // sector full - log.Infow("starting to seal deal sector", "sector", sector.SectorNumber, "trigger", "filled") + log.Infow("starting to seal deal sector", "trigger", "filled") return true, ctx.Send(SectorStartPacking{}) } @@ -149,15 +155,15 @@ func (m *Sealing) maybeStartSealing(ctx statemachine.Context, sector SectorInfo, } if now.After(sealTime) { - log.Infow("starting to seal deal sector", "sector", sector.SectorNumber, "trigger", "wait-timeout") + log.Infow("starting to seal deal sector", "trigger", "wait-timeout", "creation", sector.CreationTime) return true, ctx.Send(SectorStartPacking{}) } m.sectorTimers[m.minerSectorID(sector.SectorNumber)] = time.AfterFunc(sealTime.Sub(now), func() { - log.Infow("starting to seal deal sector", "sector", sector.SectorNumber, "trigger", "wait-timer") + log.Infow("starting to seal deal sector", "trigger", "wait-timer") if err := ctx.Send(SectorStartPacking{}); err != nil { - log.Errorw("sending SectorStartPacking event failed", "sector", sector.SectorNumber, "error", err) + log.Errorw("sending SectorStartPacking event failed", "error", err) } }) } diff --git a/storage/pipeline/sector_state.go b/storage/pipeline/sector_state.go index 7a56c136b..84c08f43b 100644 --- a/storage/pipeline/sector_state.go +++ b/storage/pipeline/sector_state.go @@ -53,6 +53,7 @@ var ExistSectorStateList = map[SectorState]struct{}{ UpdateReplica: {}, ProveReplicaUpdate: {}, SubmitReplicaUpdate: {}, + WaitMutable: {}, ReplicaUpdateWait: {}, UpdateActivating: {}, ReleaseSectorKey: {}, @@ -110,6 +111,7 @@ const ( UpdateReplica SectorState = "UpdateReplica" ProveReplicaUpdate SectorState = "ProveReplicaUpdate" SubmitReplicaUpdate SectorState = "SubmitReplicaUpdate" + WaitMutable SectorState = "WaitMutable" ReplicaUpdateWait SectorState = "ReplicaUpdateWait" FinalizeReplicaUpdate SectorState = "FinalizeReplicaUpdate" UpdateActivating SectorState = "UpdateActivating" @@ -161,7 +163,7 @@ func toStatState(st SectorState, finEarly bool) statSectorState { return sstStaging case Packing, GetTicket, PreCommit1, PreCommit2, PreCommitting, PreCommitWait, SubmitPreCommitBatch, PreCommitBatchWait, WaitSeed, Committing, CommitFinalize, FinalizeSector, SnapDealsPacking, UpdateReplica, ProveReplicaUpdate, FinalizeReplicaUpdate, ReceiveSector: return sstSealing - case SubmitCommit, CommitWait, SubmitCommitAggregate, CommitAggregateWait, SubmitReplicaUpdate, ReplicaUpdateWait: + case SubmitCommit, CommitWait, SubmitCommitAggregate, CommitAggregateWait, WaitMutable, SubmitReplicaUpdate, ReplicaUpdateWait: if finEarly { // we use statSectorState for throttling storage use. With FinalizeEarly // we can consider sectors in states after CommitFinalize as finalized, so @@ -184,6 +186,7 @@ func IsUpgradeState(st SectorState) bool { UpdateReplica, ProveReplicaUpdate, SubmitReplicaUpdate, + WaitMutable, SnapDealsAddPieceFailed, SnapDealsDealsExpired, diff --git a/storage/pipeline/states_failed.go b/storage/pipeline/states_failed.go index b90833b2d..942f4f8dc 100644 --- a/storage/pipeline/states_failed.go +++ b/storage/pipeline/states_failed.go @@ -257,8 +257,9 @@ func (m *Sealing) handleSubmitReplicaUpdateFailed(ctx statemachine.Context, sect return nil } if !active { - log.Errorf("sector marked for upgrade %d no longer active, aborting upgrade", sector.SectorNumber) - return ctx.Send(SectorAbortUpgrade{}) + err := xerrors.Errorf("sector marked for upgrade %d no longer active, aborting upgrade", sector.SectorNumber) + log.Errorf(err.Error()) + return ctx.Send(SectorAbortUpgrade{err}) } return ctx.Send(SectorRetrySubmitReplicaUpdate{}) @@ -421,6 +422,8 @@ func (m *Sealing) handleAbortUpgrade(ctx statemachine.Context, sector SectorInfo return xerrors.Errorf("should never reach AbortUpgrade as a non-CCUpdate sector") } + m.cleanupAssignedDeals(sector) + // Remove snap deals replica if any if err := m.sealer.ReleaseReplicaUpgrade(ctx.Context(), m.minerSector(sector.SectorType, sector.SectorNumber)); err != nil { return xerrors.Errorf("removing CC update files from sector storage") diff --git a/storage/pipeline/states_proving.go b/storage/pipeline/states_proving.go index f4b957249..bed61a452 100644 --- a/storage/pipeline/states_proving.go +++ b/storage/pipeline/states_proving.go @@ -138,6 +138,12 @@ func (m *Sealing) handleProvingSector(ctx statemachine.Context, sector SectorInf delete(m.available, m.minerSectorID(sector.SectorNumber)) m.inputLk.Unlock() + // guard against manual state updates from snap-deals states into Proving + // note: normally snap deals should be aborted through the abort command, but + // apparently sometimes some SPs would use update-state to force the sector back + // into the Proving state, breaking the deal input pipeline in the process. + m.cleanupAssignedDeals(sector) + // TODO: Watch termination // TODO: Auto-extend if set diff --git a/storage/pipeline/states_replica_update.go b/storage/pipeline/states_replica_update.go index 9170f5fb5..6a4708379 100644 --- a/storage/pipeline/states_replica_update.go +++ b/storage/pipeline/states_replica_update.go @@ -57,8 +57,9 @@ func (m *Sealing) handleProveReplicaUpdate(ctx statemachine.Context, sector Sect return nil } if !active { - log.Errorf("sector marked for upgrade %d no longer active, aborting upgrade", sector.SectorNumber) - return ctx.Send(SectorAbortUpgrade{}) + err := xerrors.Errorf("sector marked for upgrade %d no longer active, aborting upgrade", sector.SectorNumber) + log.Errorf(err.Error()) + return ctx.Send(SectorAbortUpgrade{err}) } vanillaProofs, err := m.sealer.ProveReplicaUpdate1(sector.sealingCtx(ctx.Context()), m.minerSector(sector.SectorType, sector.SectorNumber), *sector.CommR, *sector.UpdateSealed, *sector.UpdateUnsealed) @@ -97,6 +98,17 @@ func (m *Sealing) handleSubmitReplicaUpdate(ctx statemachine.Context, sector Sec log.Errorf("handleSubmitReplicaUpdate: api error, not proceeding: %+v", err) return nil } + + dlinfo, err := m.Api.StateMinerProvingDeadline(ctx.Context(), m.maddr, ts.Key()) + if err != nil { + log.Errorf("handleSubmitReplicaUpdate: api error, not proceeding: %w", err) + } + // if sector's deadline is immutable wait in a non error state + // sector's deadline is immutable if it is the current deadline or the next deadline + if sl.Deadline == dlinfo.Index || (dlinfo.Index+1)%dlinfo.WPoStPeriodDeadlines == sl.Deadline { + return ctx.Send(SectorDeadlineImmutable{}) + } + updateProof, err := sector.SectorType.RegisteredUpdateProof() if err != nil { log.Errorf("failed to get update proof type from seal proof: %+v", err) @@ -187,6 +199,67 @@ func (m *Sealing) handleSubmitReplicaUpdate(ctx statemachine.Context, sector Sec return ctx.Send(SectorReplicaUpdateSubmitted{Message: mcid}) } +func (m *Sealing) handleWaitMutable(ctx statemachine.Context, sector SectorInfo) error { + immutable := true + for immutable { + ts, err := m.Api.ChainHead(ctx.Context()) + if err != nil { + log.Errorf("handleWaitMutable: api error, not proceeding: %+v", err) + return nil + } + + sl, err := m.Api.StateSectorPartition(ctx.Context(), m.maddr, sector.SectorNumber, ts.Key()) + if err != nil { + log.Errorf("handleWaitMutable: api error, not proceeding: %+v", err) + return nil + } + + dlinfo, err := m.Api.StateMinerProvingDeadline(ctx.Context(), m.maddr, ts.Key()) + if err != nil { + log.Errorf("handleWaitMutable: api error, not proceeding: %w", err) + return nil + } + + sectorDeadlineOpen := sl.Deadline == dlinfo.Index + sectorDeadlineNext := (dlinfo.Index+1)%dlinfo.WPoStPeriodDeadlines == sl.Deadline + immutable = sectorDeadlineOpen || sectorDeadlineNext + + // Sleep for immutable epochs + if immutable { + dlineEpochsRemaining := dlinfo.NextOpen() - ts.Height() + var targetEpoch abi.ChainEpoch + if sectorDeadlineOpen { + // sleep for remainder of deadline + targetEpoch = ts.Height() + dlineEpochsRemaining + } else { + // sleep for remainder of deadline and next one + targetEpoch = ts.Height() + dlineEpochsRemaining + dlinfo.WPoStChallengeWindow + } + + atHeight := make(chan struct{}) + err := m.events.ChainAt(ctx.Context(), func(context.Context, *types.TipSet, abi.ChainEpoch) error { + close(atHeight) + return nil + }, func(ctx context.Context, ts *types.TipSet) error { + log.Warn("revert in handleWaitMutable") + return nil + }, 5, targetEpoch) + if err != nil { + log.Errorf("handleWaitMutalbe: events error: api error, not proceeding: %w", err) + return nil + } + + select { + case <-atHeight: + case <-ctx.Context().Done(): + return ctx.Context().Err() + } + } + + } + return ctx.Send(SectorDeadlineMutable{}) +} + func (m *Sealing) handleReplicaUpdateWait(ctx statemachine.Context, sector SectorInfo) error { if sector.ReplicaUpdateMessage == nil { log.Errorf("handleReplicaUpdateWait: no replica update message cid recorded") diff --git a/storage/pipeline/states_sealing.go b/storage/pipeline/states_sealing.go index b40a9bf45..5b5d2e372 100644 --- a/storage/pipeline/states_sealing.go +++ b/storage/pipeline/states_sealing.go @@ -33,7 +33,7 @@ import ( var DealSectorPriority = 1024 var MaxTicketAge = policy.MaxPreCommitRandomnessLookback -func (m *Sealing) handlePacking(ctx statemachine.Context, sector SectorInfo) error { +func (m *Sealing) cleanupAssignedDeals(sector SectorInfo) { m.inputLk.Lock() // make sure we are not accepting deals into this sector for _, c := range m.assignedPieces[m.minerSectorID(sector.SectorNumber)] { @@ -51,6 +51,10 @@ func (m *Sealing) handlePacking(ctx statemachine.Context, sector SectorInfo) err delete(m.openSectors, m.minerSectorID(sector.SectorNumber)) delete(m.assignedPieces, m.minerSectorID(sector.SectorNumber)) m.inputLk.Unlock() +} + +func (m *Sealing) handlePacking(ctx statemachine.Context, sector SectorInfo) error { + m.cleanupAssignedDeals(sector) // if this is a snapdeals sector, but it ended up not having any deals, abort the upgrade if sector.State == SnapDealsPacking && !sector.hasDeals() { diff --git a/storage/sealer/faults.go b/storage/sealer/faults.go index e05bbb7b8..db7b75bec 100644 --- a/storage/sealer/faults.go +++ b/storage/sealer/faults.go @@ -5,7 +5,6 @@ import ( "crypto/rand" "fmt" "sync" - "time" "golang.org/x/xerrors" @@ -15,8 +14,6 @@ import ( "github.com/filecoin-project/lotus/storage/sealer/storiface" ) -var PostCheckTimeout = 160 * time.Second - // FaultTracker TODO: Track things more actively type FaultTracker interface { CheckProvable(ctx context.Context, pp abi.RegisteredPoStProof, sectors []storiface.SectorRef, rg storiface.RGetter) (map[abi.SectorID]string, error) @@ -50,6 +47,12 @@ func (m *Manager) CheckProvable(ctx context.Context, pp abi.RegisteredPoStProof, badLk.Unlock() } + if m.partitionCheckTimeout > 0 { + var cancel2 context.CancelFunc + ctx, cancel2 = context.WithTimeout(ctx, m.partitionCheckTimeout) + defer cancel2() + } + var wg sync.WaitGroup wg.Add(len(sectors)) @@ -57,7 +60,9 @@ func (m *Manager) CheckProvable(ctx context.Context, pp abi.RegisteredPoStProof, select { case throttle <- struct{}{}: case <-ctx.Done(): - return nil, ctx.Err() + addBad(sector.ID, fmt.Sprintf("waiting for check worker: %s", ctx.Err())) + wg.Done() + continue } go func(sector storiface.SectorRef) { @@ -107,8 +112,13 @@ func (m *Manager) CheckProvable(ctx context.Context, pp abi.RegisteredPoStProof, return } - vctx, cancel2 := context.WithTimeout(ctx, PostCheckTimeout) - defer cancel2() + vctx := ctx + + if m.singleCheckTimeout > 0 { + var cancel2 context.CancelFunc + vctx, cancel2 = context.WithTimeout(ctx, m.singleCheckTimeout) + defer cancel2() + } _, err = m.storage.GenerateSingleVanillaProof(vctx, sector.ID.Miner, storiface.PostSectorChallenge{ SealProof: sector.ProofType, diff --git a/storage/sealer/manager.go b/storage/sealer/manager.go index b0c023b09..b0f506539 100644 --- a/storage/sealer/manager.go +++ b/storage/sealer/manager.go @@ -7,6 +7,7 @@ import ( "net/http" "sort" "sync" + "time" "github.com/google/uuid" "github.com/hashicorp/go-multierror" @@ -19,6 +20,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-statestore" + "github.com/filecoin-project/lotus/node/config" "github.com/filecoin-project/lotus/storage/paths" "github.com/filecoin-project/lotus/storage/sealer/ffiwrapper" "github.com/filecoin-project/lotus/storage/sealer/fsutil" @@ -71,6 +73,8 @@ type Manager struct { work *statestore.StateStore parallelCheckLimit int + singleCheckTimeout time.Duration + partitionCheckTimeout time.Duration disableBuiltinWindowPoSt bool disableBuiltinWinningPoSt bool disallowRemoteFinalize bool @@ -90,57 +94,12 @@ 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 Config struct { - ParallelFetchLimit int - - // Local worker config - AllowSectorDownload bool - AllowAddPiece bool - AllowPreCommit1 bool - AllowPreCommit2 bool - AllowCommit bool - AllowUnseal bool - AllowReplicaUpdate bool - AllowProveReplicaUpdate2 bool - AllowRegenSectorKey bool - - LocalWorkerName string - - // ResourceFiltering instructs the system which resource filtering strategy - // to use when evaluating tasks against this worker. An empty value defaults - // to "hardware". - ResourceFiltering ResourceFilteringStrategy - - // PoSt config - ParallelCheckLimit int - DisableBuiltinWindowPoSt bool - DisableBuiltinWinningPoSt bool - - DisallowRemoteFinalize bool - - Assigner string -} - type StorageAuth http.Header type WorkerStateStore *statestore.StateStore type ManagerStateStore *statestore.StateStore -func New(ctx context.Context, lstor *paths.Local, stor paths.Store, ls paths.LocalStorage, si paths.SectorIndex, sc Config, wss WorkerStateStore, mss ManagerStateStore) (*Manager, error) { +func New(ctx context.Context, lstor *paths.Local, stor paths.Store, ls paths.LocalStorage, si paths.SectorIndex, sc config.SealerConfig, pc config.ProvingConfig, 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) @@ -164,9 +123,11 @@ func New(ctx context.Context, lstor *paths.Local, stor paths.Store, ls paths.Loc localProver: prover, - parallelCheckLimit: sc.ParallelCheckLimit, - disableBuiltinWindowPoSt: sc.DisableBuiltinWindowPoSt, - disableBuiltinWinningPoSt: sc.DisableBuiltinWinningPoSt, + parallelCheckLimit: pc.ParallelCheckLimit, + singleCheckTimeout: time.Duration(pc.SingleCheckTimeout), + partitionCheckTimeout: time.Duration(pc.PartitionCheckTimeout), + disableBuiltinWindowPoSt: pc.DisableBuiltinWindowPoSt, + disableBuiltinWinningPoSt: pc.DisableBuiltinWinningPoSt, disallowRemoteFinalize: sc.DisallowRemoteFinalize, work: mss, @@ -212,7 +173,7 @@ func New(ctx context.Context, lstor *paths.Local, stor paths.Store, ls paths.Loc } wcfg := WorkerConfig{ - IgnoreResourceFiltering: sc.ResourceFiltering == ResourceFilteringDisabled, + IgnoreResourceFiltering: sc.ResourceFiltering == config.ResourceFilteringDisabled, TaskTypes: localTasks, Name: sc.LocalWorkerName, } @@ -235,8 +196,8 @@ func (m *Manager) AddLocalStorage(ctx context.Context, path string) error { return xerrors.Errorf("opening local path: %w", err) } - if err := m.ls.SetStorage(func(sc *paths.StorageConfig) { - sc.StoragePaths = append(sc.StoragePaths, paths.LocalPath{Path: path}) + if err := m.ls.SetStorage(func(sc *storiface.StorageConfig) { + sc.StoragePaths = append(sc.StoragePaths, storiface.LocalPath{Path: path}) }); err != nil { return xerrors.Errorf("get storage config: %w", err) } @@ -269,8 +230,8 @@ func (m *Manager) DetachLocalStorage(ctx context.Context, path string) error { // drop from the persisted storage.json var found bool - if err := m.ls.SetStorage(func(sc *paths.StorageConfig) { - out := make([]paths.LocalPath, 0, len(sc.StoragePaths)) + if err := m.ls.SetStorage(func(sc *storiface.StorageConfig) { + out := make([]storiface.LocalPath, 0, len(sc.StoragePaths)) for _, storagePath := range sc.StoragePaths { if storagePath.Path != path { out = append(out, storagePath) @@ -784,11 +745,6 @@ func (m *Manager) FinalizeReplicaUpdate(ctx context.Context, sector storiface.Se move := func(types storiface.SectorFileType) error { // get a selector for moving stuff into long-term storage fetchSel := newMoveSelector(m.index, sector.ID, types, storiface.PathStorage, !m.disallowRemoteFinalize) - { - if len(keepUnsealed) == 0 { - moveUnsealed = storiface.FTNone - } - } err = m.sched.Schedule(ctx, sector, sealtasks.TTFetch, fetchSel, m.schedFetch(sector, types, storiface.PathStorage, storiface.AcquireMove), @@ -804,7 +760,8 @@ func (m *Manager) FinalizeReplicaUpdate(ctx context.Context, sector storiface.Se err = multierr.Append(move(storiface.FTUpdate|storiface.FTUpdateCache), move(storiface.FTCache)) err = multierr.Append(err, move(storiface.FTSealed)) // Sealed separate from cache just in case ReleaseSectorKey was already called - if moveUnsealed != storiface.FTNone { + // if we found unsealed files, AND have been asked to keep at least one, move unsealed + if moveUnsealed != storiface.FTNone && len(keepUnsealed) != 0 { err = multierr.Append(err, move(moveUnsealed)) } diff --git a/storage/sealer/manager_test.go b/storage/sealer/manager_test.go index 739cfdd24..5759d0bc7 100644 --- a/storage/sealer/manager_test.go +++ b/storage/sealer/manager_test.go @@ -39,7 +39,7 @@ func init() { logging.SetAllLoggers(logging.LevelDebug) } -type testStorage paths.StorageConfig +type testStorage storiface.StorageConfig func (t testStorage) DiskUsage(path string) (int64, error) { return 1, nil // close enough @@ -50,7 +50,7 @@ func newTestStorage(t *testing.T) *testStorage { require.NoError(t, err) { - b, err := json.MarshalIndent(&paths.LocalStorageMeta{ + b, err := json.MarshalIndent(&storiface.LocalStorageMeta{ ID: storiface.ID(uuid.New().String()), Weight: 1, CanSeal: true, @@ -63,7 +63,7 @@ func newTestStorage(t *testing.T) *testStorage { } return &testStorage{ - StoragePaths: []paths.LocalPath{ + StoragePaths: []storiface.LocalPath{ {Path: tp}, }, } @@ -82,12 +82,12 @@ func (t testStorage) cleanup() { } } -func (t testStorage) GetStorage() (paths.StorageConfig, error) { - return paths.StorageConfig(t), nil +func (t testStorage) GetStorage() (storiface.StorageConfig, error) { + return storiface.StorageConfig(t), nil } -func (t *testStorage) SetStorage(f func(*paths.StorageConfig)) error { - f((*paths.StorageConfig)(t)) +func (t *testStorage) SetStorage(f func(*storiface.StorageConfig)) error { + f((*storiface.StorageConfig)(t)) return nil } diff --git a/storage/sealer/piece_provider_test.go b/storage/sealer/piece_provider_test.go index c4c71bc53..3605b2597 100644 --- a/storage/sealer/piece_provider_test.go +++ b/storage/sealer/piece_provider_test.go @@ -21,6 +21,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-statestore" + "github.com/filecoin-project/lotus/node/config" "github.com/filecoin-project/lotus/storage/paths" "github.com/filecoin-project/lotus/storage/sealer/sealtasks" "github.com/filecoin-project/lotus/storage/sealer/storiface" @@ -30,7 +31,7 @@ import ( // only uses miner and does NOT use any remote worker. func TestPieceProviderSimpleNoRemoteWorker(t *testing.T) { // Set up sector storage manager - sealerCfg := Config{ + sealerCfg := config.SealerConfig{ ParallelFetchLimit: 10, AllowAddPiece: true, AllowPreCommit1: true, @@ -89,7 +90,7 @@ func TestReadPieceRemoteWorkers(t *testing.T) { logging.SetAllLoggers(logging.LevelDebug) // miner's worker can only add pieces to an unsealed sector. - sealerCfg := Config{ + sealerCfg := config.SealerConfig{ ParallelFetchLimit: 10, AllowAddPiece: true, AllowPreCommit1: false, @@ -198,7 +199,7 @@ func generatePieceData(size uint64) []byte { return bz } -func newPieceProviderTestHarness(t *testing.T, mgrConfig Config, sectorProofType abi.RegisteredSealProof) *pieceProviderTestHarness { +func newPieceProviderTestHarness(t *testing.T, mgrConfig config.SealerConfig, sectorProofType abi.RegisteredSealProof) *pieceProviderTestHarness { ctx := context.Background() // listen on tcp socket to create an http server later address := "0.0.0.0:0" @@ -217,7 +218,7 @@ func newPieceProviderTestHarness(t *testing.T, mgrConfig Config, sectorProofType 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) + mgr, err := New(ctx, localStore, remoteStore, storage, index, mgrConfig, config.ProvingConfig{}, wsts, smsts) require.NoError(t, err) // start a http server on the manager to serve sector file requests. diff --git a/storage/sealer/storiface/storage.go b/storage/sealer/storiface/storage.go index 6d6063c54..a5aa8907a 100644 --- a/storage/sealer/storiface/storage.go +++ b/storage/sealer/storiface/storage.go @@ -153,3 +153,61 @@ type SecDataHttpHeader struct { Key string Value string } + +// StorageConfig .lotusstorage/storage.json +type StorageConfig struct { + StoragePaths []LocalPath +} + +type LocalPath struct { + Path string +} + +// LocalStorageMeta [path]/sectorstore.json +type LocalStorageMeta struct { + ID ID + + // A high weight means data is more likely to be stored in this path + Weight uint64 // 0 = readonly + + // Intermediate data for the sealing process will be stored here + CanSeal bool + + // Finalized sectors that will be proved over time will be stored here + CanStore bool + + // MaxStorage specifies the maximum number of bytes to use for sector storage + // (0 = unlimited) + MaxStorage uint64 + + // List of storage groups this path belongs to + Groups []string + + // List of storage groups to which data from this path can be moved. If none + // are specified, allow to all + AllowTo []string + + // AllowTypes lists sector file types which are allowed to be put into this + // path. If empty, all file types are allowed. + // + // Valid values: + // - "unsealed" + // - "sealed" + // - "cache" + // - "update" + // - "update-cache" + // Any other value will generate a warning and be ignored. + AllowTypes []string + + // DenyTypes lists sector file types which aren't allowed to be put into this + // path. + // + // Valid values: + // - "unsealed" + // - "sealed" + // - "cache" + // - "update" + // - "update-cache" + // Any other value will generate a warning and be ignored. + DenyTypes []string +} diff --git a/storage/wdpost/wdpost_run.go b/storage/wdpost/wdpost_run.go index 53b7d55c9..0518bd760 100644 --- a/storage/wdpost/wdpost_run.go +++ b/storage/wdpost/wdpost_run.go @@ -7,6 +7,7 @@ import ( "github.com/ipfs/go-cid" "go.opencensus.io/trace" + "go.uber.org/zap" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" @@ -253,6 +254,14 @@ func (s *WindowPoStScheduler) runPoStCycle(ctx context.Context, manual bool, di ctx, span := trace.StartSpan(ctx, "storage.runPoStCycle") defer span.End() + start := time.Now() + + log := log.WithOptions(zap.Fields(zap.Time("cycle", start))) + log.Infow("starting PoSt cycle", "manual", manual, "ts", ts, "deadline", di.Index) + defer func() { + log.Infow("post cycle done", "took", time.Now().Sub(start)) + }() + if !manual { // TODO: extract from runPoStCycle, run on fault cutoff boundaries s.asyncFaultRecover(di, ts) diff --git a/testplans/lotus-soup/go.mod b/testplans/lotus-soup/go.mod index 067a09e1e..4b3a24c0b 100644 --- a/testplans/lotus-soup/go.mod +++ b/testplans/lotus-soup/go.mod @@ -9,9 +9,9 @@ require ( github.com/drand/drand v1.3.0 github.com/filecoin-project/go-address v1.0.0 github.com/filecoin-project/go-data-transfer v1.15.2 - github.com/filecoin-project/go-fil-markets v1.24.0-v17 + github.com/filecoin-project/go-fil-markets v1.25.0 github.com/filecoin-project/go-jsonrpc v0.1.8 - github.com/filecoin-project/go-state-types v0.9.8 + github.com/filecoin-project/go-state-types v0.9.9 github.com/filecoin-project/go-storedcounter v0.1.0 github.com/filecoin-project/lotus v0.0.0-00010101000000-000000000000 github.com/filecoin-project/specs-actors v0.9.15 @@ -47,10 +47,12 @@ require ( github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect github.com/akavel/rsrc v0.8.0 // indirect github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a // indirect + github.com/armon/go-metrics v0.3.9 // indirect github.com/avast/retry-go v2.6.0+incompatible // indirect github.com/benbjohnson/clock v1.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bep/debounce v1.2.0 // indirect + github.com/boltdb/bolt v1.3.1 // indirect github.com/buger/goterm v1.0.3 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect @@ -141,7 +143,12 @@ require ( github.com/hannahhoward/cbor-gen-for v0.0.0-20200817222906-ea96cece81f1 // indirect github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e // indirect github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-hclog v0.16.2 // indirect + github.com/hashicorp/go-immutable-radix v1.3.1 // indirect + github.com/hashicorp/go-msgpack v0.5.5 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/hashicorp/raft v1.1.1 // indirect + github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea // indirect github.com/huin/goupnp v1.0.3 // indirect github.com/icza/backscanner v0.0.0-20210726202459-ac2ffc679f94 // indirect github.com/influxdata/influxdb v1.9.4 // indirect @@ -180,7 +187,7 @@ require ( github.com/ipfs/go-unixfsnode v1.4.0 // indirect github.com/ipfs/go-verifcid v0.0.1 // indirect github.com/ipfs/interface-go-ipfs-core v0.7.0 // indirect - github.com/ipld/go-car/v2 v2.4.1 // indirect + github.com/ipld/go-car/v2 v2.5.0 // indirect github.com/ipld/go-codec-dagpb v1.3.2 // indirect github.com/ipld/go-ipld-prime v0.17.0 // indirect github.com/ipld/go-ipld-selector-text-lite v0.0.1 // indirect @@ -202,13 +209,16 @@ require ( github.com/libp2p/go-flow-metrics v0.1.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.2.0 // indirect github.com/libp2p/go-libp2p-connmgr v0.4.0 // indirect + github.com/libp2p/go-libp2p-consensus v0.0.1 // indirect github.com/libp2p/go-libp2p-core v0.20.0 // indirect + github.com/libp2p/go-libp2p-gorpc v0.4.0 // indirect github.com/libp2p/go-libp2p-gostream v0.4.0 // indirect github.com/libp2p/go-libp2p-kad-dht v0.18.0 // indirect github.com/libp2p/go-libp2p-kbucket v0.5.0 // indirect github.com/libp2p/go-libp2p-noise v0.5.0 // indirect github.com/libp2p/go-libp2p-peerstore v0.8.0 // indirect github.com/libp2p/go-libp2p-pubsub v0.8.0 // indirect + github.com/libp2p/go-libp2p-raft v0.1.8 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect github.com/libp2p/go-libp2p-routing-helpers v0.2.3 // indirect github.com/libp2p/go-libp2p-tls v0.5.0 // indirect @@ -281,6 +291,7 @@ require ( github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect github.com/uber/jaeger-client-go v2.28.0+incompatible // indirect github.com/uber/jaeger-lib v2.4.1+incompatible // indirect + github.com/ugorji/go/codec v1.2.6 // indirect github.com/urfave/cli/v2 v2.8.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.1 // indirect diff --git a/testplans/lotus-soup/go.sum b/testplans/lotus-soup/go.sum index 82c704f82..dcc5f884d 100644 --- a/testplans/lotus-soup/go.sum +++ b/testplans/lotus-soup/go.sum @@ -83,6 +83,7 @@ github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/zstd v1.4.1 h1:3oxKN3wbHibqx897utPC2LTQU4J+IHWWJO+glkAkpFM= github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= @@ -144,7 +145,10 @@ github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= github.com/armon/go-metrics v0.3.3/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= +github.com/armon/go-metrics v0.3.9 h1:O2sNqxBdvq8Eq5xmzljcYzAORli6RWCvEym4cJf9m18= +github.com/armon/go-metrics v0.3.9/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= @@ -187,6 +191,7 @@ github.com/bep/debounce v1.2.0 h1:wXds8Kq8qRfwAOpAxHrJDbCXgC5aHSzgQb/0gKsHQqo= github.com/bep/debounce v1.2.0/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= +github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/bonitoo-io/go-sql-bigquery v0.3.4-1.4.0/go.mod h1:J4Y6YJm0qTWB9aFziB7cPeSyc6dOZFyJdteSeybVpXQ= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= @@ -405,8 +410,8 @@ github.com/filecoin-project/go-fil-commcid v0.1.0 h1:3R4ds1A9r6cr8mvZBfMYxTS88Oq github.com/filecoin-project/go-fil-commcid v0.1.0/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= github.com/filecoin-project/go-fil-commp-hashhash v0.1.0 h1:imrrpZWEHRnNqqv0tN7LXep5bFEVOVmQWHJvl2mgsGo= github.com/filecoin-project/go-fil-commp-hashhash v0.1.0/go.mod h1:73S8WSEWh9vr0fDJVnKADhfIv/d6dCbAGaAGWbdJEI8= -github.com/filecoin-project/go-fil-markets v1.24.0-v17 h1:YjT0usMeR6kdAo3RBfftTPe5bNIgNmBbo5YzJHF1iLk= -github.com/filecoin-project/go-fil-markets v1.24.0-v17/go.mod h1:JW/UHkHDqP4MikCIIWNY5IHvTTsdv/zNMk9jJXKzhIU= +github.com/filecoin-project/go-fil-markets v1.25.0 h1:zWkc1v84JL9KttiqOy2IIZB0jksIdAt1WLCdOP/KvAg= +github.com/filecoin-project/go-fil-markets v1.25.0/go.mod h1:3lzXZt5mRHTHAmZ10sUviiutaLVL57B99FgBU1MYqWY= 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= @@ -430,8 +435,8 @@ github.com/filecoin-project/go-state-types v0.1.0/go.mod h1:ezYnPf0bNkTsDibL/psS github.com/filecoin-project/go-state-types v0.1.6/go.mod h1:UwGVoMsULoCK+bWjEdd/xLCvLAQFBC7EDT477SKml+Q= github.com/filecoin-project/go-state-types v0.1.8/go.mod h1:UwGVoMsULoCK+bWjEdd/xLCvLAQFBC7EDT477SKml+Q= github.com/filecoin-project/go-state-types v0.1.10/go.mod h1:UwGVoMsULoCK+bWjEdd/xLCvLAQFBC7EDT477SKml+Q= -github.com/filecoin-project/go-state-types v0.9.8 h1:xkdITiR7h691z1tWOhNCJxHI+cq+Mq7ATkpHQ7f1gu8= -github.com/filecoin-project/go-state-types v0.9.8/go.mod h1:+HCZifUV+e8TlQkgll22Ucuiq8OrVJkK+4Kh4u75iiw= +github.com/filecoin-project/go-state-types v0.9.9 h1:gd7Mo6f9jHHpLahttBE88YeQA77i4GK6W5kFdQDnuME= +github.com/filecoin-project/go-state-types v0.9.9/go.mod h1:+HCZifUV+e8TlQkgll22Ucuiq8OrVJkK+4Kh4u75iiw= github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= github.com/filecoin-project/go-statemachine v1.0.2 h1:421SSWBk8GIoCoWYYTE/d+qCWccgmRH0uXotXRDjUbc= github.com/filecoin-project/go-statemachine v1.0.2/go.mod h1:jZdXXiHa61n4NmgWFG4w8tnqgvZVHYbJ3yW7+y8bF54= @@ -465,6 +470,7 @@ github.com/filecoin-project/specs-actors/v8 v8.0.1/go.mod h1:UYIPg65iPWoFw5NEftR github.com/filecoin-project/storetheindex v0.4.17 h1:w0dVc954TGPukoVbidlYvn9Xt+wVhk5vBvrqeJiRo8I= github.com/filecoin-project/storetheindex v0.4.17/go.mod h1:y2dL8C5D3PXi183hdxgGtM8vVYOZ1lg515tpl/D3tN8= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= +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= @@ -782,11 +788,18 @@ github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v0.12.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v0.16.2 h1:K4ev2ib4LdQETX5cSZBG0DVLk1jwGqSPXBjdah3veNs= +github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.2.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= +github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= @@ -798,6 +811,7 @@ github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerX github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= @@ -812,6 +826,10 @@ github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/memberlist v0.1.4/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/memberlist v0.2.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= +github.com/hashicorp/raft v1.1.1 h1:HJr7UE1x/JrJSc9Oy6aDBHtNHUUBHjcQjTgvUVihoZs= +github.com/hashicorp/raft v1.1.1/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8= +github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea h1:xykPFhrBAS2J0VBzVa5e80b5ZtYuNQtgXjN40qBZlD4= +github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea/go.mod h1:pNv7Wc3ycL6F5oOWn+tPGo2gWD4a5X+yp/ntwdKLjRk= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hashicorp/serf v0.9.0/go.mod h1:YL0HO+FifKOW2u1ke99DGVu1zhcpZzNwrLIqBC7vbYU= github.com/hodgesds/perf-utils v0.0.8/go.mod h1:F6TfvsbtrF88i++hou29dTXlI2sfsJv+gRZDtmTJkAs= @@ -1042,8 +1060,8 @@ github.com/ipld/go-car v0.1.0/go.mod h1:RCWzaUh2i4mOEkB3W45Vc+9jnS/M6Qay5ooytiBH github.com/ipld/go-car v0.4.0 h1:U6W7F1aKF/OJMHovnOVdst2cpQE5GhmHibQkAixgNcQ= github.com/ipld/go-car v0.4.0/go.mod h1:Uslcn4O9cBKK9wqHm/cLTFacg6RAPv6LZx2mxd2Ypl4= github.com/ipld/go-car/v2 v2.1.1/go.mod h1:+2Yvf0Z3wzkv7NeI69i8tuZ+ft7jyjPYIWZzeVNeFcI= -github.com/ipld/go-car/v2 v2.4.1 h1:9S+FYbQzQJ/XzsdiOV13W5Iu/i+gUnr6csbSD9laFEg= -github.com/ipld/go-car/v2 v2.4.1/go.mod h1:zjpRf0Jew9gHqSvjsKVyoq9OY9SWoEKdYCQUKVaaPT0= +github.com/ipld/go-car/v2 v2.5.0 h1:S9h7A6qBAJ+B1M1jIKtau+HPDe30UbM71vsyBzwvRIE= +github.com/ipld/go-car/v2 v2.5.0/go.mod h1:jKjGOqoCj5zn6KjnabD6JbnCsMntqU2hLiU6baZVO3E= github.com/ipld/go-codec-dagpb v1.2.0/go.mod h1:6nBN7X7h8EOsEejZGqC7tej5drsdBAXbMHyBT+Fne5s= github.com/ipld/go-codec-dagpb v1.3.0/go.mod h1:ga4JTU3abYApDC3pZ00BC2RSvC3qfBb9MSJkMLSwnhA= github.com/ipld/go-codec-dagpb v1.3.1/go.mod h1:ErNNglIi5KMur/MfFE/svtgQthzVvf+43MrzLbpcIZY= @@ -1202,7 +1220,9 @@ github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniV github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= github.com/libp2p/go-libp2p v0.8.3/go.mod h1:EsH1A+8yoWK+L4iKcbPYu6MPluZ+CHWI9El8cTaefiM= github.com/libp2p/go-libp2p v0.10.0/go.mod h1:yBJNpb+mGJdgrwbKAKrhPU0u3ogyNFTfjJ6bdM+Q/G8= +github.com/libp2p/go-libp2p v0.13.0/go.mod h1:pM0beYdACRfHO1WcJlp65WXyG2A6NqYM+t2DTVAJxMo= github.com/libp2p/go-libp2p v0.14.3/go.mod h1:d12V4PdKbpL0T1/gsUNN8DfgMuRPDX8bS2QxCZlwRH0= +github.com/libp2p/go-libp2p v0.14.4/go.mod h1:EIRU0Of4J5S8rkockZM7eJp2S0UrCyi55m2kJVru3rM= github.com/libp2p/go-libp2p v0.16.0/go.mod h1:ump42BsirwAWxKzsCiFnTtN1Yc+DuPu76fyMX364/O4= github.com/libp2p/go-libp2p v0.17.0/go.mod h1:Fkin50rsGdv5mm5BshBUtPRZknt9esfmYXBOYcwOTgw= github.com/libp2p/go-libp2p v0.22.0 h1:2Tce0kHOp5zASFKJbNzRElvh0iZwdtG5uZheNW8chIw= @@ -1216,6 +1236,7 @@ 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/go.mod h1:YxaJlpr81FhdOv3W3BTconZPfhaYivRdf53g+S2wobk= github.com/libp2p/go-libp2p-autonat v0.4.2/go.mod h1:YxaJlpr81FhdOv3W3BTconZPfhaYivRdf53g+S2wobk= github.com/libp2p/go-libp2p-autonat v0.6.0/go.mod h1:bFC6kY8jwzNNWoqc8iGE57vsfwyJ/lP4O4DOV1e0B2o= github.com/libp2p/go-libp2p-autonat v0.7.0/go.mod h1:uPvPn6J7cN+LCfFwW5tpOYvAz5NvPTc4iBamTV/WDMg= @@ -1234,6 +1255,8 @@ github.com/libp2p/go-libp2p-connmgr v0.2.4/go.mod h1:YV0b/RIm8NGPnnNWM7hG9Q38OeQ github.com/libp2p/go-libp2p-connmgr v0.3.0/go.mod h1:RVoyPjJm0J9Vd1m6qUN2Tn7kJm4rL1Ml20pFsFgPGik= github.com/libp2p/go-libp2p-connmgr v0.4.0 h1:q/KZUS1iMDIQckMZarMYwhQisJqiFPHAVC1c4DR3hDE= github.com/libp2p/go-libp2p-connmgr v0.4.0/go.mod h1:exFQQm19PFAx+QuJmBPw4MM58QejzPJRFFFYnNmgi2w= +github.com/libp2p/go-libp2p-consensus v0.0.1 h1:jcVbHRZLwTXU9iT/mPi+Lx4/OrIzq3bU1TbZNhYFCV8= +github.com/libp2p/go-libp2p-consensus v0.0.1/go.mod h1:+9Wrfhc5QOqWB0gXI0m6ARlkHfdJpcFXmRU0WoHz4Mo= github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= github.com/libp2p/go-libp2p-core v0.0.2/go.mod h1:9dAcntw/n46XycV4RnlBq3BpgrmyUi9LuoTNdPrbUco= github.com/libp2p/go-libp2p-core v0.0.3/go.mod h1:j+YQMNz9WNSkNezXOsahp9kwZBKBvxLpKD316QWSJXE= @@ -1274,6 +1297,9 @@ github.com/libp2p/go-libp2p-discovery v0.3.0/go.mod h1:o03drFnz9BVAZdzC/QUQ+NeQO github.com/libp2p/go-libp2p-discovery v0.4.0/go.mod h1:bZ0aJSrFc/eX2llP0ryhb1kpgkPyTo23SJ5b7UQCMh4= github.com/libp2p/go-libp2p-discovery v0.5.0/go.mod h1:+srtPIU9gDaBNu//UHvcdliKBIcr4SfDcm0/PfPJLug= github.com/libp2p/go-libp2p-discovery v0.6.0/go.mod h1:/u1voHt0tKIe5oIA1RHBKQLVCWPna2dXmPNHc2zR9S8= +github.com/libp2p/go-libp2p-gorpc v0.4.0 h1:kxHg5C3IuXeOq5FHPGbMHwQzKDlTVeB/NDr0ndc8J/g= +github.com/libp2p/go-libp2p-gorpc v0.4.0/go.mod h1:jux2Mb6BfUE1n58KbVCmWtqvpiZo0DDaKobKInf4s5o= +github.com/libp2p/go-libp2p-gostream v0.3.1/go.mod h1:1V3b+u4Zhaq407UUY9JLCpboaeufAeVQbnvAt12LRsI= github.com/libp2p/go-libp2p-gostream v0.4.0 h1:heduMMEB78yBqeEQv+P7Fn5X926MHC2jDIC7/7yLpYA= github.com/libp2p/go-libp2p-gostream v0.4.0/go.mod h1:21DVGBcCQwRfEXZpCnZ2kG24QiEkBpEQvG53gYXE4u0= github.com/libp2p/go-libp2p-kad-dht v0.18.0 h1:akqO3gPMwixR7qFSFq70ezRun97g5hrA/lBW9jrjUYM= @@ -1292,6 +1318,7 @@ github.com/libp2p/go-libp2p-nat v0.0.5/go.mod h1:1qubaE5bTZMJE+E/uu2URroMbzdubFz github.com/libp2p/go-libp2p-nat v0.0.6/go.mod h1:iV59LVhB3IkFvS6S6sauVTSOrNEANnINbI/fkaLimiw= github.com/libp2p/go-libp2p-nat v0.1.0/go.mod h1:DQzAG+QbDYjN1/C3B6vXucLtz3u9rEonLVPtZVzQqks= 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.2.0/go.mod h1:IEbYhBBzGyvdLBoxxULL/SGbJARhUeqlO8lVSREYu2Q= github.com/libp2p/go-libp2p-noise v0.3.0/go.mod h1:JNjHbociDJKHD64KTkzGnzqJ0FEV5gHJa6AB00kbCNQ= github.com/libp2p/go-libp2p-noise v0.5.0 h1:gwJZ/3iH3MRnBrLIyr/YLdCOnmqfJMptlsFFUIc3j0Y= @@ -1322,6 +1349,8 @@ github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqU github.com/libp2p/go-libp2p-quic-transport v0.13.0/go.mod h1:39/ZWJ1TW/jx1iFkKzzUg00W6tDJh73FC0xYudjr7Hc= github.com/libp2p/go-libp2p-quic-transport v0.15.0/go.mod h1:wv4uGwjcqe8Mhjj7N/Ic0aKjA+/10UnMlSzLO0yRpYQ= github.com/libp2p/go-libp2p-quic-transport v0.15.2/go.mod h1:wv4uGwjcqe8Mhjj7N/Ic0aKjA+/10UnMlSzLO0yRpYQ= +github.com/libp2p/go-libp2p-raft v0.1.8 h1:Fq0aWHbbhi6WJXf+yaOQeMzV+9UgkbHIIGyaJbH3vpo= +github.com/libp2p/go-libp2p-raft v0.1.8/go.mod h1:+YDisn3uszb7vxshLgKoDdRGs79WSbHRgrOdrYqDPk4= github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= github.com/libp2p/go-libp2p-record v0.1.2/go.mod h1:pal0eNcT5nqZaTV7UGhqeGqxFgGdsU/9W//C8dqjQDk= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= @@ -1339,6 +1368,7 @@ 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.4.0/go.mod h1:XVFcO52VoLoo0eitSxNQWYq4D6sydGOweTOAjJNraCw= github.com/libp2p/go-libp2p-swarm v0.5.0/go.mod h1:sU9i6BoHE0Ve5SKz3y9WfKrh8dUat6JknzUehFx8xW4= github.com/libp2p/go-libp2p-swarm v0.8.0/go.mod h1:sOMp6dPuqco0r0GHTzfVheVBh6UEL0L1lXUZ5ot2Fvc= github.com/libp2p/go-libp2p-swarm v0.9.0/go.mod h1:2f8d8uxTJmpeqHF/1ujjdXZp+98nNIbujVOMEZxCbZ8= @@ -1362,6 +1392,7 @@ github.com/libp2p/go-libp2p-tls v0.5.0/go.mod h1:1a4tq0xQSZ0kAkDkZVAppuP3SAIUHcn 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/go.mod h1:J4ko0ObtZSmgn5BX5AmegP+dK3CSnU2lMCKsSq/EY0s= github.com/libp2p/go-libp2p-transport-upgrader v0.4.2/go.mod h1:NR8ne1VwfreD5VIWIU62Agt/J18ekORFU/j1i2y8zvk= github.com/libp2p/go-libp2p-transport-upgrader v0.4.3/go.mod h1:bpkldbOWXMrXhpZbSV1mQxTrefOg2Fi+k1ClDSA4ppw= github.com/libp2p/go-libp2p-transport-upgrader v0.5.0/go.mod h1:Rc+XODlB3yce7dvFV4q/RmyJGsFcCZRkeZMu/Zdg0mo= @@ -1374,6 +1405,7 @@ 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/go.mod h1:dowuvDu8CRWmr0iqySMiSxK+W0iL5cMVO9S94Y6gkv4= github.com/libp2p/go-libp2p-yamux v0.5.4/go.mod h1:tfrXbyaTqqSU654GTvK3ocnSZL3BuHoeTSqhcel1wsE= github.com/libp2p/go-libp2p-yamux v0.6.0/go.mod h1:MRhd6mAYnFRnSISp4M8i0ClV/j+mWHo2mYLifWGw33k= github.com/libp2p/go-libp2p-yamux v0.7.0/go.mod h1:fMyA0CsPfHkIuBU0wjRGrCjTBFiXTXxG0k5M4ETv+08= @@ -1430,7 +1462,9 @@ github.com/libp2p/go-stream-muxer-multistream v0.3.0/go.mod h1:yDh8abSIzmZtqtOt6 github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc= github.com/libp2p/go-tcp-transport v0.1.1/go.mod h1:3HzGvLbx6etZjnFlERyakbaYPdfjg2pWP97dFZworkY= github.com/libp2p/go-tcp-transport v0.2.0/go.mod h1:vX2U0CnWimU4h0SGSEsg++AzvBcroCGYw28kh94oLe0= +github.com/libp2p/go-tcp-transport v0.2.1/go.mod h1:zskiJ70MEfWz2MKxvFB/Pv+tPIB1PpPUrHIWQ8aFw7M= github.com/libp2p/go-tcp-transport v0.2.3/go.mod h1:9dvr03yqrPyYGIEN6Dy5UvdJZjyPFvl1S/igQ5QD1SU= +github.com/libp2p/go-tcp-transport v0.2.4/go.mod h1:9dvr03yqrPyYGIEN6Dy5UvdJZjyPFvl1S/igQ5QD1SU= github.com/libp2p/go-tcp-transport v0.4.0/go.mod h1:0y52Rwrn4076xdJYu/51/qJIdxz+EWDAOG2S45sV3VI= github.com/libp2p/go-testutil v0.1.0/go.mod h1:81b2n5HypcVyrCg/MJx4Wgfp/VHojytjVe/gLzZ2Ehc= github.com/libp2p/go-ws-transport v0.1.0/go.mod h1:rjw1MG1LU9YDC6gzmwObkPd/Sqwhw7yT74kj3raBFuo= @@ -1447,6 +1481,7 @@ github.com/libp2p/go-yamux v1.3.5/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZ github.com/libp2p/go-yamux v1.3.7/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= github.com/libp2p/go-yamux v1.4.0/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= github.com/libp2p/go-yamux v1.4.1/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= +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/go.mod h1:3So6P6TV6r75R9jiBpiIKgU/66lOarCZjqROGxzPpPQ= github.com/libp2p/go-yamux/v2 v2.3.0/go.mod h1:iTU+lOIn/2h0AgKcL49clNTwfEw+WSfDYrXe05EyKIs= github.com/libp2p/go-yamux/v3 v3.1.2 h1:lNEy28MBk1HavUAlzKgShp+F6mn/ea1nDYWftZhFW9Q= @@ -1545,6 +1580,7 @@ github.com/miekg/dns v1.1.22/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKju github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.28/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= +github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= @@ -1647,6 +1683,7 @@ github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= 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/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= github.com/multiformats/go-multistream v0.2.1/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= github.com/multiformats/go-multistream v0.2.2/go.mod h1:UIcnm7Zuo8HKG+HkWgfQsGL+/MIEhyTqbODbIUwSXKs= github.com/multiformats/go-multistream v0.3.3 h1:d5PZpjwRgVlbwfdTDjife7XszfZd8KYWfROYFlGcR8o= @@ -1729,6 +1766,7 @@ github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= @@ -1763,6 +1801,7 @@ github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndr github.com/prometheus/alertmanager v0.20.0/go.mod h1:9g2i48FAyZW6BtbsnvHtMHQXl2aVtrORKwKVCQ+nbrg= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U= @@ -1784,6 +1823,7 @@ github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= @@ -1801,6 +1841,7 @@ github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJ github.com/prometheus/node_exporter v1.0.0-rc.0.0.20200428091818-01054558c289/go.mod h1:FGbBv5OPKjch+jNUJmEQpMZytIdyW0NdBtWFcfSKusc= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190425082905-87a4384529e0/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= @@ -1968,7 +2009,12 @@ github.com/uber/jaeger-lib v1.5.1-0.20181102163054-1fc5c315e03c/go.mod h1:ComeND github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/ugorji/go v1.1.13/go.mod h1:jxau1n+/wyTGLQoCkjok9r5zFa/FxT6eI5HiHKQszjc= +github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn0= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.13/go.mod h1:oNVt3Dq+FO91WNQ/9JnHKQP2QJxTzoN7wCBFCq1OeuU= +github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ= +github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= @@ -2365,6 +2411,7 @@ golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190523142557-0e01d883c5c5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190524122548-abf6ff778158/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190526052359-791d8a0f4d09/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/testplans/lotus-soup/testkit/role_miner.go b/testplans/lotus-soup/testkit/role_miner.go index 1a3319add..3b74a50cb 100644 --- a/testplans/lotus-soup/testkit/role_miner.go +++ b/testplans/lotus-soup/testkit/role_miner.go @@ -40,7 +40,6 @@ import ( "github.com/filecoin-project/lotus/node/config" "github.com/filecoin-project/lotus/node/impl" "github.com/filecoin-project/lotus/node/repo" - "github.com/filecoin-project/lotus/storage/paths" sealing "github.com/filecoin-project/lotus/storage/pipeline" "github.com/filecoin-project/lotus/storage/sealer/storiface" ) @@ -198,9 +197,9 @@ func PrepareMiner(t *TestEnvironment) (*LotusMiner, error) { } } - var localPaths []paths.LocalPath + var localPaths []storiface.LocalPath - b, err := json.MarshalIndent(&paths.LocalStorageMeta{ + b, err := json.MarshalIndent(&storiface.LocalStorageMeta{ ID: storiface.ID(uuid.New().String()), Weight: 10, CanSeal: true, @@ -214,11 +213,11 @@ func PrepareMiner(t *TestEnvironment) (*LotusMiner, error) { return nil, fmt.Errorf("persisting storage metadata (%s): %w", filepath.Join(lr.Path(), "sectorstore.json"), err) } - localPaths = append(localPaths, paths.LocalPath{ + localPaths = append(localPaths, storiface.LocalPath{ Path: lr.Path(), }) - if err := lr.SetStorage(func(sc *paths.StorageConfig) { + if err := lr.SetStorage(func(sc *storiface.StorageConfig) { sc.StoragePaths = append(sc.StoragePaths, localPaths...) }); err != nil { return nil, err