Compare commits

..
Author SHA1 Message Date
Dirk McCormick 09159ee849 fix: dagstore miner api test 2023-04-27 15:38:39 +02:00
Dirk McCormick 6d1e7f5fb5 feat: update to go-fil-markets v1.26.0 2023-04-27 15:38:39 +02:00
Masih H. Derkani cb04cdd4e8 chore: upgrade to index-provider 0.10.0
Upgrade to the latest index-provider and as a result also upgrade
go-fil-markets.

Note that the index-provider go module is renamed and moved to `ipni`
GitHub org.
2023-04-27 15:38:39 +02:00
409 changed files with 8485 additions and 15564 deletions
+149 -295
View File
@@ -7,19 +7,14 @@ executors:
golang: golang:
docker: docker:
# Must match GO_VERSION_MIN in project root # Must match GO_VERSION_MIN in project root
- image: cimg/go:1.19.7 - image: cimg/go:1.18.8
resource_class: medium+
golang-2xl:
docker:
# Must match GO_VERSION_MIN in project root
- image: cimg/go:1.19.7
resource_class: 2xlarge resource_class: 2xlarge
ubuntu: ubuntu:
docker: docker:
- image: ubuntu:20.04 - image: ubuntu:20.04
commands: commands:
build-platform-specific: prepare:
parameters: parameters:
linux: linux:
default: true default: true
@@ -36,13 +31,22 @@ commands:
steps: steps:
- checkout - checkout
- git_fetch_all_tags - git_fetch_all_tags
- run: git submodule sync
- run: git submodule update --init
- when: - when:
condition: <<parameters.linux>> condition: <<parameters.linux>>
steps: steps:
- install-ubuntu-deps - run:
- check-go-version name: Check Go Version
command: |
v=`go version | { read _ _ v _; echo ${v#go}; }`
if [[ $v != `cat GO_VERSION_MIN` ]]; then
echo "GO_VERSION_MIN file does not match the go version being used."
echo "Please update image to cimg/go:`cat GO_VERSION_MIN` or update GO_VERSION_MIN to $v."
exit 1
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: - when:
condition: <<parameters.darwin>> condition: <<parameters.darwin>>
steps: steps:
@@ -63,7 +67,8 @@ commands:
name: Install Rust name: Install Rust
command: | command: |
curl https://sh.rustup.rs -sSf | sh -s -- -y curl https://sh.rustup.rs -sSf | sh -s -- -y
- run: make deps - run: git submodule sync
- run: git submodule update --init
download-params: download-params:
steps: steps:
- restore_cache: - restore_cache:
@@ -72,7 +77,7 @@ commands:
- 'v26-2k-lotus-params' - 'v26-2k-lotus-params'
paths: paths:
- /var/tmp/filecoin-proof-parameters/ - /var/tmp/filecoin-proof-parameters/
- run: ./lotus fetch-params 2048 - run: ./lotus fetch-params 2048
- save_cache: - save_cache:
name: Save parameters cache name: Save parameters cache
key: 'v26-2k-lotus-params' key: 'v26-2k-lotus-params'
@@ -94,43 +99,12 @@ commands:
name: fetch all tags name: fetch all tags
command: | command: |
git fetch --all git fetch --all
install-ubuntu-deps:
steps:
- run: sudo apt-get update
- run: sudo apt-get install ocl-icd-opencl-dev libhwloc-dev
check-go-version:
steps:
- run: |
v=`go version | { read _ _ v _; echo ${v#go}; }`
if [[ $v != `cat GO_VERSION_MIN` ]]; then
echo "GO_VERSION_MIN file does not match the go version being used."
echo "Please update image to cimg/go:`cat GO_VERSION_MIN` or update GO_VERSION_MIN to $v."
exit 1
fi
jobs: jobs:
build:
executor: golang
working_directory: ~/lotus
steps:
- checkout
- git_fetch_all_tags
- run: git submodule sync
- run: git submodule update --init
- install-ubuntu-deps
- check-go-version
- run: make deps lotus
- persist_to_workspace:
root: ~/
paths:
- "lotus"
mod-tidy-check: mod-tidy-check:
executor: golang executor: golang
working_directory: ~/lotus
steps: steps:
- install-ubuntu-deps - prepare
- attach_workspace:
at: ~/
- run: go mod tidy -v - run: go mod tidy -v
- run: - run:
name: Check git diff name: Check git diff
@@ -141,14 +115,13 @@ jobs:
test: test:
description: | description: |
Run tests with gotestsum. Run tests with gotestsum.
working_directory: ~/lotus
parameters: &test-params parameters: &test-params
executor: executor:
type: executor type: executor
default: golang default: golang
go-test-flags: go-test-flags:
type: string type: string
default: "-timeout 20m" default: "-timeout 30m"
description: Flags passed to go test. description: Flags passed to go test.
target: target:
type: string type: string
@@ -157,22 +130,21 @@ jobs:
proofs-log-test: proofs-log-test:
type: string type: string
default: "0" default: "0"
get-params:
type: boolean
default: false
suite: suite:
type: string type: string
default: unit default: unit
description: Test suite name to report to CircleCI. description: Test suite name to report to CircleCI.
gotestsum-format:
type: string
default: standard-verbose
description: gotestsum format. https://github.com/gotestyourself/gotestsum#format
executor: << parameters.executor >> executor: << parameters.executor >>
steps: steps:
- install-ubuntu-deps - prepare
- attach_workspace: - run:
at: ~/ command: make deps lotus
- when: no_output_timeout: 30m
condition: << parameters.get-params >> - download-params
steps:
- download-params
- run: - run:
name: go test name: go test
environment: environment:
@@ -183,11 +155,12 @@ jobs:
mkdir -p /tmp/test-reports/<< parameters.suite >> mkdir -p /tmp/test-reports/<< parameters.suite >>
mkdir -p /tmp/test-artifacts mkdir -p /tmp/test-artifacts
gotestsum \ gotestsum \
--format standard-verbose \ --format << parameters.gotestsum-format >> \
--junitfile /tmp/test-reports/<< parameters.suite >>/junit.xml \ --junitfile /tmp/test-reports/<< parameters.suite >>/junit.xml \
--jsonfile /tmp/test-artifacts/<< parameters.suite >>.json \ --jsonfile /tmp/test-artifacts/<< parameters.suite >>.json \
--packages="<< parameters.target >>" \ -- \
-- << parameters.go-test-flags >> << parameters.go-test-flags >> \
<< parameters.target >>
no_output_timeout: 30m no_output_timeout: 30m
- store_test_results: - store_test_results:
path: /tmp/test-reports path: /tmp/test-reports
@@ -195,7 +168,6 @@ jobs:
path: /tmp/test-artifacts/<< parameters.suite >>.json path: /tmp/test-artifacts/<< parameters.suite >>.json
test-conformance: test-conformance:
working_directory: ~/lotus
description: | description: |
Run tests using a corpus of interoperable test vectors for Filecoin Run tests using a corpus of interoperable test vectors for Filecoin
implementations to test their correctness and compliance with the Filecoin implementations to test their correctness and compliance with the Filecoin
@@ -211,9 +183,10 @@ jobs:
submodule is used. submodule is used.
executor: << parameters.executor >> executor: << parameters.executor >>
steps: steps:
- install-ubuntu-deps - prepare
- attach_workspace: - run:
at: ~/ command: make deps lotus
no_output_timeout: 30m
- download-params - download-params
- when: - when:
condition: condition:
@@ -256,7 +229,7 @@ jobs:
build-linux-amd64: build-linux-amd64:
executor: golang executor: golang
steps: steps:
- build-platform-specific - prepare
- run: make lotus lotus-miner lotus-worker - run: make lotus lotus-miner lotus-worker
- run: - run:
name: check tag and version output match name: check tag and version output match
@@ -275,7 +248,7 @@ jobs:
macos: macos:
xcode: "13.4.1" xcode: "13.4.1"
steps: steps:
- build-platform-specific: - prepare:
linux: false linux: false
darwin: true darwin: true
darwin-architecture: amd64 darwin-architecture: amd64
@@ -299,12 +272,14 @@ jobs:
resource_class: filecoin-project/self-hosted-m1 resource_class: filecoin-project/self-hosted-m1
steps: steps:
- run: echo 'export PATH=/opt/homebrew/bin:"$PATH"' >> "$BASH_ENV" - run: echo 'export PATH=/opt/homebrew/bin:"$PATH"' >> "$BASH_ENV"
- build-platform-specific: - prepare:
linux: false linux: false
darwin: true darwin: true
darwin-architecture: arm64 darwin-architecture: arm64
- run: | - run: |
export CPATH=$(brew --prefix)/include && export LIBRARY_PATH=$(brew --prefix)/lib && make lotus lotus-miner lotus-worker export CPATH=$(brew --prefix)/include
export LIBRARY_PATH=$(brew --prefix)/lib
make lotus lotus-miner lotus-worker
- run: otool -hv lotus - run: otool -hv lotus
- run: - run:
name: check tag and version output match name: check tag and version output match
@@ -355,18 +330,16 @@ jobs:
gofmt: gofmt:
executor: golang executor: golang
working_directory: ~/lotus
steps: steps:
- prepare
- run: - run:
command: "! go fmt ./... 2>&1 | read" command: "! go fmt ./... 2>&1 | read"
gen-check: gen-check:
executor: golang executor: golang
working_directory: ~/lotus
steps: steps:
- install-ubuntu-deps - prepare
- attach_workspace: - run: make deps
at: ~/
- run: go install golang.org/x/tools/cmd/goimports - run: go install golang.org/x/tools/cmd/goimports
- run: go install github.com/hannahhoward/cbor-gen-for - run: go install github.com/hannahhoward/cbor-gen-for
- run: make gen - run: make gen
@@ -376,29 +349,32 @@ jobs:
docs-check: docs-check:
executor: golang executor: golang
working_directory: ~/lotus
steps: steps:
- install-ubuntu-deps - prepare
- attach_workspace:
at: ~/
- run: go install golang.org/x/tools/cmd/goimports - run: go install golang.org/x/tools/cmd/goimports
- run: zcat build/openrpc/full.json.gz | jq > ../pre-openrpc-full - run: zcat build/openrpc/full.json.gz | jq > ../pre-openrpc-full
- run: zcat build/openrpc/miner.json.gz | jq > ../pre-openrpc-miner - run: zcat build/openrpc/miner.json.gz | jq > ../pre-openrpc-miner
- run: zcat build/openrpc/worker.json.gz | jq > ../pre-openrpc-worker - run: zcat build/openrpc/worker.json.gz | jq > ../pre-openrpc-worker
- run: make deps
- run: make docsgen - run: make docsgen
- run: zcat build/openrpc/full.json.gz | jq > ../post-openrpc-full - run: zcat build/openrpc/full.json.gz | jq > ../post-openrpc-full
- run: zcat build/openrpc/miner.json.gz | jq > ../post-openrpc-miner - run: zcat build/openrpc/miner.json.gz | jq > ../post-openrpc-miner
- run: zcat build/openrpc/worker.json.gz | jq > ../post-openrpc-worker - run: zcat build/openrpc/worker.json.gz | jq > ../post-openrpc-worker
- run: diff ../pre-openrpc-full ../post-openrpc-full && diff ../pre-openrpc-miner ../post-openrpc-miner && diff ../pre-openrpc-worker ../post-openrpc-worker && git --no-pager diff && git --no-pager diff --quiet - run: diff ../pre-openrpc-full ../post-openrpc-full && diff ../pre-openrpc-miner ../post-openrpc-miner && diff ../pre-openrpc-worker ../post-openrpc-worker && git --no-pager diff && git --no-pager diff --quiet
lint-all: lint: &lint
description: | description: |
Run golangci-lint. Run golangci-lint.
working_directory: ~/lotus
parameters: parameters:
executor: executor:
type: executor type: executor
default: golang default: golang
concurrency:
type: string
default: '2'
description: |
Concurrency used to run linters. Defaults to 2 because NumCPU is not
aware of container CPU limits.
args: args:
type: string type: string
default: '' default: ''
@@ -406,14 +382,17 @@ jobs:
Arguments to pass to golangci-lint Arguments to pass to golangci-lint
executor: << parameters.executor >> executor: << parameters.executor >>
steps: steps:
- install-ubuntu-deps - prepare
- attach_workspace: - run:
at: ~/ command: make deps
no_output_timeout: 30m
- run: - run:
name: Lint name: Lint
command: | command: |
golangci-lint run -v --timeout 10m \ golangci-lint run -v --timeout 2m \
--concurrency 4 << parameters.args >> --concurrency << parameters.concurrency >> << parameters.args >>
lint-all:
<<: *lint
build-docker: build-docker:
description: > description: >
@@ -515,553 +494,432 @@ jobs:
extra_build_args: --target <<parameters.image>> --build-arg GOFLAGS=-tags=<<parameters.network>> extra_build_args: --target <<parameters.image>> --build-arg GOFLAGS=-tags=<<parameters.network>>
workflows: workflows:
version: 2.1
ci: ci:
jobs: jobs:
- build
- lint-all: - lint-all:
requires: concurrency: "16" # expend all docker 2xlarge CPUs.
- build - mod-tidy-check
- mod-tidy-check: - gofmt
requires: - gen-check
- build - docs-check
- gofmt:
requires:
- build
- gen-check:
requires:
- build
- docs-check:
requires:
- build
- test: - test:
name: test-itest-api name: test-itest-api
requires:
- build
suite: itest-api suite: itest-api
target: "./itests/api_test.go" target: "./itests/api_test.go"
- test: - test:
name: test-itest-batch_deal name: test-itest-batch_deal
requires:
- build
suite: itest-batch_deal suite: itest-batch_deal
target: "./itests/batch_deal_test.go" target: "./itests/batch_deal_test.go"
- test: - test:
name: test-itest-ccupgrade name: test-itest-ccupgrade
requires:
- build
suite: itest-ccupgrade suite: itest-ccupgrade
target: "./itests/ccupgrade_test.go" target: "./itests/ccupgrade_test.go"
- test: - test:
name: test-itest-cli name: test-itest-cli
requires:
- build
suite: itest-cli suite: itest-cli
target: "./itests/cli_test.go" target: "./itests/cli_test.go"
- test: - test:
name: test-itest-deadlines name: test-itest-deadlines
requires:
- build
suite: itest-deadlines suite: itest-deadlines
target: "./itests/deadlines_test.go" target: "./itests/deadlines_test.go"
- test: - test:
name: test-itest-deals_512mb name: test-itest-deals_512mb
requires:
- build
suite: itest-deals_512mb suite: itest-deals_512mb
target: "./itests/deals_512mb_test.go" target: "./itests/deals_512mb_test.go"
- test: - test:
name: test-itest-deals_anycid name: test-itest-deals_anycid
requires:
- build
suite: itest-deals_anycid suite: itest-deals_anycid
target: "./itests/deals_anycid_test.go" target: "./itests/deals_anycid_test.go"
- test: - test:
name: test-itest-deals_concurrent name: test-itest-deals_concurrent
requires:
- build
suite: itest-deals_concurrent suite: itest-deals_concurrent
target: "./itests/deals_concurrent_test.go" target: "./itests/deals_concurrent_test.go"
executor: golang-2xl
- test: - test:
name: test-itest-deals_invalid_utf8_label name: test-itest-deals_invalid_utf8_label
requires:
- build
suite: itest-deals_invalid_utf8_label suite: itest-deals_invalid_utf8_label
target: "./itests/deals_invalid_utf8_label_test.go" target: "./itests/deals_invalid_utf8_label_test.go"
- test: - test:
name: test-itest-deals_max_staging_deals name: test-itest-deals_max_staging_deals
requires:
- build
suite: itest-deals_max_staging_deals suite: itest-deals_max_staging_deals
target: "./itests/deals_max_staging_deals_test.go" target: "./itests/deals_max_staging_deals_test.go"
- test: - test:
name: test-itest-deals_offline name: test-itest-deals_offline
requires:
- build
suite: itest-deals_offline suite: itest-deals_offline
target: "./itests/deals_offline_test.go" target: "./itests/deals_offline_test.go"
- test: - test:
name: test-itest-deals_padding name: test-itest-deals_padding
requires:
- build
suite: itest-deals_padding suite: itest-deals_padding
target: "./itests/deals_padding_test.go" target: "./itests/deals_padding_test.go"
- test: - test:
name: test-itest-deals_partial_retrieval_dm-level name: test-itest-deals_partial_retrieval_dm-level
requires:
- build
suite: itest-deals_partial_retrieval_dm-level suite: itest-deals_partial_retrieval_dm-level
target: "./itests/deals_partial_retrieval_dm-level_test.go" target: "./itests/deals_partial_retrieval_dm-level_test.go"
- test: - test:
name: test-itest-deals_partial_retrieval name: test-itest-deals_partial_retrieval
requires:
- build
suite: itest-deals_partial_retrieval suite: itest-deals_partial_retrieval
target: "./itests/deals_partial_retrieval_test.go" target: "./itests/deals_partial_retrieval_test.go"
- test: - test:
name: test-itest-deals_power name: test-itest-deals_power
requires:
- build
suite: itest-deals_power suite: itest-deals_power
target: "./itests/deals_power_test.go" target: "./itests/deals_power_test.go"
- test: - test:
name: test-itest-deals_pricing name: test-itest-deals_pricing
requires:
- build
suite: itest-deals_pricing suite: itest-deals_pricing
target: "./itests/deals_pricing_test.go" target: "./itests/deals_pricing_test.go"
- test: - test:
name: test-itest-deals_publish name: test-itest-deals_publish
requires:
- build
suite: itest-deals_publish suite: itest-deals_publish
target: "./itests/deals_publish_test.go" target: "./itests/deals_publish_test.go"
- test: - test:
name: test-itest-deals_remote_retrieval name: test-itest-deals_remote_retrieval
requires:
- build
suite: itest-deals_remote_retrieval suite: itest-deals_remote_retrieval
target: "./itests/deals_remote_retrieval_test.go" target: "./itests/deals_remote_retrieval_test.go"
- test: - test:
name: test-itest-deals_retry_deal_no_funds name: test-itest-deals_retry_deal_no_funds
requires:
- build
suite: itest-deals_retry_deal_no_funds suite: itest-deals_retry_deal_no_funds
target: "./itests/deals_retry_deal_no_funds_test.go" target: "./itests/deals_retry_deal_no_funds_test.go"
- test: - test:
name: test-itest-deals name: test-itest-deals
requires:
- build
suite: itest-deals suite: itest-deals
target: "./itests/deals_test.go" target: "./itests/deals_test.go"
- test: - test:
name: test-itest-decode_params name: test-itest-decode_params
requires:
- build
suite: itest-decode_params suite: itest-decode_params
target: "./itests/decode_params_test.go" target: "./itests/decode_params_test.go"
- test: - test:
name: test-itest-dup_mpool_messages name: test-itest-dup_mpool_messages
requires:
- build
suite: itest-dup_mpool_messages suite: itest-dup_mpool_messages
target: "./itests/dup_mpool_messages_test.go" target: "./itests/dup_mpool_messages_test.go"
- test: - test:
name: test-itest-eth_account_abstraction name: test-itest-eth_account_abstraction
requires:
- build
suite: itest-eth_account_abstraction suite: itest-eth_account_abstraction
target: "./itests/eth_account_abstraction_test.go" target: "./itests/eth_account_abstraction_test.go"
- test: - test:
name: test-itest-eth_api name: test-itest-eth_api
requires:
- build
suite: itest-eth_api suite: itest-eth_api
target: "./itests/eth_api_test.go" target: "./itests/eth_api_test.go"
- test: - test:
name: test-itest-eth_balance name: test-itest-eth_balance
requires:
- build
suite: itest-eth_balance suite: itest-eth_balance
target: "./itests/eth_balance_test.go" target: "./itests/eth_balance_test.go"
- test: - test:
name: test-itest-eth_block_hash name: test-itest-eth_block_hash
requires:
- build
suite: itest-eth_block_hash suite: itest-eth_block_hash
target: "./itests/eth_block_hash_test.go" target: "./itests/eth_block_hash_test.go"
- test: - test:
name: test-itest-eth_bytecode name: test-itest-eth_bytecode
requires:
- build
suite: itest-eth_bytecode suite: itest-eth_bytecode
target: "./itests/eth_bytecode_test.go" target: "./itests/eth_bytecode_test.go"
- test: - test:
name: test-itest-eth_config name: test-itest-eth_config
requires:
- build
suite: itest-eth_config suite: itest-eth_config
target: "./itests/eth_config_test.go" target: "./itests/eth_config_test.go"
- test: - test:
name: test-itest-eth_conformance name: test-itest-eth_conformance
requires:
- build
suite: itest-eth_conformance suite: itest-eth_conformance
target: "./itests/eth_conformance_test.go" target: "./itests/eth_conformance_test.go"
- test: - test:
name: test-itest-eth_deploy name: test-itest-eth_deploy
requires:
- build
suite: itest-eth_deploy suite: itest-eth_deploy
target: "./itests/eth_deploy_test.go" target: "./itests/eth_deploy_test.go"
- test: - test:
name: test-itest-eth_fee_history name: test-itest-eth_fee_history
requires:
- build
suite: itest-eth_fee_history suite: itest-eth_fee_history
target: "./itests/eth_fee_history_test.go" target: "./itests/eth_fee_history_test.go"
- test: - test:
name: test-itest-eth_filter name: test-itest-eth_filter
requires:
- build
suite: itest-eth_filter suite: itest-eth_filter
target: "./itests/eth_filter_test.go" target: "./itests/eth_filter_test.go"
- test: - test:
name: test-itest-eth_hash_lookup name: test-itest-eth_hash_lookup
requires:
- build
suite: itest-eth_hash_lookup suite: itest-eth_hash_lookup
target: "./itests/eth_hash_lookup_test.go" target: "./itests/eth_hash_lookup_test.go"
- test: - test:
name: test-itest-eth_transactions name: test-itest-eth_transactions
requires:
- build
suite: itest-eth_transactions suite: itest-eth_transactions
target: "./itests/eth_transactions_test.go" target: "./itests/eth_transactions_test.go"
- test: - test:
name: test-itest-fevm_address name: test-itest-fevm_address
requires:
- build
suite: itest-fevm_address suite: itest-fevm_address
target: "./itests/fevm_address_test.go" target: "./itests/fevm_address_test.go"
- test: - test:
name: test-itest-fevm_events name: test-itest-fevm_events
requires:
- build
suite: itest-fevm_events suite: itest-fevm_events
target: "./itests/fevm_events_test.go" target: "./itests/fevm_events_test.go"
- test: - test:
name: test-itest-fevm name: test-itest-fevm
requires:
- build
suite: itest-fevm suite: itest-fevm
target: "./itests/fevm_test.go" target: "./itests/fevm_test.go"
- test: - test:
name: test-itest-gas_estimation name: test-itest-gas_estimation
requires:
- build
suite: itest-gas_estimation suite: itest-gas_estimation
target: "./itests/gas_estimation_test.go" target: "./itests/gas_estimation_test.go"
- test: - test:
name: test-itest-gateway name: test-itest-gateway
requires:
- build
suite: itest-gateway suite: itest-gateway
target: "./itests/gateway_test.go" target: "./itests/gateway_test.go"
- test: - test:
name: test-itest-get_messages_in_ts name: test-itest-get_messages_in_ts
requires:
- build
suite: itest-get_messages_in_ts suite: itest-get_messages_in_ts
target: "./itests/get_messages_in_ts_test.go" target: "./itests/get_messages_in_ts_test.go"
- test: - test:
name: test-itest-lite_migration name: test-itest-lite_migration
requires:
- build
suite: itest-lite_migration suite: itest-lite_migration
target: "./itests/lite_migration_test.go" target: "./itests/lite_migration_test.go"
- test: - test:
name: test-itest-lookup_robust_address name: test-itest-lookup_robust_address
requires:
- build
suite: itest-lookup_robust_address suite: itest-lookup_robust_address
target: "./itests/lookup_robust_address_test.go" target: "./itests/lookup_robust_address_test.go"
- test: - test:
name: test-itest-mempool name: test-itest-mempool
requires:
- build
suite: itest-mempool suite: itest-mempool
target: "./itests/mempool_test.go" target: "./itests/mempool_test.go"
- test: - test:
name: test-itest-migration name: test-itest-migration
requires:
- build
suite: itest-migration suite: itest-migration
target: "./itests/migration_test.go" target: "./itests/migration_test.go"
- test: - test:
name: test-itest-mpool_msg_uuid name: test-itest-mpool_msg_uuid
requires:
- build
suite: itest-mpool_msg_uuid suite: itest-mpool_msg_uuid
target: "./itests/mpool_msg_uuid_test.go" target: "./itests/mpool_msg_uuid_test.go"
- test: - test:
name: test-itest-mpool_push_with_uuid name: test-itest-mpool_push_with_uuid
requires:
- build
suite: itest-mpool_push_with_uuid suite: itest-mpool_push_with_uuid
target: "./itests/mpool_push_with_uuid_test.go" target: "./itests/mpool_push_with_uuid_test.go"
- test:
name: test-itest-msgindex
requires:
- build
suite: itest-msgindex
target: "./itests/msgindex_test.go"
- test: - test:
name: test-itest-multisig name: test-itest-multisig
requires:
- build
suite: itest-multisig suite: itest-multisig
target: "./itests/multisig_test.go" target: "./itests/multisig_test.go"
- test: - test:
name: test-itest-net name: test-itest-net
requires:
- build
suite: itest-net suite: itest-net
target: "./itests/net_test.go" target: "./itests/net_test.go"
- test: - test:
name: test-itest-nonce name: test-itest-nonce
requires:
- build
suite: itest-nonce suite: itest-nonce
target: "./itests/nonce_test.go" target: "./itests/nonce_test.go"
- test: - test:
name: test-itest-path_detach_redeclare name: test-itest-path_detach_redeclare
requires:
- build
suite: itest-path_detach_redeclare suite: itest-path_detach_redeclare
target: "./itests/path_detach_redeclare_test.go" target: "./itests/path_detach_redeclare_test.go"
- test: - test:
name: test-itest-path_type_filters name: test-itest-path_type_filters
requires:
- build
suite: itest-path_type_filters suite: itest-path_type_filters
target: "./itests/path_type_filters_test.go" target: "./itests/path_type_filters_test.go"
- test: - test:
name: test-itest-paych_api name: test-itest-paych_api
requires:
- build
suite: itest-paych_api suite: itest-paych_api
target: "./itests/paych_api_test.go" target: "./itests/paych_api_test.go"
- test: - test:
name: test-itest-paych_cli name: test-itest-paych_cli
requires:
- build
suite: itest-paych_cli suite: itest-paych_cli
target: "./itests/paych_cli_test.go" target: "./itests/paych_cli_test.go"
- test: - test:
name: test-itest-pending_deal_allocation name: test-itest-pending_deal_allocation
requires:
- build
suite: itest-pending_deal_allocation suite: itest-pending_deal_allocation
target: "./itests/pending_deal_allocation_test.go" target: "./itests/pending_deal_allocation_test.go"
- test: - test:
name: test-itest-raft_messagesigner name: test-itest-raft_messagesigner
requires:
- build
suite: itest-raft_messagesigner suite: itest-raft_messagesigner
target: "./itests/raft_messagesigner_test.go" target: "./itests/raft_messagesigner_test.go"
- test: - test:
name: test-itest-remove_verifreg_datacap name: test-itest-remove_verifreg_datacap
requires:
- build
suite: itest-remove_verifreg_datacap suite: itest-remove_verifreg_datacap
target: "./itests/remove_verifreg_datacap_test.go" target: "./itests/remove_verifreg_datacap_test.go"
- test: - test:
name: test-itest-sdr_upgrade name: test-itest-sdr_upgrade
requires:
- build
suite: itest-sdr_upgrade suite: itest-sdr_upgrade
target: "./itests/sdr_upgrade_test.go" target: "./itests/sdr_upgrade_test.go"
- test:
name: test-itest-sealing_resources
requires:
- build
suite: itest-sealing_resources
target: "./itests/sealing_resources_test.go"
- test: - test:
name: test-itest-sector_finalize_early name: test-itest-sector_finalize_early
requires:
- build
suite: itest-sector_finalize_early suite: itest-sector_finalize_early
target: "./itests/sector_finalize_early_test.go" target: "./itests/sector_finalize_early_test.go"
- test: - test:
name: test-itest-sector_import_full name: test-itest-sector_import_full
requires:
- build
suite: itest-sector_import_full suite: itest-sector_import_full
target: "./itests/sector_import_full_test.go" target: "./itests/sector_import_full_test.go"
- test: - test:
name: test-itest-sector_import_simple name: test-itest-sector_import_simple
requires:
- build
suite: itest-sector_import_simple suite: itest-sector_import_simple
target: "./itests/sector_import_simple_test.go" target: "./itests/sector_import_simple_test.go"
- test: - test:
name: test-itest-sector_make_cc_avail name: test-itest-sector_make_cc_avail
requires:
- build
suite: itest-sector_make_cc_avail suite: itest-sector_make_cc_avail
target: "./itests/sector_make_cc_avail_test.go" target: "./itests/sector_make_cc_avail_test.go"
- test: - test:
name: test-itest-sector_miner_collateral name: test-itest-sector_miner_collateral
requires:
- build
suite: itest-sector_miner_collateral suite: itest-sector_miner_collateral
target: "./itests/sector_miner_collateral_test.go" target: "./itests/sector_miner_collateral_test.go"
- test: - test:
name: test-itest-sector_numassign name: test-itest-sector_numassign
requires:
- build
suite: itest-sector_numassign suite: itest-sector_numassign
target: "./itests/sector_numassign_test.go" target: "./itests/sector_numassign_test.go"
- test: - test:
name: test-itest-sector_pledge name: test-itest-sector_pledge
requires:
- build
suite: itest-sector_pledge suite: itest-sector_pledge
target: "./itests/sector_pledge_test.go" target: "./itests/sector_pledge_test.go"
- test: - test:
name: test-itest-sector_prefer_no_upgrade name: test-itest-sector_prefer_no_upgrade
requires:
- build
suite: itest-sector_prefer_no_upgrade suite: itest-sector_prefer_no_upgrade
target: "./itests/sector_prefer_no_upgrade_test.go" target: "./itests/sector_prefer_no_upgrade_test.go"
- test: - test:
name: test-itest-sector_revert_available name: test-itest-sector_revert_available
requires:
- build
suite: itest-sector_revert_available suite: itest-sector_revert_available
target: "./itests/sector_revert_available_test.go" target: "./itests/sector_revert_available_test.go"
- test: - test:
name: test-itest-sector_terminate name: test-itest-sector_terminate
requires:
- build
suite: itest-sector_terminate suite: itest-sector_terminate
target: "./itests/sector_terminate_test.go" target: "./itests/sector_terminate_test.go"
- test: - test:
name: test-itest-sector_unseal name: test-itest-sector_unseal
requires:
- build
suite: itest-sector_unseal suite: itest-sector_unseal
target: "./itests/sector_unseal_test.go" target: "./itests/sector_unseal_test.go"
- test: - test:
name: test-itest-self_sent_txn name: test-itest-self_sent_txn
requires:
- build
suite: itest-self_sent_txn suite: itest-self_sent_txn
target: "./itests/self_sent_txn_test.go" target: "./itests/self_sent_txn_test.go"
- test: - test:
name: test-itest-splitstore name: test-itest-splitstore
requires:
- build
suite: itest-splitstore suite: itest-splitstore
target: "./itests/splitstore_test.go" target: "./itests/splitstore_test.go"
- test: - test:
name: test-itest-tape name: test-itest-tape
requires:
- build
suite: itest-tape suite: itest-tape
target: "./itests/tape_test.go" target: "./itests/tape_test.go"
- test: - test:
name: test-itest-verifreg name: test-itest-verifreg
requires:
- build
suite: itest-verifreg suite: itest-verifreg
target: "./itests/verifreg_test.go" target: "./itests/verifreg_test.go"
- test: - test:
name: test-itest-wdpost_config name: test-itest-wdpost_config
requires:
- build
suite: itest-wdpost_config suite: itest-wdpost_config
target: "./itests/wdpost_config_test.go" target: "./itests/wdpost_config_test.go"
- test: - test:
name: test-itest-wdpost_dispute name: test-itest-wdpost_dispute
requires:
- build
suite: itest-wdpost_dispute suite: itest-wdpost_dispute
target: "./itests/wdpost_dispute_test.go" target: "./itests/wdpost_dispute_test.go"
- test: - test:
name: test-itest-wdpost_no_miner_storage name: test-itest-wdpost_no_miner_storage
requires:
- build
suite: itest-wdpost_no_miner_storage suite: itest-wdpost_no_miner_storage
target: "./itests/wdpost_no_miner_storage_test.go" target: "./itests/wdpost_no_miner_storage_test.go"
- test: - test:
name: test-itest-wdpost name: test-itest-wdpost
requires:
- build
suite: itest-wdpost suite: itest-wdpost
target: "./itests/wdpost_test.go" target: "./itests/wdpost_test.go"
get-params: true
- test: - test:
name: test-itest-wdpost_worker_config name: test-itest-wdpost_worker_config
requires:
- build
suite: itest-wdpost_worker_config suite: itest-wdpost_worker_config
target: "./itests/wdpost_worker_config_test.go" target: "./itests/wdpost_worker_config_test.go"
executor: golang-2xl
- test: - test:
name: test-itest-worker name: test-itest-worker
requires:
- build
suite: itest-worker suite: itest-worker
target: "./itests/worker_test.go" target: "./itests/worker_test.go"
executor: golang-2xl
- test: - test:
name: test-itest-worker_upgrade name: test-itest-worker_upgrade
requires:
- build
suite: itest-worker_upgrade suite: itest-worker_upgrade
target: "./itests/worker_upgrade_test.go" target: "./itests/worker_upgrade_test.go"
- test: - test:
name: test-unit-cli name: test-unit-cli
requires:
- build
suite: utest-unit-cli suite: utest-unit-cli
target: "./cli/... ./cmd/... ./api/..." target: "./cli/... ./cmd/... ./api/..."
get-params: true
- test: - test:
name: test-unit-node name: test-unit-node
requires:
- build
suite: utest-unit-node suite: utest-unit-node
target: "./node/..." target: "./node/..."
- test: - test:
name: test-unit-rest name: test-unit-rest
requires:
- build
suite: utest-unit-rest suite: utest-unit-rest
target: "./api/... ./blockstore/... ./build/... ./chain/... ./cli/... ./cmd/... ./conformance/... ./extern/... ./gateway/... ./journal/... ./lib/... ./markets/... ./node/... ./paychmgr/... ./storage/... ./tools/..." target: "./api/... ./blockstore/... ./build/... ./chain/... ./cli/... ./cmd/... ./conformance/... ./extern/... ./gateway/... ./journal/... ./lib/... ./markets/... ./node/... ./paychmgr/... ./storage/... ./tools/..."
executor: golang-2xl
- test: - test:
name: test-unit-storage name: test-unit-storage
requires:
- build
suite: utest-unit-storage suite: utest-unit-storage
target: "./storage/... ./extern/..." target: "./storage/... ./extern/..."
- test: - test:
go-test-flags: "-run=TestMulticoreSDR" go-test-flags: "-run=TestMulticoreSDR"
requires:
- build
suite: multicore-sdr-check suite: multicore-sdr-check
target: "./storage/sealer/ffiwrapper" target: "./storage/sealer/ffiwrapper"
proofs-log-test: "1" proofs-log-test: "1"
- test-conformance: - test-conformance:
requires:
- build
suite: conformance suite: conformance
target: "./conformance" target: "./conformance"
@@ -1073,7 +931,6 @@ workflows:
branches: branches:
only: only:
- /^release\/v\d+\.\d+\.\d+(-rc\d+)?$/ - /^release\/v\d+\.\d+\.\d+(-rc\d+)?$/
- /^ci\/.*$/
tags: tags:
only: only:
- /^v\d+\.\d+\.\d+(-rc\d+)?$/ - /^v\d+\.\d+\.\d+(-rc\d+)?$/
@@ -1083,7 +940,6 @@ workflows:
branches: branches:
only: only:
- /^release\/v\d+\.\d+\.\d+(-rc\d+)?$/ - /^release\/v\d+\.\d+\.\d+(-rc\d+)?$/
- /^ci\/.*$/
tags: tags:
only: only:
- /^v\d+\.\d+\.\d+(-rc\d+)?$/ - /^v\d+\.\d+\.\d+(-rc\d+)?$/
@@ -1093,7 +949,6 @@ workflows:
branches: branches:
only: only:
- /^release\/v\d+\.\d+\.\d+(-rc\d+)?$/ - /^release\/v\d+\.\d+\.\d+(-rc\d+)?$/
- /^ci\/.*$/
tags: tags:
only: only:
- /^v\d+\.\d+\.\d+(-rc\d+)?$/ - /^v\d+\.\d+\.\d+(-rc\d+)?$/
@@ -1106,7 +961,7 @@ workflows:
filters: filters:
branches: branches:
ignore: ignore:
- /^.*$/ - /.*/
tags: tags:
only: only:
- /^v\d+\.\d+\.\d+(-rc\d+)?$/ - /^v\d+\.\d+\.\d+(-rc\d+)?$/
@@ -1121,7 +976,6 @@ workflows:
branches: branches:
only: only:
- /^release\/v\d+\.\d+\.\d+(-rc\d+)?$/ - /^release\/v\d+\.\d+\.\d+(-rc\d+)?$/
- /^ci\/.*$/
- build-docker: - build-docker:
name: "Docker push (lotus-all-in-one / stable / mainnet)" name: "Docker push (lotus-all-in-one / stable / mainnet)"
image: lotus-all-in-one image: lotus-all-in-one
+73 -122
View File
@@ -7,19 +7,14 @@ executors:
golang: golang:
docker: docker:
# Must match GO_VERSION_MIN in project root # Must match GO_VERSION_MIN in project root
- image: cimg/go:1.19.7 - image: cimg/go:1.18.8
resource_class: medium+
golang-2xl:
docker:
# Must match GO_VERSION_MIN in project root
- image: cimg/go:1.19.7
resource_class: 2xlarge resource_class: 2xlarge
ubuntu: ubuntu:
docker: docker:
- image: ubuntu:20.04 - image: ubuntu:20.04
commands: commands:
build-platform-specific: prepare:
parameters: parameters:
linux: linux:
default: true default: true
@@ -36,13 +31,22 @@ commands:
steps: steps:
- checkout - checkout
- git_fetch_all_tags - git_fetch_all_tags
- run: git submodule sync
- run: git submodule update --init
- when: - when:
condition: <<parameters.linux>> condition: <<parameters.linux>>
steps: steps:
- install-ubuntu-deps - run:
- check-go-version name: Check Go Version
command: |
v=`go version | { read _ _ v _; echo ${v#go}; }`
if [["[[ $v != `cat GO_VERSION_MIN` ]]"]]; then
echo "GO_VERSION_MIN file does not match the go version being used."
echo "Please update image to cimg/go:`cat GO_VERSION_MIN` or update GO_VERSION_MIN to $v."
exit 1
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: - when:
condition: <<parameters.darwin>> condition: <<parameters.darwin>>
steps: steps:
@@ -63,7 +67,8 @@ commands:
name: Install Rust name: Install Rust
command: | command: |
curl https://sh.rustup.rs -sSf | sh -s -- -y curl https://sh.rustup.rs -sSf | sh -s -- -y
- run: make deps - run: git submodule sync
- run: git submodule update --init
download-params: download-params:
steps: steps:
- restore_cache: - restore_cache:
@@ -72,7 +77,7 @@ commands:
- 'v26-2k-lotus-params' - 'v26-2k-lotus-params'
paths: paths:
- /var/tmp/filecoin-proof-parameters/ - /var/tmp/filecoin-proof-parameters/
- run: ./lotus fetch-params 2048 - run: ./lotus fetch-params 2048
- save_cache: - save_cache:
name: Save parameters cache name: Save parameters cache
key: 'v26-2k-lotus-params' key: 'v26-2k-lotus-params'
@@ -94,43 +99,12 @@ commands:
name: fetch all tags name: fetch all tags
command: | command: |
git fetch --all git fetch --all
install-ubuntu-deps:
steps:
- run: sudo apt-get update
- run: sudo apt-get install ocl-icd-opencl-dev libhwloc-dev
check-go-version:
steps:
- run: |
v=`go version | { read _ _ v _; echo ${v#go}; }`
if [["[[ $v != `cat GO_VERSION_MIN` ]]"]]; then
echo "GO_VERSION_MIN file does not match the go version being used."
echo "Please update image to cimg/go:`cat GO_VERSION_MIN` or update GO_VERSION_MIN to $v."
exit 1
fi
jobs: jobs:
build:
executor: golang
working_directory: ~/lotus
steps:
- checkout
- git_fetch_all_tags
- run: git submodule sync
- run: git submodule update --init
- install-ubuntu-deps
- check-go-version
- run: make deps lotus
- persist_to_workspace:
root: ~/
paths:
- "lotus"
mod-tidy-check: mod-tidy-check:
executor: golang executor: golang
working_directory: ~/lotus
steps: steps:
- install-ubuntu-deps - prepare
- attach_workspace:
at: ~/
- run: go mod tidy -v - run: go mod tidy -v
- run: - run:
name: Check git diff name: Check git diff
@@ -141,14 +115,13 @@ jobs:
test: test:
description: | description: |
Run tests with gotestsum. Run tests with gotestsum.
working_directory: ~/lotus
parameters: &test-params parameters: &test-params
executor: executor:
type: executor type: executor
default: golang default: golang
go-test-flags: go-test-flags:
type: string type: string
default: "-timeout 20m" default: "-timeout 30m"
description: Flags passed to go test. description: Flags passed to go test.
target: target:
type: string type: string
@@ -157,22 +130,21 @@ jobs:
proofs-log-test: proofs-log-test:
type: string type: string
default: "0" default: "0"
get-params:
type: boolean
default: false
suite: suite:
type: string type: string
default: unit default: unit
description: Test suite name to report to CircleCI. description: Test suite name to report to CircleCI.
gotestsum-format:
type: string
default: standard-verbose
description: gotestsum format. https://github.com/gotestyourself/gotestsum#format
executor: << parameters.executor >> executor: << parameters.executor >>
steps: steps:
- install-ubuntu-deps - prepare
- attach_workspace: - run:
at: ~/ command: make deps lotus
- when: no_output_timeout: 30m
condition: << parameters.get-params >> - download-params
steps:
- download-params
- run: - run:
name: go test name: go test
environment: environment:
@@ -183,11 +155,12 @@ jobs:
mkdir -p /tmp/test-reports/<< parameters.suite >> mkdir -p /tmp/test-reports/<< parameters.suite >>
mkdir -p /tmp/test-artifacts mkdir -p /tmp/test-artifacts
gotestsum \ gotestsum \
--format standard-verbose \ --format << parameters.gotestsum-format >> \
--junitfile /tmp/test-reports/<< parameters.suite >>/junit.xml \ --junitfile /tmp/test-reports/<< parameters.suite >>/junit.xml \
--jsonfile /tmp/test-artifacts/<< parameters.suite >>.json \ --jsonfile /tmp/test-artifacts/<< parameters.suite >>.json \
--packages="<< parameters.target >>" \ -- \
-- << parameters.go-test-flags >> << parameters.go-test-flags >> \
<< parameters.target >>
no_output_timeout: 30m no_output_timeout: 30m
- store_test_results: - store_test_results:
path: /tmp/test-reports path: /tmp/test-reports
@@ -195,7 +168,6 @@ jobs:
path: /tmp/test-artifacts/<< parameters.suite >>.json path: /tmp/test-artifacts/<< parameters.suite >>.json
test-conformance: test-conformance:
working_directory: ~/lotus
description: | description: |
Run tests using a corpus of interoperable test vectors for Filecoin Run tests using a corpus of interoperable test vectors for Filecoin
implementations to test their correctness and compliance with the Filecoin implementations to test their correctness and compliance with the Filecoin
@@ -211,9 +183,10 @@ jobs:
submodule is used. submodule is used.
executor: << parameters.executor >> executor: << parameters.executor >>
steps: steps:
- install-ubuntu-deps - prepare
- attach_workspace: - run:
at: ~/ command: make deps lotus
no_output_timeout: 30m
- download-params - download-params
- when: - when:
condition: condition:
@@ -256,7 +229,7 @@ jobs:
build-linux-amd64: build-linux-amd64:
executor: golang executor: golang
steps: steps:
- build-platform-specific - prepare
- run: make lotus lotus-miner lotus-worker - run: make lotus lotus-miner lotus-worker
- run: - run:
name: check tag and version output match name: check tag and version output match
@@ -275,7 +248,7 @@ jobs:
macos: macos:
xcode: "13.4.1" xcode: "13.4.1"
steps: steps:
- build-platform-specific: - prepare:
linux: false linux: false
darwin: true darwin: true
darwin-architecture: amd64 darwin-architecture: amd64
@@ -299,12 +272,14 @@ jobs:
resource_class: filecoin-project/self-hosted-m1 resource_class: filecoin-project/self-hosted-m1
steps: steps:
- run: echo 'export PATH=/opt/homebrew/bin:"$PATH"' >> "$BASH_ENV" - run: echo 'export PATH=/opt/homebrew/bin:"$PATH"' >> "$BASH_ENV"
- build-platform-specific: - prepare:
linux: false linux: false
darwin: true darwin: true
darwin-architecture: arm64 darwin-architecture: arm64
- run: | - run: |
export CPATH=$(brew --prefix)/include && export LIBRARY_PATH=$(brew --prefix)/lib && make lotus lotus-miner lotus-worker export CPATH=$(brew --prefix)/include
export LIBRARY_PATH=$(brew --prefix)/lib
make lotus lotus-miner lotus-worker
- run: otool -hv lotus - run: otool -hv lotus
- run: - run:
name: check tag and version output match name: check tag and version output match
@@ -355,18 +330,16 @@ jobs:
gofmt: gofmt:
executor: golang executor: golang
working_directory: ~/lotus
steps: steps:
- prepare
- run: - run:
command: "! go fmt ./... 2>&1 | read" command: "! go fmt ./... 2>&1 | read"
gen-check: gen-check:
executor: golang executor: golang
working_directory: ~/lotus
steps: steps:
- install-ubuntu-deps - prepare
- attach_workspace: - run: make deps
at: ~/
- run: go install golang.org/x/tools/cmd/goimports - run: go install golang.org/x/tools/cmd/goimports
- run: go install github.com/hannahhoward/cbor-gen-for - run: go install github.com/hannahhoward/cbor-gen-for
- run: make gen - run: make gen
@@ -376,29 +349,32 @@ jobs:
docs-check: docs-check:
executor: golang executor: golang
working_directory: ~/lotus
steps: steps:
- install-ubuntu-deps - prepare
- attach_workspace:
at: ~/
- run: go install golang.org/x/tools/cmd/goimports - run: go install golang.org/x/tools/cmd/goimports
- run: zcat build/openrpc/full.json.gz | jq > ../pre-openrpc-full - run: zcat build/openrpc/full.json.gz | jq > ../pre-openrpc-full
- run: zcat build/openrpc/miner.json.gz | jq > ../pre-openrpc-miner - run: zcat build/openrpc/miner.json.gz | jq > ../pre-openrpc-miner
- run: zcat build/openrpc/worker.json.gz | jq > ../pre-openrpc-worker - run: zcat build/openrpc/worker.json.gz | jq > ../pre-openrpc-worker
- run: make deps
- run: make docsgen - run: make docsgen
- run: zcat build/openrpc/full.json.gz | jq > ../post-openrpc-full - run: zcat build/openrpc/full.json.gz | jq > ../post-openrpc-full
- run: zcat build/openrpc/miner.json.gz | jq > ../post-openrpc-miner - run: zcat build/openrpc/miner.json.gz | jq > ../post-openrpc-miner
- run: zcat build/openrpc/worker.json.gz | jq > ../post-openrpc-worker - run: zcat build/openrpc/worker.json.gz | jq > ../post-openrpc-worker
- run: diff ../pre-openrpc-full ../post-openrpc-full && diff ../pre-openrpc-miner ../post-openrpc-miner && diff ../pre-openrpc-worker ../post-openrpc-worker && git --no-pager diff && git --no-pager diff --quiet - run: diff ../pre-openrpc-full ../post-openrpc-full && diff ../pre-openrpc-miner ../post-openrpc-miner && diff ../pre-openrpc-worker ../post-openrpc-worker && git --no-pager diff && git --no-pager diff --quiet
lint-all: lint: &lint
description: | description: |
Run golangci-lint. Run golangci-lint.
working_directory: ~/lotus
parameters: parameters:
executor: executor:
type: executor type: executor
default: golang default: golang
concurrency:
type: string
default: '2'
description: |
Concurrency used to run linters. Defaults to 2 because NumCPU is not
aware of container CPU limits.
args: args:
type: string type: string
default: '' default: ''
@@ -406,14 +382,17 @@ jobs:
Arguments to pass to golangci-lint Arguments to pass to golangci-lint
executor: << parameters.executor >> executor: << parameters.executor >>
steps: steps:
- install-ubuntu-deps - prepare
- attach_workspace: - run:
at: ~/ command: make deps
no_output_timeout: 30m
- run: - run:
name: Lint name: Lint
command: | command: |
golangci-lint run -v --timeout 10m \ golangci-lint run -v --timeout 2m \
--concurrency 4 << parameters.args >> --concurrency << parameters.concurrency >> << parameters.args >>
lint-all:
<<: *lint
build-docker: build-docker:
description: > description: >
@@ -515,61 +494,37 @@ jobs:
extra_build_args: --target <<parameters.image>> --build-arg GOFLAGS=-tags=<<parameters.network>> extra_build_args: --target <<parameters.image>> --build-arg GOFLAGS=-tags=<<parameters.network>>
workflows: workflows:
version: 2.1
ci: ci:
jobs: jobs:
- build
- lint-all: - lint-all:
requires: concurrency: "16" # expend all docker 2xlarge CPUs.
- build - mod-tidy-check
- mod-tidy-check: - gofmt
requires: - gen-check
- build - docs-check
- gofmt:
requires:
- build
- gen-check:
requires:
- build
- docs-check:
requires:
- build
[[- range $file := .ItestFiles -]] [[- range $file := .ItestFiles -]]
[[ with $name := $file | stripSuffix ]] [[ with $name := $file | stripSuffix ]]
- test: - test:
name: test-itest-[[ $name ]] name: test-itest-[[ $name ]]
requires:
- build
suite: itest-[[ $name ]] suite: itest-[[ $name ]]
target: "./itests/[[ $file ]]" target: "./itests/[[ $file ]]"
[[- if or (eq $name "worker") (eq $name "deals_concurrent") (eq $name "wdpost_worker_config")]] [[ end ]]
executor: golang-2xl [[- end -]]
[[- end]]
[[- if (eq $name "wdpost")]]
get-params: true
[[end]]
[[- end ]][[- end]]
[[- range $suite, $pkgs := .UnitSuites]] [[range $suite, $pkgs := .UnitSuites]]
- test: - test:
name: test-[[ $suite ]] name: test-[[ $suite ]]
requires:
- build
suite: utest-[[ $suite ]] suite: utest-[[ $suite ]]
target: "[[ $pkgs ]]" target: "[[ $pkgs ]]"
[[if eq $suite "unit-cli"]]get-params: true[[end]]
[[- if eq $suite "unit-rest"]]executor: golang-2xl[[end]]
[[- end]] [[- end]]
- test: - test:
go-test-flags: "-run=TestMulticoreSDR" go-test-flags: "-run=TestMulticoreSDR"
requires:
- build
suite: multicore-sdr-check suite: multicore-sdr-check
target: "./storage/sealer/ffiwrapper" target: "./storage/sealer/ffiwrapper"
proofs-log-test: "1" proofs-log-test: "1"
- test-conformance: - test-conformance:
requires:
- build
suite: conformance suite: conformance
target: "./conformance" target: "./conformance"
@@ -581,7 +536,6 @@ workflows:
branches: branches:
only: only:
- /^release\/v\d+\.\d+\.\d+(-rc\d+)?$/ - /^release\/v\d+\.\d+\.\d+(-rc\d+)?$/
- /^ci\/.*$/
tags: tags:
only: only:
- /^v\d+\.\d+\.\d+(-rc\d+)?$/ - /^v\d+\.\d+\.\d+(-rc\d+)?$/
@@ -591,7 +545,6 @@ workflows:
branches: branches:
only: only:
- /^release\/v\d+\.\d+\.\d+(-rc\d+)?$/ - /^release\/v\d+\.\d+\.\d+(-rc\d+)?$/
- /^ci\/.*$/
tags: tags:
only: only:
- /^v\d+\.\d+\.\d+(-rc\d+)?$/ - /^v\d+\.\d+\.\d+(-rc\d+)?$/
@@ -601,7 +554,6 @@ workflows:
branches: branches:
only: only:
- /^release\/v\d+\.\d+\.\d+(-rc\d+)?$/ - /^release\/v\d+\.\d+\.\d+(-rc\d+)?$/
- /^ci\/.*$/
tags: tags:
only: only:
- /^v\d+\.\d+\.\d+(-rc\d+)?$/ - /^v\d+\.\d+\.\d+(-rc\d+)?$/
@@ -614,7 +566,7 @@ workflows:
filters: filters:
branches: branches:
ignore: ignore:
- /^.*$/ - /.*/
tags: tags:
only: only:
- /^v\d+\.\d+\.\d+(-rc\d+)?$/ - /^v\d+\.\d+\.\d+(-rc\d+)?$/
@@ -629,7 +581,6 @@ workflows:
branches: branches:
only: only:
- /^release\/v\d+\.\d+\.\d+(-rc\d+)?$/ - /^release\/v\d+\.\d+\.\d+(-rc\d+)?$/
- /^ci\/.*$/
[[- range .Networks]] [[- range .Networks]]
- build-docker: - build-docker:
name: "Docker push (lotus-all-in-one / stable / [[.]])" name: "Docker push (lotus-all-in-one / stable / [[.]])"
+35 -20
View File
@@ -9,9 +9,15 @@ body:
options: options:
- label: This is **not** a security-related bug/issue. If it is, please follow please follow the [security policy](https://github.com/filecoin-project/lotus/security/policy). - label: This is **not** a security-related bug/issue. If it is, please follow please follow the [security policy](https://github.com/filecoin-project/lotus/security/policy).
required: true required: true
- label: This is **not** a question or a support request. If you have any lotus related questions, please ask in the [lotus forum](https://github.com/filecoin-project/lotus/discussions).
required: true
- label: This is **not** a new feature request. If it is, please file a [feature request](https://github.com/filecoin-project/lotus/issues/new?assignees=&labels=need%2Ftriage%2Ckind%2Ffeature&template=feature_request.yml) instead.
required: true
- label: This is **not** an enhancement request. If it is, please file a [improvement suggestion](https://github.com/filecoin-project/lotus/issues/new?assignees=&labels=need%2Ftriage%2Ckind%2Fenhancement&template=enhancement.yml) instead.
required: true
- label: I **have** searched on the [issue tracker](https://github.com/filecoin-project/lotus/issues) and the [lotus forum](https://github.com/filecoin-project/lotus/discussions), and there is no existing related issue or discussion. - label: I **have** searched on the [issue tracker](https://github.com/filecoin-project/lotus/issues) and the [lotus forum](https://github.com/filecoin-project/lotus/discussions), and there is no existing related issue or discussion.
required: true required: true
- label: I am running the [`Latest release`](https://github.com/filecoin-project/lotus/releases), the most recent RC(release canadiate) for the upcoming release or the dev branch(master), or have an issue updating to any of these. - label: I am running the [`Latest release`](https://github.com/filecoin-project/lotus/releases), or the most recent RC(release canadiate) for the upcoming release or the dev branch(master), or have an issue updating to any of these.
required: true required: true
- label: I did not make any code changes to lotus. - label: I did not make any code changes to lotus.
required: false required: false
@@ -22,11 +28,19 @@ body:
options: options:
- label: lotus daemon - chain sync - label: lotus daemon - chain sync
required: false required: false
- label: lotus fvm/fevm - Lotus FVM and FEVM interactions - label: lotus miner - mining and block production
required: false required: false
- label: lotus miner/worker - sealing - label: lotus miner/worker - sealing
required: false required: false
- label: lotus miner - proving(WindowPoSt/WinningPoSt) - label: lotus miner - proving(WindowPoSt)
required: false
- label: lotus miner/market - storage deal
required: false
- label: lotus miner/market - retrieval deal
required: false
- label: lotus miner/market - data transfer
required: false
- label: lotus client
required: false required: false
- label: lotus JSON-RPC API - label: lotus JSON-RPC API
required: false required: false
@@ -42,33 +56,22 @@ body:
description: Enter the output of `lotus version` and `lotus-miner version` if applicable. description: Enter the output of `lotus version` and `lotus-miner version` if applicable.
placeholder: | placeholder: |
e.g. e.g.
Daemon: 1.19.0+mainnet+git.64059ca87+api1.5.0 Daemon:1.11.0-rc2+debug+git.0519cd371.dirty+api1.3.0
Local: lotus-miner version 1.19.0+mainnet+git.64059ca87 Local: lotus version 1.11.0-rc2+debug+git.0519cd371.dirty
validations: validations:
required: true required: true
- type: textarea
id: ReproSteps
attributes:
label: Repro Steps
description: "Steps to reproduce the behavior"
value: |
1. Run '...'
2. Do '...'
3. See error '...'
...
validations:
required: false
- type: textarea - type: textarea
id: Description id: Description
attributes: attributes:
label: Describe the Bug label: Describe the Bug
description: | description: |
This is where you get to tell us what went wrong, when doing so, please try to provide a clear and concise description of the bug with all related information: This is where you get to tell us what went wrong, when doing so, please try to provide a clear and concise description of the bug with all related information:
* What you were doing when you experienced the bug? * What you were doding when you experienced the bug?
* Any *error* messages you saw, *where* you saw them, and what you believe may have caused them (if you have any ideas). * Any *error* messages you saw, *where* you saw them, and what you believe may have caused them (if you have any ideas).
* What is the expected behaviour? * What is the expected behaviour?
* For sealing issues, include the output of `lotus-miner sectors status --log <sectorId>` for the failed sector(s). * For sealing issues, include the output of `lotus-miner sectors status --log <sectorId>` for the failed sector(s).
* For proving issues, include the output of `lotus-miner proving` info. * For proving issues, include the output of `lotus-miner proving` info.
* For deal making issues, include the output of `lotus client list-deals -v` and/or `lotus-miner storage-deals|retrieval-deals|data-transfers list [-v]` commands for the deal(s) in question.
validations: validations:
required: true required: true
- type: textarea - type: textarea
@@ -80,6 +83,18 @@ body:
Please provide debug logs of the problem, remember you can get set log level control for: Please provide debug logs of the problem, remember you can get set log level control for:
* lotus: use `lotus log list` to get all log systems available and set level by `lotus log set-level`. An example can be found [here](https://lotus.filecoin.io/lotus/configure/defaults/#log-level-control). * lotus: use `lotus log list` to get all log systems available and set level by `lotus log set-level`. An example can be found [here](https://lotus.filecoin.io/lotus/configure/defaults/#log-level-control).
* lotus-miner:`lotus-miner log list` to get all log systems available and set level by `lotus-miner log set-level * lotus-miner:`lotus-miner log list` to get all log systems available and set level by `lotus-miner log set-level
If you don't provide detailed logs when you raise the issue it will almost certainly be the first request we make before furthur diagnosing the problem. If you don't provide detailed logs when you raise the issue it will almost certainly be the first request I make before furthur diagnosing the problem.
validations: validations:
required: true required: true
- type: textarea
id: RepoSteps
attributes:
label: Repo Steps
description: "Steps to reproduce the behavior"
value: |
1. Run '...'
2. Do '...'
3. See error '...'
...
validations:
required: false
-8
View File
@@ -1,8 +0,0 @@
blank_issues_enabled: true
contact_links:
- name: Ask a question about Lotus or get support
url: https://github.com/filecoin-project/lotus/discussions/new/choose
about: Ask a question or request support for using Lotus
- name: Filecoin protocol feature or enhancement
url: https://github.com/filecoin-project/FIPs/discussions/new/choose
about: Write a discussion in the Filecoin Improvement Proposal repo
+20 -14
View File
@@ -7,7 +7,13 @@ body:
label: Checklist label: Checklist
description: Please check off the following boxes before continuing to create an improvement suggestion! description: Please check off the following boxes before continuing to create an improvement suggestion!
options: options:
- label: I **have** a specific, actionable, and well motivated improvement to an existing lotus feature. - label: This is **not** a new feature or an enhancement to the Filecoin protocol. If it is, please open an [FIP issue](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0001.md).
required: true
- label: This is **not** a new feature request. If it is, please file a [feature request](https://github.com/filecoin-project/lotus/issues/new?assignees=&labels=need%2Ftriage%2Ckind%2Ffeature&template=feature_request.yml) instead.
required: true
- label: This is **not** brainstorming ideas. If you have an idea you'd like to discuss, please open a new discussion on [the lotus forum](https://github.com/filecoin-project/lotus/discussions/categories/ideas) and select the category as `Ideas`.
required: true
- label: I **have** a specific, actionable, and well motivated improvement to propose.
required: true required: true
- type: checkboxes - type: checkboxes
attributes: attributes:
@@ -16,11 +22,19 @@ body:
options: options:
- label: lotus daemon - chain sync - label: lotus daemon - chain sync
required: false required: false
- label: lotus fvm/fevm - Lotus FVM and FEVM interactions - label: lotus miner - mining and block production
required: false required: false
- label: lotus miner/worker - sealing - label: lotus miner/worker - sealing
required: false required: false
- label: lotus miner - proving(WindowPoSt/WinningPoSt) - label: lotus miner - proving(WindowPoSt)
required: false
- label: lotus miner/market - storage deal
required: false
- label: lotus miner/market - retrieval deal
required: false
- label: lotus miner/market - data transfer
required: false
- label: lotus client
required: false required: false
- label: lotus JSON-RPC API - label: lotus JSON-RPC API
required: false required: false
@@ -31,17 +45,9 @@ body:
- type: textarea - type: textarea
id: request id: request
attributes: attributes:
label: Enhancement Suggestion label: Improvement Suggestion
description: A clear and concise description of the suggested enhancement? description: A clear and concise description of what the motivation or the current problem is and what is the suggested improvement?
placeholder: Ex. Currently lotus... However it would be great if [enhancement] was implemented... With the ability to... placeholder: Ex. Currently lotus... However, as a storage provider, I'd like...
validations:
required: true
- type: textarea
id: request
attributes:
label: Use-Case
description: How would this enhancement help you?
placeholder: Ex. With the [enhancement] node operators would be able to... For Storage Providers it would enable...
validations: validations:
required: true required: true
+14 -3
View File
@@ -7,6 +7,8 @@ body:
label: Checklist label: Checklist
description: Please check off the following boxes before continuing to create a new feature request! description: Please check off the following boxes before continuing to create a new feature request!
options: options:
- label: This is **not** a new feature or an enhancement to the Filecoin protocol. If it is, please open an [FIP issue](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0001.md).
required: true
- label: This is **not** brainstorming ideas. If you have an idea you'd like to discuss, please open a new discussion on [the lotus forum](https://github.com/filecoin-project/lotus/discussions/categories/ideas) and select the category as `Ideas`. - label: This is **not** brainstorming ideas. If you have an idea you'd like to discuss, please open a new discussion on [the lotus forum](https://github.com/filecoin-project/lotus/discussions/categories/ideas) and select the category as `Ideas`.
required: true required: true
- label: I **have** a specific, actionable, and well motivated feature request to propose. - label: I **have** a specific, actionable, and well motivated feature request to propose.
@@ -18,11 +20,19 @@ body:
options: options:
- label: lotus daemon - chain sync - label: lotus daemon - chain sync
required: false required: false
- label: lotus fvm/fevm - Lotus FVM and FEVM interactions - label: lotus miner - mining and block production
required: false required: false
- label: lotus miner/worker - sealing - label: lotus miner/worker - sealing
required: false required: false
- label: lotus miner - proving(WindowPoSt/WinningPoSt) - label: lotus miner - proving(WindowPoSt)
required: false
- label: lotus miner/market - storage deal
required: false
- label: lotus miner/market - retrieval deal
required: false
- label: lotus miner/market - data transfer
required: false
- label: lotus client
required: false required: false
- label: lotus JSON-RPC API - label: lotus JSON-RPC API
required: false required: false
@@ -46,7 +56,7 @@ body:
validations: validations:
required: true required: true
- type: textarea - type: textarea
id: alternatives id: alternates
attributes: attributes:
label: Describe alternatives you've considered label: Describe alternatives you've considered
description: A clear and concise description of any alternative solutions or features you've considered. description: A clear and concise description of any alternative solutions or features you've considered.
@@ -59,3 +69,4 @@ body:
description: Add any other context, design docs or screenshots about the feature request here. description: Add any other context, design docs or screenshots about the feature request here.
validations: validations:
required: false required: false
@@ -1,83 +0,0 @@
name: "Bug Report - developer/service provider"
description: "Bug report template about FEVM/FVM for developers/service providers"
labels: [need/triage, kind/bug, area/fevm]
body:
- type: checkboxes
attributes:
label: Checklist
description: Please check off the following boxes before continuing to file a bug report!
options:
- label: This is **not** a security-related bug/issue. If it is, please follow please follow the [security policy](https://github.com/filecoin-project/lotus/security/policy).
required: true
- label: I **have** searched on the [issue tracker](https://github.com/filecoin-project/lotus/issues) and the [lotus forum](https://github.com/filecoin-project/lotus/discussions), and there is no existing related issue or discussion.
required: true
- label: I did not make any code changes to lotus.
required: false
- type: checkboxes
attributes:
label: Lotus component
description: Please select the lotus component you are filing a bug for
options:
- label: lotus Ethereum RPC
required: false
- label: lotus FVM - Lotus FVM interactions
required: false
- label: FEVM tooling
required: false
- label: Other
required: false
- type: textarea
id: version
attributes:
label: Lotus Version
render: text
description: Enter the output of `lotus version` if applicable.
placeholder: |
e.g.
Daemon: 1.19.0+mainnet+git.64059ca87+api1.5.0
Local: lotus-miner version 1.19.0+mainnet+git.64059ca87
validations:
required: true
- type: textarea
id: repro
attributes:
label: Repro Steps
description: "Steps to reproduce the behavior"
value: |
1. Run '...'
2. Do '...'
3. See error '...'
...
validations:
required: false
- type: textarea
id: Description
attributes:
label: Describe the Bug
description: |
This is where you get to tell us what went wrong, when doing so, please try to provide a clear and concise description of the bug with all related information:
* What you were doing when you experienced the bug? What are you trying to build?
* Any *error* messages and logs you saw, *where* you saw them, and what you believe may have caused them (if you have any ideas).
* What is the expected behaviour? Links to the actual code?
validations:
required: true
- type: textarea
id: toolingInfo
attributes:
label: Tooling
render: text
description: |
What kind of tooling are you using:
* Are you using ether.js, Alchemy, Hardhat, etc.
validations:
required: true
- type: textarea
id: extraInfo
attributes:
label: Configuration Options
render: text
description: |
Please provide your updated FEVM related configuration options, or custome enviroment variables related to Lotus FEVM
* lotus: use `lotus config updated` to get your configuration options, and copy the [FEVM] section
validations:
required: true
-1
View File
@@ -52,4 +52,3 @@ dist/
# The following files are checked into git and result # The following files are checked into git and result
# in dirty git state if removed from the docker context # in dirty git state if removed from the docker context
!extern/filecoin-ffi/rust/filecoin.pc !extern/filecoin-ffi/rust/filecoin.pc
!extern/test-vectors
+2 -462
View File
@@ -1,451 +1,5 @@
# Lotus changelog # Lotus changelog
# UNRELEASED
## New features
- feat: Added new environment variable `LOTUS_EXEC_TRACE_CACHE_SIZE` to configure execution trace cache size ([filecoin-project/lotus#10585](https://github.com/filecoin-project/lotus/pull/10585))
- If unset, we default to caching 16 most recent execution traces. Node operatores may want to set this to 0 while exchanges may want to crank it up.
# v1.23.0 / 2023-04-21
This is the stable feature release for the upcoming MANDATORY network upgrade at `2023-04-27T13:00:00Z`, epoch `2809800`. This feature release delivers the nv19 Lighting and nv20 Thunder network upgrade for mainnet, and includes numerous improvements and enhancements for node operators, ETH RPC-providers and storage providers.
## ☢️ Upgrade Warnings ☢️
Please read carefully through the **upgrade warnings** section if you are upgrading from a v1.20.X release, or the v1.22.0 release. If you are upgrading from a v1.21.0-rcX these warnings should be familiar to you.
- Starting from this release, the SplitStore feature is automatically activated on new nodes. However, for existing Lotus users, you need to explicitly configure SplitStore by uncommenting the `EnableSplitstore` option in your `config.toml` file. To enable SplitStore, set `EnableSplitstore=true`, and to disable it, set `EnableSplitstore=false`. **It's important to note that your Lotus node will not start unless this configuration is properly set. Set it to false if you are running a full archival node!**
- This feature release requires a **minimum Go version of v1.19.7 or higher to successfully build Lotus**. Additionally, Go version v1.20 and higher is now also supported.
- **Storage Providers:** The proofs libraries now have CUDA enabled by default, which requires you to install (CUDA)[https://lotus.filecoin.io/tutorials/lotus-miner/cuda/] if you haven't already done so. If you prefer to use OpenCL on your GPUs instead, you can use the `FFI_USE_OPENCL=1` flag when building from source. On the other hand, if you want to disable GPUs altogether, you can use the `FFI_NO_GPU=1` environment variable when building from source.
- **Storage Providers:** The `lotus-miner sectors extend` command has been refactored to the functionality of `lotus-miner sectors renew`.
- **Exchanges/Node operators/RPC-providers::** Execution traces (returned from `lotus state exec-trace`, `lotus state replay`, etc.), has changed to account for changes introduced by the by the FVM. **Please make sure to read the `Execution trace format change` section carefully, as these are interface breaking changes**
- **Syncing issues:** If you have been struggling with syncing issues in normal operations you can try to adjust the amount of threads used for more concurrent FMV execution through via the `LOTUS_FVM_CONCURRENCY` enviroment variable. It is set to 4 threads by default. Recommended formula for concurrency == YOUR_RAM/4 , but max during a network upgrade is 24. If you are a Storage Provider and are pushing many messages within a short period of time, exporting `LOTUS_SKIP_APPLY_TS_MESSAGE_CALL_WITH_GAS=1` will also help with keeping in sync.
- **Catching up from a Snapshot:** Users have noticed that catching up sync from a snapshot is taking a lot longer these day. This is largely related to the built-in market actor consuming a lot of computational demand for block validation. A FIP for a short-term mitigation for this is currently in Last Call and will be included network version 19 upgrade if accepted. You [can read the FIP here.](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0060.md)
## Highlights
### Execution Trace Format Changes
Execution traces (returned from `lotus state exec-trace`, `lotus state replay`, etc.), has changed to account for changes introduced by the FVM. Specifically:
- The `Msg` field no longer matches the Filecoin message format as many of the message fields didn't make sense in on-chain sub-calls. Instead, it now has the fields `To`, `From`, `Value`, `Method`, `Params`, and `ParamsCodec` where `ParamsCodec` is a new field indicating the IPLD codec of the parameters.
- Importantly, the `Msg.CID` field has been removed. This field is still present in top-level invocation results, just not inside the execution trace itself.
- The `MsgRct` field no longer includes a `GasUsed` field and now has a `ReturnCodec` field to indicating the IPLD codec of the return value.
- The `Error` and `Duration` fields have been removed as these are not set by the FVM. The top-level message "invocation result" retains the `Error` and `Duration` fields, they've only been removed from the trace itself.
- Gas Charges no longer include "virtual" gas fields (those starting with `v...`) or source location information (`loc`) as neither field is set by the FVM.
A note on "codecs": FVM parameters and return values are IPLD blocks where the "codec" specifies the data encoding. The codec will generally be one of:
- `0x51`, `0x71` - CBOR or DagCBOR. You should generally treat these as equivalent.
- `0x55` - Raw bytes.
- `0x00` - Nothing. If the codec is `0x00`, the parameter and/or return value should be empty and should be treated as "void" (not specified).
<details>
<summary>
Old <code>ExecutionTrace</code>:
</summary>
```json
{
"Msg": {
"Version": 0,
"To": "f01234",
"From": "f04321",
"Nonce": 1,
"Value": "0",
"GasLimit": 0,
"GasFeeCap": "1234",
"GasPremium": "1234",
"Method": 42,
"Params": "<base64-data-or-null>",
"CID": {
"/": "bafyxyz....."
},
},
"MsgRct": {
"ExitCode": 0,
"Return": "<base64-data-or-null>",
"GasUsed": 12345,
},
"Error": "",
"Duration": 568191845,
"GasCharges": [
{
"Name": "OnMethodInvocation",
"loc": null,
"tg": 23856,
"cg": 23856,
"sg": 0,
"vtg": 0,
"vcg": 0,
"vsg": 0,
"tt": 0
},
{
"Name": "wasm_exec",
"loc": null,
"tg": 1764,
"cg": 1764,
"sg": 0,
"vtg": 0,
"vcg": 0,
"vsg": 0,
"tt": 0
},
{
"Name": "OnSyscall",
"loc": null,
"tg": 14000,
"cg": 14000,
"sg": 0,
"vtg": 0,
"vcg": 0,
"vsg": 0,
"tt": 0
},
],
"Subcalls": [
{
"Msg": { },
"MsgRct": { },
"Error": "",
"Duration": 1235,
"GasCharges": [],
"Subcalls": [],
},
]
}
```
</details>
<details>
<summary>
New <code>ExecutionTrace</code>:
</summary>
```json
{
"Msg": {
"To": "f01234",
"From": "f04321",
"Value": "0",
"Method": 42,
"Params": "<base64-data-or-null>",
"ParamsCodec": 81
},
"MsgRct": {
"ExitCode": 0,
"Return": "<base64-data-or-null>",
"ReturnCodec": 81
},
"GasCharges": [
{
"Name": "OnMethodInvocation",
"loc": null,
"tg": 23856,
"cg": 23856,
"tt": 0
},
{
"Name": "wasm_exec",
"loc": null,
"tg": 1764,
"cg": 1764,
"sg": 0,
"tt": 0
},
{
"Name": "OnSyscall",
"loc": null,
"tg": 14000,
"cg": 14000,
"sg": 0,
"tt": 0
},
],
"Subcalls": [
{
"Msg": { },
"MsgRct": { },
"GasCharges": [],
"Subcalls": [],
},
]
}
```
</details>
**SplitStore**
This feature release introduces numerous improvements and fixes to tackle SplitStore related issues that has been reported. With this feature release SplitStore is automatically activated by default on new nodes. However, for existing Lotus users, you need to explicitly configure SplitStore by uncommenting the `EnableSplitstore` option in your `config.toml` file. To enable SplitStore, set `EnableSplitstore=true`, and to disable it, set `EnableSplitstore=false`. **It's important to note that your Lotus node will not start unless this configuration is properly set. Set it to false if you are running a full archival node!**
SplitStore also has some new configuration settings that you can set in your config.toml file:
- `HotstoreMaxSpaceTarget` suggests the max allowed space (in bytes) the hotstore can take.
- `HotstoreMaxSpaceThreshold` a moving GC will be triggered when total moving size exceeds this threshold (in bytes).
- `HotstoreMaxSpaceSafetyBuffer` a safety buffer to prevent moving GC from an overflowing disk.
The SplitStore also has two new commands:
- `lotus chain prune hot` is a much less resource-intensive GC and is best suited for situations where you don't have the spare disk space for a full GC.
- `lotus chain prune hot-moving` will run a full moving garbage collection of the hotstore. This commands create a new hotstore before deleting the old one so you need working room in the hotstore directory. The current size of a fully GC'd hotstore is around 295 GiB so you need to make sure you have at least that available.
You can read more about the new SplitStore commands in [the documentation](https://lotus.filecoin.io/lotus/configure/splitstore/#manual-chain-store-garbage-collection).
**RPC API improvements**
This feature release includes all the RPC API improvements made in the Lotus v1.20.x patch releases. It includes an updated FFI that sets the FVM parallelism to 4 by default.
Node operators with higher memory specs can experiment with setting LOTUS_FVM_CONCURRENCY to higher values, up to 48, to allow for more concurrent FVM execution.
**Experimental scheduler assigners**
In this release there are four new expirmental scheduler assigners:
- The `experiment-spread-qcount` - similar to the spread assigner but also takes into account task counts which are in running/preparing/queued states.
- The `experiment-spread-tasks` - similar to the spread assigner, but counts running tasks on a per-task-type basis
- The `experiment-spread-tasks-qcount` - similar to the spread assigner, but also takes into account task counts which are in running/preparing/queued states, as well as counting running tasks on a per-task-type basis. Check the results for this assigner on ([storage-only lotus-workers here](https://github.com/filecoin-project/lotus/issues/8566#issuecomment-1446978856)).
- The `experiment-random` - In each schedule loop the assinger figures a set of all workers which can handle the task and then picks a random one. Check the results for this assigner on ([storage-only lotus-workers here](https://github.com/filecoin-project/lotus/issues/8566#issuecomment-1447064218)).
**Graceful shutdown of lotus-workers**
We have cleaned up some commands in the `lotus-worker` to make it less confusing how to gracefully shutting down a `lotus-worker` while there are incoming sealing tasks in the pipeline. To shut down a `lotus-worker` gracefully:
1. `lotus-worker tasks disable --all` and wait for the worker to finish processing its current tasks.
2. `lotus-worker stop` to detach it and do maintenance/upgrades.
**CLI speedups**
The `lotus-miner sector list` is now running in parallel - which should speed up the process from anywhere between 2x-10x+. You can tune it additionally with the `check-parallelism` option in the command. The `Lotus-Miner info` command also has a large speed improvement, as calls to the lotus legacy market has been removed.
## New features
- feat: splitstore: Pause compaction when out of sync ([filecoin-project/lotus/#10641](https://github.com/filecoin-project/lotus/pull/10641))
- Pause the SplitStore compaction if the node is out of sync. Resumes the compation when its back in sync.
- feat: splitstore: limit moving gc threads (#10621) ([filecoin-project/lotus/#10621](https://github.com/filecoin-project/lotus/pull/10621))
- Makes moving gc less likely to cause node falling out of sync.
- feat: splitstore: Update config default value (#10605) ([filecoin-project/lotus/#10605](https://github.com/filecoin-project/lotus/pull/10605))
- Sets Splitstore HotStoreMaxSpaceTarget config to 650GB as default
- feat: splitstore: Splitstore enabled by default (#10429) ([filecoin-project/lotus#10429](https://github.com/filecoin-project/lotus/pull/10429))
- Enables SplitStore by default on new Lotus nodes. Existing Lotus users need to explicitly configure
- feat: splitstore: Configure max space used by hotstore and GC makes best effort to respect ([filecoin-project/lotus#10391](https://github.com/filecoin-project/lotus/pull/10391))
- Adds three new configs for setting the maximum allowed space the hotstore can take.
- feat: splitstore: Badger GC of hotstore command ([filecoin-project/lotus#10387](https://github.com/filecoin-project/lotus/pull/10387))
- Adds a `lotus chain prune hot` command, to run the garbage collection of the hotstore in a user driven way.
- feat: sched: Assigner experiments ([filecoin-project/lotus#10356](https://github.com/filecoin-project/lotus/pull/10356))
- Introduces experimental scheduler assigners that works better for setups that uses storage-only lotus-workers.
- fix: wdpost: disabled post worker handling ([filecoin-project/lotus#10394](https://github.com/filecoin-project/lotus/pull/10394))
- Improved scheduling logic for Proof-of-SpaceTime workers.
- feat: cli: list claims and remove expired claims ([filecoin-project/lotus#9875](https://github.com/filecoin-project/lotus/pull/9875))
- Adds a command to list claims made by a provider `lotus filplus list-claims`. And `lotus filplus remove-expired-claims` to remove expired claims.
- feat: cli: make sectors list much faster ([filecoin-project/lotus#10202](https://github.com/filecoin-project/lotus/pull/10202))
- Makes `lotus-miner sector list` checks run in parallel.
- feat: cli: Add an EVM command to fetch a contract's bytecode ([filecoin-project/lotus#10443](https://github.com/filecoin-project/lotus/pull/10443))
- Adds an `lotus evm bytecode` command to fetch a contract's bytecode.
- feat: mempool: Reduce minimum replace fee from 1.25x to 1.1x (#10416) ([filecoin-project/lotus#10416](https://github.com/filecoin-project/lotus/pull/10416))
- Reduces replacement message fee logic to help include update message replacements from developers using Ethereum tools like MetaMask.
- feat: update renew-sectors with FIP-0045 logic ([filecoin-project/lotus#10328](https://github.com/filecoin-project/lotus/pull/10328))
- Updates the `lotus-miner sectors extend` with FIP-0045 logic to include the ability to drop claims and set the maximum number of messages contained in a message.
- feat: IPC: Abstract common consensus functions and consensus interface ([filecoin-project/lotus#9481](https://github.com/filecoin-project/lotus/pull/9481))
- Add eudico's consensus interface to Lotus and implement EC behind that interface. This abstraction is the stepping-stone for Mir's integration.
- fix: worker: add all tasks flag ([filecoin-project/lotus#10232](https://github.com/filecoin-project/lotus/pull/10232))
- Adds an `all` flag for the `lotus-worker tasks enable/disable` cmds.
- feat:shed:add cid to cbor serialization command ([filecoin-project/lotus#10032](https://github.com/filecoin-project/lotus/pull/10032))
- Adds two `lotus-shed` commands, `lotus-shed cid bytes` and `lotus-shed cid cbor` to serialize cid to cbor and cid to bytes.
- feat: add toolshed commands to inspect statetree size ([filecoin-project/lotus#9982](https://github.com/filecoin-project/lotus/pull/9982))
- Adds two commands, `lotus-shed stat-actor` and `lotus-shed stat-obj` that work with an offline lotus repo to report dag size stats.
- feat: shed: encode address to bytes ([filecoin-project/lotus#10105](https://github.com/filecoin-project/lotus/pull/10105))
- Adds a `lotus-shed address encode` for encoding a filecoin address to hex bytes.
- feat: chain: export-range ([filecoin-project/lotus#10145](https://github.com/filecoin-project/lotus/pull/10145))
- Adds a `lotus chain export-range` command that can create archival-grade ranged exports of the chain as quickly as possible.
- feat: stmgr: cache migrated stateroots ([filecoin-project/lotus#10282](https://github.com/filecoin-project/lotus/pull/10282))
- Cache network migration results to avoid running migrations twice.
- feat: shed: Add a tool to read data from sectors ([filecoin-project/lotus#10169](https://github.com/filecoin-project/lotus/pull/10169))
- Adds a lotus-shed sectors read command that extract data from sectors from a running lotus-miner deployment.
- feat: cli: Refactor renew and remove extend ([filecoin-project/lotus#9920](https://github.com/filecoin-project/lotus/pull/9920))
- Refactors the `lotus-miner sectors extend` command to have the functionality of `lotus-miner sectors renew`. The `lotus-miner sectors renew` command has been deprecated.
- feat: shed: Add beneficiary commands ([filecoin-project/lotus#10037](https://github.com/filecoin-project/lotus/pull/10037))
- Adds the beneficiary address command to `lotus-shed`. You can now use `lotus-shed actor propose-change-beneficiary` and `lotus-shed actor confirm-change-beneficiary` to change beneficiary addresses.
## Improvements
- backport: fix: miner: correctly count sector extensions (10555) ([filecoin-project/lotus#10555](https://github.com/filecoin-project/lotus/pull/10555))
- Fixes the issue with sector extensions.
- fix: proving: Initialize slice with with same length as partition (#10574) ([filecoin-project/lotus#10574])(https://github.com/filecoin-project/lotus/pull/10574)
- Fixes an issue where `lotus-miner proving compute window-post` paniced when trying to make skipped sectors human readable.
- feat: stmgr: speed up calculation of genesis circ supply (#10553) ([filecoin-project/lotus#10553])(https://github.com/filecoin-project/lotus/pull/10553)
- perf: eth: gas estimate set applyTsMessages false (#10546) ([filecoin-project/lotus#10456](https://github.com/filecoin-project/lotus/pull/10546))
- feat: config: Force existing users to opt into new defaults (#10488) ([filecoin-project/lotus#10488](https://github.com/filecoin-project/lotus/pull/10488))
- Force existing users to opt into the new SplitStore defaults.
- fix: splitstore: Demote now common logs (#10516) ([filecoin-project/lotus#10516](https://github.com/filecoin-project/lotus/pull/10516))
- fix: splitstore: Don't enforce walking receipt tree during compaction ([filecoin-project/lotus#10502](https://github.com/filecoin-project/lotus/pull/10502))
- fix: splitstore: Fix the overzealous fix (#10366) ([filecoin-project/lotus#10366](https://github.com/filecoin-project/lotus/pull/10366))
- fix: splitstore: Two fixes, better logging and comments (#10332) ([filecoin-project/lotus#10332](https://github.com/filecoin-project/lotus/pull/10332))
- fix: fsm: shutdown removed sectors FSMs ([filecoin-project/lotus#10363](https://github.com/filecoin-project/lotus/pull/10363))
- Fixes an issue where removed sectors still got state machine events.
- fix: rpcenc: Don't hang when source dies ([filecoin-project/lotus#10116](https://github.com/filecoin-project/lotus/pull/10116))
- Fixes an issue where AddPiece tasks could get stuck if the Boost process was abruptly lost.
- fix: make debugging windowPoSt-failures human readable ([filecoin-project/lotus#10390](https://github.com/filecoin-project/lotus/pull/10390))
- Makes the skipped sector list in `lotus-miner proving compute window-post` human readable.
- fix: cli: Hide `lotus-worker set` command ([filecoin-project/lotus#10384](https://github.com/filecoin-project/lotus/pull/10384))
- Hides the `lotus-worker set` command. This command will be deprecated later.
- fix: worker: Hide `wait-quiet` cmd ([filecoin-project/lotus#10331](https://github.com/filecoin-project/lotus/pull/10331))
- Hides the `lotus-worker wait-quiet` command. This command will be deprecated later.
- fix: post: Tune down default post-parallel-reads ([filecoin-project/lotus#10365](https://github.com/filecoin-project/lotus/pull/10365))
- Tuning down the default post-parallel-reads to a more conservative number to prevent sectors from being skipped due to network timeouts.
- fix: cli: error if backup file already exists ([filecoin-project/lotus#10209](https://github.com/filecoin-project/lotus/pull/10209))
- Error out if a backup file with the same name already exists when using the `lotus-miner backup` or `lotus backup` command
- fix: cli: option to set-seal-delay in seconds ([filecoin-project/lotus#10208](https://github.com/filecoin-project/lotus/pull/10208))
- Adds the option to specify `lotus-miner sectors set-seal-delay` in seconds
- fix: cli: extend cmd to get the right sector number ([filecoin-project/lotus#10182](https://github.com/filecoin-project/lotus/pull/10182))
- Making sure the `lotus-miner sectors extend` command gets the correct sector number.
- feat: wdpost: Emit more detailed errors ([filecoin-project/lotus#10121](https://github.com/filecoin-project/lotus/pull/10121))
- Emits more detailed windowPoSt error messages, making it easier to debug PoSt issues.
- fix: Lotus Gateway: Add missing methods - master ([filecoin-project/lotus#10420](https://github.com/filecoin-project/lotus/pull/10420))
- Adds `StateNetworkName`, `MpoolGetNonce`, `StateCall` and `StateDecodeParams` methods to Lotus Gateway.
- fix: stmgr: don't attempt to lookup genesis state (#10472) ([filecoin-project/lotus#10472](https://github.com/filecoin-project/lotus/pull/10472))
- feat: gateway: export StateVerifierStatus ([filecoin-project/lotus#10477](https://github.com/filecoin-project/lotus/pull/10477))
- fix: gateway: correctly apply the fee history lookback max ([filecoin-project/lotus#10464](https://github.com/filecoin-project/lotus/pull/10464))
- fix: gateway: drop overzealous guard on MsigGetVested ([filecoin-project/lotus#10451](https://github.com/filecoin-project/lotus/pull/10451))
- feat: apply gateway lookback limit to eth API lookback ([filecoin-project/lotus#10467](https://github.com/filecoin-project/lotus/pull/10467))
- fix: revert "Eth API: drop support for 'pending' block parameter." ([filecoin-project/lotus#10474](https://github.com/filecoin-project/lotus/pull/10474))
- fix: Eth API: make net_version return the chain ID ([filecoin-project/lotus#10456](https://github.com/filecoin-project/lotus/pull/10456))
- fix: eth: handle a potential divide by zero in receipt handling ([filecoin-project/lotus#10495](https://github.com/filecoin-project/lotus/pull/10495))
- fix: ethrpc: Don't lock up when eth subscriber goes away ([filecoin-project/lotus#10485](https://github.com/filecoin-project/lotus/pull/10485))
- feat: eth: Avoid StateCompute in EthTxnReceipt lookup (#10460) ([filecoin-project/lotus#10460](https://github.com/filecoin-project/lotus/pull/10460))
- feat: eth: optimize eth block loading + eth_feeHistory ([filecoin-project/lotus#10446](https://github.com/filecoin-project/lotus/pull/10446))
- feat: state: skip tipset execution when possible ([filecoin-project/lotus#10445](https://github.com/filecoin-project/lotus/pull/10445))
- feat: eth API: reject masked ID addresses embedded in f410f payloads ([filecoin-project/lotus#10440](https://github.com/filecoin-project/lotus/pull/10440))
- fix: Eth API: make block parameter parsing sounder. ([filecoin-project/lotus#10427](https://github.com/filecoin-project/lotus/pull/10427))
- fix: eth API: return correct txIdx around null blocks (#10419) ([filecoin-project/lotus#10419](https://github.com/filecoin-project/lotus/pull/10419))
- fix: EthAPI: use StateCompute for feeHistory; apply minimum gas premium (#10413) ([filecoin-project/lotus#10413](https://github.com/filecoin-project/lotus/pull/10413))
- refactor: EthAPI: Drop unnecessary param from newEthTxReceipt ([filecoin-project/lotus#10411](https://github.com/filecoin-project/lotus/pull/10411))
- fix: eth API: correct gateway restrictions, drop unimplemented methods ([filecoin-project/lotus#10409](https://github.com/filecoin-project/lotus/pull/10409))
- fix: EthAPI: Correctly get parent hash ([filecoin-project/lotus#10389](https://github.com/filecoin-project/lotus/pull/10389))
- fix: EthAPI: Make newEthBlockFromFilecoinTipSet faster and correct ([filecoin-project/lotus#10380](https://github.com/filecoin-project/lotus/pull/10380))
- fix: eth: incorrect struct tags (#10309) ([filecoin-project/lotus#10309](https://github.com/filecoin-project/lotus/pull/10309))
- refactor: update cache to the new generic version (#10463) ([filecoin-project/lotus#10463](https://github.com/filecoin-project/lotus/pull/10463))
- feat: consensus: log ApplyBlock timing/gas stats ([filecoin-project/lotus#10470](https://github.com/filecoin-project/lotus/pull/10470))
- feat: chain: make chain tipset fetching 1000x faster ([filecoin-project/lotus#10423](https://github.com/filecoin-project/lotus/pull/10423))
- chain: explicitly check that gasLimit is above zero ([filecoin-project/lotus#10198](https://github.com/filecoin-project/lotus/pull/10198))
- feat: blockstore: Envvar can adjust badger compaction worker poolsize ([filecoin-project/lotus#9973](https://github.com/filecoin-project/lotus/pull/9973))
- feat: stmgr: add env to disable premigrations ([filecoin-project/lotus#10283](https://github.com/filecoin-project/lotus/pull/10283))
- chore: Remove legacy market info from lotus-miner info ([filecoin-project/lotus#10364](https://github.com/filecoin-project/lotus/pull/10364))
- Removes the legacy market info in the `Lotus-Miner info`. Speeds up the command significantly.
- chore: blockstore: Plumb through a proper Flush() method on all blockstores ([filecoin-project/lotus#10465](https://github.com/filecoin-project/lotus/pull/10465))
- fix: extend LOTUS_CHAIN_BADGERSTORE_DISABLE_FSYNC to the markset ([filecoin-project/lotus#10172](https://github.com/filecoin-project/lotus/pull/10172))
- feat: vm: switch to the new exec trace format (#10372) ([filecoin-project/lotus#10372](https://github.com/filecoin-project/lotus/pull/10372))
- fix: Remove workaround that is no longer needed ([filecoin-project/lotus#9995](https://github.com/filecoin-project/lotus/pull/9995))
- feat: Check for allocation expiry when waiting to seal sectors ([filecoin-project/lotus#9878](https://github.com/filecoin-project/lotus/pull/9878))
- feat: Allow libp2p user agent to be overriden ([filecoin-project/lotus#10149](https://github.com/filecoin-project/lotus/pull/10149))
- feat: cli: Add global color flag ([filecoin-project/lotus#10022](https://github.com/filecoin-project/lotus/pull/10022))
- fix: should not serve non v0 api in v0 ([filecoin-project/lotus#10066](https://github.com/filecoin-project/lotus/pull/10066))
- fix: build: drop drand incentinet servers ([filecoin-project/lotus#10476](https://github.com/filecoin-project/lotus/pull/10476))
- fix: sealing: stub out the FileSize function on Windows ([filecoin-project/lotus#10035](https://github.com/filecoin-project/lotus/pull/10035))
## Dependencies
- github.com/filecoin-project/go-dagaggregator-unixfs (v0.2.0 -> v0.3.0):
- github.com/filecoin-project/go-fil-markets (v1.25.2 -> v1.27.0-rc1):
- github.com/filecoin-project/go-jsonrpc (v0.2.1 -> v0.2.3):
- github.com/filecoin-project/go-statemachine (v1.0.2 -> v1.0.3):
- github.com/filecoin-project/go-state-types (v0.10.0 -> v0.11.0-alpha-3)
- github.com/ipfs/go-cid (v0.3.2 -> v0.4.0):
- github.com/ipfs/go-libipfs (v0.5.0 -> v0.7.0):
- github.com/ipfs/go-path (v0.3.0 -> v0.3.1):
- chore: deps: update to go-state-types v0.11.0-alpha-3 (([filecoin-project/lotus#10606](https://github.com/filecoin-project/lotus/pull/10606))
- deps: update go-libp2p-pubsub to v0.9.3 ([filecoin-project/lotus#10483](https://github.com/filecoin-project/lotus/pull/10483))
- deps: Update go-jsonrpc to v0.2.2 ([filecoin-project/lotus#10395](https://github.com/filecoin-project/lotus/pull/10395))
- Update to go-data-transfer v2 and libp2p, still wip ([filecoin-project/lotus#10382](https://github.com/filecoin-project/lotus/pull/10382))
- dep: ipld: update ipld prime to v0.20.0 ([filecoin-project/lotus#10247](https://github.com/filecoin-project/lotus/pull/10247))
- chore: node: migrate go-bitswap to go-libipfs/bitswap ([filecoin-project/lotus#10138](https://github.com/filecoin-project/lotus/pull/10138))
- chore: all: bump go-libipfs to replace go-block-format ([filecoin-project/lotus#10126](https://github.com/filecoin-project/lotus/pull/10126))
- chore: market: Upgrade to index-provider 0.10.0 ([filecoin-project/lotus#9981](https://github.com/filecoin-project/lotus/pull/9981))
- chore: all: bump go-libipfs ([filecoin-project/lotus#10563](https://github.com/filecoin-project/lotus/pull/10563))
## Others
- Update service_developer_bug_report.yml ([filecoin-project/lotus#10321](https://github.com/filecoin-project/lotus/pull/10321))
- Update service_developer_bug_report.yml ([filecoin-project/lotus#10321](https://github.com/filecoin-project/lotus/pull/10321))
- chore: github: Service-provider/dev bug template ([filecoin-project/lotus#10321](https://github.com/filecoin-project/lotus/pull/10321))
- chore: github: update enhancement and feature templates ([filecoin-project/lotus#10291](https://github.com/filecoin-project/lotus/pull/10291))
- chore: github: Update bug_report template ([filecoin-project/lotus#10289](https://github.com/filecoin-project/lotus/pull/10289))
- fix: itest: avoid failing the test when we race the miner ([filecoin-project/lotus#10461](https://github.com/filecoin-project/lotus/pull/10461))
- fix: github: Discussion and FIP links in `New Issue` ([filecoin-project/lotus#10268](https://github.com/filecoin-project/lotus/pull/10268))
- fix: state: short-circuit genesis state computation ([filecoin-project/lotus#10397](https://github.com/filecoin-project/lotus/pull/10397))
- fix: rpcenc: deflake TestReaderRedirectDrop ([filecoin-project/lotus#10406](https://github.com/filecoin-project/lotus/pull/10406))
- fix: tests: Fix TestMinerAllInfo test ([filecoin-project/lotus#10319](https://github.com/filecoin-project/lotus/pull/10319))
- fix: tests: Make TestWorkerKeyChange not flaky ([filecoin-project/lotus#10320](https://github.com/filecoin-project/lotus/pull/10320))
- test: eth: make sure we can deploy a new placeholder on transfer (#10281) ([filecoin-project/lotus#10281](https://github.com/filecoin-project/lotus/pull/10281))
- fix: itests: Fix flaky paych test ([filecoin-project/lotus#10100](https://github.com/filecoin-project/lotus/pull/10100))
- fix: cli: add ArgsUsage ([filecoin-project/lotus#10147](https://github.com/filecoin-project/lotus/pull/10147))
- chore: cli: cleanup cli ([filecoin-project/lotus#10114](https://github.com/filecoin-project/lotus/pull/10114))
- chore: cli: Remove unneeded individual color flags ([filecoin-project/lotus#10028](https://github.com/filecoin-project/lotus/pull/10028))
- fix: cli: remove requirements in helptext ([filecoin-project/lotus#9969](https://github.com/filecoin-project/lotus/pull/9969))
- chore: build: release v1.21.0-rc1 prep ([filecoin-project/lotus#10524](https://github.com/filecoin-project/lotus/pull/10524))
- chore: merge release/v1.20.0 into master ([filecoin-project/lotus#10308](https://github.com/filecoin-project/lotus/pull/10308))
- chore: merge release branch into master ([filecoin-project/lotus#10272](https://github.com/filecoin-project/lotus/pull/10272))
- chore: merge release/v1.20.0 into master ([filecoin-project/lotus#10238](https://github.com/filecoin-project/lotus/pull/10238))
- chore: releases to master ([filecoin-project/lotus#10490](https://github.com/filecoin-project/lotus/pull/10490))
- chore: merge releases into master ([filecoin-project/lotus#10377](https://github.com/filecoin-project/lotus/pull/10377))
- chore: merge release/v1.20.0 into master ([filecoin-project/lotus#10030](https://github.com/filecoin-project/lotus/pull/10030))
- chore: update ffi to increase execution parallelism (#10480) ([filecoin-project/lotus#10480](https://github.com/filecoin-project/lotus/pull/10480))
- chore: update the FFI for release (#10435) ([filecoin-project/lotus#10444](https://github.com/filecoin-project/lotus/pull/10444))
- build: bump version to v1.21.0-dev ([filecoin-project/lotus#10249](https://github.com/filecoin-project/lotus/pull/10249))
- build: docker: Update GO-version (#10591) ([filecoin-project/lotus#10249](https://github.com/filecoin-project/lotus/pull/10591))
- chore: merge release/v1.20.0 into master ([filecoin-project/lotus#10184](https://github.com/filecoin-project/lotus/pull/10184))
- docs: API Gateway: patch documentation note about make gen command ([filecoin-project/lotus#10422](https://github.com/filecoin-project/lotus/pull/10422))
- chore: docs: fix docs typos ([filecoin-project/lotus#10155](https://github.com/filecoin-project/lotus/pull/10155))
- chore: docker: Add back <<network>> parameter for docker push ([filecoin-project/lotus#10096](https://github.com/filecoin-project/lotus/pull/10096))
- chore: docker: Properly balance <<?>> in circleci docker config ([filecoin-project/lotus#10088](https://github.com/filecoin-project/lotus/pull/10088))
- chore: ci: Fix dirty git state when building docker images ([filecoin-project/lotus#10125](https://github.com/filecoin-project/lotus/pull/10125))
- chore: build: Remove AppImage and Snapcraft build automation ([filecoin-project/lotus#10003](https://github.com/filecoin-project/lotus/pull/10003))
- chore: ci: Update codeql to v2 ([filecoin-project/lotus#10120](https://github.com/filecoin-project/lotus/pull/10120))
- feat: ci: make ci more efficient ([filecoin-project/lotus#9910](https://github.com/filecoin-project/lotus/pull/9910))
- feat: scripts: go.mod dep diff script ([filecoin-project/lotus#9711](https://github.com/filecoin-project/lotus/pull/9711))
## Contributors
| Contributor | Commits | Lines ± | Files Changed |
|-------------|---------|---------|---------------|
| Hannah Howard | 2 | +2909/-6026 | 84 |
| Łukasz Magiera | 42 | +2967/-1848 | 95 |
| Steven Allen | 20 | +1703/-1345 | 88 |
| Alfonso de la Rocha | 17 | +823/-1808 | 86 |
| Peter Rabbitson | 9 | +1957/-219 | 34 |
| Geoff Stuart | 12 | +818/-848 | 29 |
| hannahhoward | 5 | +507/-718 | 36 |
| Hector Sanjuan | 6 | +443/-726 | 35 |
| Kevin Li | 1 | +1124/-14 | 22 |
| zenground0 | 30 | +791/-269 | 88 |
| frrist | 1 | +992/-16 | 13 |
| Travis Person | 4 | +837/-53 | 24 |
| Phi | 20 | +622/-254 | 34 |
| Ian Davis | 7 | +35/-729 | 20 |
| Aayush | 10 | +378/-177 | 40 |
| Raúl Kripalani | 15 | +207/-138 | 19 |
| Arsenii Petrovich | 7 | +248/-94 | 30 |
| ZenGround0 | 5 | +238/-39 | 15 |
| Neel Virdy | 1 | +109/-107 | 58 |
| ychiao | 1 | +135/-39 | 3 |
| Jorropo | 2 | +87/-82 | 67 |
| Marten Seemann | 8 | +69/-64 | 17 |
| Rod Vagg | 1 | +55/-16 | 3 |
| Masih H. Derkani | 3 | +39/-27 | 12 |
| raulk | 2 | +30/-29 | 5 |
| dependabot[bot] | 4 | +37/-17 | 8 |
| beck | 2 | +38/-2 | 2 |
| Jennifer Wang | 4 | +20/-19 | 19 |
| Richard Guan | 3 | +28/-8 | 5 |
| omahs | 7 | +14/-14 | 7 |
| dirkmc | 2 | +19/-7 | 6 |
| David Choi | 2 | +16/-5 | 2 |
| Mike Greenberg | 1 | +18/-1 | 1 |
| Adin Schmahmann | 1 | +19/-0 | 2 |
| Phi-rjan | 5 | +12/-4 | 5 |
| Dirk McCormick | 2 | +6/-6 | 3 |
| Aayush Rajasekaran | 2 | +9/-3 | 2 |
| Jiaying Wang | 5 | +6/-4 | 5 |
| Anjor Kanekar | 1 | +5/-5 | 1 |
| vyzo | 1 | +3/-3 | 2 |
| 0x5459 | 1 | +1/-1 | 1 |
# v1.22.1 / 2023-04-23 # v1.22.1 / 2023-04-23
## Important Notice ## Important Notice
@@ -612,6 +166,7 @@ verifiedregistry bafk2bzacedej3dnr62g2je2abmyjg3xqv4otvh6e26du5fcrhvw7zgcaaez3a
### Dependencies ### Dependencies
github.com/filecoin-project/go-state-types (v0.11.0-rc1 -> v0.11.1): github.com/filecoin-project/go-state-types (v0.11.0-rc1 -> v0.11.1):
# v1.20.4 / 2023-03-17 # v1.20.4 / 2023-03-17
This is a patch release intended to alleviate performance issues reported by some users since the nv18 upgrade. This is a patch release intended to alleviate performance issues reported by some users since the nv18 upgrade.
@@ -631,22 +186,7 @@ Users with higher memory specs can experiment with setting `LOTUS_FVM_CONCURRENC
# v1.20.3 / 2023-03-09 # v1.20.3 / 2023-03-09
A 🐈 stepped on the ⌨️ and made a mistake while resolving conflicts 😨. This releases only includes #10439 to fix that mistake. v1.20.2 is retracted - Please skip v1.20.2 and **only** update to v1.20.3!!! A 🐈 stepped on the ⌨️ and made a mistake while resolving conflicts 😨. This releases only includes #10439 to fix that mistake. v1.20.2 is retracted - Please skip v1.20.2 and only update to v1.20.3!!!
## Changelog
> compare to v1.20.1
This is a HIGHLY RECOMMENDED patch release for node operators/API service providers that run ETH RPC service and an optional release for Storage Providers.
## Bug fixes
- fix: EthAPI: use StateCompute for feeHistory; apply minimum gas premium #10413
- fix: eth API: return correct txIdx around null blocks #10419
- fix: Eth API: make block parameter parsing sounder. #10427
## Improvement
- feat: Lotus Gateway: Add missing methods - master #10420
- feat: mempool: Reduce minimum replace fee from 1.25x to 1.1x #10416
- We recommend storage providers to update your nodes to this patch, that will help improve developers who use Ethereum tooling's experience.
# v1.20.2 / 2023-03-09 # v1.20.2 / 2023-03-09
+1 -1
View File
@@ -1,5 +1,5 @@
##################################### #####################################
FROM golang:1.19.7-buster AS lotus-builder FROM golang:1.18.8-buster AS lotus-builder
MAINTAINER Lotus Development Team 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 RUN apt-get update && apt-get install -y ca-certificates build-essential clang ocl-icd-opencl-dev ocl-icd-libopencl1 jq libhwloc-dev
+273
View File
@@ -0,0 +1,273 @@
##### DEPRECATED
FROM golang:1.18.8-buster AS builder-deps
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
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 \
RUST_VERSION=1.63.0
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 --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
FROM builder-local AS builder-test
MAINTAINER Lotus Development Team
WORKDIR /opt/filecoin
RUN make debug
FROM builder-local AS builder
MAINTAINER Lotus Development Team
WORKDIR /opt/filecoin
ARG RUSTFLAGS=""
ARG GOFLAGS=""
RUN make lotus lotus-miner lotus-worker lotus-shed lotus-wallet lotus-gateway lotus-stats
FROM ubuntu:20.04 AS base
MAINTAINER Lotus Development Team
# Base resources
COPY --from=builder /etc/ssl/certs /etc/ssl/certs
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 \
&& echo "libnvidia-opencl.so.1" > /etc/OpenCL/vendors/nvidia.icd
###
FROM base AS lotus
MAINTAINER Lotus Development Team
COPY --from=builder /opt/filecoin/lotus /usr/local/bin/
COPY --from=builder /opt/filecoin/lotus-shed /usr/local/bin/
COPY scripts/docker-lotus-entrypoint.sh /
ENV FILECOIN_PARAMETER_CACHE /var/tmp/filecoin-proof-parameters
ENV LOTUS_PATH /var/lib/lotus
ENV DOCKER_LOTUS_IMPORT_SNAPSHOT https://fil-chain-snapshots-fallback.s3.amazonaws.com/mainnet/minimal_finality_stateroots_latest.car
ENV DOCKER_LOTUS_IMPORT_WALLET ""
RUN mkdir /var/lib/lotus /var/tmp/filecoin-proof-parameters
RUN chown fc: /var/lib/lotus /var/tmp/filecoin-proof-parameters
VOLUME /var/lib/lotus
VOLUME /var/tmp/filecoin-proof-parameters
USER fc
EXPOSE 1234
ENTRYPOINT ["/docker-lotus-entrypoint.sh"]
CMD ["-help"]
###
FROM base AS lotus-wallet
MAINTAINER Lotus Development Team
COPY --from=builder /opt/filecoin/lotus-wallet /usr/local/bin/
ENV WALLET_PATH /var/lib/lotus-wallet
RUN mkdir /var/lib/lotus-wallet
RUN chown fc: /var/lib/lotus-wallet
VOLUME /var/lib/lotus-wallet
USER fc
EXPOSE 1777
ENTRYPOINT ["/usr/local/bin/lotus-wallet"]
CMD ["-help"]
###
FROM base AS lotus-gateway
MAINTAINER Lotus Development Team
COPY --from=builder /opt/filecoin/lotus-gateway /usr/local/bin/
USER fc
EXPOSE 1234
ENTRYPOINT ["/usr/local/bin/lotus-gateway"]
CMD ["-help"]
###
FROM base AS lotus-miner
MAINTAINER Lotus Development Team
COPY --from=builder /opt/filecoin/lotus-miner /usr/local/bin/
COPY scripts/docker-lotus-miner-entrypoint.sh /
ENV FILECOIN_PARAMETER_CACHE /var/tmp/filecoin-proof-parameters
ENV LOTUS_MINER_PATH /var/lib/lotus-miner
RUN mkdir /var/lib/lotus-miner /var/tmp/filecoin-proof-parameters
RUN chown fc: /var/lib/lotus-miner /var/tmp/filecoin-proof-parameters
VOLUME /var/lib/lotus-miner
VOLUME /var/tmp/filecoin-proof-parameters
USER fc
EXPOSE 2345
ENTRYPOINT ["/docker-lotus-miner-entrypoint.sh"]
CMD ["-help"]
###
FROM base AS lotus-worker
MAINTAINER Lotus Development Team
COPY --from=builder /opt/filecoin/lotus-worker /usr/local/bin/
ENV FILECOIN_PARAMETER_CACHE /var/tmp/filecoin-proof-parameters
ENV LOTUS_WORKER_PATH /var/lib/lotus-worker
RUN mkdir /var/lib/lotus-worker
RUN chown fc: /var/lib/lotus-worker
VOLUME /var/lib/lotus-worker
USER fc
EXPOSE 3456
ENTRYPOINT ["/usr/local/bin/lotus-worker"]
CMD ["-help"]
###
from base as lotus-all-in-one
ENV FILECOIN_PARAMETER_CACHE /var/tmp/filecoin-proof-parameters
ENV LOTUS_MINER_PATH /var/lib/lotus-miner
ENV LOTUS_PATH /var/lib/lotus
ENV LOTUS_WORKER_PATH /var/lib/lotus-worker
ENV WALLET_PATH /var/lib/lotus-wallet
ENV DOCKER_LOTUS_IMPORT_SNAPSHOT https://fil-chain-snapshots-fallback.s3.amazonaws.com/mainnet/minimal_finality_stateroots_latest.car
COPY --from=builder /opt/filecoin/lotus /usr/local/bin/
COPY --from=builder /opt/filecoin/lotus-shed /usr/local/bin/
COPY --from=builder /opt/filecoin/lotus-wallet /usr/local/bin/
COPY --from=builder /opt/filecoin/lotus-gateway /usr/local/bin/
COPY --from=builder /opt/filecoin/lotus-miner /usr/local/bin/
COPY --from=builder /opt/filecoin/lotus-worker /usr/local/bin/
COPY --from=builder /opt/filecoin/lotus-stats /usr/local/bin/
RUN mkdir /var/tmp/filecoin-proof-parameters
RUN mkdir /var/lib/lotus
RUN mkdir /var/lib/lotus-miner
RUN mkdir /var/lib/lotus-worker
RUN mkdir /var/lib/lotus-wallet
RUN chown fc: /var/tmp/filecoin-proof-parameters
RUN chown fc: /var/lib/lotus
RUN chown fc: /var/lib/lotus-miner
RUN chown fc: /var/lib/lotus-worker
RUN chown fc: /var/lib/lotus-wallet
VOLUME /var/tmp/filecoin-proof-parameters
VOLUME /var/lib/lotus
VOLUME /var/lib/lotus-miner
VOLUME /var/lib/lotus-worker
VOLUME /var/lib/lotus-wallet
EXPOSE 1234
EXPOSE 2345
EXPOSE 3456
EXPOSE 1777
###
from base as lotus-test
ENV FILECOIN_PARAMETER_CACHE /var/tmp/filecoin-proof-parameters
ENV LOTUS_MINER_PATH /var/lib/lotus-miner
ENV LOTUS_PATH /var/lib/lotus
ENV LOTUS_WORKER_PATH /var/lib/lotus-worker
ENV WALLET_PATH /var/lib/lotus-wallet
COPY --from=builder-test /opt/filecoin/lotus /usr/local/bin/
COPY --from=builder-test /opt/filecoin/lotus-miner /usr/local/bin/
COPY --from=builder-test /opt/filecoin/lotus-worker /usr/local/bin/
COPY --from=builder-test /opt/filecoin/lotus-seed /usr/local/bin/
RUN mkdir /var/tmp/filecoin-proof-parameters
RUN mkdir /var/lib/lotus
RUN mkdir /var/lib/lotus-miner
RUN mkdir /var/lib/lotus-worker
RUN mkdir /var/lib/lotus-wallet
RUN chown fc: /var/tmp/filecoin-proof-parameters
RUN chown fc: /var/lib/lotus
RUN chown fc: /var/lib/lotus-miner
RUN chown fc: /var/lib/lotus-worker
RUN chown fc: /var/lib/lotus-wallet
VOLUME /var/tmp/filecoin-proof-parameters
VOLUME /var/lib/lotus
VOLUME /var/lib/lotus-miner
VOLUME /var/lib/lotus-worker
VOLUME /var/lib/lotus-wallet
EXPOSE 1234
EXPOSE 2345
EXPOSE 3456
EXPOSE 1777
+1 -1
View File
@@ -1 +1 @@
1.19.7 1.18.8
+2 -2
View File
@@ -71,10 +71,10 @@ For other distributions you can find the required dependencies [here.](https://l
#### Go #### Go
To build Lotus, you need a working installation of [Go 1.19.7 or higher](https://golang.org/dl/): To build Lotus, you need a working installation of [Go 1.18.8 or higher](https://golang.org/dl/):
```bash ```bash
wget -c https://golang.org/dl/go1.19.7.linux-amd64.tar.gz -O - | sudo tar -xz -C /usr/local wget -c https://golang.org/dl/go1.18.8.linux-amd64.tar.gz -O - | sudo tar -xz -C /usr/local
``` ```
**TIP:** **TIP:**
+13 -38
View File
@@ -7,13 +7,13 @@ import (
"time" "time"
"github.com/google/uuid" "github.com/google/uuid"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
blocks "github.com/ipfs/go-libipfs/blocks"
"github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/peer"
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-bitfield" "github.com/filecoin-project/go-bitfield"
datatransfer "github.com/filecoin-project/go-data-transfer/v2" datatransfer "github.com/filecoin-project/go-data-transfer"
"github.com/filecoin-project/go-fil-markets/retrievalmarket" "github.com/filecoin-project/go-fil-markets/retrievalmarket"
"github.com/filecoin-project/go-fil-markets/storagemarket" "github.com/filecoin-project/go-fil-markets/storagemarket"
"github.com/filecoin-project/go-jsonrpc" "github.com/filecoin-project/go-jsonrpc"
@@ -173,24 +173,10 @@ type FullNode interface {
// If oldmsgskip is set, messages from before the requested roots are also not included. // If oldmsgskip is set, messages from before the requested roots are also not included.
ChainExport(ctx context.Context, nroots abi.ChainEpoch, oldmsgskip bool, tsk types.TipSetKey) (<-chan []byte, error) //perm:read ChainExport(ctx context.Context, nroots abi.ChainEpoch, oldmsgskip bool, tsk types.TipSetKey) (<-chan []byte, error) //perm:read
// ChainExportRangeInternal triggers the export of a chain // ChainPrune prunes the stored chain state and garbage collects; only supported if you
// CAR-snapshot directly to disk. It is similar to ChainExport,
// except, depending on options, the snapshot can include receipts,
// messages and stateroots for the length between the specified head
// and tail, thus producing "archival-grade" snapshots that include
// all the on-chain data. The header chain is included back to
// genesis and these snapshots can be used to initialize Filecoin
// nodes.
ChainExportRangeInternal(ctx context.Context, head, tail types.TipSetKey, cfg ChainExportConfig) error //perm:admin
// ChainPrune forces compaction on cold store and garbage collects; only supported if you
// are using the splitstore // are using the splitstore
ChainPrune(ctx context.Context, opts PruneOpts) error //perm:admin ChainPrune(ctx context.Context, opts PruneOpts) error //perm:admin
// ChainHotGC does online (badger) GC on the hot store; only supported if you are using
// the splitstore
ChainHotGC(ctx context.Context, opts HotGCOpts) error //perm:admin
// ChainCheckBlockstore performs an (asynchronous) health check on the chain/state blockstore // ChainCheckBlockstore performs an (asynchronous) health check on the chain/state blockstore
// if supported by the underlying implementation. // if supported by the underlying implementation.
ChainCheckBlockstore(context.Context) error //perm:admin ChainCheckBlockstore(context.Context) error //perm:admin
@@ -297,10 +283,8 @@ type FullNode interface {
MpoolGetNonce(context.Context, address.Address) (uint64, error) //perm:read MpoolGetNonce(context.Context, address.Address) (uint64, error) //perm:read
MpoolSub(context.Context) (<-chan MpoolUpdate, error) //perm:read MpoolSub(context.Context) (<-chan MpoolUpdate, error) //perm:read
// MpoolClear clears pending messages from the mpool. // MpoolClear clears pending messages from the mpool
// If clearLocal is true, ALL messages will be cleared. MpoolClear(context.Context, bool) error //perm:write
// If clearLocal is false, local messages will be protected, all others will be cleared.
MpoolClear(ctx context.Context, clearLocal bool) error //perm:write
// MpoolGetConfig returns (a copy of) the current mpool config // MpoolGetConfig returns (a copy of) the current mpool config
MpoolGetConfig(context.Context) (*types.MpoolConfig, error) //perm:read MpoolGetConfig(context.Context) (*types.MpoolConfig, error) //perm:read
@@ -799,12 +783,10 @@ type FullNode interface {
EthGetBlockByHash(ctx context.Context, blkHash ethtypes.EthHash, fullTxInfo bool) (ethtypes.EthBlock, error) //perm:read EthGetBlockByHash(ctx context.Context, blkHash ethtypes.EthHash, fullTxInfo bool) (ethtypes.EthBlock, error) //perm:read
EthGetBlockByNumber(ctx context.Context, blkNum string, fullTxInfo bool) (ethtypes.EthBlock, error) //perm:read EthGetBlockByNumber(ctx context.Context, blkNum string, fullTxInfo bool) (ethtypes.EthBlock, error) //perm:read
EthGetTransactionByHash(ctx context.Context, txHash *ethtypes.EthHash) (*ethtypes.EthTx, error) //perm:read EthGetTransactionByHash(ctx context.Context, txHash *ethtypes.EthHash) (*ethtypes.EthTx, error) //perm:read
EthGetTransactionByHashLimited(ctx context.Context, txHash *ethtypes.EthHash, limit abi.ChainEpoch) (*ethtypes.EthTx, error) //perm:read
EthGetTransactionHashByCid(ctx context.Context, cid cid.Cid) (*ethtypes.EthHash, error) //perm:read EthGetTransactionHashByCid(ctx context.Context, cid cid.Cid) (*ethtypes.EthHash, error) //perm:read
EthGetMessageCidByTransactionHash(ctx context.Context, txHash *ethtypes.EthHash) (*cid.Cid, error) //perm:read EthGetMessageCidByTransactionHash(ctx context.Context, txHash *ethtypes.EthHash) (*cid.Cid, error) //perm:read
EthGetTransactionCount(ctx context.Context, sender ethtypes.EthAddress, blkOpt string) (ethtypes.EthUint64, error) //perm:read EthGetTransactionCount(ctx context.Context, sender ethtypes.EthAddress, blkOpt string) (ethtypes.EthUint64, error) //perm:read
EthGetTransactionReceipt(ctx context.Context, txHash ethtypes.EthHash) (*EthTxReceipt, error) //perm:read EthGetTransactionReceipt(ctx context.Context, txHash ethtypes.EthHash) (*EthTxReceipt, error) //perm:read
EthGetTransactionReceiptLimited(ctx context.Context, txHash ethtypes.EthHash, limit abi.ChainEpoch) (*EthTxReceipt, error) //perm:read
EthGetTransactionByBlockHashAndIndex(ctx context.Context, blkHash ethtypes.EthHash, txIndex ethtypes.EthUint64) (ethtypes.EthTx, error) //perm:read EthGetTransactionByBlockHashAndIndex(ctx context.Context, blkHash ethtypes.EthHash, txIndex ethtypes.EthUint64) (ethtypes.EthTx, error) //perm:read
EthGetTransactionByBlockNumberAndIndex(ctx context.Context, blkNum ethtypes.EthUint64, txIndex ethtypes.EthUint64) (ethtypes.EthTx, error) //perm:read EthGetTransactionByBlockNumberAndIndex(ctx context.Context, blkNum ethtypes.EthUint64, txIndex ethtypes.EthUint64) (ethtypes.EthTx, error) //perm:read
@@ -812,7 +794,6 @@ type FullNode interface {
EthGetStorageAt(ctx context.Context, address ethtypes.EthAddress, position ethtypes.EthBytes, blkParam string) (ethtypes.EthBytes, error) //perm:read EthGetStorageAt(ctx context.Context, address ethtypes.EthAddress, position ethtypes.EthBytes, blkParam string) (ethtypes.EthBytes, error) //perm:read
EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam string) (ethtypes.EthBigInt, error) //perm:read EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam string) (ethtypes.EthBigInt, error) //perm:read
EthChainId(ctx context.Context) (ethtypes.EthUint64, error) //perm:read EthChainId(ctx context.Context) (ethtypes.EthUint64, error) //perm:read
EthSyncing(ctx context.Context) (ethtypes.EthSyncingResult, error) //perm:read
NetVersion(ctx context.Context) (string, error) //perm:read NetVersion(ctx context.Context) (string, error) //perm:read
NetListening(ctx context.Context) (bool, error) //perm:read NetListening(ctx context.Context) (bool, error) //perm:read
EthProtocolVersion(ctx context.Context) (ethtypes.EthUint64, error) //perm:read EthProtocolVersion(ctx context.Context) (ethtypes.EthUint64, error) //perm:read
@@ -830,23 +811,23 @@ type FullNode interface {
// Polling method for a filter, returns event logs which occurred since last poll. // Polling method for a filter, returns event logs which occurred since last poll.
// (requires write perm since timestamp of last filter execution will be written) // (requires write perm since timestamp of last filter execution will be written)
EthGetFilterChanges(ctx context.Context, id ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) //perm:read EthGetFilterChanges(ctx context.Context, id ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) //perm:write
// Returns event logs matching filter with given id. // Returns event logs matching filter with given id.
// (requires write perm since timestamp of last filter execution will be written) // (requires write perm since timestamp of last filter execution will be written)
EthGetFilterLogs(ctx context.Context, id ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) //perm:read EthGetFilterLogs(ctx context.Context, id ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) //perm:write
// Installs a persistent filter based on given filter spec. // Installs a persistent filter based on given filter spec.
EthNewFilter(ctx context.Context, filter *ethtypes.EthFilterSpec) (ethtypes.EthFilterID, error) //perm:read EthNewFilter(ctx context.Context, filter *ethtypes.EthFilterSpec) (ethtypes.EthFilterID, error) //perm:write
// Installs a persistent filter to notify when a new block arrives. // Installs a persistent filter to notify when a new block arrives.
EthNewBlockFilter(ctx context.Context) (ethtypes.EthFilterID, error) //perm:read EthNewBlockFilter(ctx context.Context) (ethtypes.EthFilterID, error) //perm:write
// Installs a persistent filter to notify when new messages arrive in the message pool. // Installs a persistent filter to notify when new messages arrive in the message pool.
EthNewPendingTransactionFilter(ctx context.Context) (ethtypes.EthFilterID, error) //perm:read EthNewPendingTransactionFilter(ctx context.Context) (ethtypes.EthFilterID, error) //perm:write
// Uninstalls a filter with given id. // Uninstalls a filter with given id.
EthUninstallFilter(ctx context.Context, id ethtypes.EthFilterID) (bool, error) //perm:read EthUninstallFilter(ctx context.Context, id ethtypes.EthFilterID) (bool, error) //perm:write
// Subscribe to different event types using websockets // Subscribe to different event types using websockets
// eventTypes is one or more of: // eventTypes is one or more of:
@@ -855,10 +836,10 @@ type FullNode interface {
// - logs: notify new event logs that match a criteria // - logs: notify new event logs that match a criteria
// params contains additional parameters used with the log event type // params contains additional parameters used with the log event type
// The client will receive a stream of EthSubscriptionResponse values until EthUnsubscribe is called. // The client will receive a stream of EthSubscriptionResponse values until EthUnsubscribe is called.
EthSubscribe(ctx context.Context, params jsonrpc.RawParams) (ethtypes.EthSubscriptionID, error) //perm:read EthSubscribe(ctx context.Context, params jsonrpc.RawParams) (ethtypes.EthSubscriptionID, error) //perm:write
// Unsubscribe from a websocket subscription // Unsubscribe from a websocket subscription
EthUnsubscribe(ctx context.Context, id ethtypes.EthSubscriptionID) (bool, error) //perm:read EthUnsubscribe(ctx context.Context, id ethtypes.EthSubscriptionID) (bool, error) //perm:write
// Returns the client version // Returns the client version
Web3ClientVersion(ctx context.Context) (string, error) //perm:read Web3ClientVersion(ctx context.Context) (string, error) //perm:read
@@ -1363,12 +1344,6 @@ type PruneOpts struct {
RetainState int64 RetainState int64
} }
type HotGCOpts struct {
Threshold float64
Periodic bool
Moving bool
}
type EthTxReceipt struct { type EthTxReceipt struct {
TransactionHash ethtypes.EthHash `json:"transactionHash"` TransactionHash ethtypes.EthHash `json:"transactionHash"`
TransactionIndex ethtypes.EthUint64 `json:"transactionIndex"` TransactionIndex ethtypes.EthUint64 `json:"transactionIndex"`
+4 -9
View File
@@ -3,8 +3,8 @@ package api
import ( import (
"context" "context"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
blocks "github.com/ipfs/go-libipfs/blocks"
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-jsonrpc" "github.com/filecoin-project/go-jsonrpc"
@@ -26,16 +26,13 @@ import (
// When adding / changing methods in this file: // When adding / changing methods in this file:
// * Do the change here // * Do the change here
// * Adjust implementation in `node/impl/` // * Adjust implementation in `node/impl/`
// * Run `make clean && make deps && make gen` - this will: // * Run `make gen` - this will:
// * Generate proxy structs // * Generate proxy structs
// * Generate mocks // * Generate mocks
// * Generate markdown docs // * Generate markdown docs
// * Generate openrpc blobs // * Generate openrpc blobs
type Gateway interface { type Gateway interface {
StateMinerSectorCount(context.Context, address.Address, types.TipSetKey) (MinerSectors, error)
GasEstimateGasPremium(context.Context, uint64, address.Address, int64, types.TipSetKey) (types.BigInt, error)
StateReplay(context.Context, types.TipSetKey, cid.Cid) (*InvocResult, error)
ChainHasObj(context.Context, cid.Cid) (bool, error) ChainHasObj(context.Context, cid.Cid) (bool, error)
ChainPutObj(context.Context, blocks.Block) error ChainPutObj(context.Context, blocks.Block) error
ChainHead(ctx context.Context) (*types.TipSet, error) ChainHead(ctx context.Context) (*types.TipSet, error)
@@ -73,7 +70,6 @@ type Gateway interface {
StateNetworkName(context.Context) (dtypes.NetworkName, error) StateNetworkName(context.Context) (dtypes.NetworkName, error)
StateNetworkVersion(context.Context, types.TipSetKey) (apitypes.NetworkVersion, error) StateNetworkVersion(context.Context, types.TipSetKey) (apitypes.NetworkVersion, error)
StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error) StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error)
StateVerifierStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error)
StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error)
StateSearchMsg(ctx context.Context, from types.TipSetKey, msg cid.Cid, limit abi.ChainEpoch, allowReplaced bool) (*MsgLookup, error) StateSearchMsg(ctx context.Context, from types.TipSetKey, msg cid.Cid, limit abi.ChainEpoch, allowReplaced bool) (*MsgLookup, error)
StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*MsgLookup, error) StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*MsgLookup, error)
@@ -88,17 +84,16 @@ type Gateway interface {
EthGetBlockByHash(ctx context.Context, blkHash ethtypes.EthHash, fullTxInfo bool) (ethtypes.EthBlock, error) EthGetBlockByHash(ctx context.Context, blkHash ethtypes.EthHash, fullTxInfo bool) (ethtypes.EthBlock, error)
EthGetBlockByNumber(ctx context.Context, blkNum string, fullTxInfo bool) (ethtypes.EthBlock, error) EthGetBlockByNumber(ctx context.Context, blkNum string, fullTxInfo bool) (ethtypes.EthBlock, error)
EthGetTransactionByHash(ctx context.Context, txHash *ethtypes.EthHash) (*ethtypes.EthTx, error) EthGetTransactionByHash(ctx context.Context, txHash *ethtypes.EthHash) (*ethtypes.EthTx, error)
EthGetTransactionByHashLimited(ctx context.Context, txHash *ethtypes.EthHash, limit abi.ChainEpoch) (*ethtypes.EthTx, error)
EthGetTransactionHashByCid(ctx context.Context, cid cid.Cid) (*ethtypes.EthHash, error) EthGetTransactionHashByCid(ctx context.Context, cid cid.Cid) (*ethtypes.EthHash, error)
EthGetMessageCidByTransactionHash(ctx context.Context, txHash *ethtypes.EthHash) (*cid.Cid, error) EthGetMessageCidByTransactionHash(ctx context.Context, txHash *ethtypes.EthHash) (*cid.Cid, error)
EthGetTransactionCount(ctx context.Context, sender ethtypes.EthAddress, blkOpt string) (ethtypes.EthUint64, error) EthGetTransactionCount(ctx context.Context, sender ethtypes.EthAddress, blkOpt string) (ethtypes.EthUint64, error)
EthGetTransactionReceipt(ctx context.Context, txHash ethtypes.EthHash) (*EthTxReceipt, error) EthGetTransactionReceipt(ctx context.Context, txHash ethtypes.EthHash) (*EthTxReceipt, error)
EthGetTransactionReceiptLimited(ctx context.Context, txHash ethtypes.EthHash, limit abi.ChainEpoch) (*EthTxReceipt, error) EthGetTransactionByBlockHashAndIndex(ctx context.Context, blkHash ethtypes.EthHash, txIndex ethtypes.EthUint64) (ethtypes.EthTx, error)
EthGetTransactionByBlockNumberAndIndex(ctx context.Context, blkNum ethtypes.EthUint64, txIndex ethtypes.EthUint64) (ethtypes.EthTx, error)
EthGetCode(ctx context.Context, address ethtypes.EthAddress, blkOpt string) (ethtypes.EthBytes, error) EthGetCode(ctx context.Context, address ethtypes.EthAddress, blkOpt string) (ethtypes.EthBytes, error)
EthGetStorageAt(ctx context.Context, address ethtypes.EthAddress, position ethtypes.EthBytes, blkParam string) (ethtypes.EthBytes, error) EthGetStorageAt(ctx context.Context, address ethtypes.EthAddress, position ethtypes.EthBytes, blkParam string) (ethtypes.EthBytes, error)
EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam string) (ethtypes.EthBigInt, error) EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam string) (ethtypes.EthBigInt, error)
EthChainId(ctx context.Context) (ethtypes.EthUint64, error) EthChainId(ctx context.Context) (ethtypes.EthUint64, error)
EthSyncing(ctx context.Context) (ethtypes.EthSyncingResult, error)
NetVersion(ctx context.Context) (string, error) NetVersion(ctx context.Context) (string, error)
NetListening(ctx context.Context) (bool, error) NetListening(ctx context.Context) (bool, error)
EthProtocolVersion(ctx context.Context) (ethtypes.EthUint64, error) EthProtocolVersion(ctx context.Context) (ethtypes.EthUint64, error)
+1 -1
View File
@@ -73,5 +73,5 @@ type CommonNet interface {
type NatInfo struct { type NatInfo struct {
Reachability network.Reachability Reachability network.Reachability
PublicAddrs []string PublicAddr string
} }
+4 -8
View File
@@ -11,7 +11,7 @@ import (
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-bitfield" "github.com/filecoin-project/go-bitfield"
datatransfer "github.com/filecoin-project/go-data-transfer/v2" datatransfer "github.com/filecoin-project/go-data-transfer"
"github.com/filecoin-project/go-fil-markets/piecestore" "github.com/filecoin-project/go-fil-markets/piecestore"
"github.com/filecoin-project/go-fil-markets/retrievalmarket" "github.com/filecoin-project/go-fil-markets/retrievalmarket"
"github.com/filecoin-project/go-fil-markets/storagemarket" "github.com/filecoin-project/go-fil-markets/storagemarket"
@@ -129,8 +129,6 @@ type StorageMiner interface {
SectorMatchPendingPiecesToOpenSectors(ctx context.Context) error //perm:admin SectorMatchPendingPiecesToOpenSectors(ctx context.Context) error //perm:admin
// SectorAbortUpgrade can be called on sectors that are in the process of being upgraded to abort it // SectorAbortUpgrade can be called on sectors that are in the process of being upgraded to abort it
SectorAbortUpgrade(context.Context, abi.SectorNumber) error //perm:admin SectorAbortUpgrade(context.Context, abi.SectorNumber) error //perm:admin
// SectorUnseal unseals the provided sector
SectorUnseal(ctx context.Context, number abi.SectorNumber) error //perm:admin
// SectorNumAssignerMeta returns sector number assigner metadata - reserved/allocated // SectorNumAssignerMeta returns sector number assigner metadata - reserved/allocated
SectorNumAssignerMeta(ctx context.Context) (NumAssignerMeta, error) //perm:read SectorNumAssignerMeta(ctx context.Context) (NumAssignerMeta, error) //perm:read
@@ -214,11 +212,9 @@ type StorageMiner interface {
StorageDetachLocal(ctx context.Context, path string) error //perm:admin StorageDetachLocal(ctx context.Context, path string) error //perm:admin
StorageRedeclareLocal(ctx context.Context, id *storiface.ID, dropMissing bool) error //perm:admin StorageRedeclareLocal(ctx context.Context, id *storiface.ID, dropMissing bool) error //perm:admin
MarketImportDealData(ctx context.Context, propcid cid.Cid, path string) error //perm:write MarketImportDealData(ctx context.Context, propcid cid.Cid, path string) error //perm:write
MarketListDeals(ctx context.Context) ([]*MarketDeal, error) //perm:read MarketListDeals(ctx context.Context) ([]*MarketDeal, error) //perm:read
MarketListRetrievalDeals(ctx context.Context) ([]retrievalmarket.ProviderDealState, error) //perm:read
// MarketListRetrievalDeals is deprecated, returns empty list
MarketListRetrievalDeals(ctx context.Context) ([]struct{}, error) //perm:read
MarketGetDealUpdates(ctx context.Context) (<-chan storagemarket.MinerDeal, error) //perm:read MarketGetDealUpdates(ctx context.Context) (<-chan storagemarket.MinerDeal, error) //perm:read
MarketListIncompleteDeals(ctx context.Context) ([]storagemarket.MinerDeal, error) //perm:read MarketListIncompleteDeals(ctx context.Context) ([]storagemarket.MinerDeal, error) //perm:read
MarketSetAsk(ctx context.Context, price types.BigInt, verifiedPrice types.BigInt, duration abi.ChainEpoch, minPieceSize abi.PaddedPieceSize, maxPieceSize abi.PaddedPieceSize) error //perm:admin MarketSetAsk(ctx context.Context, price types.BigInt, verifiedPrice types.BigInt, duration abi.ChainEpoch, minPieceSize abi.PaddedPieceSize, maxPieceSize abi.PaddedPieceSize) error //perm:admin
+227 -229
View File
@@ -50,6 +50,22 @@ func (t *PaymentInfo) MarshalCBOR(w io.Writer) error {
return err return err
} }
// t.WaitSentinel (cid.Cid) (struct)
if len("WaitSentinel") > cbg.MaxLength {
return xerrors.Errorf("Value in field \"WaitSentinel\" was too long")
}
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("WaitSentinel"))); err != nil {
return err
}
if _, err := io.WriteString(w, string("WaitSentinel")); err != nil {
return err
}
if err := cbg.WriteCid(cw, t.WaitSentinel); err != nil {
return xerrors.Errorf("failed to write cid field t.WaitSentinel: %w", err)
}
// t.Vouchers ([]*paych.SignedVoucher) (slice) // t.Vouchers ([]*paych.SignedVoucher) (slice)
if len("Vouchers") > cbg.MaxLength { if len("Vouchers") > cbg.MaxLength {
return xerrors.Errorf("Value in field \"Vouchers\" was too long") return xerrors.Errorf("Value in field \"Vouchers\" was too long")
@@ -74,23 +90,6 @@ func (t *PaymentInfo) MarshalCBOR(w io.Writer) error {
return err return err
} }
} }
// t.WaitSentinel (cid.Cid) (struct)
if len("WaitSentinel") > cbg.MaxLength {
return xerrors.Errorf("Value in field \"WaitSentinel\" was too long")
}
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("WaitSentinel"))); err != nil {
return err
}
if _, err := io.WriteString(w, string("WaitSentinel")); err != nil {
return err
}
if err := cbg.WriteCid(cw, t.WaitSentinel); err != nil {
return xerrors.Errorf("failed to write cid field t.WaitSentinel: %w", err)
}
return nil return nil
} }
@@ -141,6 +140,19 @@ func (t *PaymentInfo) UnmarshalCBOR(r io.Reader) (err error) {
return xerrors.Errorf("unmarshaling t.Channel: %w", err) return xerrors.Errorf("unmarshaling t.Channel: %w", err)
} }
}
// t.WaitSentinel (cid.Cid) (struct)
case "WaitSentinel":
{
c, err := cbg.ReadCid(cr)
if err != nil {
return xerrors.Errorf("failed to read cid field t.WaitSentinel: %w", err)
}
t.WaitSentinel = c
} }
// t.Vouchers ([]*paych.SignedVoucher) (slice) // t.Vouchers ([]*paych.SignedVoucher) (slice)
case "Vouchers": case "Vouchers":
@@ -172,20 +184,6 @@ func (t *PaymentInfo) UnmarshalCBOR(r io.Reader) (err error) {
t.Vouchers[i] = &v t.Vouchers[i] = &v
} }
// t.WaitSentinel (cid.Cid) (struct)
case "WaitSentinel":
{
c, err := cbg.ReadCid(cr)
if err != nil {
return xerrors.Errorf("failed to read cid field t.WaitSentinel: %w", err)
}
t.WaitSentinel = c
}
default: default:
// Field doesn't exist on this type, so ignore it // Field doesn't exist on this type, so ignore it
cbg.ScanForLinks(r, func(cid.Cid) {}) cbg.ScanForLinks(r, func(cid.Cid) {})
@@ -206,19 +204,19 @@ func (t *SealedRef) MarshalCBOR(w io.Writer) error {
return err return err
} }
// t.Size (abi.UnpaddedPieceSize) (uint64) // t.SectorID (abi.SectorNumber) (uint64)
if len("Size") > cbg.MaxLength { if len("SectorID") > cbg.MaxLength {
return xerrors.Errorf("Value in field \"Size\" was too long") return xerrors.Errorf("Value in field \"SectorID\" was too long")
} }
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Size"))); err != nil { if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("SectorID"))); err != nil {
return err return err
} }
if _, err := io.WriteString(w, string("Size")); err != nil { if _, err := io.WriteString(w, string("SectorID")); err != nil {
return err return err
} }
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.Size)); err != nil { if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.SectorID)); err != nil {
return err return err
} }
@@ -238,19 +236,19 @@ func (t *SealedRef) MarshalCBOR(w io.Writer) error {
return err return err
} }
// t.SectorID (abi.SectorNumber) (uint64) // t.Size (abi.UnpaddedPieceSize) (uint64)
if len("SectorID") > cbg.MaxLength { if len("Size") > cbg.MaxLength {
return xerrors.Errorf("Value in field \"SectorID\" was too long") return xerrors.Errorf("Value in field \"Size\" was too long")
} }
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("SectorID"))); err != nil { if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Size"))); err != nil {
return err return err
} }
if _, err := io.WriteString(w, string("SectorID")); err != nil { if _, err := io.WriteString(w, string("Size")); err != nil {
return err return err
} }
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.SectorID)); err != nil { if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.Size)); err != nil {
return err return err
} }
@@ -295,8 +293,8 @@ func (t *SealedRef) UnmarshalCBOR(r io.Reader) (err error) {
} }
switch name { switch name {
// t.Size (abi.UnpaddedPieceSize) (uint64) // t.SectorID (abi.SectorNumber) (uint64)
case "Size": case "SectorID":
{ {
@@ -307,7 +305,7 @@ func (t *SealedRef) UnmarshalCBOR(r io.Reader) (err error) {
if maj != cbg.MajUnsignedInt { if maj != cbg.MajUnsignedInt {
return fmt.Errorf("wrong type for uint64 field") return fmt.Errorf("wrong type for uint64 field")
} }
t.Size = abi.UnpaddedPieceSize(extra) t.SectorID = abi.SectorNumber(extra)
} }
// t.Offset (abi.PaddedPieceSize) (uint64) // t.Offset (abi.PaddedPieceSize) (uint64)
@@ -325,8 +323,8 @@ func (t *SealedRef) UnmarshalCBOR(r io.Reader) (err error) {
t.Offset = abi.PaddedPieceSize(extra) t.Offset = abi.PaddedPieceSize(extra)
} }
// t.SectorID (abi.SectorNumber) (uint64) // t.Size (abi.UnpaddedPieceSize) (uint64)
case "SectorID": case "Size":
{ {
@@ -337,7 +335,7 @@ func (t *SealedRef) UnmarshalCBOR(r io.Reader) (err error) {
if maj != cbg.MajUnsignedInt { if maj != cbg.MajUnsignedInt {
return fmt.Errorf("wrong type for uint64 field") return fmt.Errorf("wrong type for uint64 field")
} }
t.SectorID = abi.SectorNumber(extra) t.Size = abi.UnpaddedPieceSize(extra)
} }
@@ -476,28 +474,6 @@ func (t *SealTicket) MarshalCBOR(w io.Writer) error {
return err return err
} }
// t.Epoch (abi.ChainEpoch) (int64)
if len("Epoch") > cbg.MaxLength {
return xerrors.Errorf("Value in field \"Epoch\" was too long")
}
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Epoch"))); err != nil {
return err
}
if _, err := io.WriteString(w, string("Epoch")); err != nil {
return err
}
if t.Epoch >= 0 {
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.Epoch)); err != nil {
return err
}
} else {
if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.Epoch-1)); err != nil {
return err
}
}
// t.Value (abi.SealRandomness) (slice) // t.Value (abi.SealRandomness) (slice)
if len("Value") > cbg.MaxLength { if len("Value") > cbg.MaxLength {
return xerrors.Errorf("Value in field \"Value\" was too long") return xerrors.Errorf("Value in field \"Value\" was too long")
@@ -521,6 +497,28 @@ func (t *SealTicket) MarshalCBOR(w io.Writer) error {
if _, err := cw.Write(t.Value[:]); err != nil { if _, err := cw.Write(t.Value[:]); err != nil {
return err return err
} }
// t.Epoch (abi.ChainEpoch) (int64)
if len("Epoch") > cbg.MaxLength {
return xerrors.Errorf("Value in field \"Epoch\" was too long")
}
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Epoch"))); err != nil {
return err
}
if _, err := io.WriteString(w, string("Epoch")); err != nil {
return err
}
if t.Epoch >= 0 {
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.Epoch)); err != nil {
return err
}
} else {
if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.Epoch-1)); err != nil {
return err
}
}
return nil return nil
} }
@@ -562,33 +560,7 @@ func (t *SealTicket) UnmarshalCBOR(r io.Reader) (err error) {
} }
switch name { switch name {
// t.Epoch (abi.ChainEpoch) (int64) // t.Value (abi.SealRandomness) (slice)
case "Epoch":
{
maj, extra, err := cr.ReadHeader()
var extraI int64
if err != nil {
return err
}
switch maj {
case cbg.MajUnsignedInt:
extraI = int64(extra)
if extraI < 0 {
return fmt.Errorf("int64 positive overflow")
}
case cbg.MajNegativeInt:
extraI = int64(extra)
if extraI < 0 {
return fmt.Errorf("int64 negative overflow")
}
extraI = -1 - extraI
default:
return fmt.Errorf("wrong type for int64 field: %d", maj)
}
t.Epoch = abi.ChainEpoch(extraI)
}
// t.Value (abi.SealRandomness) (slice)
case "Value": case "Value":
maj, extra, err = cr.ReadHeader() maj, extra, err = cr.ReadHeader()
@@ -610,6 +582,32 @@ func (t *SealTicket) UnmarshalCBOR(r io.Reader) (err error) {
if _, err := io.ReadFull(cr, t.Value[:]); err != nil { if _, err := io.ReadFull(cr, t.Value[:]); err != nil {
return err return err
} }
// t.Epoch (abi.ChainEpoch) (int64)
case "Epoch":
{
maj, extra, err := cr.ReadHeader()
var extraI int64
if err != nil {
return err
}
switch maj {
case cbg.MajUnsignedInt:
extraI = int64(extra)
if extraI < 0 {
return fmt.Errorf("int64 positive overflow")
}
case cbg.MajNegativeInt:
extraI = int64(extra)
if extraI < 0 {
return fmt.Errorf("int64 negative oveflow")
}
extraI = -1 - extraI
default:
return fmt.Errorf("wrong type for int64 field: %d", maj)
}
t.Epoch = abi.ChainEpoch(extraI)
}
default: default:
// Field doesn't exist on this type, so ignore it // Field doesn't exist on this type, so ignore it
@@ -631,28 +629,6 @@ func (t *SealSeed) MarshalCBOR(w io.Writer) error {
return err return err
} }
// t.Epoch (abi.ChainEpoch) (int64)
if len("Epoch") > cbg.MaxLength {
return xerrors.Errorf("Value in field \"Epoch\" was too long")
}
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Epoch"))); err != nil {
return err
}
if _, err := io.WriteString(w, string("Epoch")); err != nil {
return err
}
if t.Epoch >= 0 {
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.Epoch)); err != nil {
return err
}
} else {
if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.Epoch-1)); err != nil {
return err
}
}
// t.Value (abi.InteractiveSealRandomness) (slice) // t.Value (abi.InteractiveSealRandomness) (slice)
if len("Value") > cbg.MaxLength { if len("Value") > cbg.MaxLength {
return xerrors.Errorf("Value in field \"Value\" was too long") return xerrors.Errorf("Value in field \"Value\" was too long")
@@ -676,6 +652,28 @@ func (t *SealSeed) MarshalCBOR(w io.Writer) error {
if _, err := cw.Write(t.Value[:]); err != nil { if _, err := cw.Write(t.Value[:]); err != nil {
return err return err
} }
// t.Epoch (abi.ChainEpoch) (int64)
if len("Epoch") > cbg.MaxLength {
return xerrors.Errorf("Value in field \"Epoch\" was too long")
}
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Epoch"))); err != nil {
return err
}
if _, err := io.WriteString(w, string("Epoch")); err != nil {
return err
}
if t.Epoch >= 0 {
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.Epoch)); err != nil {
return err
}
} else {
if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.Epoch-1)); err != nil {
return err
}
}
return nil return nil
} }
@@ -717,33 +715,7 @@ func (t *SealSeed) UnmarshalCBOR(r io.Reader) (err error) {
} }
switch name { switch name {
// t.Epoch (abi.ChainEpoch) (int64) // t.Value (abi.InteractiveSealRandomness) (slice)
case "Epoch":
{
maj, extra, err := cr.ReadHeader()
var extraI int64
if err != nil {
return err
}
switch maj {
case cbg.MajUnsignedInt:
extraI = int64(extra)
if extraI < 0 {
return fmt.Errorf("int64 positive overflow")
}
case cbg.MajNegativeInt:
extraI = int64(extra)
if extraI < 0 {
return fmt.Errorf("int64 negative overflow")
}
extraI = -1 - extraI
default:
return fmt.Errorf("wrong type for int64 field: %d", maj)
}
t.Epoch = abi.ChainEpoch(extraI)
}
// t.Value (abi.InteractiveSealRandomness) (slice)
case "Value": case "Value":
maj, extra, err = cr.ReadHeader() maj, extra, err = cr.ReadHeader()
@@ -765,6 +737,32 @@ func (t *SealSeed) UnmarshalCBOR(r io.Reader) (err error) {
if _, err := io.ReadFull(cr, t.Value[:]); err != nil { if _, err := io.ReadFull(cr, t.Value[:]); err != nil {
return err return err
} }
// t.Epoch (abi.ChainEpoch) (int64)
case "Epoch":
{
maj, extra, err := cr.ReadHeader()
var extraI int64
if err != nil {
return err
}
switch maj {
case cbg.MajUnsignedInt:
extraI = int64(extra)
if extraI < 0 {
return fmt.Errorf("int64 positive overflow")
}
case cbg.MajNegativeInt:
extraI = int64(extra)
if extraI < 0 {
return fmt.Errorf("int64 negative oveflow")
}
extraI = -1 - extraI
default:
return fmt.Errorf("wrong type for int64 field: %d", maj)
}
t.Epoch = abi.ChainEpoch(extraI)
}
default: default:
// Field doesn't exist on this type, so ignore it // Field doesn't exist on this type, so ignore it
@@ -786,22 +784,6 @@ func (t *PieceDealInfo) MarshalCBOR(w io.Writer) error {
return err return err
} }
// t.DealID (abi.DealID) (uint64)
if len("DealID") > cbg.MaxLength {
return xerrors.Errorf("Value in field \"DealID\" was too long")
}
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("DealID"))); err != nil {
return err
}
if _, err := io.WriteString(w, string("DealID")); err != nil {
return err
}
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.DealID)); err != nil {
return err
}
// t.PublishCid (cid.Cid) (struct) // t.PublishCid (cid.Cid) (struct)
if len("PublishCid") > cbg.MaxLength { if len("PublishCid") > cbg.MaxLength {
return xerrors.Errorf("Value in field \"PublishCid\" was too long") return xerrors.Errorf("Value in field \"PublishCid\" was too long")
@@ -824,6 +806,22 @@ func (t *PieceDealInfo) MarshalCBOR(w io.Writer) error {
} }
} }
// t.DealID (abi.DealID) (uint64)
if len("DealID") > cbg.MaxLength {
return xerrors.Errorf("Value in field \"DealID\" was too long")
}
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("DealID"))); err != nil {
return err
}
if _, err := io.WriteString(w, string("DealID")); err != nil {
return err
}
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.DealID)); err != nil {
return err
}
// t.DealProposal (market.DealProposal) (struct) // t.DealProposal (market.DealProposal) (struct)
if len("DealProposal") > cbg.MaxLength { if len("DealProposal") > cbg.MaxLength {
return xerrors.Errorf("Value in field \"DealProposal\" was too long") return xerrors.Errorf("Value in field \"DealProposal\" was too long")
@@ -912,22 +910,7 @@ func (t *PieceDealInfo) UnmarshalCBOR(r io.Reader) (err error) {
} }
switch name { switch name {
// t.DealID (abi.DealID) (uint64) // t.PublishCid (cid.Cid) (struct)
case "DealID":
{
maj, extra, err = cr.ReadHeader()
if err != nil {
return err
}
if maj != cbg.MajUnsignedInt {
return fmt.Errorf("wrong type for uint64 field")
}
t.DealID = abi.DealID(extra)
}
// t.PublishCid (cid.Cid) (struct)
case "PublishCid": case "PublishCid":
{ {
@@ -949,6 +932,21 @@ func (t *PieceDealInfo) UnmarshalCBOR(r io.Reader) (err error) {
t.PublishCid = &c t.PublishCid = &c
} }
}
// t.DealID (abi.DealID) (uint64)
case "DealID":
{
maj, extra, err = cr.ReadHeader()
if err != nil {
return err
}
if maj != cbg.MajUnsignedInt {
return fmt.Errorf("wrong type for uint64 field")
}
t.DealID = abi.DealID(extra)
} }
// t.DealProposal (market.DealProposal) (struct) // t.DealProposal (market.DealProposal) (struct)
case "DealProposal": case "DealProposal":
@@ -1142,28 +1140,6 @@ func (t *DealSchedule) MarshalCBOR(w io.Writer) error {
return err return err
} }
// t.EndEpoch (abi.ChainEpoch) (int64)
if len("EndEpoch") > cbg.MaxLength {
return xerrors.Errorf("Value in field \"EndEpoch\" was too long")
}
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("EndEpoch"))); err != nil {
return err
}
if _, err := io.WriteString(w, string("EndEpoch")); err != nil {
return err
}
if t.EndEpoch >= 0 {
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.EndEpoch)); err != nil {
return err
}
} else {
if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.EndEpoch-1)); err != nil {
return err
}
}
// t.StartEpoch (abi.ChainEpoch) (int64) // t.StartEpoch (abi.ChainEpoch) (int64)
if len("StartEpoch") > cbg.MaxLength { if len("StartEpoch") > cbg.MaxLength {
return xerrors.Errorf("Value in field \"StartEpoch\" was too long") return xerrors.Errorf("Value in field \"StartEpoch\" was too long")
@@ -1185,6 +1161,28 @@ func (t *DealSchedule) MarshalCBOR(w io.Writer) error {
return err return err
} }
} }
// t.EndEpoch (abi.ChainEpoch) (int64)
if len("EndEpoch") > cbg.MaxLength {
return xerrors.Errorf("Value in field \"EndEpoch\" was too long")
}
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("EndEpoch"))); err != nil {
return err
}
if _, err := io.WriteString(w, string("EndEpoch")); err != nil {
return err
}
if t.EndEpoch >= 0 {
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.EndEpoch)); err != nil {
return err
}
} else {
if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.EndEpoch-1)); err != nil {
return err
}
}
return nil return nil
} }
@@ -1226,33 +1224,7 @@ func (t *DealSchedule) UnmarshalCBOR(r io.Reader) (err error) {
} }
switch name { switch name {
// t.EndEpoch (abi.ChainEpoch) (int64) // t.StartEpoch (abi.ChainEpoch) (int64)
case "EndEpoch":
{
maj, extra, err := cr.ReadHeader()
var extraI int64
if err != nil {
return err
}
switch maj {
case cbg.MajUnsignedInt:
extraI = int64(extra)
if extraI < 0 {
return fmt.Errorf("int64 positive overflow")
}
case cbg.MajNegativeInt:
extraI = int64(extra)
if extraI < 0 {
return fmt.Errorf("int64 negative overflow")
}
extraI = -1 - extraI
default:
return fmt.Errorf("wrong type for int64 field: %d", maj)
}
t.EndEpoch = abi.ChainEpoch(extraI)
}
// t.StartEpoch (abi.ChainEpoch) (int64)
case "StartEpoch": case "StartEpoch":
{ {
maj, extra, err := cr.ReadHeader() maj, extra, err := cr.ReadHeader()
@@ -1269,7 +1241,7 @@ func (t *DealSchedule) UnmarshalCBOR(r io.Reader) (err error) {
case cbg.MajNegativeInt: case cbg.MajNegativeInt:
extraI = int64(extra) extraI = int64(extra)
if extraI < 0 { if extraI < 0 {
return fmt.Errorf("int64 negative overflow") return fmt.Errorf("int64 negative oveflow")
} }
extraI = -1 - extraI extraI = -1 - extraI
default: default:
@@ -1278,6 +1250,32 @@ func (t *DealSchedule) UnmarshalCBOR(r io.Reader) (err error) {
t.StartEpoch = abi.ChainEpoch(extraI) t.StartEpoch = abi.ChainEpoch(extraI)
} }
// t.EndEpoch (abi.ChainEpoch) (int64)
case "EndEpoch":
{
maj, extra, err := cr.ReadHeader()
var extraI int64
if err != nil {
return err
}
switch maj {
case cbg.MajUnsignedInt:
extraI = int64(extra)
if extraI < 0 {
return fmt.Errorf("int64 positive overflow")
}
case cbg.MajNegativeInt:
extraI = int64(extra)
if extraI < 0 {
return fmt.Errorf("int64 negative oveflow")
}
extraI = -1 - extraI
default:
return fmt.Errorf("wrong type for int64 field: %d", maj)
}
t.EndEpoch = abi.ChainEpoch(extraI)
}
default: default:
// Field doesn't exist on this type, so ignore it // Field doesn't exist on this type, so ignore it
+4 -4
View File
@@ -14,9 +14,9 @@ import (
"unicode" "unicode"
"github.com/google/uuid" "github.com/google/uuid"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
"github.com/ipfs/go-graphsync" "github.com/ipfs/go-graphsync"
blocks "github.com/ipfs/go-libipfs/blocks"
textselector "github.com/ipld/go-ipld-selector-text-lite" textselector "github.com/ipld/go-ipld-selector-text-lite"
pubsub "github.com/libp2p/go-libp2p-pubsub" pubsub "github.com/libp2p/go-libp2p-pubsub"
"github.com/libp2p/go-libp2p/core/metrics" "github.com/libp2p/go-libp2p/core/metrics"
@@ -27,7 +27,7 @@ import (
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-bitfield" "github.com/filecoin-project/go-bitfield"
datatransfer "github.com/filecoin-project/go-data-transfer/v2" datatransfer "github.com/filecoin-project/go-data-transfer"
"github.com/filecoin-project/go-fil-markets/filestore" "github.com/filecoin-project/go-fil-markets/filestore"
"github.com/filecoin-project/go-fil-markets/retrievalmarket" "github.com/filecoin-project/go-fil-markets/retrievalmarket"
"github.com/filecoin-project/go-jsonrpc/auth" "github.com/filecoin-project/go-jsonrpc/auth"
@@ -152,8 +152,8 @@ func init() {
addExample(map[string]int{"name": 42}) addExample(map[string]int{"name": 42})
addExample(map[string]time.Time{"name": time.Unix(1615243938, 0).UTC()}) addExample(map[string]time.Time{"name": time.Unix(1615243938, 0).UTC()})
addExample(&types.ExecutionTrace{ addExample(&types.ExecutionTrace{
Msg: ExampleValue("init", reflect.TypeOf(types.MessageTrace{}), nil).(types.MessageTrace), Msg: ExampleValue("init", reflect.TypeOf(&types.Message{}), nil).(*types.Message),
MsgRct: ExampleValue("init", reflect.TypeOf(types.ReturnTrace{}), nil).(types.ReturnTrace), MsgRct: ExampleValue("init", reflect.TypeOf(&types.MessageReceipt{}), nil).(*types.MessageReceipt),
}) })
addExample(map[string]types.Actor{ addExample(map[string]types.Actor{
"t01236": ExampleValue("init", reflect.TypeOf(types.Actor{}), nil).(types.Actor), "t01236": ExampleValue("init", reflect.TypeOf(types.Actor{}), nil).(types.Actor),
-1
View File
@@ -21,7 +21,6 @@ func CreateEthRPCAliases(as apitypes.Aliaser) {
as.AliasMethod("eth_getStorageAt", "Filecoin.EthGetStorageAt") as.AliasMethod("eth_getStorageAt", "Filecoin.EthGetStorageAt")
as.AliasMethod("eth_getBalance", "Filecoin.EthGetBalance") as.AliasMethod("eth_getBalance", "Filecoin.EthGetBalance")
as.AliasMethod("eth_chainId", "Filecoin.EthChainId") as.AliasMethod("eth_chainId", "Filecoin.EthChainId")
as.AliasMethod("eth_syncing", "Filecoin.EthSyncing")
as.AliasMethod("eth_feeHistory", "Filecoin.EthFeeHistory") as.AliasMethod("eth_feeHistory", "Filecoin.EthFeeHistory")
as.AliasMethod("eth_protocolVersion", "Filecoin.EthProtocolVersion") as.AliasMethod("eth_protocolVersion", "Filecoin.EthProtocolVersion")
as.AliasMethod("eth_maxPriorityFeePerGas", "Filecoin.EthMaxPriorityFeePerGas") as.AliasMethod("eth_maxPriorityFeePerGas", "Filecoin.EthMaxPriorityFeePerGas")
+2 -75
View File
@@ -12,8 +12,8 @@ import (
gomock "github.com/golang/mock/gomock" gomock "github.com/golang/mock/gomock"
uuid "github.com/google/uuid" uuid "github.com/google/uuid"
blocks "github.com/ipfs/go-block-format"
cid "github.com/ipfs/go-cid" cid "github.com/ipfs/go-cid"
blocks "github.com/ipfs/go-libipfs/blocks"
metrics "github.com/libp2p/go-libp2p/core/metrics" metrics "github.com/libp2p/go-libp2p/core/metrics"
network0 "github.com/libp2p/go-libp2p/core/network" network0 "github.com/libp2p/go-libp2p/core/network"
peer "github.com/libp2p/go-libp2p/core/peer" peer "github.com/libp2p/go-libp2p/core/peer"
@@ -21,7 +21,7 @@ import (
address "github.com/filecoin-project/go-address" address "github.com/filecoin-project/go-address"
bitfield "github.com/filecoin-project/go-bitfield" bitfield "github.com/filecoin-project/go-bitfield"
datatransfer "github.com/filecoin-project/go-data-transfer/v2" datatransfer "github.com/filecoin-project/go-data-transfer"
retrievalmarket "github.com/filecoin-project/go-fil-markets/retrievalmarket" retrievalmarket "github.com/filecoin-project/go-fil-markets/retrievalmarket"
jsonrpc "github.com/filecoin-project/go-jsonrpc" jsonrpc "github.com/filecoin-project/go-jsonrpc"
auth "github.com/filecoin-project/go-jsonrpc/auth" auth "github.com/filecoin-project/go-jsonrpc/auth"
@@ -155,20 +155,6 @@ func (mr *MockFullNodeMockRecorder) ChainExport(arg0, arg1, arg2, arg3 interface
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainExport", reflect.TypeOf((*MockFullNode)(nil).ChainExport), arg0, arg1, arg2, arg3) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainExport", reflect.TypeOf((*MockFullNode)(nil).ChainExport), arg0, arg1, arg2, arg3)
} }
// ChainExportRangeInternal mocks base method.
func (m *MockFullNode) ChainExportRangeInternal(arg0 context.Context, arg1, arg2 types.TipSetKey, arg3 api.ChainExportConfig) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ChainExportRangeInternal", arg0, arg1, arg2, arg3)
ret0, _ := ret[0].(error)
return ret0
}
// ChainExportRangeInternal indicates an expected call of ChainExportRangeInternal.
func (mr *MockFullNodeMockRecorder) ChainExportRangeInternal(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainExportRangeInternal", reflect.TypeOf((*MockFullNode)(nil).ChainExportRangeInternal), arg0, arg1, arg2, arg3)
}
// ChainGetBlock mocks base method. // ChainGetBlock mocks base method.
func (m *MockFullNode) ChainGetBlock(arg0 context.Context, arg1 cid.Cid) (*types.BlockHeader, error) { func (m *MockFullNode) ChainGetBlock(arg0 context.Context, arg1 cid.Cid) (*types.BlockHeader, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
@@ -394,20 +380,6 @@ func (mr *MockFullNodeMockRecorder) ChainHead(arg0 interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainHead", reflect.TypeOf((*MockFullNode)(nil).ChainHead), arg0) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainHead", reflect.TypeOf((*MockFullNode)(nil).ChainHead), arg0)
} }
// ChainHotGC mocks base method.
func (m *MockFullNode) ChainHotGC(arg0 context.Context, arg1 api.HotGCOpts) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ChainHotGC", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// ChainHotGC indicates an expected call of ChainHotGC.
func (mr *MockFullNodeMockRecorder) ChainHotGC(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainHotGC", reflect.TypeOf((*MockFullNode)(nil).ChainHotGC), arg0, arg1)
}
// ChainNotify mocks base method. // ChainNotify mocks base method.
func (m *MockFullNode) ChainNotify(arg0 context.Context) (<-chan []*api.HeadChange, error) { func (m *MockFullNode) ChainNotify(arg0 context.Context) (<-chan []*api.HeadChange, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
@@ -1296,21 +1268,6 @@ func (mr *MockFullNodeMockRecorder) EthGetTransactionByHash(arg0, arg1 interface
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthGetTransactionByHash", reflect.TypeOf((*MockFullNode)(nil).EthGetTransactionByHash), arg0, arg1) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthGetTransactionByHash", reflect.TypeOf((*MockFullNode)(nil).EthGetTransactionByHash), arg0, arg1)
} }
// EthGetTransactionByHashLimited mocks base method.
func (m *MockFullNode) EthGetTransactionByHashLimited(arg0 context.Context, arg1 *ethtypes.EthHash, arg2 abi.ChainEpoch) (*ethtypes.EthTx, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthGetTransactionByHashLimited", arg0, arg1, arg2)
ret0, _ := ret[0].(*ethtypes.EthTx)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthGetTransactionByHashLimited indicates an expected call of EthGetTransactionByHashLimited.
func (mr *MockFullNodeMockRecorder) EthGetTransactionByHashLimited(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthGetTransactionByHashLimited", reflect.TypeOf((*MockFullNode)(nil).EthGetTransactionByHashLimited), arg0, arg1, arg2)
}
// EthGetTransactionCount mocks base method. // EthGetTransactionCount mocks base method.
func (m *MockFullNode) EthGetTransactionCount(arg0 context.Context, arg1 ethtypes.EthAddress, arg2 string) (ethtypes.EthUint64, error) { func (m *MockFullNode) EthGetTransactionCount(arg0 context.Context, arg1 ethtypes.EthAddress, arg2 string) (ethtypes.EthUint64, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
@@ -1356,21 +1313,6 @@ func (mr *MockFullNodeMockRecorder) EthGetTransactionReceipt(arg0, arg1 interfac
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthGetTransactionReceipt", reflect.TypeOf((*MockFullNode)(nil).EthGetTransactionReceipt), arg0, arg1) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthGetTransactionReceipt", reflect.TypeOf((*MockFullNode)(nil).EthGetTransactionReceipt), arg0, arg1)
} }
// EthGetTransactionReceiptLimited mocks base method.
func (m *MockFullNode) EthGetTransactionReceiptLimited(arg0 context.Context, arg1 ethtypes.EthHash, arg2 abi.ChainEpoch) (*api.EthTxReceipt, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthGetTransactionReceiptLimited", arg0, arg1, arg2)
ret0, _ := ret[0].(*api.EthTxReceipt)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthGetTransactionReceiptLimited indicates an expected call of EthGetTransactionReceiptLimited.
func (mr *MockFullNodeMockRecorder) EthGetTransactionReceiptLimited(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthGetTransactionReceiptLimited", reflect.TypeOf((*MockFullNode)(nil).EthGetTransactionReceiptLimited), arg0, arg1, arg2)
}
// EthMaxPriorityFeePerGas mocks base method. // EthMaxPriorityFeePerGas mocks base method.
func (m *MockFullNode) EthMaxPriorityFeePerGas(arg0 context.Context) (ethtypes.EthBigInt, error) { func (m *MockFullNode) EthMaxPriorityFeePerGas(arg0 context.Context) (ethtypes.EthBigInt, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
@@ -1476,21 +1418,6 @@ func (mr *MockFullNodeMockRecorder) EthSubscribe(arg0, arg1 interface{}) *gomock
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthSubscribe", reflect.TypeOf((*MockFullNode)(nil).EthSubscribe), arg0, arg1) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthSubscribe", reflect.TypeOf((*MockFullNode)(nil).EthSubscribe), arg0, arg1)
} }
// EthSyncing mocks base method.
func (m *MockFullNode) EthSyncing(arg0 context.Context) (ethtypes.EthSyncingResult, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthSyncing", arg0)
ret0, _ := ret[0].(ethtypes.EthSyncingResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthSyncing indicates an expected call of EthSyncing.
func (mr *MockFullNodeMockRecorder) EthSyncing(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthSyncing", reflect.TypeOf((*MockFullNode)(nil).EthSyncing), arg0)
}
// EthUninstallFilter mocks base method. // EthUninstallFilter mocks base method.
func (m *MockFullNode) EthUninstallFilter(arg0 context.Context, arg1 ethtypes.EthFilterID) (bool, error) { func (m *MockFullNode) EthUninstallFilter(arg0 context.Context, arg1 ethtypes.EthFilterID) (bool, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
+42 -185
View File
@@ -8,8 +8,8 @@ import (
"time" "time"
"github.com/google/uuid" "github.com/google/uuid"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
blocks "github.com/ipfs/go-libipfs/blocks"
"github.com/libp2p/go-libp2p/core/metrics" "github.com/libp2p/go-libp2p/core/metrics"
"github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-libp2p/core/network"
"github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/peer"
@@ -18,7 +18,7 @@ import (
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-bitfield" "github.com/filecoin-project/go-bitfield"
datatransfer "github.com/filecoin-project/go-data-transfer/v2" datatransfer "github.com/filecoin-project/go-data-transfer"
"github.com/filecoin-project/go-fil-markets/piecestore" "github.com/filecoin-project/go-fil-markets/piecestore"
"github.com/filecoin-project/go-fil-markets/retrievalmarket" "github.com/filecoin-project/go-fil-markets/retrievalmarket"
"github.com/filecoin-project/go-fil-markets/storagemarket" "github.com/filecoin-project/go-fil-markets/storagemarket"
@@ -117,7 +117,7 @@ type EthSubscriberStruct struct {
} }
type EthSubscriberMethods struct { type EthSubscriberMethods struct {
EthSubscription func(p0 context.Context, p1 jsonrpc.RawParams) error `notify:"true" rpc_method:"eth_subscription"` EthSubscription func(p0 context.Context, p1 jsonrpc.RawParams) error `notify:"true"rpc_method:"eth_subscription"`
} }
type EthSubscriberStub struct { type EthSubscriberStub struct {
@@ -140,8 +140,6 @@ type FullNodeMethods struct {
ChainExport func(p0 context.Context, p1 abi.ChainEpoch, p2 bool, p3 types.TipSetKey) (<-chan []byte, error) `perm:"read"` ChainExport func(p0 context.Context, p1 abi.ChainEpoch, p2 bool, p3 types.TipSetKey) (<-chan []byte, error) `perm:"read"`
ChainExportRangeInternal func(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey, p3 ChainExportConfig) error `perm:"admin"`
ChainGetBlock func(p0 context.Context, p1 cid.Cid) (*types.BlockHeader, error) `perm:"read"` ChainGetBlock func(p0 context.Context, p1 cid.Cid) (*types.BlockHeader, error) `perm:"read"`
ChainGetBlockMessages func(p0 context.Context, p1 cid.Cid) (*BlockMessages, error) `perm:"read"` ChainGetBlockMessages func(p0 context.Context, p1 cid.Cid) (*BlockMessages, error) `perm:"read"`
@@ -172,8 +170,6 @@ type FullNodeMethods struct {
ChainHead func(p0 context.Context) (*types.TipSet, error) `perm:"read"` ChainHead func(p0 context.Context) (*types.TipSet, error) `perm:"read"`
ChainHotGC func(p0 context.Context, p1 HotGCOpts) error `perm:"admin"`
ChainNotify func(p0 context.Context) (<-chan []*HeadChange, error) `perm:"read"` ChainNotify func(p0 context.Context) (<-chan []*HeadChange, error) `perm:"read"`
ChainPrune func(p0 context.Context, p1 PruneOpts) error `perm:"admin"` ChainPrune func(p0 context.Context, p1 PruneOpts) error `perm:"admin"`
@@ -274,9 +270,9 @@ type FullNodeMethods struct {
EthGetCode func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBytes, error) `perm:"read"` EthGetCode func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBytes, error) `perm:"read"`
EthGetFilterChanges func(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) `perm:"read"` EthGetFilterChanges func(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) `perm:"write"`
EthGetFilterLogs func(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) `perm:"read"` EthGetFilterLogs func(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) `perm:"write"`
EthGetLogs func(p0 context.Context, p1 *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) `perm:"read"` EthGetLogs func(p0 context.Context, p1 *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) `perm:"read"`
@@ -290,35 +286,29 @@ type FullNodeMethods struct {
EthGetTransactionByHash func(p0 context.Context, p1 *ethtypes.EthHash) (*ethtypes.EthTx, error) `perm:"read"` EthGetTransactionByHash func(p0 context.Context, p1 *ethtypes.EthHash) (*ethtypes.EthTx, error) `perm:"read"`
EthGetTransactionByHashLimited func(p0 context.Context, p1 *ethtypes.EthHash, p2 abi.ChainEpoch) (*ethtypes.EthTx, error) `perm:"read"`
EthGetTransactionCount func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthUint64, error) `perm:"read"` EthGetTransactionCount func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthUint64, error) `perm:"read"`
EthGetTransactionHashByCid func(p0 context.Context, p1 cid.Cid) (*ethtypes.EthHash, error) `perm:"read"` EthGetTransactionHashByCid func(p0 context.Context, p1 cid.Cid) (*ethtypes.EthHash, error) `perm:"read"`
EthGetTransactionReceipt func(p0 context.Context, p1 ethtypes.EthHash) (*EthTxReceipt, error) `perm:"read"` EthGetTransactionReceipt func(p0 context.Context, p1 ethtypes.EthHash) (*EthTxReceipt, error) `perm:"read"`
EthGetTransactionReceiptLimited func(p0 context.Context, p1 ethtypes.EthHash, p2 abi.ChainEpoch) (*EthTxReceipt, error) `perm:"read"`
EthMaxPriorityFeePerGas func(p0 context.Context) (ethtypes.EthBigInt, error) `perm:"read"` EthMaxPriorityFeePerGas func(p0 context.Context) (ethtypes.EthBigInt, error) `perm:"read"`
EthNewBlockFilter func(p0 context.Context) (ethtypes.EthFilterID, error) `perm:"read"` EthNewBlockFilter func(p0 context.Context) (ethtypes.EthFilterID, error) `perm:"write"`
EthNewFilter func(p0 context.Context, p1 *ethtypes.EthFilterSpec) (ethtypes.EthFilterID, error) `perm:"read"` EthNewFilter func(p0 context.Context, p1 *ethtypes.EthFilterSpec) (ethtypes.EthFilterID, error) `perm:"write"`
EthNewPendingTransactionFilter func(p0 context.Context) (ethtypes.EthFilterID, error) `perm:"read"` EthNewPendingTransactionFilter func(p0 context.Context) (ethtypes.EthFilterID, error) `perm:"write"`
EthProtocolVersion func(p0 context.Context) (ethtypes.EthUint64, error) `perm:"read"` EthProtocolVersion func(p0 context.Context) (ethtypes.EthUint64, error) `perm:"read"`
EthSendRawTransaction func(p0 context.Context, p1 ethtypes.EthBytes) (ethtypes.EthHash, error) `perm:"read"` EthSendRawTransaction func(p0 context.Context, p1 ethtypes.EthBytes) (ethtypes.EthHash, error) `perm:"read"`
EthSubscribe func(p0 context.Context, p1 jsonrpc.RawParams) (ethtypes.EthSubscriptionID, error) `perm:"read"` EthSubscribe func(p0 context.Context, p1 jsonrpc.RawParams) (ethtypes.EthSubscriptionID, error) `perm:"write"`
EthSyncing func(p0 context.Context) (ethtypes.EthSyncingResult, error) `perm:"read"` EthUninstallFilter func(p0 context.Context, p1 ethtypes.EthFilterID) (bool, error) `perm:"write"`
EthUninstallFilter func(p0 context.Context, p1 ethtypes.EthFilterID) (bool, error) `perm:"read"` EthUnsubscribe func(p0 context.Context, p1 ethtypes.EthSubscriptionID) (bool, error) `perm:"write"`
EthUnsubscribe func(p0 context.Context, p1 ethtypes.EthSubscriptionID) (bool, error) `perm:"read"`
FilecoinAddressToEthAddress func(p0 context.Context, p1 address.Address) (ethtypes.EthAddress, error) `perm:"read"` FilecoinAddressToEthAddress func(p0 context.Context, p1 address.Address) (ethtypes.EthAddress, error) `perm:"read"`
@@ -698,9 +688,11 @@ type GatewayMethods struct {
EthGetStorageAt func(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 string) (ethtypes.EthBytes, error) `` EthGetStorageAt func(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 string) (ethtypes.EthBytes, error) ``
EthGetTransactionByHash func(p0 context.Context, p1 *ethtypes.EthHash) (*ethtypes.EthTx, error) `` EthGetTransactionByBlockHashAndIndex func(p0 context.Context, p1 ethtypes.EthHash, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) ``
EthGetTransactionByHashLimited func(p0 context.Context, p1 *ethtypes.EthHash, p2 abi.ChainEpoch) (*ethtypes.EthTx, error) `` EthGetTransactionByBlockNumberAndIndex func(p0 context.Context, p1 ethtypes.EthUint64, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) ``
EthGetTransactionByHash func(p0 context.Context, p1 *ethtypes.EthHash) (*ethtypes.EthTx, error) ``
EthGetTransactionCount func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthUint64, error) `` EthGetTransactionCount func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthUint64, error) ``
@@ -708,8 +700,6 @@ type GatewayMethods struct {
EthGetTransactionReceipt func(p0 context.Context, p1 ethtypes.EthHash) (*EthTxReceipt, error) `` EthGetTransactionReceipt func(p0 context.Context, p1 ethtypes.EthHash) (*EthTxReceipt, error) ``
EthGetTransactionReceiptLimited func(p0 context.Context, p1 ethtypes.EthHash, p2 abi.ChainEpoch) (*EthTxReceipt, error) ``
EthMaxPriorityFeePerGas func(p0 context.Context) (ethtypes.EthBigInt, error) `` EthMaxPriorityFeePerGas func(p0 context.Context) (ethtypes.EthBigInt, error) ``
EthNewBlockFilter func(p0 context.Context) (ethtypes.EthFilterID, error) `` EthNewBlockFilter func(p0 context.Context) (ethtypes.EthFilterID, error) ``
@@ -724,14 +714,10 @@ type GatewayMethods struct {
EthSubscribe func(p0 context.Context, p1 jsonrpc.RawParams) (ethtypes.EthSubscriptionID, error) `` EthSubscribe func(p0 context.Context, p1 jsonrpc.RawParams) (ethtypes.EthSubscriptionID, error) ``
EthSyncing func(p0 context.Context) (ethtypes.EthSyncingResult, error) ``
EthUninstallFilter func(p0 context.Context, p1 ethtypes.EthFilterID) (bool, error) `` EthUninstallFilter func(p0 context.Context, p1 ethtypes.EthFilterID) (bool, error) ``
EthUnsubscribe func(p0 context.Context, p1 ethtypes.EthSubscriptionID) (bool, error) `` EthUnsubscribe func(p0 context.Context, p1 ethtypes.EthSubscriptionID) (bool, error) ``
GasEstimateGasPremium func(p0 context.Context, p1 uint64, p2 address.Address, p3 int64, p4 types.TipSetKey) (types.BigInt, error) ``
GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) `` GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) ``
MpoolGetNonce func(p0 context.Context, p1 address.Address) (uint64, error) `` MpoolGetNonce func(p0 context.Context, p1 address.Address) (uint64, error) ``
@@ -774,24 +760,18 @@ type GatewayMethods struct {
StateMinerProvingDeadline func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) `` StateMinerProvingDeadline func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) ``
StateMinerSectorCount func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MinerSectors, error) ``
StateNetworkName func(p0 context.Context) (dtypes.NetworkName, error) `` StateNetworkName func(p0 context.Context) (dtypes.NetworkName, error) ``
StateNetworkVersion func(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) `` StateNetworkVersion func(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) ``
StateReadState func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*ActorState, error) `` StateReadState func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*ActorState, error) ``
StateReplay func(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*InvocResult, error) ``
StateSearchMsg func(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) `` StateSearchMsg func(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) ``
StateSectorGetInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) `` StateSectorGetInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) ``
StateVerifiedClientStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) `` StateVerifiedClientStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) ``
StateVerifierStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) ``
StateWaitMsg func(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) `` StateWaitMsg func(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) ``
Version func(p0 context.Context) (APIVersion, error) `` Version func(p0 context.Context) (APIVersion, error) ``
@@ -971,7 +951,7 @@ type StorageMinerMethods struct {
MarketListIncompleteDeals func(p0 context.Context) ([]storagemarket.MinerDeal, error) `perm:"read"` MarketListIncompleteDeals func(p0 context.Context) ([]storagemarket.MinerDeal, error) `perm:"read"`
MarketListRetrievalDeals func(p0 context.Context) ([]struct{}, error) `perm:"read"` MarketListRetrievalDeals func(p0 context.Context) ([]retrievalmarket.ProviderDealState, error) `perm:"read"`
MarketPendingDeals func(p0 context.Context) (PendingDealInfo, error) `perm:"write"` MarketPendingDeals func(p0 context.Context) (PendingDealInfo, error) `perm:"write"`
@@ -1089,8 +1069,6 @@ type StorageMinerMethods struct {
SectorTerminatePending func(p0 context.Context) ([]abi.SectorID, error) `perm:"admin"` SectorTerminatePending func(p0 context.Context) ([]abi.SectorID, error) `perm:"admin"`
SectorUnseal func(p0 context.Context, p1 abi.SectorNumber) error `perm:"admin"`
SectorsList func(p0 context.Context) ([]abi.SectorNumber, error) `perm:"read"` SectorsList func(p0 context.Context) ([]abi.SectorNumber, error) `perm:"read"`
SectorsListInStates func(p0 context.Context, p1 []SectorState) ([]abi.SectorNumber, error) `perm:"read"` SectorsListInStates func(p0 context.Context, p1 []SectorState) ([]abi.SectorNumber, error) `perm:"read"`
@@ -1469,17 +1447,6 @@ func (s *FullNodeStub) ChainExport(p0 context.Context, p1 abi.ChainEpoch, p2 boo
return nil, ErrNotSupported return nil, ErrNotSupported
} }
func (s *FullNodeStruct) ChainExportRangeInternal(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey, p3 ChainExportConfig) error {
if s.Internal.ChainExportRangeInternal == nil {
return ErrNotSupported
}
return s.Internal.ChainExportRangeInternal(p0, p1, p2, p3)
}
func (s *FullNodeStub) ChainExportRangeInternal(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey, p3 ChainExportConfig) error {
return ErrNotSupported
}
func (s *FullNodeStruct) ChainGetBlock(p0 context.Context, p1 cid.Cid) (*types.BlockHeader, error) { func (s *FullNodeStruct) ChainGetBlock(p0 context.Context, p1 cid.Cid) (*types.BlockHeader, error) {
if s.Internal.ChainGetBlock == nil { if s.Internal.ChainGetBlock == nil {
return nil, ErrNotSupported return nil, ErrNotSupported
@@ -1645,17 +1612,6 @@ func (s *FullNodeStub) ChainHead(p0 context.Context) (*types.TipSet, error) {
return nil, ErrNotSupported return nil, ErrNotSupported
} }
func (s *FullNodeStruct) ChainHotGC(p0 context.Context, p1 HotGCOpts) error {
if s.Internal.ChainHotGC == nil {
return ErrNotSupported
}
return s.Internal.ChainHotGC(p0, p1)
}
func (s *FullNodeStub) ChainHotGC(p0 context.Context, p1 HotGCOpts) error {
return ErrNotSupported
}
func (s *FullNodeStruct) ChainNotify(p0 context.Context) (<-chan []*HeadChange, error) { func (s *FullNodeStruct) ChainNotify(p0 context.Context) (<-chan []*HeadChange, error) {
if s.Internal.ChainNotify == nil { if s.Internal.ChainNotify == nil {
return nil, ErrNotSupported return nil, ErrNotSupported
@@ -2294,17 +2250,6 @@ func (s *FullNodeStub) EthGetTransactionByHash(p0 context.Context, p1 *ethtypes.
return nil, ErrNotSupported return nil, ErrNotSupported
} }
func (s *FullNodeStruct) EthGetTransactionByHashLimited(p0 context.Context, p1 *ethtypes.EthHash, p2 abi.ChainEpoch) (*ethtypes.EthTx, error) {
if s.Internal.EthGetTransactionByHashLimited == nil {
return nil, ErrNotSupported
}
return s.Internal.EthGetTransactionByHashLimited(p0, p1, p2)
}
func (s *FullNodeStub) EthGetTransactionByHashLimited(p0 context.Context, p1 *ethtypes.EthHash, p2 abi.ChainEpoch) (*ethtypes.EthTx, error) {
return nil, ErrNotSupported
}
func (s *FullNodeStruct) EthGetTransactionCount(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthUint64, error) { func (s *FullNodeStruct) EthGetTransactionCount(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthUint64, error) {
if s.Internal.EthGetTransactionCount == nil { if s.Internal.EthGetTransactionCount == nil {
return *new(ethtypes.EthUint64), ErrNotSupported return *new(ethtypes.EthUint64), ErrNotSupported
@@ -2338,17 +2283,6 @@ func (s *FullNodeStub) EthGetTransactionReceipt(p0 context.Context, p1 ethtypes.
return nil, ErrNotSupported return nil, ErrNotSupported
} }
func (s *FullNodeStruct) EthGetTransactionReceiptLimited(p0 context.Context, p1 ethtypes.EthHash, p2 abi.ChainEpoch) (*EthTxReceipt, error) {
if s.Internal.EthGetTransactionReceiptLimited == nil {
return nil, ErrNotSupported
}
return s.Internal.EthGetTransactionReceiptLimited(p0, p1, p2)
}
func (s *FullNodeStub) EthGetTransactionReceiptLimited(p0 context.Context, p1 ethtypes.EthHash, p2 abi.ChainEpoch) (*EthTxReceipt, error) {
return nil, ErrNotSupported
}
func (s *FullNodeStruct) EthMaxPriorityFeePerGas(p0 context.Context) (ethtypes.EthBigInt, error) { func (s *FullNodeStruct) EthMaxPriorityFeePerGas(p0 context.Context) (ethtypes.EthBigInt, error) {
if s.Internal.EthMaxPriorityFeePerGas == nil { if s.Internal.EthMaxPriorityFeePerGas == nil {
return *new(ethtypes.EthBigInt), ErrNotSupported return *new(ethtypes.EthBigInt), ErrNotSupported
@@ -2426,17 +2360,6 @@ func (s *FullNodeStub) EthSubscribe(p0 context.Context, p1 jsonrpc.RawParams) (e
return *new(ethtypes.EthSubscriptionID), ErrNotSupported return *new(ethtypes.EthSubscriptionID), ErrNotSupported
} }
func (s *FullNodeStruct) EthSyncing(p0 context.Context) (ethtypes.EthSyncingResult, error) {
if s.Internal.EthSyncing == nil {
return *new(ethtypes.EthSyncingResult), ErrNotSupported
}
return s.Internal.EthSyncing(p0)
}
func (s *FullNodeStub) EthSyncing(p0 context.Context) (ethtypes.EthSyncingResult, error) {
return *new(ethtypes.EthSyncingResult), ErrNotSupported
}
func (s *FullNodeStruct) EthUninstallFilter(p0 context.Context, p1 ethtypes.EthFilterID) (bool, error) { func (s *FullNodeStruct) EthUninstallFilter(p0 context.Context, p1 ethtypes.EthFilterID) (bool, error) {
if s.Internal.EthUninstallFilter == nil { if s.Internal.EthUninstallFilter == nil {
return false, ErrNotSupported return false, ErrNotSupported
@@ -4472,6 +4395,28 @@ func (s *GatewayStub) EthGetStorageAt(p0 context.Context, p1 ethtypes.EthAddress
return *new(ethtypes.EthBytes), ErrNotSupported return *new(ethtypes.EthBytes), ErrNotSupported
} }
func (s *GatewayStruct) EthGetTransactionByBlockHashAndIndex(p0 context.Context, p1 ethtypes.EthHash, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) {
if s.Internal.EthGetTransactionByBlockHashAndIndex == nil {
return *new(ethtypes.EthTx), ErrNotSupported
}
return s.Internal.EthGetTransactionByBlockHashAndIndex(p0, p1, p2)
}
func (s *GatewayStub) EthGetTransactionByBlockHashAndIndex(p0 context.Context, p1 ethtypes.EthHash, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) {
return *new(ethtypes.EthTx), ErrNotSupported
}
func (s *GatewayStruct) EthGetTransactionByBlockNumberAndIndex(p0 context.Context, p1 ethtypes.EthUint64, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) {
if s.Internal.EthGetTransactionByBlockNumberAndIndex == nil {
return *new(ethtypes.EthTx), ErrNotSupported
}
return s.Internal.EthGetTransactionByBlockNumberAndIndex(p0, p1, p2)
}
func (s *GatewayStub) EthGetTransactionByBlockNumberAndIndex(p0 context.Context, p1 ethtypes.EthUint64, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) {
return *new(ethtypes.EthTx), ErrNotSupported
}
func (s *GatewayStruct) EthGetTransactionByHash(p0 context.Context, p1 *ethtypes.EthHash) (*ethtypes.EthTx, error) { func (s *GatewayStruct) EthGetTransactionByHash(p0 context.Context, p1 *ethtypes.EthHash) (*ethtypes.EthTx, error) {
if s.Internal.EthGetTransactionByHash == nil { if s.Internal.EthGetTransactionByHash == nil {
return nil, ErrNotSupported return nil, ErrNotSupported
@@ -4483,17 +4428,6 @@ func (s *GatewayStub) EthGetTransactionByHash(p0 context.Context, p1 *ethtypes.E
return nil, ErrNotSupported return nil, ErrNotSupported
} }
func (s *GatewayStruct) EthGetTransactionByHashLimited(p0 context.Context, p1 *ethtypes.EthHash, p2 abi.ChainEpoch) (*ethtypes.EthTx, error) {
if s.Internal.EthGetTransactionByHashLimited == nil {
return nil, ErrNotSupported
}
return s.Internal.EthGetTransactionByHashLimited(p0, p1, p2)
}
func (s *GatewayStub) EthGetTransactionByHashLimited(p0 context.Context, p1 *ethtypes.EthHash, p2 abi.ChainEpoch) (*ethtypes.EthTx, error) {
return nil, ErrNotSupported
}
func (s *GatewayStruct) EthGetTransactionCount(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthUint64, error) { func (s *GatewayStruct) EthGetTransactionCount(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthUint64, error) {
if s.Internal.EthGetTransactionCount == nil { if s.Internal.EthGetTransactionCount == nil {
return *new(ethtypes.EthUint64), ErrNotSupported return *new(ethtypes.EthUint64), ErrNotSupported
@@ -4527,17 +4461,6 @@ func (s *GatewayStub) EthGetTransactionReceipt(p0 context.Context, p1 ethtypes.E
return nil, ErrNotSupported return nil, ErrNotSupported
} }
func (s *GatewayStruct) EthGetTransactionReceiptLimited(p0 context.Context, p1 ethtypes.EthHash, p2 abi.ChainEpoch) (*EthTxReceipt, error) {
if s.Internal.EthGetTransactionReceiptLimited == nil {
return nil, ErrNotSupported
}
return s.Internal.EthGetTransactionReceiptLimited(p0, p1, p2)
}
func (s *GatewayStub) EthGetTransactionReceiptLimited(p0 context.Context, p1 ethtypes.EthHash, p2 abi.ChainEpoch) (*EthTxReceipt, error) {
return nil, ErrNotSupported
}
func (s *GatewayStruct) EthMaxPriorityFeePerGas(p0 context.Context) (ethtypes.EthBigInt, error) { func (s *GatewayStruct) EthMaxPriorityFeePerGas(p0 context.Context) (ethtypes.EthBigInt, error) {
if s.Internal.EthMaxPriorityFeePerGas == nil { if s.Internal.EthMaxPriorityFeePerGas == nil {
return *new(ethtypes.EthBigInt), ErrNotSupported return *new(ethtypes.EthBigInt), ErrNotSupported
@@ -4615,17 +4538,6 @@ func (s *GatewayStub) EthSubscribe(p0 context.Context, p1 jsonrpc.RawParams) (et
return *new(ethtypes.EthSubscriptionID), ErrNotSupported return *new(ethtypes.EthSubscriptionID), ErrNotSupported
} }
func (s *GatewayStruct) EthSyncing(p0 context.Context) (ethtypes.EthSyncingResult, error) {
if s.Internal.EthSyncing == nil {
return *new(ethtypes.EthSyncingResult), ErrNotSupported
}
return s.Internal.EthSyncing(p0)
}
func (s *GatewayStub) EthSyncing(p0 context.Context) (ethtypes.EthSyncingResult, error) {
return *new(ethtypes.EthSyncingResult), ErrNotSupported
}
func (s *GatewayStruct) EthUninstallFilter(p0 context.Context, p1 ethtypes.EthFilterID) (bool, error) { func (s *GatewayStruct) EthUninstallFilter(p0 context.Context, p1 ethtypes.EthFilterID) (bool, error) {
if s.Internal.EthUninstallFilter == nil { if s.Internal.EthUninstallFilter == nil {
return false, ErrNotSupported return false, ErrNotSupported
@@ -4648,17 +4560,6 @@ func (s *GatewayStub) EthUnsubscribe(p0 context.Context, p1 ethtypes.EthSubscrip
return false, ErrNotSupported return false, ErrNotSupported
} }
func (s *GatewayStruct) GasEstimateGasPremium(p0 context.Context, p1 uint64, p2 address.Address, p3 int64, p4 types.TipSetKey) (types.BigInt, error) {
if s.Internal.GasEstimateGasPremium == nil {
return *new(types.BigInt), ErrNotSupported
}
return s.Internal.GasEstimateGasPremium(p0, p1, p2, p3, p4)
}
func (s *GatewayStub) GasEstimateGasPremium(p0 context.Context, p1 uint64, p2 address.Address, p3 int64, p4 types.TipSetKey) (types.BigInt, error) {
return *new(types.BigInt), ErrNotSupported
}
func (s *GatewayStruct) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { func (s *GatewayStruct) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) {
if s.Internal.GasEstimateMessageGas == nil { if s.Internal.GasEstimateMessageGas == nil {
return nil, ErrNotSupported return nil, ErrNotSupported
@@ -4890,17 +4791,6 @@ func (s *GatewayStub) StateMinerProvingDeadline(p0 context.Context, p1 address.A
return nil, ErrNotSupported return nil, ErrNotSupported
} }
func (s *GatewayStruct) StateMinerSectorCount(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MinerSectors, error) {
if s.Internal.StateMinerSectorCount == nil {
return *new(MinerSectors), ErrNotSupported
}
return s.Internal.StateMinerSectorCount(p0, p1, p2)
}
func (s *GatewayStub) StateMinerSectorCount(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MinerSectors, error) {
return *new(MinerSectors), ErrNotSupported
}
func (s *GatewayStruct) StateNetworkName(p0 context.Context) (dtypes.NetworkName, error) { func (s *GatewayStruct) StateNetworkName(p0 context.Context) (dtypes.NetworkName, error) {
if s.Internal.StateNetworkName == nil { if s.Internal.StateNetworkName == nil {
return *new(dtypes.NetworkName), ErrNotSupported return *new(dtypes.NetworkName), ErrNotSupported
@@ -4934,17 +4824,6 @@ func (s *GatewayStub) StateReadState(p0 context.Context, p1 address.Address, p2
return nil, ErrNotSupported return nil, ErrNotSupported
} }
func (s *GatewayStruct) StateReplay(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*InvocResult, error) {
if s.Internal.StateReplay == nil {
return nil, ErrNotSupported
}
return s.Internal.StateReplay(p0, p1, p2)
}
func (s *GatewayStub) StateReplay(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*InvocResult, error) {
return nil, ErrNotSupported
}
func (s *GatewayStruct) StateSearchMsg(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) { func (s *GatewayStruct) StateSearchMsg(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) {
if s.Internal.StateSearchMsg == nil { if s.Internal.StateSearchMsg == nil {
return nil, ErrNotSupported return nil, ErrNotSupported
@@ -4978,17 +4857,6 @@ func (s *GatewayStub) StateVerifiedClientStatus(p0 context.Context, p1 address.A
return nil, ErrNotSupported return nil, ErrNotSupported
} }
func (s *GatewayStruct) StateVerifierStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) {
if s.Internal.StateVerifierStatus == nil {
return nil, ErrNotSupported
}
return s.Internal.StateVerifierStatus(p0, p1, p2)
}
func (s *GatewayStub) StateVerifierStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) {
return nil, ErrNotSupported
}
func (s *GatewayStruct) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) { func (s *GatewayStruct) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) {
if s.Internal.StateWaitMsg == nil { if s.Internal.StateWaitMsg == nil {
return nil, ErrNotSupported return nil, ErrNotSupported
@@ -5803,15 +5671,15 @@ func (s *StorageMinerStub) MarketListIncompleteDeals(p0 context.Context) ([]stor
return *new([]storagemarket.MinerDeal), ErrNotSupported return *new([]storagemarket.MinerDeal), ErrNotSupported
} }
func (s *StorageMinerStruct) MarketListRetrievalDeals(p0 context.Context) ([]struct{}, error) { func (s *StorageMinerStruct) MarketListRetrievalDeals(p0 context.Context) ([]retrievalmarket.ProviderDealState, error) {
if s.Internal.MarketListRetrievalDeals == nil { if s.Internal.MarketListRetrievalDeals == nil {
return *new([]struct{}), ErrNotSupported return *new([]retrievalmarket.ProviderDealState), ErrNotSupported
} }
return s.Internal.MarketListRetrievalDeals(p0) return s.Internal.MarketListRetrievalDeals(p0)
} }
func (s *StorageMinerStub) MarketListRetrievalDeals(p0 context.Context) ([]struct{}, error) { func (s *StorageMinerStub) MarketListRetrievalDeals(p0 context.Context) ([]retrievalmarket.ProviderDealState, error) {
return *new([]struct{}), ErrNotSupported return *new([]retrievalmarket.ProviderDealState), ErrNotSupported
} }
func (s *StorageMinerStruct) MarketPendingDeals(p0 context.Context) (PendingDealInfo, error) { func (s *StorageMinerStruct) MarketPendingDeals(p0 context.Context) (PendingDealInfo, error) {
@@ -6452,17 +6320,6 @@ func (s *StorageMinerStub) SectorTerminatePending(p0 context.Context) ([]abi.Sec
return *new([]abi.SectorID), ErrNotSupported return *new([]abi.SectorID), ErrNotSupported
} }
func (s *StorageMinerStruct) SectorUnseal(p0 context.Context, p1 abi.SectorNumber) error {
if s.Internal.SectorUnseal == nil {
return ErrNotSupported
}
return s.Internal.SectorUnseal(p0, p1)
}
func (s *StorageMinerStub) SectorUnseal(p0 context.Context, p1 abi.SectorNumber) error {
return ErrNotSupported
}
func (s *StorageMinerStruct) SectorsList(p0 context.Context) ([]abi.SectorNumber, error) { func (s *StorageMinerStruct) SectorsList(p0 context.Context) ([]abi.SectorNumber, error) {
if s.Internal.SectorsList == nil { if s.Internal.SectorsList == nil {
return *new([]abi.SectorNumber), ErrNotSupported return *new([]abi.SectorNumber), ErrNotSupported
+35 -41
View File
@@ -8,15 +8,13 @@ import (
"github.com/google/uuid" "github.com/google/uuid"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
"github.com/ipfs/go-graphsync" "github.com/ipfs/go-graphsync"
"github.com/ipld/go-ipld-prime"
"github.com/ipld/go-ipld-prime/codec/dagjson"
pubsub "github.com/libp2p/go-libp2p-pubsub" pubsub "github.com/libp2p/go-libp2p-pubsub"
"github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-libp2p/core/network"
"github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/peer"
ma "github.com/multiformats/go-multiaddr" ma "github.com/multiformats/go-multiaddr"
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
datatransfer "github.com/filecoin-project/go-data-transfer/v2" datatransfer "github.com/filecoin-project/go-data-transfer"
"github.com/filecoin-project/go-fil-markets/retrievalmarket" "github.com/filecoin-project/go-fil-markets/retrievalmarket"
"github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/builtin/v9/miner" "github.com/filecoin-project/go-state-types/builtin/v9/miner"
@@ -112,12 +110,16 @@ func NewDataTransferChannel(hostID peer.ID, channelState datatransfer.ChannelSta
IsSender: channelState.Sender() == hostID, IsSender: channelState.Sender() == hostID,
Message: channelState.Message(), Message: channelState.Message(),
} }
voucher := channelState.Voucher() stringer, ok := channelState.Voucher().(fmt.Stringer)
voucherJSON, err := ipld.Encode(voucher.Voucher, dagjson.Encode) if ok {
if err != nil { channel.Voucher = stringer.String()
channel.Voucher = fmt.Errorf("Voucher Serialization: %w", err).Error()
} else { } else {
channel.Voucher = string(voucherJSON) voucherJSON, err := json.Marshal(channelState.Voucher())
if err != nil {
channel.Voucher = fmt.Errorf("Voucher Serialization: %w", err).Error()
} else {
channel.Voucher = string(voucherJSON)
}
} }
if channel.IsSender { if channel.IsSender {
channel.IsInitiator = !channelState.IsPull() channel.IsInitiator = !channelState.IsPull()
@@ -314,30 +316,31 @@ type NetworkParams struct {
} }
type ForkUpgradeParams struct { type ForkUpgradeParams struct {
UpgradeSmokeHeight abi.ChainEpoch UpgradeSmokeHeight abi.ChainEpoch
UpgradeBreezeHeight abi.ChainEpoch UpgradeBreezeHeight abi.ChainEpoch
UpgradeIgnitionHeight abi.ChainEpoch UpgradeIgnitionHeight abi.ChainEpoch
UpgradeLiftoffHeight abi.ChainEpoch UpgradeLiftoffHeight abi.ChainEpoch
UpgradeAssemblyHeight abi.ChainEpoch UpgradeAssemblyHeight abi.ChainEpoch
UpgradeRefuelHeight abi.ChainEpoch UpgradeRefuelHeight abi.ChainEpoch
UpgradeTapeHeight abi.ChainEpoch UpgradeTapeHeight abi.ChainEpoch
UpgradeKumquatHeight abi.ChainEpoch UpgradeKumquatHeight abi.ChainEpoch
BreezeGasTampingDuration abi.ChainEpoch UpgradePriceListOopsHeight abi.ChainEpoch
UpgradeCalicoHeight abi.ChainEpoch BreezeGasTampingDuration abi.ChainEpoch
UpgradePersianHeight abi.ChainEpoch UpgradeCalicoHeight abi.ChainEpoch
UpgradeOrangeHeight abi.ChainEpoch UpgradePersianHeight abi.ChainEpoch
UpgradeClausHeight abi.ChainEpoch UpgradeOrangeHeight abi.ChainEpoch
UpgradeTrustHeight abi.ChainEpoch UpgradeClausHeight abi.ChainEpoch
UpgradeNorwegianHeight abi.ChainEpoch UpgradeTrustHeight abi.ChainEpoch
UpgradeTurboHeight abi.ChainEpoch UpgradeNorwegianHeight abi.ChainEpoch
UpgradeHyperdriveHeight abi.ChainEpoch UpgradeTurboHeight abi.ChainEpoch
UpgradeChocolateHeight abi.ChainEpoch UpgradeHyperdriveHeight abi.ChainEpoch
UpgradeOhSnapHeight abi.ChainEpoch UpgradeChocolateHeight abi.ChainEpoch
UpgradeSkyrHeight abi.ChainEpoch UpgradeOhSnapHeight abi.ChainEpoch
UpgradeSharkHeight abi.ChainEpoch UpgradeSkyrHeight abi.ChainEpoch
UpgradeHyggeHeight abi.ChainEpoch UpgradeSharkHeight abi.ChainEpoch
UpgradeLightningHeight abi.ChainEpoch UpgradeHyggeHeight abi.ChainEpoch
UpgradeThunderHeight abi.ChainEpoch UpgradeLightningHeight abi.ChainEpoch
UpgradeThunderHeight abi.ChainEpoch
} }
type NonceMapType map[address.Address]uint64 type NonceMapType map[address.Address]uint64
@@ -397,12 +400,3 @@ func (m *MsgUuidMapType) UnmarshalJSON(b []byte) error {
} }
return nil return nil
} }
// ChainExportConfig holds configuration for chain ranged exports.
type ChainExportConfig struct {
WriteBufferSize int
NumWorkers int
IncludeMessages bool
IncludeReceipts bool
IncludeStateRoots bool
}
+2 -2
View File
@@ -3,14 +3,14 @@ package v0api
import ( import (
"context" "context"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
blocks "github.com/ipfs/go-libipfs/blocks"
textselector "github.com/ipld/go-ipld-selector-text-lite" textselector "github.com/ipld/go-ipld-selector-text-lite"
"github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/peer"
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-bitfield" "github.com/filecoin-project/go-bitfield"
datatransfer "github.com/filecoin-project/go-data-transfer/v2" datatransfer "github.com/filecoin-project/go-data-transfer"
"github.com/filecoin-project/go-fil-markets/retrievalmarket" "github.com/filecoin-project/go-fil-markets/retrievalmarket"
"github.com/filecoin-project/go-fil-markets/storagemarket" "github.com/filecoin-project/go-fil-markets/storagemarket"
"github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/abi"
+1 -4
View File
@@ -3,8 +3,8 @@ package v0api
import ( import (
"context" "context"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
blocks "github.com/ipfs/go-libipfs/blocks"
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/abi"
@@ -35,9 +35,6 @@ import (
// * Generate openrpc blobs // * Generate openrpc blobs
type Gateway interface { type Gateway interface {
StateMinerSectorCount(context.Context, address.Address, types.TipSetKey) (api.MinerSectors, error)
GasEstimateGasPremium(context.Context, uint64, address.Address, int64, types.TipSetKey) (types.BigInt, error)
StateReplay(context.Context, types.TipSetKey, cid.Cid) (*api.InvocResult, error)
ChainHasObj(context.Context, cid.Cid) (bool, error) ChainHasObj(context.Context, cid.Cid) (bool, error)
ChainPutObj(context.Context, blocks.Block) error ChainPutObj(context.Context, blocks.Block) error
ChainHead(ctx context.Context) (*types.TipSet, error) ChainHead(ctx context.Context) (*types.TipSet, error)
+2 -41
View File
@@ -5,14 +5,14 @@ package v0api
import ( import (
"context" "context"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
blocks "github.com/ipfs/go-libipfs/blocks"
"github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/peer"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-bitfield" "github.com/filecoin-project/go-bitfield"
datatransfer "github.com/filecoin-project/go-data-transfer/v2" datatransfer "github.com/filecoin-project/go-data-transfer"
"github.com/filecoin-project/go-fil-markets/retrievalmarket" "github.com/filecoin-project/go-fil-markets/retrievalmarket"
"github.com/filecoin-project/go-fil-markets/storagemarket" "github.com/filecoin-project/go-fil-markets/storagemarket"
"github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/abi"
@@ -449,8 +449,6 @@ type GatewayMethods struct {
ChainReadObj func(p0 context.Context, p1 cid.Cid) ([]byte, error) `` ChainReadObj func(p0 context.Context, p1 cid.Cid) ([]byte, error) ``
GasEstimateGasPremium func(p0 context.Context, p1 uint64, p2 address.Address, p3 int64, p4 types.TipSetKey) (types.BigInt, error) ``
GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) `` GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) ``
MpoolGetNonce func(p0 context.Context, p1 address.Address) (uint64, error) `` MpoolGetNonce func(p0 context.Context, p1 address.Address) (uint64, error) ``
@@ -489,14 +487,10 @@ type GatewayMethods struct {
StateMinerProvingDeadline func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) `` StateMinerProvingDeadline func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) ``
StateMinerSectorCount func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MinerSectors, error) ``
StateNetworkName func(p0 context.Context) (dtypes.NetworkName, error) `` StateNetworkName func(p0 context.Context) (dtypes.NetworkName, error) ``
StateNetworkVersion func(p0 context.Context, p1 types.TipSetKey) (abinetwork.Version, error) `` StateNetworkVersion func(p0 context.Context, p1 types.TipSetKey) (abinetwork.Version, error) ``
StateReplay func(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*api.InvocResult, error) ``
StateSearchMsg func(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) `` StateSearchMsg func(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) ``
StateSectorGetInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) `` StateSectorGetInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) ``
@@ -2680,17 +2674,6 @@ func (s *GatewayStub) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, erro
return *new([]byte), ErrNotSupported return *new([]byte), ErrNotSupported
} }
func (s *GatewayStruct) GasEstimateGasPremium(p0 context.Context, p1 uint64, p2 address.Address, p3 int64, p4 types.TipSetKey) (types.BigInt, error) {
if s.Internal.GasEstimateGasPremium == nil {
return *new(types.BigInt), ErrNotSupported
}
return s.Internal.GasEstimateGasPremium(p0, p1, p2, p3, p4)
}
func (s *GatewayStub) GasEstimateGasPremium(p0 context.Context, p1 uint64, p2 address.Address, p3 int64, p4 types.TipSetKey) (types.BigInt, error) {
return *new(types.BigInt), ErrNotSupported
}
func (s *GatewayStruct) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { func (s *GatewayStruct) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) {
if s.Internal.GasEstimateMessageGas == nil { if s.Internal.GasEstimateMessageGas == nil {
return nil, ErrNotSupported return nil, ErrNotSupported
@@ -2900,17 +2883,6 @@ func (s *GatewayStub) StateMinerProvingDeadline(p0 context.Context, p1 address.A
return nil, ErrNotSupported return nil, ErrNotSupported
} }
func (s *GatewayStruct) StateMinerSectorCount(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MinerSectors, error) {
if s.Internal.StateMinerSectorCount == nil {
return *new(api.MinerSectors), ErrNotSupported
}
return s.Internal.StateMinerSectorCount(p0, p1, p2)
}
func (s *GatewayStub) StateMinerSectorCount(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MinerSectors, error) {
return *new(api.MinerSectors), ErrNotSupported
}
func (s *GatewayStruct) StateNetworkName(p0 context.Context) (dtypes.NetworkName, error) { func (s *GatewayStruct) StateNetworkName(p0 context.Context) (dtypes.NetworkName, error) {
if s.Internal.StateNetworkName == nil { if s.Internal.StateNetworkName == nil {
return *new(dtypes.NetworkName), ErrNotSupported return *new(dtypes.NetworkName), ErrNotSupported
@@ -2933,17 +2905,6 @@ func (s *GatewayStub) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey
return *new(abinetwork.Version), ErrNotSupported return *new(abinetwork.Version), ErrNotSupported
} }
func (s *GatewayStruct) StateReplay(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*api.InvocResult, error) {
if s.Internal.StateReplay == nil {
return nil, ErrNotSupported
}
return s.Internal.StateReplay(p0, p1, p2)
}
func (s *GatewayStub) StateReplay(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*api.InvocResult, error) {
return nil, ErrNotSupported
}
func (s *GatewayStruct) StateSearchMsg(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) { func (s *GatewayStruct) StateSearchMsg(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) {
if s.Internal.StateSearchMsg == nil { if s.Internal.StateSearchMsg == nil {
return nil, ErrNotSupported return nil, ErrNotSupported
+2 -2
View File
@@ -11,8 +11,8 @@ import (
gomock "github.com/golang/mock/gomock" gomock "github.com/golang/mock/gomock"
uuid "github.com/google/uuid" uuid "github.com/google/uuid"
blocks "github.com/ipfs/go-block-format"
cid "github.com/ipfs/go-cid" cid "github.com/ipfs/go-cid"
blocks "github.com/ipfs/go-libipfs/blocks"
metrics "github.com/libp2p/go-libp2p/core/metrics" metrics "github.com/libp2p/go-libp2p/core/metrics"
network0 "github.com/libp2p/go-libp2p/core/network" network0 "github.com/libp2p/go-libp2p/core/network"
peer "github.com/libp2p/go-libp2p/core/peer" peer "github.com/libp2p/go-libp2p/core/peer"
@@ -20,7 +20,7 @@ import (
address "github.com/filecoin-project/go-address" address "github.com/filecoin-project/go-address"
bitfield "github.com/filecoin-project/go-bitfield" bitfield "github.com/filecoin-project/go-bitfield"
datatransfer "github.com/filecoin-project/go-data-transfer/v2" datatransfer "github.com/filecoin-project/go-data-transfer"
retrievalmarket "github.com/filecoin-project/go-fil-markets/retrievalmarket" retrievalmarket "github.com/filecoin-project/go-fil-markets/retrievalmarket"
storagemarket "github.com/filecoin-project/go-fil-markets/storagemarket" storagemarket "github.com/filecoin-project/go-fil-markets/storagemarket"
auth "github.com/filecoin-project/go-jsonrpc/auth" auth "github.com/filecoin-project/go-jsonrpc/auth"
+1 -1
View File
@@ -3,8 +3,8 @@ package blockstore
import ( import (
"context" "context"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
blocks "github.com/ipfs/go-libipfs/blocks"
"golang.org/x/xerrors" "golang.org/x/xerrors"
) )
+1 -1
View File
@@ -5,9 +5,9 @@ import (
"sync" "sync"
"time" "time"
block "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
ipld "github.com/ipfs/go-ipld-format" ipld "github.com/ipfs/go-ipld-format"
block "github.com/ipfs/go-libipfs/blocks"
"golang.org/x/xerrors" "golang.org/x/xerrors"
) )
+7 -121
View File
@@ -13,14 +13,13 @@ import (
"github.com/dgraph-io/badger/v2" "github.com/dgraph-io/badger/v2"
"github.com/dgraph-io/badger/v2/options" "github.com/dgraph-io/badger/v2/options"
"github.com/dgraph-io/badger/v2/pb" "github.com/dgraph-io/badger/v2/pb"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
ipld "github.com/ipfs/go-ipld-format" ipld "github.com/ipfs/go-ipld-format"
blocks "github.com/ipfs/go-libipfs/blocks"
logger "github.com/ipfs/go-log/v2" logger "github.com/ipfs/go-log/v2"
pool "github.com/libp2p/go-buffer-pool" pool "github.com/libp2p/go-buffer-pool"
"github.com/multiformats/go-base32" "github.com/multiformats/go-base32"
"go.uber.org/zap" "go.uber.org/zap"
"golang.org/x/xerrors"
"github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/blockstore"
) )
@@ -45,8 +44,7 @@ const (
// MemoryMap is equivalent to badger/options.MemoryMap. // MemoryMap is equivalent to badger/options.MemoryMap.
MemoryMap = options.MemoryMap MemoryMap = options.MemoryMap
// LoadToRAM is equivalent to badger/options.LoadToRAM. // LoadToRAM is equivalent to badger/options.LoadToRAM.
LoadToRAM = options.LoadToRAM LoadToRAM = options.LoadToRAM
defaultGCThreshold = 0.125
) )
// Options embeds the badger options themselves, and augments them with // Options embeds the badger options themselves, and augments them with
@@ -396,9 +394,6 @@ func (b *Blockstore) doCopy(from, to *badger.DB) error {
if workers < 2 { if workers < 2 {
workers = 2 workers = 2
} }
if workers > 8 {
workers = 8
}
stream := from.NewStream() stream := from.NewStream()
stream.NumGo = workers stream.NumGo = workers
@@ -444,7 +439,7 @@ func (b *Blockstore) deleteDB(path string) {
} }
} }
func (b *Blockstore) onlineGC(ctx context.Context, threshold float64, checkFreq time.Duration, check func() error) error { func (b *Blockstore) onlineGC() error {
b.lockDB() b.lockDB()
defer b.unlockDB() defer b.unlockDB()
@@ -453,26 +448,14 @@ func (b *Blockstore) onlineGC(ctx context.Context, threshold float64, checkFreq
if nworkers < 2 { if nworkers < 2 {
nworkers = 2 nworkers = 2
} }
if nworkers > 7 { // max out at 1 goroutine per badger level
nworkers = 7
}
err := b.db.Flatten(nworkers) err := b.db.Flatten(nworkers)
if err != nil { if err != nil {
return err return err
} }
checkTick := time.NewTimer(checkFreq)
defer checkTick.Stop()
for err == nil { for err == nil {
select { err = b.db.RunValueLogGC(0.125)
case <-ctx.Done():
err = ctx.Err()
case <-checkTick.C:
err = check()
checkTick.Reset(checkFreq)
default:
err = b.db.RunValueLogGC(threshold)
}
} }
if err == badger.ErrNoRewrite { if err == badger.ErrNoRewrite {
@@ -485,7 +468,7 @@ func (b *Blockstore) onlineGC(ctx context.Context, threshold float64, checkFreq
// CollectGarbage compacts and runs garbage collection on the value log; // CollectGarbage compacts and runs garbage collection on the value log;
// implements the BlockstoreGC trait // implements the BlockstoreGC trait
func (b *Blockstore) CollectGarbage(ctx context.Context, opts ...blockstore.BlockstoreGCOption) error { func (b *Blockstore) CollectGarbage(opts ...blockstore.BlockstoreGCOption) error {
if err := b.access(); err != nil { if err := b.access(); err != nil {
return err return err
} }
@@ -502,58 +485,8 @@ func (b *Blockstore) CollectGarbage(ctx context.Context, opts ...blockstore.Bloc
if options.FullGC { if options.FullGC {
return b.movingGC() return b.movingGC()
} }
threshold := options.Threshold
if threshold == 0 {
threshold = defaultGCThreshold
}
checkFreq := options.CheckFreq
if checkFreq < 30*time.Second { // disallow checking more frequently than block time
checkFreq = 30 * time.Second
}
check := options.Check
if check == nil {
check = func() error {
return nil
}
}
return b.onlineGC(ctx, threshold, checkFreq, check)
}
// GCOnce runs garbage collection on the value log; return b.onlineGC()
// implements BlockstoreGCOnce trait
func (b *Blockstore) GCOnce(ctx context.Context, opts ...blockstore.BlockstoreGCOption) error {
if err := b.access(); err != nil {
return err
}
defer b.viewers.Done()
var options blockstore.BlockstoreGCOptions
for _, opt := range opts {
err := opt(&options)
if err != nil {
return err
}
}
if options.FullGC {
return xerrors.Errorf("FullGC option specified for GCOnce but full GC is non incremental")
}
threshold := options.Threshold
if threshold == 0 {
threshold = defaultGCThreshold
}
b.lockDB()
defer b.unlockDB()
// Note no compaction needed before single GC as we will hit at most one vlog anyway
err := b.db.RunValueLogGC(threshold)
if err == badger.ErrNoRewrite {
// not really an error in this case, it signals the end of GC
return nil
}
return err
} }
// Size returns the aggregate size of the blockstore // Size returns the aggregate size of the blockstore
@@ -618,18 +551,6 @@ func (b *Blockstore) View(ctx context.Context, cid cid.Cid, fn func([]byte) erro
}) })
} }
func (b *Blockstore) Flush(context.Context) error {
if err := b.access(); err != nil {
return err
}
defer b.viewers.Done()
b.lockDB()
defer b.unlockDB()
return b.db.Sync()
}
// Has implements Blockstore.Has. // Has implements Blockstore.Has.
func (b *Blockstore) Has(ctx context.Context, cid cid.Cid) (bool, error) { func (b *Blockstore) Has(ctx context.Context, cid cid.Cid) (bool, error) {
if err := b.access(); err != nil { if err := b.access(); err != nil {
@@ -746,20 +667,6 @@ func (b *Blockstore) Put(ctx context.Context, block blocks.Block) error {
} }
put := func(db *badger.DB) error { put := func(db *badger.DB) error {
// Check if we have it before writing it.
switch err := db.View(func(txn *badger.Txn) error {
_, err := txn.Get(k)
return err
}); err {
case badger.ErrKeyNotFound:
case nil:
// Already exists, skip the put.
return nil
default:
return err
}
// Then write it.
err := db.Update(func(txn *badger.Txn) error { err := db.Update(func(txn *badger.Txn) error {
return txn.Set(k, block.RawData()) return txn.Set(k, block.RawData())
}) })
@@ -815,33 +722,12 @@ func (b *Blockstore) PutMany(ctx context.Context, blocks []blocks.Block) error {
keys = append(keys, k) keys = append(keys, k)
} }
err := b.db.View(func(txn *badger.Txn) error {
for i, k := range keys {
switch _, err := txn.Get(k); err {
case badger.ErrKeyNotFound:
case nil:
keys[i] = nil
default:
// Something is actually wrong
return err
}
}
return nil
})
if err != nil {
return err
}
put := func(db *badger.DB) error { put := func(db *badger.DB) error {
batch := db.NewWriteBatch() batch := db.NewWriteBatch()
defer batch.Cancel() defer batch.Cancel()
for i, block := range blocks { for i, block := range blocks {
k := keys[i] k := keys[i]
if k == nil {
// skipped because we already have it.
continue
}
if err := batch.Set(k, block.RawData()); err != nil { if err := batch.Set(k, block.RawData()); err != nil {
return err return err
} }
+3 -3
View File
@@ -10,8 +10,8 @@ import (
"strings" "strings"
"testing" "testing"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
blocks "github.com/ipfs/go-libipfs/blocks"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
@@ -145,7 +145,7 @@ func testMove(t *testing.T, optsF func(string) Options) {
return nil return nil
}) })
g.Go(func() error { g.Go(func() error {
return db.CollectGarbage(ctx, blockstore.WithFullGC(true)) return db.CollectGarbage(blockstore.WithFullGC(true))
}) })
err = g.Wait() err = g.Wait()
@@ -230,7 +230,7 @@ func testMove(t *testing.T, optsF func(string) Options) {
checkPath() checkPath()
// now do another FullGC to test the double move and following of symlinks // now do another FullGC to test the double move and following of symlinks
if err := db.CollectGarbage(ctx, blockstore.WithFullGC(true)); err != nil { if err := db.CollectGarbage(blockstore.WithFullGC(true)); err != nil {
t.Fatal(err) t.Fatal(err)
} }
+1 -1
View File
@@ -9,10 +9,10 @@ import (
"strings" "strings"
"testing" "testing"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
u "github.com/ipfs/go-ipfs-util" u "github.com/ipfs/go-ipfs-util"
ipld "github.com/ipfs/go-ipld-format" ipld "github.com/ipfs/go-ipld-format"
blocks "github.com/ipfs/go-libipfs/blocks"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/blockstore"
+1 -46
View File
@@ -2,7 +2,6 @@ package blockstore
import ( import (
"context" "context"
"time"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
ds "github.com/ipfs/go-datastore" ds "github.com/ipfs/go-datastore"
@@ -19,7 +18,6 @@ type Blockstore interface {
blockstore.Blockstore blockstore.Blockstore
blockstore.Viewer blockstore.Viewer
BatchDeleter BatchDeleter
Flusher
} }
// BasicBlockstore is an alias to the original IPFS Blockstore. // BasicBlockstore is an alias to the original IPFS Blockstore.
@@ -27,10 +25,6 @@ type BasicBlockstore = blockstore.Blockstore
type Viewer = blockstore.Viewer type Viewer = blockstore.Viewer
type Flusher interface {
Flush(context.Context) error
}
type BatchDeleter interface { type BatchDeleter interface {
DeleteMany(ctx context.Context, cids []cid.Cid) error DeleteMany(ctx context.Context, cids []cid.Cid) error
} }
@@ -42,12 +36,7 @@ type BlockstoreIterator interface {
// BlockstoreGC is a trait for blockstores that support online garbage collection // BlockstoreGC is a trait for blockstores that support online garbage collection
type BlockstoreGC interface { type BlockstoreGC interface {
CollectGarbage(ctx context.Context, options ...BlockstoreGCOption) error CollectGarbage(options ...BlockstoreGCOption) error
}
// BlockstoreGCOnce is a trait for a blockstore that supports incremental online garbage collection
type BlockstoreGCOnce interface {
GCOnce(ctx context.Context, options ...BlockstoreGCOption) error
} }
// BlockstoreGCOption is a functional interface for controlling blockstore GC options // BlockstoreGCOption is a functional interface for controlling blockstore GC options
@@ -56,12 +45,6 @@ type BlockstoreGCOption = func(*BlockstoreGCOptions) error
// BlockstoreGCOptions is a struct with GC options // BlockstoreGCOptions is a struct with GC options
type BlockstoreGCOptions struct { type BlockstoreGCOptions struct {
FullGC bool FullGC bool
// fraction of garbage in badger vlog before its worth processing in online GC
Threshold float64
// how often to call the check function
CheckFreq time.Duration
// function to call periodically to pause or early terminate GC
Check func() error
} }
func WithFullGC(fullgc bool) BlockstoreGCOption { func WithFullGC(fullgc bool) BlockstoreGCOption {
@@ -71,27 +54,6 @@ func WithFullGC(fullgc bool) BlockstoreGCOption {
} }
} }
func WithThreshold(threshold float64) BlockstoreGCOption {
return func(opts *BlockstoreGCOptions) error {
opts.Threshold = threshold
return nil
}
}
func WithCheckFreq(f time.Duration) BlockstoreGCOption {
return func(opts *BlockstoreGCOptions) error {
opts.CheckFreq = f
return nil
}
}
func WithCheck(check func() error) BlockstoreGCOption {
return func(opts *BlockstoreGCOptions) error {
opts.Check = check
return nil
}
}
// BlockstoreSize is a trait for on-disk blockstores that can report their size // BlockstoreSize is a trait for on-disk blockstores that can report their size
type BlockstoreSize interface { type BlockstoreSize interface {
Size() (int64, error) Size() (int64, error)
@@ -130,13 +92,6 @@ type adaptedBlockstore struct {
var _ Blockstore = (*adaptedBlockstore)(nil) var _ Blockstore = (*adaptedBlockstore)(nil)
func (a *adaptedBlockstore) Flush(ctx context.Context) error {
if flusher, canFlush := a.Blockstore.(Flusher); canFlush {
return flusher.Flush(ctx)
}
return nil
}
func (a *adaptedBlockstore) View(ctx context.Context, cid cid.Cid, callback func([]byte) error) error { func (a *adaptedBlockstore) View(ctx context.Context, cid cid.Cid, callback func([]byte) error) error {
blk, err := a.Get(ctx, cid) blk, err := a.Get(ctx, cid)
if err != nil { if err != nil {
+1 -3
View File
@@ -4,9 +4,9 @@ import (
"context" "context"
"os" "os"
block "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
ipld "github.com/ipfs/go-ipld-format" ipld "github.com/ipfs/go-ipld-format"
block "github.com/ipfs/go-libipfs/blocks"
) )
// buflog is a logger for the buffered blockstore. It is subscoped from the // buflog is a logger for the buffered blockstore. It is subscoped from the
@@ -46,8 +46,6 @@ var (
_ Viewer = (*BufferedBlockstore)(nil) _ Viewer = (*BufferedBlockstore)(nil)
) )
func (bs *BufferedBlockstore) Flush(ctx context.Context) error { return bs.write.Flush(ctx) }
func (bs *BufferedBlockstore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) { func (bs *BufferedBlockstore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) {
a, err := bs.read.AllKeysChan(ctx) a, err := bs.read.AllKeysChan(ctx)
if err != nil { if err != nil {
+1 -5
View File
@@ -4,8 +4,8 @@ import (
"context" "context"
"io" "io"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
blocks "github.com/ipfs/go-libipfs/blocks"
) )
var _ Blockstore = (*discardstore)(nil) var _ Blockstore = (*discardstore)(nil)
@@ -38,10 +38,6 @@ func (b *discardstore) View(ctx context.Context, cid cid.Cid, f func([]byte) err
return b.bs.View(ctx, cid, f) return b.bs.View(ctx, cid, f)
} }
func (b *discardstore) Flush(ctx context.Context) error {
return nil
}
func (b *discardstore) Put(ctx context.Context, blk blocks.Block) error { func (b *discardstore) Put(ctx context.Context, blk blocks.Block) error {
return nil return nil
} }
+1 -1
View File
@@ -5,9 +5,9 @@ import (
"sync" "sync"
"time" "time"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
ipld "github.com/ipfs/go-ipld-format" ipld "github.com/ipfs/go-ipld-format"
blocks "github.com/ipfs/go-libipfs/blocks"
"golang.org/x/xerrors" "golang.org/x/xerrors"
) )
+1 -5
View File
@@ -4,8 +4,8 @@ import (
"context" "context"
"io" "io"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
blocks "github.com/ipfs/go-libipfs/blocks"
mh "github.com/multiformats/go-multihash" mh "github.com/multiformats/go-multihash"
"golang.org/x/xerrors" "golang.org/x/xerrors"
) )
@@ -179,7 +179,3 @@ func (b *idstore) Close() error {
} }
return nil return nil
} }
func (b *idstore) Flush(ctx context.Context) error {
return b.bs.Flush(ctx)
}
+3 -3
View File
@@ -3,11 +3,11 @@ package blockstore
import ( import (
"bytes" "bytes"
"context" "context"
"io" "io/ioutil"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
httpapi "github.com/ipfs/go-ipfs-http-client" httpapi "github.com/ipfs/go-ipfs-http-client"
blocks "github.com/ipfs/go-libipfs/blocks"
iface "github.com/ipfs/interface-go-ipfs-core" iface "github.com/ipfs/interface-go-ipfs-core"
"github.com/ipfs/interface-go-ipfs-core/options" "github.com/ipfs/interface-go-ipfs-core/options"
"github.com/ipfs/interface-go-ipfs-core/path" "github.com/ipfs/interface-go-ipfs-core/path"
@@ -103,7 +103,7 @@ func (i *IPFSBlockstore) Get(ctx context.Context, cid cid.Cid) (blocks.Block, er
return nil, xerrors.Errorf("getting ipfs block: %w", err) return nil, xerrors.Errorf("getting ipfs block: %w", err)
} }
data, err := io.ReadAll(rd) data, err := ioutil.ReadAll(rd)
if err != nil { if err != nil {
return nil, err return nil, err
} }
+1 -3
View File
@@ -3,9 +3,9 @@ package blockstore
import ( import (
"context" "context"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
ipld "github.com/ipfs/go-ipld-format" ipld "github.com/ipfs/go-ipld-format"
blocks "github.com/ipfs/go-libipfs/blocks"
) )
// NewMemory returns a temporary memory-backed blockstore. // NewMemory returns a temporary memory-backed blockstore.
@@ -17,8 +17,6 @@ func NewMemory() MemBlockstore {
// To match behavior of badger blockstore we index by multihash only. // To match behavior of badger blockstore we index by multihash only.
type MemBlockstore map[string]blocks.Block type MemBlockstore map[string]blocks.Block
func (MemBlockstore) Flush(context.Context) error { return nil }
func (m MemBlockstore) DeleteBlock(ctx context.Context, k cid.Cid) error { func (m MemBlockstore) DeleteBlock(ctx context.Context, k cid.Cid) error {
delete(m, string(k.Hash())) delete(m, string(k.Hash()))
return nil return nil
+1 -1
View File
@@ -4,8 +4,8 @@ import (
"context" "context"
"testing" "testing"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
blocks "github.com/ipfs/go-libipfs/blocks"
mh "github.com/multiformats/go-multihash" mh "github.com/multiformats/go-multihash"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
+1 -3
View File
@@ -8,9 +8,9 @@ import (
"sync" "sync"
"sync/atomic" "sync/atomic"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
ipld "github.com/ipfs/go-ipld-format" ipld "github.com/ipfs/go-ipld-format"
blocks "github.com/ipfs/go-libipfs/blocks"
"github.com/libp2p/go-msgio" "github.com/libp2p/go-msgio"
cbg "github.com/whyrusleeping/cbor-gen" cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors" "golang.org/x/xerrors"
@@ -410,8 +410,6 @@ func (n *NetworkStore) HashOnRead(enabled bool) {
return return
} }
func (*NetworkStore) Flush(context.Context) error { return nil }
func (n *NetworkStore) Stop(ctx context.Context) error { func (n *NetworkStore) Stop(ctx context.Context) error {
close(n.closing) close(n.closing)
+1 -1
View File
@@ -5,9 +5,9 @@ import (
"context" "context"
"encoding/binary" "encoding/binary"
block "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
ipld "github.com/ipfs/go-ipld-format" ipld "github.com/ipfs/go-ipld-format"
block "github.com/ipfs/go-libipfs/blocks"
"github.com/libp2p/go-msgio" "github.com/libp2p/go-msgio"
cbg "github.com/whyrusleeping/cbor-gen" cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors" "golang.org/x/xerrors"
+1 -1
View File
@@ -6,8 +6,8 @@ import (
"io" "io"
"testing" "testing"
block "github.com/ipfs/go-block-format"
ipld "github.com/ipfs/go-ipld-format" ipld "github.com/ipfs/go-ipld-format"
block "github.com/ipfs/go-libipfs/blocks"
"github.com/libp2p/go-msgio" "github.com/libp2p/go-msgio"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
+1 -1
View File
@@ -12,8 +12,8 @@ import (
"sync" "sync"
"time" "time"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
blocks "github.com/ipfs/go-libipfs/blocks"
"go.uber.org/multierr" "go.uber.org/multierr"
"golang.org/x/xerrors" "golang.org/x/xerrors"
) )
+1 -3
View File
@@ -11,8 +11,6 @@ import (
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
"go.uber.org/zap" "go.uber.org/zap"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/lotus/system"
) )
type BadgerMarkSetEnv struct { type BadgerMarkSetEnv struct {
@@ -351,7 +349,7 @@ func (s *BadgerMarkSet) write(seqno int) (err error) {
persist := s.persist persist := s.persist
s.mx.RUnlock() s.mx.RUnlock()
if persist && !system.BadgerFsyncDisable { // WARNING: disabling sync makes recovery from crash during critical section unsound if persist {
return s.db.Sync() return s.db.Sync()
} }
+7 -62
View File
@@ -8,10 +8,10 @@ import (
"sync/atomic" "sync/atomic"
"time" "time"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
dstore "github.com/ipfs/go-datastore" dstore "github.com/ipfs/go-datastore"
ipld "github.com/ipfs/go-ipld-format" ipld "github.com/ipfs/go-ipld-format"
blocks "github.com/ipfs/go-libipfs/blocks"
logging "github.com/ipfs/go-log/v2" logging "github.com/ipfs/go-log/v2"
"go.opencensus.io/stats" "go.opencensus.io/stats"
"go.uber.org/multierr" "go.uber.org/multierr"
@@ -115,23 +115,6 @@ type Config struct {
// A positive value is the number of compactions before a full GC is performed; // A positive value is the number of compactions before a full GC is performed;
// a value of 1 will perform full GC in every compaction. // a value of 1 will perform full GC in every compaction.
HotStoreFullGCFrequency uint64 HotStoreFullGCFrequency uint64
// HotstoreMaxSpaceTarget suggests the max allowed space the hotstore can take.
// This is not a hard limit, it is possible for the hotstore to exceed the target
// for example if state grows massively between compactions. The splitstore
// will make a best effort to avoid overflowing the target and in practice should
// never overflow. This field is used when doing GC at the end of a compaction to
// adaptively choose moving GC
HotstoreMaxSpaceTarget uint64
// Moving GC will be triggered when total moving size exceeds
// HotstoreMaxSpaceTarget - HotstoreMaxSpaceThreshold
HotstoreMaxSpaceThreshold uint64
// Safety buffer to prevent moving GC from overflowing disk.
// Moving GC will not occur when total moving size exceeds
// HotstoreMaxSpaceTarget - HotstoreMaxSpaceSafetyBuffer
HotstoreMaxSpaceSafetyBuffer uint64
} }
// ChainAccessor allows the Splitstore to access the chain. It will most likely // ChainAccessor allows the Splitstore to access the chain. It will most likely
@@ -164,7 +147,7 @@ type SplitStore struct {
path string path string
mx sync.Mutex mx sync.Mutex
warmupEpoch atomic.Int64 warmupEpoch abi.ChainEpoch // protected by mx
baseEpoch abi.ChainEpoch // protected by compaction lock baseEpoch abi.ChainEpoch // protected by compaction lock
pruneEpoch abi.ChainEpoch // protected by compaction lock pruneEpoch abi.ChainEpoch // protected by compaction lock
@@ -182,16 +165,10 @@ type SplitStore struct {
compactionIndex int64 compactionIndex int64
pruneIndex int64 pruneIndex int64
onlineGCCnt int64
ctx context.Context ctx context.Context
cancel func() cancel func()
outOfSync int32 // for fast checking
chainSyncMx sync.Mutex
chainSyncCond sync.Cond
chainSyncFinished bool // protected by chainSyncMx
debug *debugLog debug *debugLog
// transactional protection for concurrent read/writes during compaction // transactional protection for concurrent read/writes during compaction
@@ -218,17 +195,6 @@ type SplitStore struct {
// registered protectors // registered protectors
protectors []func(func(cid.Cid) error) error protectors []func(func(cid.Cid) error) error
// dag sizes measured during latest compaction
// logged and used for GC strategy
// protected by compaction lock
szWalk int64
szProtectedTxns int64
szKeys int64 // approximate, not counting keys protected when entering critical section
// protected by txnLk
szMarkedLiveRefs int64
} }
var _ bstore.Blockstore = (*SplitStore)(nil) var _ bstore.Blockstore = (*SplitStore)(nil)
@@ -266,7 +232,6 @@ func Open(path string, ds dstore.Datastore, hot, cold bstore.Blockstore, cfg *Co
ss.txnViewsCond.L = &ss.txnViewsMx ss.txnViewsCond.L = &ss.txnViewsMx
ss.txnSyncCond.L = &ss.txnSyncMx ss.txnSyncCond.L = &ss.txnSyncMx
ss.chainSyncCond.L = &ss.chainSyncMx
ss.ctx, ss.cancel = context.WithCancel(context.Background()) ss.ctx, ss.cancel = context.WithCancel(context.Background())
ss.reifyCond.L = &ss.reifyMx ss.reifyCond.L = &ss.reifyMx
@@ -482,23 +447,6 @@ func (s *SplitStore) GetSize(ctx context.Context, cid cid.Cid) (int, error) {
} }
} }
func (s *SplitStore) Flush(ctx context.Context) error {
s.txnLk.RLock()
defer s.txnLk.RUnlock()
if err := s.cold.Flush(ctx); err != nil {
return err
}
if err := s.hot.Flush(ctx); err != nil {
return err
}
if err := s.ds.Sync(ctx, dstore.Key{}); err != nil {
return err
}
return nil
}
func (s *SplitStore) Put(ctx context.Context, blk blocks.Block) error { func (s *SplitStore) Put(ctx context.Context, blk blocks.Block) error {
if isIdentiyCid(blk.Cid()) { if isIdentiyCid(blk.Cid()) {
return nil return nil
@@ -684,7 +632,9 @@ func (s *SplitStore) View(ctx context.Context, cid cid.Cid, cb func([]byte) erro
} }
func (s *SplitStore) isWarm() bool { func (s *SplitStore) isWarm() bool {
return s.warmupEpoch.Load() > 0 s.mx.Lock()
defer s.mx.Unlock()
return s.warmupEpoch > 0
} }
// State tracking // State tracking
@@ -755,7 +705,7 @@ func (s *SplitStore) Start(chain ChainAccessor, us stmgr.UpgradeSchedule) error
bs, err = s.ds.Get(s.ctx, warmupEpochKey) bs, err = s.ds.Get(s.ctx, warmupEpochKey)
switch err { switch err {
case nil: case nil:
s.warmupEpoch.Store(bytesToInt64(bs)) s.warmupEpoch = bytesToEpoch(bs)
case dstore.ErrNotFound: case dstore.ErrNotFound:
warmup = true warmup = true
@@ -789,7 +739,7 @@ func (s *SplitStore) Start(chain ChainAccessor, us stmgr.UpgradeSchedule) error
return xerrors.Errorf("error loading compaction index: %w", err) return xerrors.Errorf("error loading compaction index: %w", err)
} }
log.Infow("starting splitstore", "baseEpoch", s.baseEpoch, "warmupEpoch", s.warmupEpoch.Load()) log.Infow("starting splitstore", "baseEpoch", s.baseEpoch, "warmupEpoch", s.warmupEpoch)
if warmup { if warmup {
err = s.warmup(curTs) err = s.warmup(curTs)
@@ -826,11 +776,6 @@ func (s *SplitStore) Close() error {
s.txnSyncCond.Broadcast() s.txnSyncCond.Broadcast()
s.txnSyncMx.Unlock() s.txnSyncMx.Unlock()
s.chainSyncMx.Lock()
s.chainSyncFinished = true
s.chainSyncCond.Broadcast()
s.chainSyncMx.Unlock()
log.Warn("close with ongoing compaction in progress; waiting for it to finish...") log.Warn("close with ongoing compaction in progress; waiting for it to finish...")
for atomic.LoadInt32(&s.compacting) == 1 { for atomic.LoadInt32(&s.compacting) == 1 {
time.Sleep(time.Second) time.Sleep(time.Second)
+3 -3
View File
@@ -95,7 +95,7 @@ func (s *SplitStore) doCheck(curTs *types.TipSet) error {
} }
defer visitor.Close() //nolint defer visitor.Close() //nolint
size := s.walkChain(curTs, boundaryEpoch, boundaryEpoch, visitor, err = s.walkChain(curTs, boundaryEpoch, boundaryEpoch, visitor,
func(c cid.Cid) error { func(c cid.Cid) error {
if isUnitaryObject(c) { if isUnitaryObject(c) {
return errStopWalk return errStopWalk
@@ -133,7 +133,7 @@ func (s *SplitStore) doCheck(curTs *types.TipSet) error {
return err return err
} }
log.Infow("check done", "cold", *coldCnt, "missing", *missingCnt, "walk size", size) log.Infow("check done", "cold", *coldCnt, "missing", *missingCnt)
write("--") write("--")
write("cold: %d missing: %d", *coldCnt, *missingCnt) write("cold: %d missing: %d", *coldCnt, *missingCnt)
write("DONE") write("DONE")
@@ -145,7 +145,7 @@ func (s *SplitStore) doCheck(curTs *types.TipSet) error {
func (s *SplitStore) Info() map[string]interface{} { func (s *SplitStore) Info() map[string]interface{} {
info := make(map[string]interface{}) info := make(map[string]interface{})
info["base epoch"] = s.baseEpoch info["base epoch"] = s.baseEpoch
info["warmup epoch"] = s.warmupEpoch.Load() info["warmup epoch"] = s.warmupEpoch
info["compactions"] = s.compactionIndex info["compactions"] = s.compactionIndex
info["prunes"] = s.pruneIndex info["prunes"] = s.pruneIndex
info["compacting"] = s.compacting == 1 info["compacting"] = s.compacting == 1
+72 -170
View File
@@ -10,9 +10,9 @@ import (
"sync/atomic" "sync/atomic"
"time" "time"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
ipld "github.com/ipfs/go-ipld-format" ipld "github.com/ipfs/go-ipld-format"
blocks "github.com/ipfs/go-libipfs/blocks"
cbg "github.com/whyrusleeping/cbor-gen" cbg "github.com/whyrusleeping/cbor-gen"
"go.opencensus.io/stats" "go.opencensus.io/stats"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
@@ -66,8 +66,7 @@ var (
) )
const ( const (
batchSize = 16384 batchSize = 16384
cidKeySize = 128
) )
func (s *SplitStore) HeadChange(_, apply []*types.TipSet) error { func (s *SplitStore) HeadChange(_, apply []*types.TipSet) error {
@@ -91,35 +90,7 @@ func (s *SplitStore) HeadChange(_, apply []*types.TipSet) error {
// Regardless, we put a mutex in HeadChange just to be safe // Regardless, we put a mutex in HeadChange just to be safe
if !atomic.CompareAndSwapInt32(&s.compacting, 0, 1) { if !atomic.CompareAndSwapInt32(&s.compacting, 0, 1) {
// we are currently compacting // we are currently compacting -- protect the new tipset(s)
// 1. Signal sync condition to yield compaction when out of sync and resume when in sync
timestamp := time.Unix(int64(curTs.MinTimestamp()), 0)
if CheckSyncGap && time.Since(timestamp) > SyncGapTime {
/* Chain out of sync */
if atomic.CompareAndSwapInt32(&s.outOfSync, 0, 1) {
// transition from in sync to out of sync
s.chainSyncMx.Lock()
s.chainSyncFinished = false
s.chainSyncMx.Unlock()
}
// already out of sync, no signaling necessary
}
// TODO: ok to use hysteresis with no transitions between 30s and 1m?
if time.Since(timestamp) < SyncWaitTime {
/* Chain in sync */
if atomic.CompareAndSwapInt32(&s.outOfSync, 0, 0) {
// already in sync, no signaling necessary
} else {
// transition from out of sync to in sync
s.chainSyncMx.Lock()
s.chainSyncFinished = true
s.chainSyncCond.Broadcast()
s.chainSyncMx.Unlock()
}
}
// 2. protect the new tipset(s)
s.protectTipSets(apply) s.protectTipSets(apply)
return nil return nil
} }
@@ -144,6 +115,8 @@ func (s *SplitStore) HeadChange(_, apply []*types.TipSet) error {
return nil return nil
} }
// Prioritize hot store compaction over cold store prune
if epoch-s.baseEpoch > CompactionThreshold { if epoch-s.baseEpoch > CompactionThreshold {
// it's time to compact -- prepare the transaction and go! // it's time to compact -- prepare the transaction and go!
s.beginTxnProtect() s.beginTxnProtect()
@@ -203,8 +176,6 @@ func (s *SplitStore) protectTipSets(apply []*types.TipSet) {
timestamp := time.Unix(int64(curTs.MinTimestamp()), 0) timestamp := time.Unix(int64(curTs.MinTimestamp()), 0)
doSync := time.Since(timestamp) < SyncWaitTime doSync := time.Since(timestamp) < SyncWaitTime
go func() { go func() {
// we are holding the txnLk while marking
// so critical section cannot delete
if doSync { if doSync {
defer func() { defer func() {
s.txnSyncMx.Lock() s.txnSyncMx.Lock()
@@ -228,11 +199,9 @@ func (s *SplitStore) markLiveRefs(cids []cid.Cid) {
log.Debugf("marking %d live refs", len(cids)) log.Debugf("marking %d live refs", len(cids))
startMark := time.Now() startMark := time.Now()
szMarked := new(int64)
count := new(int32) count := new(int32)
visitor := newConcurrentVisitor() visitor := newConcurrentVisitor()
walkObject := func(c cid.Cid) (int64, error) { walkObject := func(c cid.Cid) error {
return s.walkObjectIncomplete(c, visitor, return s.walkObjectIncomplete(c, visitor,
func(c cid.Cid) error { func(c cid.Cid) error {
if isUnitaryObject(c) { if isUnitaryObject(c) {
@@ -259,12 +228,10 @@ func (s *SplitStore) markLiveRefs(cids []cid.Cid) {
// optimize the common case of single put // optimize the common case of single put
if len(cids) == 1 { if len(cids) == 1 {
sz, err := walkObject(cids[0]) if err := walkObject(cids[0]); err != nil {
if err != nil {
log.Errorf("error marking tipset refs: %s", err) log.Errorf("error marking tipset refs: %s", err)
} }
log.Debugw("marking live refs done", "took", time.Since(startMark), "marked", *count) log.Debugw("marking live refs done", "took", time.Since(startMark), "marked", *count)
atomic.AddInt64(szMarked, sz)
return return
} }
@@ -276,11 +243,9 @@ func (s *SplitStore) markLiveRefs(cids []cid.Cid) {
worker := func() error { worker := func() error {
for c := range workch { for c := range workch {
sz, err := walkObject(c) if err := walkObject(c); err != nil {
if err != nil {
return err return err
} }
atomic.AddInt64(szMarked, sz)
} }
return nil return nil
@@ -303,8 +268,7 @@ func (s *SplitStore) markLiveRefs(cids []cid.Cid) {
log.Errorf("error marking tipset refs: %s", err) log.Errorf("error marking tipset refs: %s", err)
} }
log.Debugw("marking live refs done", "took", time.Since(startMark), "marked", *count, "size marked", *szMarked) log.Debugw("marking live refs done", "took", time.Since(startMark), "marked", *count)
s.szMarkedLiveRefs += atomic.LoadInt64(szMarked)
} }
// transactionally protect a view // transactionally protect a view
@@ -397,7 +361,6 @@ func (s *SplitStore) protectTxnRefs(markSet MarkSet) error {
log.Infow("protecting transactional references", "refs", len(txnRefs)) log.Infow("protecting transactional references", "refs", len(txnRefs))
count := 0 count := 0
sz := new(int64)
workch := make(chan cid.Cid, len(txnRefs)) workch := make(chan cid.Cid, len(txnRefs))
startProtect := time.Now() startProtect := time.Now()
@@ -430,11 +393,10 @@ func (s *SplitStore) protectTxnRefs(markSet MarkSet) error {
worker := func() error { worker := func() error {
for c := range workch { for c := range workch {
szTxn, err := s.doTxnProtect(c, markSet) err := s.doTxnProtect(c, markSet)
if err != nil { if err != nil {
return xerrors.Errorf("error protecting transactional references to %s: %w", c, err) return xerrors.Errorf("error protecting transactional references to %s: %w", c, err)
} }
atomic.AddInt64(sz, szTxn)
} }
return nil return nil
} }
@@ -447,16 +409,16 @@ func (s *SplitStore) protectTxnRefs(markSet MarkSet) error {
if err := g.Wait(); err != nil { if err := g.Wait(); err != nil {
return err return err
} }
s.szProtectedTxns += atomic.LoadInt64(sz)
log.Infow("protecting transactional refs done", "took", time.Since(startProtect), "protected", count, "protected size", sz) log.Infow("protecting transactional refs done", "took", time.Since(startProtect), "protected", count)
} }
} }
// transactionally protect a reference by walking the object and marking. // transactionally protect a reference by walking the object and marking.
// concurrent markings are short circuited by checking the markset. // concurrent markings are short circuited by checking the markset.
func (s *SplitStore) doTxnProtect(root cid.Cid, markSet MarkSet) (int64, error) { func (s *SplitStore) doTxnProtect(root cid.Cid, markSet MarkSet) error {
if err := s.checkClosing(); err != nil { if err := s.checkClosing(); err != nil {
return 0, err return err
} }
// Note: cold objects are deleted heaviest first, so the consituents of an object // Note: cold objects are deleted heaviest first, so the consituents of an object
@@ -480,7 +442,7 @@ func (s *SplitStore) doTxnProtect(root cid.Cid, markSet MarkSet) (int64, error)
}, },
func(c cid.Cid) error { func(c cid.Cid) error {
if s.txnMissing != nil { if s.txnMissing != nil {
log.Debugf("missing object reference %s in %s", c, root) log.Warnf("missing object reference %s in %s", c, root)
s.txnRefsMx.Lock() s.txnRefsMx.Lock()
s.txnMissing[c] = struct{}{} s.txnMissing[c] = struct{}{}
s.txnRefsMx.Unlock() s.txnRefsMx.Unlock()
@@ -547,7 +509,6 @@ func (s *SplitStore) doCompact(curTs *types.TipSet) error {
// might be potentially inconsistent; abort compaction and notify the user to intervene. // might be potentially inconsistent; abort compaction and notify the user to intervene.
return xerrors.Errorf("checkpoint exists; aborting compaction") return xerrors.Errorf("checkpoint exists; aborting compaction")
} }
s.clearSizeMeasurements()
currentEpoch := curTs.Height() currentEpoch := curTs.Height()
boundaryEpoch := currentEpoch - CompactionBoundary boundaryEpoch := currentEpoch - CompactionBoundary
@@ -573,7 +534,7 @@ func (s *SplitStore) doCompact(curTs *types.TipSet) error {
} }
defer coldSet.Close() //nolint:errcheck defer coldSet.Close() //nolint:errcheck
if err := s.checkYield(); err != nil { if err := s.checkClosing(); err != nil {
return err return err
} }
@@ -637,6 +598,7 @@ func (s *SplitStore) doCompact(curTs *types.TipSet) error {
} }
err = s.walkChain(curTs, boundaryEpoch, inclMsgsEpoch, &noopVisitor{}, fHot, fCold) err = s.walkChain(curTs, boundaryEpoch, inclMsgsEpoch, &noopVisitor{}, fHot, fCold)
if err != nil { if err != nil {
return xerrors.Errorf("error marking: %w", err) return xerrors.Errorf("error marking: %w", err)
} }
@@ -645,7 +607,7 @@ func (s *SplitStore) doCompact(curTs *types.TipSet) error {
log.Infow("marking done", "took", time.Since(startMark), "marked", *count) log.Infow("marking done", "took", time.Since(startMark), "marked", *count)
if err := s.checkYield(); err != nil { if err := s.checkClosing(); err != nil {
return err return err
} }
@@ -655,7 +617,7 @@ func (s *SplitStore) doCompact(curTs *types.TipSet) error {
return xerrors.Errorf("error protecting transactional refs: %w", err) return xerrors.Errorf("error protecting transactional refs: %w", err)
} }
if err := s.checkYield(); err != nil { if err := s.checkClosing(); err != nil {
return err return err
} }
@@ -676,7 +638,7 @@ func (s *SplitStore) doCompact(curTs *types.TipSet) error {
defer purgew.Close() //nolint:errcheck defer purgew.Close() //nolint:errcheck
// some stats for logging // some stats for logging
var hotCnt, coldCnt, purgeCnt int64 var hotCnt, coldCnt, purgeCnt int
err = s.hot.ForEachKey(func(c cid.Cid) error { err = s.hot.ForEachKey(func(c cid.Cid) error {
// was it marked? // was it marked?
mark, err := markSet.Has(c) mark, err := markSet.Has(c)
@@ -727,12 +689,11 @@ func (s *SplitStore) doCompact(curTs *types.TipSet) error {
log.Infow("cold collection done", "took", time.Since(startCollect)) log.Infow("cold collection done", "took", time.Since(startCollect))
log.Infow("compaction stats", "hot", hotCnt, "cold", coldCnt, "purge", purgeCnt) log.Infow("compaction stats", "hot", hotCnt, "cold", coldCnt)
s.szKeys = hotCnt * cidKeySize stats.Record(s.ctx, metrics.SplitstoreCompactionHot.M(int64(hotCnt)))
stats.Record(s.ctx, metrics.SplitstoreCompactionHot.M(hotCnt)) stats.Record(s.ctx, metrics.SplitstoreCompactionCold.M(int64(coldCnt)))
stats.Record(s.ctx, metrics.SplitstoreCompactionCold.M(coldCnt))
if err := s.checkYield(); err != nil { if err := s.checkClosing(); err != nil {
return err return err
} }
@@ -741,7 +702,7 @@ func (s *SplitStore) doCompact(curTs *types.TipSet) error {
// possibly delete objects we didn't have when we were collecting cold objects) // possibly delete objects we didn't have when we were collecting cold objects)
s.waitForMissingRefs(markSet) s.waitForMissingRefs(markSet)
if err := s.checkYield(); err != nil { if err := s.checkClosing(); err != nil {
return err return err
} }
@@ -761,7 +722,7 @@ func (s *SplitStore) doCompact(curTs *types.TipSet) error {
} }
log.Infow("moving done", "took", time.Since(startMove)) log.Infow("moving done", "took", time.Since(startMove))
if err := s.checkYield(); err != nil { if err := s.checkClosing(); err != nil {
return err return err
} }
@@ -792,7 +753,7 @@ func (s *SplitStore) doCompact(curTs *types.TipSet) error {
} }
// wait for the head to catch up so that the current tipset is marked // wait for the head to catch up so that the current tipset is marked
s.waitForTxnSync() s.waitForSync()
if err := s.checkClosing(); err != nil { if err := s.checkClosing(); err != nil {
return err return err
@@ -812,8 +773,8 @@ func (s *SplitStore) doCompact(curTs *types.TipSet) error {
return xerrors.Errorf("error purging cold objects: %w", err) return xerrors.Errorf("error purging cold objects: %w", err)
} }
log.Infow("purging cold objects from hotstore done", "took", time.Since(startPurge)) log.Infow("purging cold objects from hotstore done", "took", time.Since(startPurge))
s.endCriticalSection() s.endCriticalSection()
log.Infow("critical section done", "total protected size", s.szProtectedTxns, "total marked live size", s.szMarkedLiveRefs)
if err := checkpoint.Close(); err != nil { if err := checkpoint.Close(); err != nil {
log.Warnf("error closing checkpoint: %s", err) log.Warnf("error closing checkpoint: %s", err)
@@ -827,13 +788,10 @@ func (s *SplitStore) doCompact(curTs *types.TipSet) error {
if err := os.Remove(s.coldSetPath()); err != nil { if err := os.Remove(s.coldSetPath()); err != nil {
log.Warnf("error removing coldset: %s", err) log.Warnf("error removing coldset: %s", err)
} }
if err := os.Remove(s.discardSetPath()); err != nil {
log.Warnf("error removing discardset: %s", err)
}
// we are done; do some housekeeping // we are done; do some housekeeping
s.endTxnProtect() s.endTxnProtect()
s.gcHotAfterCompaction() s.gcHotstore()
err = s.setBaseEpoch(boundaryEpoch) err = s.setBaseEpoch(boundaryEpoch)
if err != nil { if err != nil {
@@ -893,7 +851,7 @@ func (s *SplitStore) beginCriticalSection(markSet MarkSet) error {
return nil return nil
} }
func (s *SplitStore) waitForTxnSync() { func (s *SplitStore) waitForSync() {
log.Info("waiting for sync") log.Info("waiting for sync")
if !CheckSyncGap { if !CheckSyncGap {
log.Warnf("If you see this outside of test it is a serious splitstore issue") log.Warnf("If you see this outside of test it is a serious splitstore issue")
@@ -912,25 +870,6 @@ func (s *SplitStore) waitForTxnSync() {
} }
} }
// Block compaction operations if chain sync has fallen behind
func (s *SplitStore) waitForSync() {
if atomic.LoadInt32(&s.outOfSync) == 0 {
return
}
s.chainSyncMx.Lock()
defer s.chainSyncMx.Unlock()
for !s.chainSyncFinished {
s.chainSyncCond.Wait()
}
}
// Combined sync and closing check
func (s *SplitStore) checkYield() error {
s.waitForSync()
return s.checkClosing()
}
func (s *SplitStore) endTxnProtect() { func (s *SplitStore) endTxnProtect() {
s.txnLk.Lock() s.txnLk.Lock()
defer s.txnLk.Unlock() defer s.txnLk.Unlock()
@@ -965,7 +904,6 @@ func (s *SplitStore) walkChain(ts *types.TipSet, inclState, inclMsgs abi.ChainEp
copy(toWalk, ts.Cids()) copy(toWalk, ts.Cids())
walkCnt := new(int64) walkCnt := new(int64)
scanCnt := new(int64) scanCnt := new(int64)
szWalk := new(int64)
tsRef := func(blkCids []cid.Cid) (cid.Cid, error) { tsRef := func(blkCids []cid.Cid) (cid.Cid, error) {
return types.NewTipSetKey(blkCids...).Cid() return types.NewTipSetKey(blkCids...).Cid()
@@ -1001,64 +939,48 @@ func (s *SplitStore) walkChain(ts *types.TipSet, inclState, inclMsgs abi.ChainEp
if err != nil { if err != nil {
return xerrors.Errorf("error computing cid reference to parent tipset") return xerrors.Errorf("error computing cid reference to parent tipset")
} }
sz, err := s.walkObjectIncomplete(pRef, visitor, fHot, stopWalk) if err := s.walkObjectIncomplete(pRef, visitor, fHot, stopWalk); err != nil {
if err != nil {
return xerrors.Errorf("error walking parent tipset cid reference") return xerrors.Errorf("error walking parent tipset cid reference")
} }
atomic.AddInt64(szWalk, sz)
// message are retained if within the inclMsgs boundary // message are retained if within the inclMsgs boundary
if hdr.Height >= inclMsgs && hdr.Height > 0 { if hdr.Height >= inclMsgs && hdr.Height > 0 {
if inclMsgs < inclState { if inclMsgs < inclState {
// we need to use walkObjectIncomplete here, as messages/receipts may be missing early on if we // we need to use walkObjectIncomplete here, as messages/receipts may be missing early on if we
// synced from snapshot and have a long HotStoreMessageRetentionPolicy. // synced from snapshot and have a long HotStoreMessageRetentionPolicy.
sz, err := s.walkObjectIncomplete(hdr.Messages, visitor, fHot, stopWalk) if err := s.walkObjectIncomplete(hdr.Messages, visitor, fHot, stopWalk); err != nil {
if err != nil {
return xerrors.Errorf("error walking messages (cid: %s): %w", hdr.Messages, err) return xerrors.Errorf("error walking messages (cid: %s): %w", hdr.Messages, err)
} }
atomic.AddInt64(szWalk, sz)
sz, err = s.walkObjectIncomplete(hdr.ParentMessageReceipts, visitor, fHot, stopWalk) if err := s.walkObjectIncomplete(hdr.ParentMessageReceipts, visitor, fHot, stopWalk); err != nil {
if err != nil {
return xerrors.Errorf("error walking messages receipts (cid: %s): %w", hdr.ParentMessageReceipts, err) return xerrors.Errorf("error walking messages receipts (cid: %s): %w", hdr.ParentMessageReceipts, err)
} }
atomic.AddInt64(szWalk, sz)
} else { } else {
sz, err = s.walkObject(hdr.Messages, visitor, fHot) if err := s.walkObject(hdr.Messages, visitor, fHot); err != nil {
if err != nil {
return xerrors.Errorf("error walking messages (cid: %s): %w", hdr.Messages, err) return xerrors.Errorf("error walking messages (cid: %s): %w", hdr.Messages, err)
} }
atomic.AddInt64(szWalk, sz)
sz, err := s.walkObjectIncomplete(hdr.ParentMessageReceipts, visitor, fHot, stopWalk) if err := s.walkObjectIncomplete(hdr.ParentMessageReceipts, visitor, fHot, stopWalk); err != nil {
if err != nil {
return xerrors.Errorf("error walking message receipts (cid: %s): %w", hdr.ParentMessageReceipts, err) return xerrors.Errorf("error walking message receipts (cid: %s): %w", hdr.ParentMessageReceipts, err)
} }
atomic.AddInt64(szWalk, sz)
} }
} }
// messages and receipts outside of inclMsgs are included in the cold store // messages and receipts outside of inclMsgs are included in the cold store
if hdr.Height < inclMsgs && hdr.Height > 0 { if hdr.Height < inclMsgs && hdr.Height > 0 {
sz, err := s.walkObjectIncomplete(hdr.Messages, visitor, fCold, stopWalk) if err := s.walkObjectIncomplete(hdr.Messages, visitor, fCold, stopWalk); err != nil {
if err != nil {
return xerrors.Errorf("error walking messages (cid: %s): %w", hdr.Messages, err) return xerrors.Errorf("error walking messages (cid: %s): %w", hdr.Messages, err)
} }
atomic.AddInt64(szWalk, sz) if err := s.walkObjectIncomplete(hdr.ParentMessageReceipts, visitor, fCold, stopWalk); err != nil {
sz, err = s.walkObjectIncomplete(hdr.ParentMessageReceipts, visitor, fCold, stopWalk)
if err != nil {
return xerrors.Errorf("error walking messages receipts (cid: %s): %w", hdr.ParentMessageReceipts, err) return xerrors.Errorf("error walking messages receipts (cid: %s): %w", hdr.ParentMessageReceipts, err)
} }
atomic.AddInt64(szWalk, sz)
} }
// state is only retained if within the inclState boundary, with the exception of genesis // state is only retained if within the inclState boundary, with the exception of genesis
if hdr.Height >= inclState || hdr.Height == 0 { if hdr.Height >= inclState || hdr.Height == 0 {
sz, err := s.walkObject(hdr.ParentStateRoot, visitor, fHot) if err := s.walkObject(hdr.ParentStateRoot, visitor, fHot); err != nil {
if err != nil {
return xerrors.Errorf("error walking state root (cid: %s): %w", hdr.ParentStateRoot, err) return xerrors.Errorf("error walking state root (cid: %s): %w", hdr.ParentStateRoot, err)
} }
atomic.AddInt64(szWalk, sz)
atomic.AddInt64(scanCnt, 1) atomic.AddInt64(scanCnt, 1)
} }
@@ -1076,15 +998,13 @@ func (s *SplitStore) walkChain(ts *types.TipSet, inclState, inclMsgs abi.ChainEp
if err != nil { if err != nil {
return xerrors.Errorf("error computing cid reference to parent tipset") return xerrors.Errorf("error computing cid reference to parent tipset")
} }
sz, err := s.walkObjectIncomplete(hRef, visitor, fHot, stopWalk) if err := s.walkObjectIncomplete(hRef, visitor, fHot, stopWalk); err != nil {
if err != nil {
return xerrors.Errorf("error walking parent tipset cid reference") return xerrors.Errorf("error walking parent tipset cid reference")
} }
atomic.AddInt64(szWalk, sz)
for len(toWalk) > 0 { for len(toWalk) > 0 {
// walking can take a while, so check this with every opportunity // walking can take a while, so check this with every opportunity
if err := s.checkYield(); err != nil { if err := s.checkClosing(); err != nil {
return err return err
} }
@@ -1114,143 +1034,133 @@ func (s *SplitStore) walkChain(ts *types.TipSet, inclState, inclMsgs abi.ChainEp
if err := walkBlock(c); err != nil { if err := walkBlock(c); err != nil {
return xerrors.Errorf("error walking block (cid: %s): %w", c, err) return xerrors.Errorf("error walking block (cid: %s): %w", c, err)
} }
if err := s.checkYield(); err != nil {
return xerrors.Errorf("check yield: %w", err)
}
} }
return nil return nil
}) })
} }
if err := g.Wait(); err != nil { if err := g.Wait(); err != nil {
return xerrors.Errorf("walkBlock workers errored: %w", err) return err
} }
} }
log.Infow("chain walk done", "walked", *walkCnt, "scanned", *scanCnt, "walk size", szWalk) log.Infow("chain walk done", "walked", *walkCnt, "scanned", *scanCnt)
s.szWalk = atomic.LoadInt64(szWalk)
return nil return nil
} }
func (s *SplitStore) walkObject(c cid.Cid, visitor ObjectVisitor, f func(cid.Cid) error) (int64, error) { func (s *SplitStore) walkObject(c cid.Cid, visitor ObjectVisitor, f func(cid.Cid) error) error {
var sz int64
visit, err := visitor.Visit(c) visit, err := visitor.Visit(c)
if err != nil { if err != nil {
return 0, xerrors.Errorf("error visiting object: %w", err) return xerrors.Errorf("error visiting object: %w", err)
} }
if !visit { if !visit {
return sz, nil return nil
} }
if err := f(c); err != nil { if err := f(c); err != nil {
if err == errStopWalk { if err == errStopWalk {
return sz, nil return nil
} }
return 0, err return err
} }
if c.Prefix().Codec != cid.DagCBOR { if c.Prefix().Codec != cid.DagCBOR {
return sz, nil return nil
} }
// check this before recursing // check this before recursing
if err := s.checkClosing(); err != nil { if err := s.checkClosing(); err != nil {
return 0, xerrors.Errorf("check closing: %w", err) return err
} }
var links []cid.Cid var links []cid.Cid
err = s.view(c, func(data []byte) error { err = s.view(c, func(data []byte) error {
sz += int64(len(data))
return cbg.ScanForLinks(bytes.NewReader(data), func(c cid.Cid) { return cbg.ScanForLinks(bytes.NewReader(data), func(c cid.Cid) {
links = append(links, c) links = append(links, c)
}) })
}) })
if err != nil { if err != nil {
return 0, xerrors.Errorf("error scanning linked block (cid: %s): %w", c, err) return xerrors.Errorf("error scanning linked block (cid: %s): %w", c, err)
} }
for _, c := range links { for _, c := range links {
szLink, err := s.walkObject(c, visitor, f) err := s.walkObject(c, visitor, f)
if err != nil { if err != nil {
return 0, xerrors.Errorf("error walking link (cid: %s): %w", c, err) return xerrors.Errorf("error walking link (cid: %s): %w", c, err)
} }
sz += szLink
} }
return sz, nil return nil
} }
// like walkObject, but the object may be potentially incomplete (references missing) // like walkObject, but the object may be potentially incomplete (references missing)
func (s *SplitStore) walkObjectIncomplete(c cid.Cid, visitor ObjectVisitor, f, missing func(cid.Cid) error) (int64, error) { func (s *SplitStore) walkObjectIncomplete(c cid.Cid, visitor ObjectVisitor, f, missing func(cid.Cid) error) error {
var sz int64
visit, err := visitor.Visit(c) visit, err := visitor.Visit(c)
if err != nil { if err != nil {
return 0, xerrors.Errorf("error visiting object: %w", err) return xerrors.Errorf("error visiting object: %w", err)
} }
if !visit { if !visit {
return sz, nil return nil
} }
// occurs check -- only for DAGs // occurs check -- only for DAGs
if c.Prefix().Codec == cid.DagCBOR { if c.Prefix().Codec == cid.DagCBOR {
has, err := s.has(c) has, err := s.has(c)
if err != nil { if err != nil {
return 0, xerrors.Errorf("error occur checking %s: %w", c, err) return xerrors.Errorf("error occur checking %s: %w", c, err)
} }
if !has { if !has {
err = missing(c) err = missing(c)
if err == errStopWalk { if err == errStopWalk {
return sz, nil return nil
} }
return 0, err return err
} }
} }
if err := f(c); err != nil { if err := f(c); err != nil {
if err == errStopWalk { if err == errStopWalk {
return sz, nil return nil
} }
return 0, err return err
} }
if c.Prefix().Codec != cid.DagCBOR { if c.Prefix().Codec != cid.DagCBOR {
return sz, nil return nil
} }
// check this before recursing // check this before recursing
if err := s.checkClosing(); err != nil { if err := s.checkClosing(); err != nil {
return sz, xerrors.Errorf("check closing: %w", err) return err
} }
var links []cid.Cid var links []cid.Cid
err = s.view(c, func(data []byte) error { err = s.view(c, func(data []byte) error {
sz += int64(len(data))
return cbg.ScanForLinks(bytes.NewReader(data), func(c cid.Cid) { return cbg.ScanForLinks(bytes.NewReader(data), func(c cid.Cid) {
links = append(links, c) links = append(links, c)
}) })
}) })
if err != nil { if err != nil {
return 0, xerrors.Errorf("error scanning linked block (cid: %s): %w", c, err) return xerrors.Errorf("error scanning linked block (cid: %s): %w", c, err)
} }
for _, c := range links { for _, c := range links {
szLink, err := s.walkObjectIncomplete(c, visitor, f, missing) err := s.walkObjectIncomplete(c, visitor, f, missing)
if err != nil { if err != nil {
return 0, xerrors.Errorf("error walking link (cid: %s): %w", c, err) return xerrors.Errorf("error walking link (cid: %s): %w", c, err)
} }
sz += szLink
} }
return sz, nil return nil
} }
// internal version used during compaction and related operations // internal version used during compaction and related operations
@@ -1313,7 +1223,7 @@ func (s *SplitStore) moveColdBlocks(coldr *ColdSetReader) error {
batch := make([]blocks.Block, 0, batchSize) batch := make([]blocks.Block, 0, batchSize)
err := coldr.ForEach(func(c cid.Cid) error { err := coldr.ForEach(func(c cid.Cid) error {
if err := s.checkYield(); err != nil { if err := s.checkClosing(); err != nil {
return err return err
} }
blk, err := s.hot.Get(s.ctx, c) blk, err := s.hot.Get(s.ctx, c)
@@ -1516,9 +1426,8 @@ func (s *SplitStore) completeCompaction() error {
} }
s.compactType = none s.compactType = none
// Note: at this point we can start the splitstore; base epoch is not // Note: at this point we can start the splitstore; a compaction should run on
// incremented here so a compaction should run on the first head // the first head change, which will trigger gc on the hotstore.
// change, which will trigger gc on the hotstore.
// We don't mind the second (back-to-back) compaction as the head will // We don't mind the second (back-to-back) compaction as the head will
// have advanced during marking and coldset accumulation. // have advanced during marking and coldset accumulation.
return nil return nil
@@ -1576,13 +1485,6 @@ func (s *SplitStore) completePurge(coldr *ColdSetReader, checkpoint *Checkpoint,
return nil return nil
} }
func (s *SplitStore) clearSizeMeasurements() {
s.szKeys = 0
s.szMarkedLiveRefs = 0
s.szProtectedTxns = 0
s.szWalk = 0
}
// I really don't like having this code, but we seem to have some occasional DAG references with // I really don't like having this code, but we seem to have some occasional DAG references with
// missing constituents. During testing in mainnet *some* of these references *sometimes* appeared // missing constituents. During testing in mainnet *some* of these references *sometimes* appeared
// after a little bit. // after a little bit.
@@ -1623,7 +1525,7 @@ func (s *SplitStore) waitForMissingRefs(markSet MarkSet) {
missing = make(map[cid.Cid]struct{}) missing = make(map[cid.Cid]struct{})
for c := range towalk { for c := range towalk {
_, err := s.walkObjectIncomplete(c, visitor, err := s.walkObjectIncomplete(c, visitor,
func(c cid.Cid) error { func(c cid.Cid) error {
if isUnitaryObject(c) { if isUnitaryObject(c) {
return errStopWalk return errStopWalk
+1 -5
View File
@@ -4,9 +4,9 @@ import (
"context" "context"
"errors" "errors"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
ipld "github.com/ipfs/go-ipld-format" ipld "github.com/ipfs/go-ipld-format"
blocks "github.com/ipfs/go-libipfs/blocks"
bstore "github.com/filecoin-project/lotus/blockstore" bstore "github.com/filecoin-project/lotus/blockstore"
) )
@@ -77,10 +77,6 @@ func (es *exposedSplitStore) GetSize(ctx context.Context, c cid.Cid) (int, error
return size, err return size, err
} }
func (es *exposedSplitStore) Flush(ctx context.Context) error {
return es.s.Flush(ctx)
}
func (es *exposedSplitStore) Put(ctx context.Context, blk blocks.Block) error { func (es *exposedSplitStore) Put(ctx context.Context, blk blocks.Block) error {
return es.s.Put(ctx, blk) return es.s.Put(ctx, blk)
} }
+3 -70
View File
@@ -7,74 +7,23 @@ import (
bstore "github.com/filecoin-project/lotus/blockstore" bstore "github.com/filecoin-project/lotus/blockstore"
) )
const ( func (s *SplitStore) gcHotstore() {
// Fraction of garbage in badger vlog for online GC traversal to collect garbage
AggressiveOnlineGCThreshold = 0.0001
)
func (s *SplitStore) gcHotAfterCompaction() {
// Measure hotstore size, determine if we should do full GC, determine if we can do full GC.
// We should do full GC if
// FullGCFrequency is specified and compaction index matches frequency
// OR HotstoreMaxSpaceTarget is specified and total moving space is within 150 GB of target
// We can do full if
// HotstoreMaxSpaceTarget is not specified
// OR total moving space would not exceed 50 GB below target
//
// a) If we should not do full GC => online GC
// b) If we should do full GC and can => moving GC
// c) If we should do full GC and can't => aggressive online GC
getSize := func() int64 {
sizer, ok := s.hot.(bstore.BlockstoreSize)
if ok {
size, err := sizer.Size()
if err != nil {
log.Warnf("error getting hotstore size: %s, estimating empty hot store for targeting", err)
return 0
}
return size
}
log.Errorf("Could not measure hotstore size, assuming it is 0 bytes, which it is not")
return 0
}
hotSize := getSize()
copySizeApprox := s.szKeys + s.szMarkedLiveRefs + s.szProtectedTxns + s.szWalk
shouldTarget := s.cfg.HotstoreMaxSpaceTarget > 0 && hotSize+copySizeApprox > int64(s.cfg.HotstoreMaxSpaceTarget)-int64(s.cfg.HotstoreMaxSpaceThreshold)
shouldFreq := s.cfg.HotStoreFullGCFrequency > 0 && s.compactionIndex%int64(s.cfg.HotStoreFullGCFrequency) == 0
shouldDoFull := shouldTarget || shouldFreq
canDoFull := s.cfg.HotstoreMaxSpaceTarget == 0 || hotSize+copySizeApprox < int64(s.cfg.HotstoreMaxSpaceTarget)-int64(s.cfg.HotstoreMaxSpaceSafetyBuffer)
log.Debugw("approximating new hot store size", "key size", s.szKeys, "marked live refs", s.szMarkedLiveRefs, "protected txns", s.szProtectedTxns, "walked DAG", s.szWalk)
log.Infof("measured hot store size: %d, approximate new size: %d, should do full %t, can do full %t", hotSize, copySizeApprox, shouldDoFull, canDoFull)
var opts []bstore.BlockstoreGCOption var opts []bstore.BlockstoreGCOption
if shouldDoFull && canDoFull { if s.cfg.HotStoreFullGCFrequency > 0 && s.compactionIndex%int64(s.cfg.HotStoreFullGCFrequency) == 0 {
opts = append(opts, bstore.WithFullGC(true)) opts = append(opts, bstore.WithFullGC(true))
} else if shouldDoFull && !canDoFull {
log.Warnf("Attention! Estimated moving GC size %d is not within safety buffer %d of target max %d, performing aggressive online GC to attempt to bring hotstore size down safely", copySizeApprox, s.cfg.HotstoreMaxSpaceSafetyBuffer, s.cfg.HotstoreMaxSpaceTarget)
log.Warn("If problem continues you can 1) temporarily allocate more disk space to hotstore and 2) reflect in HotstoreMaxSpaceTarget OR trigger manual move with `lotus chain prune hot-moving`")
log.Warn("If problem continues and you do not have any more disk space you can run continue to manually trigger online GC at aggressive thresholds (< 0.01) with `lotus chain prune hot`")
opts = append(opts, bstore.WithThreshold(AggressiveOnlineGCThreshold))
} }
if err := s.gcBlockstore(s.hot, opts); err != nil { if err := s.gcBlockstore(s.hot, opts); err != nil {
log.Warnf("error garbage collecting hostore: %s", err) log.Warnf("error garbage collecting hostore: %s", err)
} }
log.Infof("measured hot store size after GC: %d", getSize())
} }
func (s *SplitStore) gcBlockstore(b bstore.Blockstore, opts []bstore.BlockstoreGCOption) error { func (s *SplitStore) gcBlockstore(b bstore.Blockstore, opts []bstore.BlockstoreGCOption) error {
if err := s.checkYield(); err != nil {
return err
}
if gc, ok := b.(bstore.BlockstoreGC); ok { if gc, ok := b.(bstore.BlockstoreGC); ok {
log.Info("garbage collecting blockstore") log.Info("garbage collecting blockstore")
startGC := time.Now() startGC := time.Now()
opts = append(opts, bstore.WithCheckFreq(90*time.Second)) if err := gc.CollectGarbage(opts...); err != nil {
opts = append(opts, bstore.WithCheck(s.checkYield))
if err := gc.CollectGarbage(s.ctx, opts...); err != nil {
return err return err
} }
@@ -84,19 +33,3 @@ func (s *SplitStore) gcBlockstore(b bstore.Blockstore, opts []bstore.BlockstoreG
return fmt.Errorf("blockstore doesn't support garbage collection: %T", b) return fmt.Errorf("blockstore doesn't support garbage collection: %T", b)
} }
func (s *SplitStore) gcBlockstoreOnce(b bstore.Blockstore, opts []bstore.BlockstoreGCOption) error {
if gc, ok := b.(bstore.BlockstoreGCOnce); ok {
log.Debug("gc blockstore once")
startGC := time.Now()
if err := gc.GCOnce(s.ctx, opts...); err != nil {
return err
}
log.Debugw("gc blockstore once done", "took", time.Since(startGC))
return nil
}
return fmt.Errorf("blockstore doesn't support gc once: %T", b)
}
+2 -19
View File
@@ -47,23 +47,6 @@ var (
PruneThreshold = 7 * build.Finality PruneThreshold = 7 * build.Finality
) )
// GCHotstore runs online GC on the chain state in the hotstore according the to options specified
func (s *SplitStore) GCHotStore(opts api.HotGCOpts) error {
if opts.Moving {
gcOpts := []bstore.BlockstoreGCOption{bstore.WithFullGC(true)}
return s.gcBlockstore(s.hot, gcOpts)
}
gcOpts := []bstore.BlockstoreGCOption{bstore.WithThreshold(opts.Threshold)}
var err error
if opts.Periodic {
err = s.gcBlockstore(s.hot, gcOpts)
} else {
err = s.gcBlockstoreOnce(s.hot, gcOpts)
}
return err
}
// PruneChain instructs the SplitStore to prune chain state in the coldstore, according to the // PruneChain instructs the SplitStore to prune chain state in the coldstore, according to the
// options specified. // options specified.
func (s *SplitStore) PruneChain(opts api.PruneOpts) error { func (s *SplitStore) PruneChain(opts api.PruneOpts) error {
@@ -346,9 +329,9 @@ func (s *SplitStore) doPrune(curTs *types.TipSet, retainStateP func(int64) bool,
} }
s.pruneIndex++ s.pruneIndex++
err = s.ds.Put(s.ctx, pruneIndexKey, int64ToBytes(s.pruneIndex)) err = s.ds.Put(s.ctx, pruneIndexKey, int64ToBytes(s.compactionIndex))
if err != nil { if err != nil {
return xerrors.Errorf("error saving prune index: %w", err) return xerrors.Errorf("error saving compaction index: %w", err)
} }
return nil return nil
+2 -2
View File
@@ -5,8 +5,8 @@ import (
"runtime" "runtime"
"sync/atomic" "sync/atomic"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
blocks "github.com/ipfs/go-libipfs/blocks"
"golang.org/x/xerrors" "golang.org/x/xerrors"
) )
@@ -101,7 +101,7 @@ func (s *SplitStore) doReify(c cid.Cid) {
defer s.txnLk.RUnlock() defer s.txnLk.RUnlock()
count := 0 count := 0
_, err := s.walkObjectIncomplete(c, newTmpVisitor(), err := s.walkObjectIncomplete(c, newTmpVisitor(),
func(c cid.Cid) error { func(c cid.Cid) error {
if isUnitaryObject(c) { if isUnitaryObject(c) {
return errStopWalk return errStopWalk
+3 -5
View File
@@ -11,11 +11,11 @@ import (
"testing" "testing"
"time" "time"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
"github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore"
dssync "github.com/ipfs/go-datastore/sync" dssync "github.com/ipfs/go-datastore/sync"
ipld "github.com/ipfs/go-ipld-format" ipld "github.com/ipfs/go-ipld-format"
blocks "github.com/ipfs/go-libipfs/blocks"
logging "github.com/ipfs/go-log/v2" logging "github.com/ipfs/go-log/v2"
mh "github.com/multiformats/go-multihash" mh "github.com/multiformats/go-multihash"
@@ -429,7 +429,7 @@ func testSplitStoreReification(t *testing.T, f func(context.Context, blockstore.
} }
defer ss.Close() //nolint defer ss.Close() //nolint
ss.warmupEpoch.Store(1) ss.warmupEpoch = 1
go ss.reifyOrchestrator() go ss.reifyOrchestrator()
waitForReification := func() { waitForReification := func() {
@@ -529,7 +529,7 @@ func testSplitStoreReificationLimit(t *testing.T, f func(context.Context, blocks
} }
defer ss.Close() //nolint defer ss.Close() //nolint
ss.warmupEpoch.Store(1) ss.warmupEpoch = 1
go ss.reifyOrchestrator() go ss.reifyOrchestrator()
waitForReification := func() { waitForReification := func() {
@@ -757,8 +757,6 @@ func (b *mockStore) DeleteMany(_ context.Context, cids []cid.Cid) error {
return nil return nil
} }
func (b *mockStore) Flush(context.Context) error { return nil }
func (b *mockStore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) { func (b *mockStore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) {
return nil, errors.New("not implemented") return nil, errors.New("not implemented")
} }
+4 -3
View File
@@ -5,9 +5,9 @@ import (
"sync/atomic" "sync/atomic"
"time" "time"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
ipld "github.com/ipfs/go-ipld-format" ipld "github.com/ipfs/go-ipld-format"
blocks "github.com/ipfs/go-libipfs/blocks"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/abi"
@@ -136,8 +136,9 @@ func (s *SplitStore) doWarmup(curTs *types.TipSet) error {
if err != nil { if err != nil {
return xerrors.Errorf("error saving warm up epoch: %w", err) return xerrors.Errorf("error saving warm up epoch: %w", err)
} }
s.mx.Lock()
s.warmupEpoch.Store(int64(epoch)) s.warmupEpoch = epoch
s.mx.Unlock()
// also save the compactionIndex, as this is used as an indicator of warmup for upgraded nodes // also save the compactionIndex, as this is used as an indicator of warmup for upgraded nodes
err = s.ds.Put(s.ctx, compactionIndexKey, int64ToBytes(s.compactionIndex)) err = s.ds.Put(s.ctx, compactionIndexKey, int64ToBytes(s.compactionIndex))
+1 -3
View File
@@ -4,8 +4,8 @@ import (
"context" "context"
"sync" "sync"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
blocks "github.com/ipfs/go-libipfs/blocks"
) )
// NewMemorySync returns a thread-safe in-memory blockstore. // NewMemorySync returns a thread-safe in-memory blockstore.
@@ -20,8 +20,6 @@ type SyncBlockstore struct {
bs MemBlockstore // specifically use a memStore to save indirection overhead. bs MemBlockstore // specifically use a memStore to save indirection overhead.
} }
func (*SyncBlockstore) Flush(context.Context) error { return nil }
func (m *SyncBlockstore) DeleteBlock(ctx context.Context, k cid.Cid) error { func (m *SyncBlockstore) DeleteBlock(ctx context.Context, k cid.Cid) error {
m.mu.Lock() m.mu.Lock()
defer m.mu.Unlock() defer m.mu.Unlock()
+1 -11
View File
@@ -6,9 +6,9 @@ import (
"sync" "sync"
"time" "time"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
ipld "github.com/ipfs/go-ipld-format" ipld "github.com/ipfs/go-ipld-format"
blocks "github.com/ipfs/go-libipfs/blocks"
"github.com/raulk/clock" "github.com/raulk/clock"
"go.uber.org/multierr" "go.uber.org/multierr"
) )
@@ -93,16 +93,6 @@ func (t *TimedCacheBlockstore) rotate() {
t.mu.Unlock() t.mu.Unlock()
} }
func (t *TimedCacheBlockstore) Flush(ctx context.Context) error {
t.mu.Lock()
defer t.mu.Unlock()
if err := t.active.Flush(ctx); err != nil {
return err
}
return t.inactive.Flush(ctx)
}
func (t *TimedCacheBlockstore) Put(ctx context.Context, b blocks.Block) error { func (t *TimedCacheBlockstore) Put(ctx context.Context, b blocks.Block) error {
// Don't check the inactive set here. We want to keep this block for at // Don't check the inactive set here. We want to keep this block for at
// least one interval. // least one interval.
+1 -1
View File
@@ -6,8 +6,8 @@ import (
"testing" "testing"
"time" "time"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
blocks "github.com/ipfs/go-libipfs/blocks"
"github.com/raulk/clock" "github.com/raulk/clock"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
+1 -10
View File
@@ -3,9 +3,9 @@ package blockstore
import ( import (
"context" "context"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
ipld "github.com/ipfs/go-ipld-format" ipld "github.com/ipfs/go-ipld-format"
blocks "github.com/ipfs/go-libipfs/blocks"
) )
type unionBlockstore []Blockstore type unionBlockstore []Blockstore
@@ -55,15 +55,6 @@ func (m unionBlockstore) GetSize(ctx context.Context, cid cid.Cid) (size int, er
return size, err return size, err
} }
func (m unionBlockstore) Flush(ctx context.Context) (err error) {
for _, bs := range m {
if err = bs.Flush(ctx); err != nil {
break
}
}
return err
}
func (m unionBlockstore) Put(ctx context.Context, block blocks.Block) (err error) { func (m unionBlockstore) Put(ctx context.Context, block blocks.Block) (err error) {
for _, bs := range m { for _, bs := range m {
if err = bs.Put(ctx, block); err != nil { if err = bs.Put(ctx, block); err != nil {
+1 -1
View File
@@ -5,7 +5,7 @@ import (
"context" "context"
"testing" "testing"
blocks "github.com/ipfs/go-block-format" blocks "github.com/ipfs/go-libipfs/blocks"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+10 -6
View File
@@ -26,13 +26,17 @@ const UnixfsLinksPerLevel = 1024
const AllowableClockDriftSecs = uint64(1) const AllowableClockDriftSecs = uint64(1)
// Used by tests and some obscure tooling // TODO: nv19: Re-enable when migration is setup
/* inline-gen template //// Used by tests and some obscure tooling
const TestNetworkVersion = network.Version{{.latestNetworkVersion}} ///* inline-gen template
/* inline-gen start */ //
const TestNetworkVersion = network.Version20 //const TestNetworkVersion = network.Version{{.latestNetworkVersion}}
//
///* inline-gen start */
/* inline-gen end */ const TestNetworkVersion = network.Version18
///* inline-gen end */
// Epochs // Epochs
const ForkLengthThreshold = Finality const ForkLengthThreshold = Finality
-5
View File
@@ -9,7 +9,6 @@ package build
import ( import (
"math/big" "math/big"
"time"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
@@ -138,7 +137,3 @@ const BootstrapPeerThreshold = 1
// ChainId defines the chain ID used in the Ethereum JSON-RPC endpoint. // ChainId defines the chain ID used in the Ethereum JSON-RPC endpoint.
// As per https://github.com/ethereum-lists/chains // As per https://github.com/ethereum-lists/chains
const Eip155ChainId = 31415926 const Eip155ChainId = 31415926
// Reducing the delivery delay for equivocation of
// consistent broadcast to just half a second.
var CBDeliveryDelay = 500 * time.Millisecond
+1 -1
View File
@@ -37,7 +37,7 @@ func BuildTypeString() string {
} }
// BuildVersion is the local build version // BuildVersion is the local build version
const BuildVersion = "1.23.2-dev" const BuildVersion = "1.22.1"
func UserVersion() string { func UserVersion() string {
if os.Getenv("LOTUS_VERSION_IGNORE_COMMIT") == "1" { if os.Getenv("LOTUS_VERSION_IGNORE_COMMIT") == "1" {
+13 -12
View File
@@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"go/format" "go/format"
"io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"strconv" "strconv"
@@ -65,7 +66,7 @@ func generateAdapters() error {
} }
{ {
af, err := os.ReadFile(filepath.Join(actDir, "actor.go.template")) af, err := ioutil.ReadFile(filepath.Join(actDir, "actor.go.template"))
if err != nil { if err != nil {
return xerrors.Errorf("loading actor template: %w", err) return xerrors.Errorf("loading actor template: %w", err)
} }
@@ -89,7 +90,7 @@ func generateAdapters() error {
return err return err
} }
if err := os.WriteFile(filepath.Join(actDir, fmt.Sprintf("%s.go", act)), fmted, 0666); err != nil { if err := ioutil.WriteFile(filepath.Join(actDir, fmt.Sprintf("%s.go", act)), fmted, 0666); err != nil {
return err return err
} }
} }
@@ -99,7 +100,7 @@ func generateAdapters() error {
} }
func generateState(actDir string, versions []int) error { func generateState(actDir string, versions []int) error {
af, err := os.ReadFile(filepath.Join(actDir, "state.go.template")) af, err := ioutil.ReadFile(filepath.Join(actDir, "state.go.template"))
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
return nil // skip return nil // skip
@@ -122,7 +123,7 @@ func generateState(actDir string, versions []int) error {
return err return err
} }
if err := os.WriteFile(filepath.Join(actDir, fmt.Sprintf("v%d.go", version)), b.Bytes(), 0666); err != nil { if err := ioutil.WriteFile(filepath.Join(actDir, fmt.Sprintf("v%d.go", version)), b.Bytes(), 0666); err != nil {
return err return err
} }
} }
@@ -131,7 +132,7 @@ func generateState(actDir string, versions []int) error {
} }
func generateMessages(actDir string) error { func generateMessages(actDir string) error {
af, err := os.ReadFile(filepath.Join(actDir, "message.go.template")) af, err := ioutil.ReadFile(filepath.Join(actDir, "message.go.template"))
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
return nil // skip return nil // skip
@@ -154,7 +155,7 @@ func generateMessages(actDir string) error {
return err return err
} }
if err := os.WriteFile(filepath.Join(actDir, fmt.Sprintf("message%d.go", version)), b.Bytes(), 0666); err != nil { if err := ioutil.WriteFile(filepath.Join(actDir, fmt.Sprintf("message%d.go", version)), b.Bytes(), 0666); err != nil {
return err return err
} }
} }
@@ -164,7 +165,7 @@ func generateMessages(actDir string) error {
func generatePolicy(policyPath string) error { func generatePolicy(policyPath string) error {
pf, err := os.ReadFile(policyPath + ".template") pf, err := ioutil.ReadFile(policyPath + ".template")
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
return nil // skip return nil // skip
@@ -186,7 +187,7 @@ func generatePolicy(policyPath string) error {
return err return err
} }
if err := os.WriteFile(policyPath, b.Bytes(), 0666); err != nil { if err := ioutil.WriteFile(policyPath, b.Bytes(), 0666); err != nil {
return err return err
} }
@@ -195,7 +196,7 @@ func generatePolicy(policyPath string) error {
func generateBuiltin(builtinPath string) error { func generateBuiltin(builtinPath string) error {
bf, err := os.ReadFile(builtinPath + ".template") bf, err := ioutil.ReadFile(builtinPath + ".template")
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
return nil // skip return nil // skip
@@ -217,7 +218,7 @@ func generateBuiltin(builtinPath string) error {
return err return err
} }
if err := os.WriteFile(builtinPath, b.Bytes(), 0666); err != nil { if err := ioutil.WriteFile(builtinPath, b.Bytes(), 0666); err != nil {
return err return err
} }
@@ -226,7 +227,7 @@ func generateBuiltin(builtinPath string) error {
func generateRegistry(registryPath string) error { func generateRegistry(registryPath string) error {
bf, err := os.ReadFile(registryPath + ".template") bf, err := ioutil.ReadFile(registryPath + ".template")
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
return nil // skip return nil // skip
@@ -247,7 +248,7 @@ func generateRegistry(registryPath string) error {
return err return err
} }
if err := os.WriteFile(registryPath, b.Bytes(), 0666); err != nil { if err := ioutil.WriteFile(registryPath, b.Bytes(), 0666); err != nil {
return err return err
} }
@@ -83,7 +83,6 @@ type State interface {
GetAllocations(clientIdAddr address.Address) (map[AllocationId]Allocation, error) GetAllocations(clientIdAddr address.Address) (map[AllocationId]Allocation, error)
GetClaim(providerIdAddr address.Address, claimId ClaimId) (*Claim, bool, error) GetClaim(providerIdAddr address.Address, claimId ClaimId) (*Claim, bool, error)
GetClaims(providerIdAddr address.Address) (map[ClaimId]Claim, error) GetClaims(providerIdAddr address.Address) (map[ClaimId]Claim, error)
GetClaimIdsBySector(providerIdAddr address.Address) (map[abi.SectorNumber][]ClaimId, error)
GetState() interface{} GetState() interface{}
} }
@@ -170,27 +170,6 @@ func (s *state{{.v}}) GetClaims(providerIdAddr address.Address) (map[ClaimId]Cla
{{end}} {{end}}
} }
func (s *state{{.v}}) GetClaimIdsBySector(providerIdAddr address.Address) (map[abi.SectorNumber][]ClaimId, error) {
{{if (le .v 8)}}
return nil, xerrors.Errorf("unsupported in actors v{{.v}}")
{{else}}
v{{.v}}Map, err := s.LoadClaimsToMap(s.store, providerIdAddr)
retMap := make(map[abi.SectorNumber][]ClaimId)
for k, v := range v{{.v}}Map {
claims, ok := retMap[v.Sector]
if !ok {
retMap[v.Sector] = []ClaimId{ClaimId(k)}
} else {
retMap[v.Sector] = append(claims, ClaimId(k))
}
}
return retMap, err
{{end}}
}
func (s *state{{.v}}) ActorKey() string { func (s *state{{.v}}) ActorKey() string {
return manifest.VerifregKey return manifest.VerifregKey
} }
-6
View File
@@ -118,12 +118,6 @@ func (s *state0) GetClaims(providerIdAddr address.Address) (map[ClaimId]Claim, e
} }
func (s *state0) GetClaimIdsBySector(providerIdAddr address.Address) (map[abi.SectorNumber][]ClaimId, error) {
return nil, xerrors.Errorf("unsupported in actors v0")
}
func (s *state0) ActorKey() string { func (s *state0) ActorKey() string {
return manifest.VerifregKey return manifest.VerifregKey
} }
-18
View File
@@ -134,24 +134,6 @@ func (s *state10) GetClaims(providerIdAddr address.Address) (map[ClaimId]Claim,
} }
func (s *state10) GetClaimIdsBySector(providerIdAddr address.Address) (map[abi.SectorNumber][]ClaimId, error) {
v10Map, err := s.LoadClaimsToMap(s.store, providerIdAddr)
retMap := make(map[abi.SectorNumber][]ClaimId)
for k, v := range v10Map {
claims, ok := retMap[v.Sector]
if !ok {
retMap[v.Sector] = []ClaimId{ClaimId(k)}
} else {
retMap[v.Sector] = append(claims, ClaimId(k))
}
}
return retMap, err
}
func (s *state10) ActorKey() string { func (s *state10) ActorKey() string {
return manifest.VerifregKey return manifest.VerifregKey
} }
-18
View File
@@ -134,24 +134,6 @@ func (s *state11) GetClaims(providerIdAddr address.Address) (map[ClaimId]Claim,
} }
func (s *state11) GetClaimIdsBySector(providerIdAddr address.Address) (map[abi.SectorNumber][]ClaimId, error) {
v11Map, err := s.LoadClaimsToMap(s.store, providerIdAddr)
retMap := make(map[abi.SectorNumber][]ClaimId)
for k, v := range v11Map {
claims, ok := retMap[v.Sector]
if !ok {
retMap[v.Sector] = []ClaimId{ClaimId(k)}
} else {
retMap[v.Sector] = append(claims, ClaimId(k))
}
}
return retMap, err
}
func (s *state11) ActorKey() string { func (s *state11) ActorKey() string {
return manifest.VerifregKey return manifest.VerifregKey
} }
-6
View File
@@ -118,12 +118,6 @@ func (s *state2) GetClaims(providerIdAddr address.Address) (map[ClaimId]Claim, e
} }
func (s *state2) GetClaimIdsBySector(providerIdAddr address.Address) (map[abi.SectorNumber][]ClaimId, error) {
return nil, xerrors.Errorf("unsupported in actors v2")
}
func (s *state2) ActorKey() string { func (s *state2) ActorKey() string {
return manifest.VerifregKey return manifest.VerifregKey
} }
-6
View File
@@ -119,12 +119,6 @@ func (s *state3) GetClaims(providerIdAddr address.Address) (map[ClaimId]Claim, e
} }
func (s *state3) GetClaimIdsBySector(providerIdAddr address.Address) (map[abi.SectorNumber][]ClaimId, error) {
return nil, xerrors.Errorf("unsupported in actors v3")
}
func (s *state3) ActorKey() string { func (s *state3) ActorKey() string {
return manifest.VerifregKey return manifest.VerifregKey
} }
-6
View File
@@ -119,12 +119,6 @@ func (s *state4) GetClaims(providerIdAddr address.Address) (map[ClaimId]Claim, e
} }
func (s *state4) GetClaimIdsBySector(providerIdAddr address.Address) (map[abi.SectorNumber][]ClaimId, error) {
return nil, xerrors.Errorf("unsupported in actors v4")
}
func (s *state4) ActorKey() string { func (s *state4) ActorKey() string {
return manifest.VerifregKey return manifest.VerifregKey
} }
-6
View File
@@ -119,12 +119,6 @@ func (s *state5) GetClaims(providerIdAddr address.Address) (map[ClaimId]Claim, e
} }
func (s *state5) GetClaimIdsBySector(providerIdAddr address.Address) (map[abi.SectorNumber][]ClaimId, error) {
return nil, xerrors.Errorf("unsupported in actors v5")
}
func (s *state5) ActorKey() string { func (s *state5) ActorKey() string {
return manifest.VerifregKey return manifest.VerifregKey
} }
-6
View File
@@ -119,12 +119,6 @@ func (s *state6) GetClaims(providerIdAddr address.Address) (map[ClaimId]Claim, e
} }
func (s *state6) GetClaimIdsBySector(providerIdAddr address.Address) (map[abi.SectorNumber][]ClaimId, error) {
return nil, xerrors.Errorf("unsupported in actors v6")
}
func (s *state6) ActorKey() string { func (s *state6) ActorKey() string {
return manifest.VerifregKey return manifest.VerifregKey
} }
-6
View File
@@ -118,12 +118,6 @@ func (s *state7) GetClaims(providerIdAddr address.Address) (map[ClaimId]Claim, e
} }
func (s *state7) GetClaimIdsBySector(providerIdAddr address.Address) (map[abi.SectorNumber][]ClaimId, error) {
return nil, xerrors.Errorf("unsupported in actors v7")
}
func (s *state7) ActorKey() string { func (s *state7) ActorKey() string {
return manifest.VerifregKey return manifest.VerifregKey
} }
-6
View File
@@ -118,12 +118,6 @@ func (s *state8) GetClaims(providerIdAddr address.Address) (map[ClaimId]Claim, e
} }
func (s *state8) GetClaimIdsBySector(providerIdAddr address.Address) (map[abi.SectorNumber][]ClaimId, error) {
return nil, xerrors.Errorf("unsupported in actors v8")
}
func (s *state8) ActorKey() string { func (s *state8) ActorKey() string {
return manifest.VerifregKey return manifest.VerifregKey
} }
-18
View File
@@ -133,24 +133,6 @@ func (s *state9) GetClaims(providerIdAddr address.Address) (map[ClaimId]Claim, e
} }
func (s *state9) GetClaimIdsBySector(providerIdAddr address.Address) (map[abi.SectorNumber][]ClaimId, error) {
v9Map, err := s.LoadClaimsToMap(s.store, providerIdAddr)
retMap := make(map[abi.SectorNumber][]ClaimId)
for k, v := range v9Map {
claims, ok := retMap[v.Sector]
if !ok {
retMap[v.Sector] = []ClaimId{ClaimId(k)}
} else {
retMap[v.Sector] = append(claims, ClaimId(k))
}
}
return retMap, err
}
func (s *state9) ActorKey() string { func (s *state9) ActorKey() string {
return manifest.VerifregKey return manifest.VerifregKey
} }
-1
View File
@@ -137,7 +137,6 @@ type State interface {
GetAllocations(clientIdAddr address.Address) (map[AllocationId]Allocation, error) GetAllocations(clientIdAddr address.Address) (map[AllocationId]Allocation, error)
GetClaim(providerIdAddr address.Address, claimId ClaimId) (*Claim, bool, error) GetClaim(providerIdAddr address.Address, claimId ClaimId) (*Claim, bool, error)
GetClaims(providerIdAddr address.Address) (map[ClaimId]Claim, error) GetClaims(providerIdAddr address.Address) (map[ClaimId]Claim, error)
GetClaimIdsBySector(providerIdAddr address.Address) (map[abi.SectorNumber][]ClaimId, error)
GetState() interface{} GetState() interface{}
} }
+9 -4
View File
@@ -3,14 +3,14 @@ package chain
import ( import (
"fmt" "fmt"
lru "github.com/hashicorp/golang-lru/v2" lru "github.com/hashicorp/golang-lru"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
) )
type BadBlockCache struct { type BadBlockCache struct {
badBlocks *lru.ARCCache[cid.Cid, BadBlockReason] badBlocks *lru.ARCCache
} }
type BadBlockReason struct { type BadBlockReason struct {
@@ -43,7 +43,7 @@ func (bbr BadBlockReason) String() string {
} }
func NewBadBlockCache() *BadBlockCache { func NewBadBlockCache() *BadBlockCache {
cache, err := lru.NewARC[cid.Cid, BadBlockReason](build.BadBlockCacheSize) cache, err := lru.NewARC(build.BadBlockCacheSize)
if err != nil { if err != nil {
panic(err) // ok panic(err) // ok
} }
@@ -66,5 +66,10 @@ func (bts *BadBlockCache) Purge() {
} }
func (bts *BadBlockCache) Has(c cid.Cid) (BadBlockReason, bool) { func (bts *BadBlockCache) Has(c cid.Cid) (BadBlockReason, bool) {
return bts.badBlocks.Get(c) rval, ok := bts.badBlocks.Get(c)
if !ok {
return BadBlockReason{}, false
}
return rval.(BadBlockReason), true
} }
+17 -22
View File
@@ -8,14 +8,14 @@ import (
dchain "github.com/drand/drand/chain" dchain "github.com/drand/drand/chain"
dclient "github.com/drand/drand/client" dclient "github.com/drand/drand/client"
hclient "github.com/drand/drand/client/http" hclient "github.com/drand/drand/client/http"
"github.com/drand/drand/common/scheme"
dlog "github.com/drand/drand/log" dlog "github.com/drand/drand/log"
gclient "github.com/drand/drand/lp2p/client" gclient "github.com/drand/drand/lp2p/client"
"github.com/drand/kyber" "github.com/drand/kyber"
lru "github.com/hashicorp/golang-lru/v2" kzap "github.com/go-kit/kit/log/zap"
lru "github.com/hashicorp/golang-lru"
logging "github.com/ipfs/go-log/v2" logging "github.com/ipfs/go-log/v2"
pubsub "github.com/libp2p/go-libp2p-pubsub" pubsub "github.com/libp2p/go-libp2p-pubsub"
"go.uber.org/zap" "go.uber.org/zap/zapcore"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/abi"
@@ -61,7 +61,7 @@ type DrandBeacon struct {
filGenTime uint64 filGenTime uint64
filRoundTime uint64 filRoundTime uint64
localCache *lru.Cache[uint64, *types.BeaconEntry] localCache *lru.Cache
} }
// DrandHTTPClient interface overrides the user agent used by drand // DrandHTTPClient interface overrides the user agent used by drand
@@ -69,18 +69,6 @@ type DrandHTTPClient interface {
SetUserAgent(string) SetUserAgent(string)
} }
type logger struct {
*zap.SugaredLogger
}
func (l *logger) With(args ...interface{}) dlog.Logger {
return &logger{l.SugaredLogger.With(args...)}
}
func (l *logger) Named(s string) dlog.Logger {
return &logger{l.SugaredLogger.Named(s)}
}
func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config dtypes.DrandConfig) (*DrandBeacon, error) { func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config dtypes.DrandConfig) (*DrandBeacon, error) {
if genesisTs == 0 { if genesisTs == 0 {
panic("what are you doing this cant be zero") panic("what are you doing this cant be zero")
@@ -91,6 +79,9 @@ func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config dtypes
return nil, xerrors.Errorf("unable to unmarshal drand chain info: %w", err) return nil, xerrors.Errorf("unable to unmarshal drand chain info: %w", err)
} }
dlogger := dlog.NewKitLoggerFrom(kzap.NewZapSugarLogger(
log.SugaredLogger.Desugar(), zapcore.InfoLevel))
var clients []dclient.Client var clients []dclient.Client
for _, url := range config.Servers { for _, url := range config.Servers {
hc, err := hclient.NewWithInfo(url, drandChain, nil) hc, err := hclient.NewWithInfo(url, drandChain, nil)
@@ -105,7 +96,7 @@ func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config dtypes
opts := []dclient.Option{ opts := []dclient.Option{
dclient.WithChainInfo(drandChain), dclient.WithChainInfo(drandChain),
dclient.WithCacheSize(1024), dclient.WithCacheSize(1024),
dclient.WithLogger(&logger{&log.SugaredLogger}), dclient.WithLogger(dlogger),
} }
if ps != nil { if ps != nil {
@@ -119,7 +110,7 @@ func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config dtypes
return nil, xerrors.Errorf("creating drand client: %w", err) return nil, xerrors.Errorf("creating drand client: %w", err)
} }
lc, err := lru.New[uint64, *types.BeaconEntry](1024) lc, err := lru.New(1024)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -169,12 +160,16 @@ func (db *DrandBeacon) Entry(ctx context.Context, round uint64) <-chan beacon.Re
return out return out
} }
func (db *DrandBeacon) cacheValue(e types.BeaconEntry) { func (db *DrandBeacon) cacheValue(e types.BeaconEntry) {
db.localCache.Add(e.Round, &e) db.localCache.Add(e.Round, e)
} }
func (db *DrandBeacon) getCachedValue(round uint64) *types.BeaconEntry { func (db *DrandBeacon) getCachedValue(round uint64) *types.BeaconEntry {
v, _ := db.localCache.Get(round) v, ok := db.localCache.Get(round)
return v if !ok {
return nil
}
e, _ := v.(types.BeaconEntry)
return &e
} }
func (db *DrandBeacon) VerifyEntry(curr types.BeaconEntry, prev types.BeaconEntry) error { func (db *DrandBeacon) VerifyEntry(curr types.BeaconEntry, prev types.BeaconEntry) error {
@@ -199,7 +194,7 @@ func (db *DrandBeacon) VerifyEntry(curr types.BeaconEntry, prev types.BeaconEntr
Round: curr.Round, Round: curr.Round,
Signature: curr.Data, Signature: curr.Data,
} }
err := dchain.NewVerifier(scheme.GetSchemeFromEnv()).VerifyBeacon(*b, db.pubkey) err := dchain.VerifyBeacon(db.pubkey, b)
if err == nil { if err == nil {
db.cacheValue(curr) db.cacheValue(curr)
} }
+3 -4
View File
@@ -3,7 +3,6 @@
package drand package drand
import ( import (
"context"
"os" "os"
"testing" "testing"
@@ -21,11 +20,11 @@ func TestPrintGroupInfo(t *testing.T) {
c, err := hclient.New(server, nil, nil) c, err := hclient.New(server, nil, nil)
assert.NoError(t, err) assert.NoError(t, err)
cg := c.(interface { cg := c.(interface {
FetchChainInfo(ctx context.Context, groupHash []byte) (*dchain.Info, error) FetchChainInfo(groupHash []byte) (*dchain.Info, error)
}) })
chain, err := cg.FetchChainInfo(context.Background(), nil) chain, err := cg.FetchChainInfo(nil)
assert.NoError(t, err) assert.NoError(t, err)
err = chain.ToJSON(os.Stdout, nil) err = chain.ToJSON(os.Stdout)
assert.NoError(t, err) assert.NoError(t, err)
} }
+7 -5
View File
@@ -5,7 +5,7 @@ import (
"sync" "sync"
"time" "time"
lru "github.com/hashicorp/golang-lru/v2" lru "github.com/hashicorp/golang-lru"
"github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/peer"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
@@ -17,7 +17,7 @@ type blockReceiptTracker struct {
// using an LRU cache because i don't want to handle all the edge cases for // using an LRU cache because i don't want to handle all the edge cases for
// manual cleanup and maintenance of a fixed size set // manual cleanup and maintenance of a fixed size set
cache *lru.Cache[types.TipSetKey, *peerSet] cache *lru.Cache
} }
type peerSet struct { type peerSet struct {
@@ -25,7 +25,7 @@ type peerSet struct {
} }
func newBlockReceiptTracker() *blockReceiptTracker { func newBlockReceiptTracker() *blockReceiptTracker {
c, _ := lru.New[types.TipSetKey, *peerSet](512) c, _ := lru.New(512)
return &blockReceiptTracker{ return &blockReceiptTracker{
cache: c, cache: c,
} }
@@ -46,18 +46,20 @@ func (brt *blockReceiptTracker) Add(p peer.ID, ts *types.TipSet) {
return return
} }
val.peers[p] = build.Clock.Now() val.(*peerSet).peers[p] = build.Clock.Now()
} }
func (brt *blockReceiptTracker) GetPeers(ts *types.TipSet) []peer.ID { func (brt *blockReceiptTracker) GetPeers(ts *types.TipSet) []peer.ID {
brt.lk.Lock() brt.lk.Lock()
defer brt.lk.Unlock() defer brt.lk.Unlock()
ps, ok := brt.cache.Get(ts.Key()) val, ok := brt.cache.Get(ts.Key())
if !ok { if !ok {
return nil return nil
} }
ps := val.(*peerSet)
out := make([]peer.ID, 0, len(ps.peers)) out := make([]peer.ID, 0, len(ps.peers))
for p := range ps.peers { for p := range ps.peers {
out = append(out, p) out = append(out, p)
-514
View File
@@ -1,514 +0,0 @@
package consensus
import (
"context"
"fmt"
"strings"
"github.com/hashicorp/go-multierror"
"github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
logging "github.com/ipfs/go-log/v2"
pubsub "github.com/libp2p/go-libp2p-pubsub"
"github.com/multiformats/go-varint"
cbg "github.com/whyrusleeping/cbor-gen"
"go.opencensus.io/stats"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
builtintypes "github.com/filecoin-project/go-state-types/builtin"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/go-state-types/network"
blockadt "github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/lotus/api"
bstore "github.com/filecoin-project/lotus/blockstore"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors/builtin"
"github.com/filecoin-project/lotus/chain/state"
"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"
"github.com/filecoin-project/lotus/lib/async"
"github.com/filecoin-project/lotus/metrics"
)
// Common operations shared by all consensus algorithm implementations.
var log = logging.Logger("consensus-common")
// RunAsyncChecks accepts a list of checks to perform in parallel.
//
// Each consensus algorithm may choose to perform a set of different
// checks when a new blocks is received.
func RunAsyncChecks(ctx context.Context, await []async.ErrorFuture) error {
var merr error
for _, fut := range await {
if err := fut.AwaitContext(ctx); err != nil {
merr = multierror.Append(merr, err)
}
}
if merr != nil {
mulErr := merr.(*multierror.Error)
mulErr.ErrorFormat = func(es []error) string {
if len(es) == 1 {
return fmt.Sprintf("1 error occurred:\n\t* %+v\n\n", es[0])
}
points := make([]string, len(es))
for i, err := range es {
points[i] = fmt.Sprintf("* %+v", err)
}
return fmt.Sprintf(
"%d errors occurred:\n\t%s\n\n",
len(es), strings.Join(points, "\n\t"))
}
return mulErr
}
return nil
}
// CommonBlkChecks performed by all consensus implementations.
func CommonBlkChecks(ctx context.Context, sm *stmgr.StateManager, cs *store.ChainStore,
b *types.FullBlock, baseTs *types.TipSet) []async.ErrorFuture {
h := b.Header
msgsCheck := async.Err(func() error {
if b.Cid() == build.WhitelistedBlock {
return nil
}
if err := checkBlockMessages(ctx, sm, cs, b, baseTs); err != nil {
return xerrors.Errorf("block had invalid messages: %w", err)
}
return nil
})
baseFeeCheck := async.Err(func() error {
baseFee, err := cs.ComputeBaseFee(ctx, baseTs)
if err != nil {
return xerrors.Errorf("computing base fee: %w", err)
}
if types.BigCmp(baseFee, b.Header.ParentBaseFee) != 0 {
return xerrors.Errorf("base fee doesn't match: %s (header) != %s (computed)",
b.Header.ParentBaseFee, baseFee)
}
return nil
})
stateRootCheck := async.Err(func() error {
stateroot, precp, err := sm.TipSetState(ctx, baseTs)
if err != nil {
return xerrors.Errorf("get tipsetstate(%d, %s) failed: %w", h.Height, h.Parents, err)
}
if stateroot != h.ParentStateRoot {
msgs, err := cs.MessagesForTipset(ctx, baseTs)
if err != nil {
log.Error("failed to load messages for tipset during tipset state mismatch error: ", err)
} else {
log.Warn("Messages for tipset with mismatching state:")
for i, m := range msgs {
mm := m.VMMessage()
log.Warnf("Message[%d]: from=%s to=%s method=%d params=%x", i, mm.From, mm.To, mm.Method, mm.Params)
}
}
return xerrors.Errorf("parent state root did not match computed state (%s != %s)", h.ParentStateRoot, stateroot)
}
if precp != h.ParentMessageReceipts {
return xerrors.Errorf("parent receipts root did not match computed value (%s != %s)", precp, h.ParentMessageReceipts)
}
return nil
})
return []async.ErrorFuture{
msgsCheck,
baseFeeCheck,
stateRootCheck,
}
}
func IsValidForSending(nv network.Version, act *types.Actor) bool {
// Before nv18 (Hygge), we only supported built-in account actors as senders.
//
// Note: this gate is probably superfluous, since:
// 1. Placeholder actors cannot be created before nv18.
// 2. EthAccount actors cannot be created before nv18.
// 3. Delegated addresses cannot be created before nv18.
//
// But it's a safeguard.
//
// Note 2: ad-hoc checks for network versions like this across the codebase
// will be problematic with networks with diverging version lineages
// (e.g. Hyperspace). We need to revisit this strategy entirely.
if nv < network.Version18 {
return builtin.IsAccountActor(act.Code)
}
// After nv18, we also support other kinds of senders.
if builtin.IsAccountActor(act.Code) || builtin.IsEthAccountActor(act.Code) {
return true
}
// Allow placeholder actors with a delegated address and nonce 0 to send a message.
// These will be converted to an EthAccount actor on first send.
if !builtin.IsPlaceholderActor(act.Code) || act.Nonce != 0 || act.Address == nil || act.Address.Protocol() != address.Delegated {
return false
}
// Only allow such actors to send if their delegated address is in the EAM's namespace.
id, _, err := varint.FromUvarint(act.Address.Payload())
return err == nil && id == builtintypes.EthereumAddressManagerActorID
}
func checkBlockMessages(ctx context.Context, sm *stmgr.StateManager, cs *store.ChainStore, b *types.FullBlock, baseTs *types.TipSet) error {
{
var sigCids []cid.Cid // this is what we get for people not wanting the marshalcbor method on the cid type
var pubks [][]byte
for _, m := range b.BlsMessages {
sigCids = append(sigCids, m.Cid())
pubk, err := sm.GetBlsPublicKey(ctx, m.From, baseTs)
if err != nil {
return xerrors.Errorf("failed to load bls public to validate block: %w", err)
}
pubks = append(pubks, pubk)
}
if err := VerifyBlsAggregate(ctx, b.Header.BLSAggregate, sigCids, pubks); err != nil {
return xerrors.Errorf("bls aggregate signature was invalid: %w", err)
}
}
nonces := make(map[address.Address]uint64)
stateroot, _, err := sm.TipSetState(ctx, baseTs)
if err != nil {
return xerrors.Errorf("failed to compute tipsettate for %s: %w", baseTs.Key(), err)
}
st, err := state.LoadStateTree(cs.ActorStore(ctx), stateroot)
if err != nil {
return xerrors.Errorf("failed to load base state tree: %w", err)
}
nv := sm.GetNetworkVersion(ctx, b.Header.Height)
pl := vm.PricelistByEpoch(b.Header.Height)
var sumGasLimit int64
checkMsg := func(msg types.ChainMsg) error {
m := msg.VMMessage()
// Phase 1: syntactic validation, as defined in the spec
minGas := pl.OnChainMessage(msg.ChainLength())
if err := m.ValidForBlockInclusion(minGas.Total(), nv); err != nil {
return xerrors.Errorf("msg %s invalid for block inclusion: %w", m.Cid(), err)
}
// ValidForBlockInclusion checks if any single message does not exceed BlockGasLimit
// So below is overflow safe
sumGasLimit += m.GasLimit
if sumGasLimit > build.BlockGasLimit {
return xerrors.Errorf("block gas limit exceeded")
}
// Phase 2: (Partial) semantic validation:
// the sender exists and is an account actor, and the nonces make sense
var sender address.Address
if nv >= network.Version13 {
sender, err = st.LookupID(m.From)
if err != nil {
return xerrors.Errorf("failed to lookup sender %s: %w", m.From, err)
}
} else {
sender = m.From
}
if _, ok := nonces[sender]; !ok {
// `GetActor` does not validate that this is an account actor.
act, err := st.GetActor(sender)
if err != nil {
return xerrors.Errorf("failed to get actor: %w", err)
}
if !IsValidForSending(nv, act) {
return xerrors.New("Sender must be an account actor")
}
nonces[sender] = act.Nonce
}
if nonces[sender] != m.Nonce {
return xerrors.Errorf("wrong nonce (exp: %d, got: %d)", nonces[sender], m.Nonce)
}
nonces[sender]++
return nil
}
// Validate message arrays in a temporary blockstore.
tmpbs := bstore.NewMemory()
tmpstore := blockadt.WrapStore(ctx, cbor.NewCborStore(tmpbs))
bmArr := blockadt.MakeEmptyArray(tmpstore)
for i, m := range b.BlsMessages {
if err := checkMsg(m); err != nil {
return xerrors.Errorf("block had invalid bls message at index %d: %w", i, err)
}
c, err := store.PutMessage(ctx, tmpbs, m)
if err != nil {
return xerrors.Errorf("failed to store message %s: %w", m.Cid(), err)
}
k := cbg.CborCid(c)
if err := bmArr.Set(uint64(i), &k); err != nil {
return xerrors.Errorf("failed to put bls message at index %d: %w", i, err)
}
}
smArr := blockadt.MakeEmptyArray(tmpstore)
for i, m := range b.SecpkMessages {
if nv >= network.Version14 && !IsValidSecpkSigType(nv, m.Signature.Type) {
return xerrors.Errorf("block had invalid signed message at index %d: %w", i, err)
}
if err := checkMsg(m); err != nil {
return xerrors.Errorf("block had invalid secpk message at index %d: %w", i, err)
}
// `From` being an account actor is only validated inside the `vm.ResolveToDeterministicAddr` call
// in `StateManager.ResolveToDeterministicAddress` here (and not in `checkMsg`).
kaddr, err := sm.ResolveToDeterministicAddress(ctx, m.Message.From, baseTs)
if err != nil {
return xerrors.Errorf("failed to resolve key addr: %w", err)
}
if err := AuthenticateMessage(m, kaddr); err != nil {
return xerrors.Errorf("failed to validate signature: %w", err)
}
c, err := store.PutMessage(ctx, tmpbs, m)
if err != nil {
return xerrors.Errorf("failed to store message %s: %w", m.Cid(), err)
}
k := cbg.CborCid(c)
if err := smArr.Set(uint64(i), &k); err != nil {
return xerrors.Errorf("failed to put secpk message at index %d: %w", i, err)
}
}
bmroot, err := bmArr.Root()
if err != nil {
return xerrors.Errorf("failed to root bls msgs: %w", err)
}
smroot, err := smArr.Root()
if err != nil {
return xerrors.Errorf("failed to root secp msgs: %w", err)
}
mrcid, err := tmpstore.Put(ctx, &types.MsgMeta{
BlsMessages: bmroot,
SecpkMessages: smroot,
})
if err != nil {
return xerrors.Errorf("failed to put msg meta: %w", err)
}
if b.Header.Messages != mrcid {
return fmt.Errorf("messages didnt match message root in header")
}
// Finally, flush.
err = vm.Copy(ctx, tmpbs, cs.ChainBlockstore(), mrcid)
if err != nil {
return xerrors.Errorf("failed to flush:%w", err)
}
return nil
}
// CreateBlockHeader generates the block header from the block template of
// the block being proposed.
func CreateBlockHeader(ctx context.Context, sm *stmgr.StateManager, pts *types.TipSet,
bt *api.BlockTemplate) (*types.BlockHeader, []*types.Message, []*types.SignedMessage, error) {
st, recpts, err := sm.TipSetState(ctx, pts)
if err != nil {
return nil, nil, nil, xerrors.Errorf("failed to load tipset state: %w", err)
}
next := &types.BlockHeader{
Miner: bt.Miner,
Parents: bt.Parents.Cids(),
Ticket: bt.Ticket,
ElectionProof: bt.Eproof,
BeaconEntries: bt.BeaconValues,
Height: bt.Epoch,
Timestamp: bt.Timestamp,
WinPoStProof: bt.WinningPoStProof,
ParentStateRoot: st,
ParentMessageReceipts: recpts,
}
var blsMessages []*types.Message
var secpkMessages []*types.SignedMessage
var blsMsgCids, secpkMsgCids []cid.Cid
var blsSigs []crypto.Signature
nv := sm.GetNetworkVersion(ctx, bt.Epoch)
for _, msg := range bt.Messages {
if msg.Signature.Type == crypto.SigTypeBLS {
blsSigs = append(blsSigs, msg.Signature)
blsMessages = append(blsMessages, &msg.Message)
c, err := sm.ChainStore().PutMessage(ctx, &msg.Message)
if err != nil {
return nil, nil, nil, err
}
blsMsgCids = append(blsMsgCids, c)
} else if IsValidSecpkSigType(nv, msg.Signature.Type) {
c, err := sm.ChainStore().PutMessage(ctx, msg)
if err != nil {
return nil, nil, nil, err
}
secpkMsgCids = append(secpkMsgCids, c)
secpkMessages = append(secpkMessages, msg)
} else {
return nil, nil, nil, xerrors.Errorf("unknown sig type: %d", msg.Signature.Type)
}
}
store := sm.ChainStore().ActorStore(ctx)
blsmsgroot, err := ToMessagesArray(store, blsMsgCids)
if err != nil {
return nil, nil, nil, xerrors.Errorf("building bls amt: %w", err)
}
secpkmsgroot, err := ToMessagesArray(store, secpkMsgCids)
if err != nil {
return nil, nil, nil, xerrors.Errorf("building secpk amt: %w", err)
}
mmcid, err := store.Put(store.Context(), &types.MsgMeta{
BlsMessages: blsmsgroot,
SecpkMessages: secpkmsgroot,
})
if err != nil {
return nil, nil, nil, err
}
next.Messages = mmcid
aggSig, err := AggregateSignatures(blsSigs)
if err != nil {
return nil, nil, nil, err
}
next.BLSAggregate = aggSig
pweight, err := sm.ChainStore().Weight(ctx, pts)
if err != nil {
return nil, nil, nil, err
}
next.ParentWeight = pweight
baseFee, err := sm.ChainStore().ComputeBaseFee(ctx, pts)
if err != nil {
return nil, nil, nil, xerrors.Errorf("computing base fee: %w", err)
}
next.ParentBaseFee = baseFee
return next, blsMessages, secpkMessages, err
}
// Basic sanity-checks performed when a block is proposed locally.
func validateLocalBlock(ctx context.Context, msg *pubsub.Message) (pubsub.ValidationResult, string) {
stats.Record(ctx, metrics.BlockPublished.M(1))
if size := msg.Size(); size > 1<<20-1<<15 {
log.Errorf("ignoring oversize block (%dB)", size)
return pubsub.ValidationIgnore, "oversize_block"
}
blk, what, err := decodeAndCheckBlock(msg)
if err != nil {
log.Errorf("got invalid local block: %s", err)
return pubsub.ValidationIgnore, what
}
msg.ValidatorData = blk
stats.Record(ctx, metrics.BlockValidationSuccess.M(1))
return pubsub.ValidationAccept, ""
}
func decodeAndCheckBlock(msg *pubsub.Message) (*types.BlockMsg, string, error) {
blk, err := types.DecodeBlockMsg(msg.GetData())
if err != nil {
return nil, "invalid", xerrors.Errorf("error decoding block: %w", err)
}
if count := len(blk.BlsMessages) + len(blk.SecpkMessages); count > build.BlockMessageLimit {
return nil, "too_many_messages", fmt.Errorf("block contains too many messages (%d)", count)
}
// make sure we have a signature
if blk.Header.BlockSig == nil {
return nil, "missing_signature", fmt.Errorf("block without a signature")
}
return blk, "", nil
}
func validateMsgMeta(ctx context.Context, msg *types.BlockMsg) error {
// TODO there has to be a simpler way to do this without the blockstore dance
// block headers use adt0
store := blockadt.WrapStore(ctx, cbor.NewCborStore(bstore.NewMemory()))
bmArr := blockadt.MakeEmptyArray(store)
smArr := blockadt.MakeEmptyArray(store)
for i, m := range msg.BlsMessages {
c := cbg.CborCid(m)
if err := bmArr.Set(uint64(i), &c); err != nil {
return err
}
}
for i, m := range msg.SecpkMessages {
c := cbg.CborCid(m)
if err := smArr.Set(uint64(i), &c); err != nil {
return err
}
}
bmroot, err := bmArr.Root()
if err != nil {
return err
}
smroot, err := smArr.Root()
if err != nil {
return err
}
mrcid, err := store.Put(store.Context(), &types.MsgMeta{
BlsMessages: bmroot,
SecpkMessages: smroot,
})
if err != nil {
return err
}
if msg.Header.Messages != mrcid {
return fmt.Errorf("messages didn't match root cid in header")
}
return nil
}
@@ -1,9 +1,8 @@
package consensus package filcns
import ( import (
"context" "context"
"sync/atomic" "sync/atomic"
"time"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor" cbor "github.com/ipfs/go-ipld-cbor"
@@ -27,6 +26,7 @@ import (
"github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/blockstore"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/builtin"
"github.com/filecoin-project/lotus/chain/actors/builtin/cron" "github.com/filecoin-project/lotus/chain/actors/builtin/cron"
"github.com/filecoin-project/lotus/chain/actors/builtin/reward" "github.com/filecoin-project/lotus/chain/actors/builtin/reward"
@@ -56,12 +56,10 @@ func NewActorRegistry() *vm.ActorRegistry {
return inv return inv
} }
type TipSetExecutor struct { type TipSetExecutor struct{}
reward RewardFunc
}
func NewTipSetExecutor(r RewardFunc) *TipSetExecutor { func NewTipSetExecutor() *TipSetExecutor {
return &TipSetExecutor{reward: r} return &TipSetExecutor{}
} }
func (t *TipSetExecutor) NewActorRegistry() *vm.ActorRegistry { func (t *TipSetExecutor) NewActorRegistry() *vm.ActorRegistry {
@@ -110,14 +108,11 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context,
TipSetGetter: stmgr.TipSetGetterForTipset(sm.ChainStore(), ts), TipSetGetter: stmgr.TipSetGetterForTipset(sm.ChainStore(), ts),
Tracing: vmTracing, Tracing: vmTracing,
ReturnEvents: sm.ChainStore().IsStoringEvents(), ReturnEvents: sm.ChainStore().IsStoringEvents(),
ExecutionLane: vm.ExecutionLanePriority,
} }
return sm.VMConstructor()(ctx, vmopt) return sm.VMConstructor()(ctx, vmopt)
} }
var cronGas int64
runCron := func(vmCron vm.Interface, epoch abi.ChainEpoch) error { runCron := func(vmCron vm.Interface, epoch abi.ChainEpoch) error {
cronMsg := &types.Message{ cronMsg := &types.Message{
To: cron.Address, To: cron.Address,
@@ -135,8 +130,6 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context,
return xerrors.Errorf("running cron: %w", err) return xerrors.Errorf("running cron: %w", err)
} }
cronGas += ret.GasUsed
if em != nil { if em != nil {
if err := em.MessageApplied(ctx, ts, cronMsg.Cid(), cronMsg, ret, true); err != nil { if err := em.MessageApplied(ctx, ts, cronMsg.Cid(), cronMsg, ret, true); err != nil {
return xerrors.Errorf("callback failed on cron message: %w", err) return xerrors.Errorf("callback failed on cron message: %w", err)
@@ -188,9 +181,7 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context,
} }
} }
vmEarly := partDone() partDone()
earlyCronGas := cronGas
cronGas = 0
partDone = metrics.Timer(ctx, metrics.VMApplyMessages) partDone = metrics.Timer(ctx, metrics.VMApplyMessages)
vmi, err := makeVm(pstate, epoch, ts.MinTimestamp()) vmi, err := makeVm(pstate, epoch, ts.MinTimestamp())
@@ -205,8 +196,6 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context,
processedMsgs = make(map[cid.Cid]struct{}) processedMsgs = make(map[cid.Cid]struct{})
) )
var msgGas int64
for _, b := range bms { for _, b := range bms {
penalty := types.NewInt(0) penalty := types.NewInt(0)
gasReward := big.Zero() gasReward := big.Zero()
@@ -221,8 +210,6 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context,
return cid.Undef, cid.Undef, err return cid.Undef, cid.Undef, err
} }
msgGas += r.GasUsed
receipts = append(receipts, &r.MessageReceipt) receipts = append(receipts, &r.MessageReceipt)
gasReward = big.Add(gasReward, r.GasCosts.MinerTip) gasReward = big.Add(gasReward, r.GasCosts.MinerTip)
penalty = big.Add(penalty, r.GasCosts.MinerPenalty) penalty = big.Add(penalty, r.GasCosts.MinerPenalty)
@@ -240,26 +227,50 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context,
processedMsgs[m.Cid()] = struct{}{} processedMsgs[m.Cid()] = struct{}{}
} }
params := &reward.AwardBlockRewardParams{ params, err := actors.SerializeParams(&reward.AwardBlockRewardParams{
Miner: b.Miner, Miner: b.Miner,
Penalty: penalty, Penalty: penalty,
GasReward: gasReward, GasReward: gasReward,
WinCount: b.WinCount, WinCount: b.WinCount,
})
if err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("failed to serialize award params: %w", err)
} }
rErr := t.reward(ctx, vmi, em, epoch, ts, params)
if rErr != nil { rwMsg := &types.Message{
return cid.Undef, cid.Undef, xerrors.Errorf("error applying reward: %w", rErr) From: builtin.SystemActorAddr,
To: reward.Address,
Nonce: uint64(epoch),
Value: types.NewInt(0),
GasFeeCap: types.NewInt(0),
GasPremium: types.NewInt(0),
GasLimit: 1 << 30,
Method: reward.Methods.AwardBlockReward,
Params: params,
}
ret, actErr := vmi.ApplyImplicitMessage(ctx, rwMsg)
if actErr != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("failed to apply reward message for miner %s: %w", b.Miner, actErr)
}
if em != nil {
if err := em.MessageApplied(ctx, ts, rwMsg.Cid(), rwMsg, ret, true); err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("callback failed on reward message: %w", err)
}
}
if ret.ExitCode != 0 {
return cid.Undef, cid.Undef, xerrors.Errorf("reward application message failed (exit %d): %s", ret.ExitCode, ret.ActorErr)
} }
} }
vmMsg := partDone() partDone()
partDone = metrics.Timer(ctx, metrics.VMApplyCron) partDone = metrics.Timer(ctx, metrics.VMApplyCron)
if err := runCron(vmi, epoch); err != nil { if err := runCron(vmi, epoch); err != nil {
return cid.Cid{}, cid.Cid{}, err return cid.Cid{}, cid.Cid{}, err
} }
vmCron := partDone() partDone()
partDone = metrics.Timer(ctx, metrics.VMApplyFlush) partDone = metrics.Timer(ctx, metrics.VMApplyFlush)
rectarr := blockadt.MakeEmptyArray(sm.ChainStore().ActorStore(ctx)) rectarr := blockadt.MakeEmptyArray(sm.ChainStore().ActorStore(ctx))
@@ -295,11 +306,6 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context,
return cid.Undef, cid.Undef, xerrors.Errorf("vm flush failed: %w", err) return cid.Undef, cid.Undef, xerrors.Errorf("vm flush failed: %w", err)
} }
vmFlush := partDone()
partDone = func() time.Duration { return time.Duration(0) }
log.Infow("ApplyBlocks stats", "early", vmEarly, "earlyCronGas", earlyCronGas, "vmMsg", vmMsg, "msgGas", msgGas, "vmCron", vmCron, "cronGas", cronGas, "vmFlush", vmFlush, "epoch", epoch, "tsk", ts.Key())
stats.Record(ctx, metrics.VMSends.M(int64(atomic.LoadUint64(&vm.StatSends))), stats.Record(ctx, metrics.VMSends.M(int64(atomic.LoadUint64(&vm.StatSends))),
metrics.VMApplied.M(int64(atomic.LoadUint64(&vm.StatApplied)))) metrics.VMApplied.M(int64(atomic.LoadUint64(&vm.StatApplied))))
+432 -74
View File
@@ -4,36 +4,46 @@ import (
"bytes" "bytes"
"context" "context"
"errors" "errors"
"fmt"
"os" "os"
"strings"
"time" "time"
"github.com/hashicorp/go-multierror"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
logging "github.com/ipfs/go-log/v2" logging "github.com/ipfs/go-log/v2"
pubsub "github.com/libp2p/go-libp2p-pubsub"
"github.com/multiformats/go-varint"
cbg "github.com/whyrusleeping/cbor-gen"
"go.opencensus.io/stats"
"go.opencensus.io/trace" "go.opencensus.io/trace"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/abi"
builtintypes "github.com/filecoin-project/go-state-types/builtin"
"github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/go-state-types/network"
blockadt "github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/specs-actors/v7/actors/runtime/proof" "github.com/filecoin-project/specs-actors/v7/actors/runtime/proof"
"github.com/filecoin-project/lotus/api" bstore "github.com/filecoin-project/lotus/blockstore"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain" "github.com/filecoin-project/lotus/chain"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/builtin"
"github.com/filecoin-project/lotus/chain/actors/builtin/power" "github.com/filecoin-project/lotus/chain/actors/builtin/power"
"github.com/filecoin-project/lotus/chain/actors/builtin/reward"
"github.com/filecoin-project/lotus/chain/beacon" "github.com/filecoin-project/lotus/chain/beacon"
"github.com/filecoin-project/lotus/chain/consensus" "github.com/filecoin-project/lotus/chain/consensus"
"github.com/filecoin-project/lotus/chain/rand" "github.com/filecoin-project/lotus/chain/rand"
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm" "github.com/filecoin-project/lotus/chain/vm"
"github.com/filecoin-project/lotus/lib/async" "github.com/filecoin-project/lotus/lib/async"
"github.com/filecoin-project/lotus/lib/sigs" "github.com/filecoin-project/lotus/lib/sigs"
"github.com/filecoin-project/lotus/metrics"
"github.com/filecoin-project/lotus/storage/sealer/ffiwrapper" "github.com/filecoin-project/lotus/storage/sealer/ffiwrapper"
"github.com/filecoin-project/lotus/storage/sealer/storiface" "github.com/filecoin-project/lotus/storage/sealer/storiface"
) )
@@ -59,39 +69,6 @@ type FilecoinEC struct {
// the theoretical max height based on systime are quickly rejected // the theoretical max height based on systime are quickly rejected
const MaxHeightDrift = 5 const MaxHeightDrift = 5
var RewardFunc = func(ctx context.Context, vmi vm.Interface, em stmgr.ExecMonitor,
epoch abi.ChainEpoch, ts *types.TipSet, params *reward.AwardBlockRewardParams) error {
ser, err := actors.SerializeParams(params)
if err != nil {
return xerrors.Errorf("failed to serialize award params: %w", err)
}
rwMsg := &types.Message{
From: builtin.SystemActorAddr,
To: reward.Address,
Nonce: uint64(epoch),
Value: types.NewInt(0),
GasFeeCap: types.NewInt(0),
GasPremium: types.NewInt(0),
GasLimit: 1 << 30,
Method: reward.Methods.AwardBlockReward,
Params: ser,
}
ret, actErr := vmi.ApplyImplicitMessage(ctx, rwMsg)
if actErr != nil {
return xerrors.Errorf("failed to apply reward message: %w", actErr)
}
if em != nil {
if err := em.MessageApplied(ctx, ts, rwMsg.Cid(), rwMsg, ret, true); err != nil {
return xerrors.Errorf("callback failed on reward message: %w", err)
}
}
if ret.ExitCode != 0 {
return xerrors.Errorf("reward application message failed (exit %d): %s", ret.ExitCode, ret.ActorErr)
}
return nil
}
func NewFilecoinExpectedConsensus(sm *stmgr.StateManager, beacon beacon.Schedule, verifier storiface.Verifier, genesis chain.Genesis) consensus.Consensus { func NewFilecoinExpectedConsensus(sm *stmgr.StateManager, beacon beacon.Schedule, verifier storiface.Verifier, genesis chain.Genesis) consensus.Consensus {
if build.InsecurePoStValidation { if build.InsecurePoStValidation {
log.Warn("*********************************************************************************************") log.Warn("*********************************************************************************************")
@@ -150,6 +127,17 @@ func (filec *FilecoinEC) ValidateBlock(ctx context.Context, b *types.FullBlock)
log.Warn("Got block from the future, but within threshold", h.Timestamp, build.Clock.Now().Unix()) log.Warn("Got block from the future, but within threshold", h.Timestamp, build.Clock.Now().Unix())
} }
msgsCheck := async.Err(func() error {
if b.Cid() == build.WhitelistedBlock {
return nil
}
if err := filec.checkBlockMessages(ctx, b, baseTs); err != nil {
return xerrors.Errorf("block had invalid messages: %w", err)
}
return nil
})
minerCheck := async.Err(func() error { minerCheck := async.Err(func() error {
if err := filec.minerIsValid(ctx, h.Miner, baseTs); err != nil { if err := filec.minerIsValid(ctx, h.Miner, baseTs); err != nil {
return xerrors.Errorf("minerIsValid failed: %w", err) return xerrors.Errorf("minerIsValid failed: %w", err)
@@ -157,6 +145,17 @@ func (filec *FilecoinEC) ValidateBlock(ctx context.Context, b *types.FullBlock)
return nil return nil
}) })
baseFeeCheck := async.Err(func() error {
baseFee, err := filec.store.ComputeBaseFee(ctx, baseTs)
if err != nil {
return xerrors.Errorf("computing base fee: %w", err)
}
if types.BigCmp(baseFee, b.Header.ParentBaseFee) != 0 {
return xerrors.Errorf("base fee doesn't match: %s (header) != %s (computed)",
b.Header.ParentBaseFee, baseFee)
}
return nil
})
pweight, err := filec.store.Weight(ctx, baseTs) pweight, err := filec.store.Weight(ctx, baseTs)
if err != nil { if err != nil {
return xerrors.Errorf("getting parent weight: %w", err) return xerrors.Errorf("getting parent weight: %w", err)
@@ -167,6 +166,34 @@ func (filec *FilecoinEC) ValidateBlock(ctx context.Context, b *types.FullBlock)
b.Header.ParentWeight, pweight) b.Header.ParentWeight, pweight)
} }
stateRootCheck := async.Err(func() error {
stateroot, precp, err := filec.sm.TipSetState(ctx, baseTs)
if err != nil {
return xerrors.Errorf("get tipsetstate(%d, %s) failed: %w", h.Height, h.Parents, err)
}
if stateroot != h.ParentStateRoot {
msgs, err := filec.store.MessagesForTipset(ctx, baseTs)
if err != nil {
log.Error("failed to load messages for tipset during tipset state mismatch error: ", err)
} else {
log.Warn("Messages for tipset with mismatching state:")
for i, m := range msgs {
mm := m.VMMessage()
log.Warnf("Message[%d]: from=%s to=%s method=%d params=%x", i, mm.From, mm.To, mm.Method, mm.Params)
}
}
return xerrors.Errorf("parent state root did not match computed state (%s != %s)", h.ParentStateRoot, stateroot)
}
if precp != h.ParentMessageReceipts {
return xerrors.Errorf("parent receipts root did not match computed value (%s != %s)", precp, h.ParentMessageReceipts)
}
return nil
})
// Stuff that needs worker address // Stuff that needs worker address
waddr, err := stmgr.GetMinerWorkerRaw(ctx, filec.sm, lbst, h.Miner) waddr, err := stmgr.GetMinerWorkerRaw(ctx, filec.sm, lbst, h.Miner)
if err != nil { if err != nil {
@@ -228,11 +255,10 @@ func (filec *FilecoinEC) ValidateBlock(ctx context.Context, b *types.FullBlock)
}) })
blockSigCheck := async.Err(func() error { blockSigCheck := async.Err(func() error {
if err := verifyBlockSignature(ctx, h, waddr); err != nil { if err := sigs.CheckBlockSignature(ctx, h, waddr); err != nil {
return xerrors.Errorf("check block signature failed: %w", err) return xerrors.Errorf("check block signature failed: %w", err)
} }
return nil return nil
}) })
beaconValuesCheck := async.Err(func() error { beaconValuesCheck := async.Err(func() error {
@@ -281,17 +307,44 @@ func (filec *FilecoinEC) ValidateBlock(ctx context.Context, b *types.FullBlock)
return nil return nil
}) })
commonChecks := consensus.CommonBlkChecks(ctx, filec.sm, filec.store, b, baseTs) await := []async.ErrorFuture{
await := append([]async.ErrorFuture{
minerCheck, minerCheck,
tktsCheck, tktsCheck,
blockSigCheck, blockSigCheck,
beaconValuesCheck, beaconValuesCheck,
wproofCheck, wproofCheck,
winnerCheck, winnerCheck,
}, commonChecks...) msgsCheck,
baseFeeCheck,
stateRootCheck,
}
return consensus.RunAsyncChecks(ctx, await) var merr error
for _, fut := range await {
if err := fut.AwaitContext(ctx); err != nil {
merr = multierror.Append(merr, err)
}
}
if merr != nil {
mulErr := merr.(*multierror.Error)
mulErr.ErrorFormat = func(es []error) string {
if len(es) == 1 {
return fmt.Sprintf("1 error occurred:\n\t* %+v\n\n", es[0])
}
points := make([]string, len(es))
for i, err := range es {
points[i] = fmt.Sprintf("* %+v", err)
}
return fmt.Sprintf(
"%d errors occurred:\n\t%s\n\n",
len(es), strings.Join(points, "\n\t"))
}
return mulErr
}
return nil
} }
func blockSanityChecks(h *types.BlockHeader) error { func blockSanityChecks(h *types.BlockHeader) error {
@@ -382,21 +435,216 @@ func (filec *FilecoinEC) VerifyWinningPoStProof(ctx context.Context, nv network.
return nil return nil
} }
func (filec *FilecoinEC) IsEpochInConsensusRange(epoch abi.ChainEpoch) bool { func IsValidForSending(nv network.Version, act *types.Actor) bool {
if filec.genesis == nil { // Before nv18 (Hygge), we only supported built-in account actors as senders.
//
// Note: this gate is probably superfluous, since:
// 1. Placeholder actors cannot be created before nv18.
// 2. EthAccount actors cannot be created before nv18.
// 3. Delegated addresses cannot be created before nv18.
//
// But it's a safeguard.
//
// Note 2: ad-hoc checks for network versions like this across the codebase
// will be problematic with networks with diverging version lineages
// (e.g. Hyperspace). We need to revisit this strategy entirely.
if nv < network.Version18 {
return builtin.IsAccountActor(act.Code)
}
// After nv18, we also support other kinds of senders.
if builtin.IsAccountActor(act.Code) || builtin.IsEthAccountActor(act.Code) {
return true return true
} }
// Don't try to sync anything before finality. Don't propagate such blocks either. // Allow placeholder actors with a delegated address and nonce 0 to send a message.
// // These will be converted to an EthAccount actor on first send.
// We use _our_ current head, not the expected head, because the network's head can lag on if !builtin.IsPlaceholderActor(act.Code) || act.Nonce != 0 || act.Address == nil || act.Address.Protocol() != address.Delegated {
// catch-up (after a network outage). return false
if epoch < filec.store.GetHeaviestTipSet().Height()-build.Finality { }
// Only allow such actors to send if their delegated address is in the EAM's namespace.
id, _, err := varint.FromUvarint(act.Address.Payload())
return err == nil && id == builtintypes.EthereumAddressManagerActorID
}
// TODO: We should extract this somewhere else and make the message pool and miner use the same logic
func (filec *FilecoinEC) checkBlockMessages(ctx context.Context, b *types.FullBlock, baseTs *types.TipSet) error {
{
var sigCids []cid.Cid // this is what we get for people not wanting the marshalcbor method on the cid type
var pubks [][]byte
for _, m := range b.BlsMessages {
sigCids = append(sigCids, m.Cid())
pubk, err := filec.sm.GetBlsPublicKey(ctx, m.From, baseTs)
if err != nil {
return xerrors.Errorf("failed to load bls public to validate block: %w", err)
}
pubks = append(pubks, pubk)
}
if err := consensus.VerifyBlsAggregate(ctx, b.Header.BLSAggregate, sigCids, pubks); err != nil {
return xerrors.Errorf("bls aggregate signature was invalid: %w", err)
}
}
nonces := make(map[address.Address]uint64)
stateroot, _, err := filec.sm.TipSetState(ctx, baseTs)
if err != nil {
return xerrors.Errorf("failed to compute tipsettate for %s: %w", baseTs.Key(), err)
}
st, err := state.LoadStateTree(filec.store.ActorStore(ctx), stateroot)
if err != nil {
return xerrors.Errorf("failed to load base state tree: %w", err)
}
nv := filec.sm.GetNetworkVersion(ctx, b.Header.Height)
pl := vm.PricelistByEpoch(b.Header.Height)
var sumGasLimit int64
checkMsg := func(msg types.ChainMsg) error {
m := msg.VMMessage()
// Phase 1: syntactic validation, as defined in the spec
minGas := pl.OnChainMessage(msg.ChainLength())
if err := m.ValidForBlockInclusion(minGas.Total(), nv); err != nil {
return xerrors.Errorf("msg %s invalid for block inclusion: %w", m.Cid(), err)
}
// ValidForBlockInclusion checks if any single message does not exceed BlockGasLimit
// So below is overflow safe
sumGasLimit += m.GasLimit
if sumGasLimit > build.BlockGasLimit {
return xerrors.Errorf("block gas limit exceeded")
}
// Phase 2: (Partial) semantic validation:
// the sender exists and is an account actor, and the nonces make sense
var sender address.Address
if nv >= network.Version13 {
sender, err = st.LookupID(m.From)
if err != nil {
return xerrors.Errorf("failed to lookup sender %s: %w", m.From, err)
}
} else {
sender = m.From
}
if _, ok := nonces[sender]; !ok {
// `GetActor` does not validate that this is an account actor.
act, err := st.GetActor(sender)
if err != nil {
return xerrors.Errorf("failed to get actor: %w", err)
}
if !IsValidForSending(nv, act) {
return xerrors.New("Sender must be an account actor")
}
nonces[sender] = act.Nonce
}
if nonces[sender] != m.Nonce {
return xerrors.Errorf("wrong nonce (exp: %d, got: %d)", nonces[sender], m.Nonce)
}
nonces[sender]++
return nil
}
// Validate message arrays in a temporary blockstore.
tmpbs := bstore.NewMemory()
tmpstore := blockadt.WrapStore(ctx, cbor.NewCborStore(tmpbs))
bmArr := blockadt.MakeEmptyArray(tmpstore)
for i, m := range b.BlsMessages {
if err := checkMsg(m); err != nil {
return xerrors.Errorf("block had invalid bls message at index %d: %w", i, err)
}
c, err := store.PutMessage(ctx, tmpbs, m)
if err != nil {
return xerrors.Errorf("failed to store message %s: %w", m.Cid(), err)
}
k := cbg.CborCid(c)
if err := bmArr.Set(uint64(i), &k); err != nil {
return xerrors.Errorf("failed to put bls message at index %d: %w", i, err)
}
}
smArr := blockadt.MakeEmptyArray(tmpstore)
for i, m := range b.SecpkMessages {
if nv >= network.Version14 && !chain.IsValidSecpkSigType(nv, m.Signature.Type) {
return xerrors.Errorf("block had invalid signed message at index %d: %w", i, err)
}
if err := checkMsg(m); err != nil {
return xerrors.Errorf("block had invalid secpk message at index %d: %w", i, err)
}
// `From` being an account actor is only validated inside the `vm.ResolveToDeterministicAddr` call
// in `StateManager.ResolveToDeterministicAddress` here (and not in `checkMsg`).
kaddr, err := filec.sm.ResolveToDeterministicAddress(ctx, m.Message.From, baseTs)
if err != nil {
return xerrors.Errorf("failed to resolve key addr: %w", err)
}
if err := chain.AuthenticateMessage(m, kaddr); err != nil {
return xerrors.Errorf("failed to validate signature: %w", err)
}
c, err := store.PutMessage(ctx, tmpbs, m)
if err != nil {
return xerrors.Errorf("failed to store message %s: %w", m.Cid(), err)
}
k := cbg.CborCid(c)
if err := smArr.Set(uint64(i), &k); err != nil {
return xerrors.Errorf("failed to put secpk message at index %d: %w", i, err)
}
}
bmroot, err := bmArr.Root()
if err != nil {
return xerrors.Errorf("failed to root bls msgs: %w", err)
}
smroot, err := smArr.Root()
if err != nil {
return xerrors.Errorf("failed to root secp msgs: %w", err)
}
mrcid, err := tmpstore.Put(ctx, &types.MsgMeta{
BlsMessages: bmroot,
SecpkMessages: smroot,
})
if err != nil {
return xerrors.Errorf("failed to put msg meta: %w", err)
}
if b.Header.Messages != mrcid {
return fmt.Errorf("messages didnt match message root in header")
}
// Finally, flush.
err = vm.Copy(ctx, tmpbs, filec.store.ChainBlockstore(), mrcid)
if err != nil {
return xerrors.Errorf("failed to flush:%w", err)
}
return nil
}
func (filec *FilecoinEC) IsEpochBeyondCurrMax(epoch abi.ChainEpoch) bool {
if filec.genesis == nil {
return false return false
} }
now := uint64(build.Clock.Now().Unix()) now := uint64(build.Clock.Now().Unix())
return epoch <= (abi.ChainEpoch((now-filec.genesis.MinTimestamp())/build.BlockDelaySecs) + MaxHeightDrift) return epoch > (abi.ChainEpoch((now-filec.genesis.MinTimestamp())/build.BlockDelaySecs) + MaxHeightDrift)
} }
func (filec *FilecoinEC) minerIsValid(ctx context.Context, maddr address.Address, baseTs *types.TipSet) error { func (filec *FilecoinEC) minerIsValid(ctx context.Context, maddr address.Address, baseTs *types.TipSet) error {
@@ -445,7 +693,140 @@ func VerifyVRF(ctx context.Context, worker address.Address, vrfBase, vrfproof []
var ErrSoftFailure = errors.New("soft validation failure") var ErrSoftFailure = errors.New("soft validation failure")
var ErrInsufficientPower = errors.New("incoming block's miner does not have minimum power") var ErrInsufficientPower = errors.New("incoming block's miner does not have minimum power")
func (filec *FilecoinEC) ValidateBlockHeader(ctx context.Context, b *types.BlockHeader) (rejectReason string, err error) { func (filec *FilecoinEC) ValidateBlockPubsub(ctx context.Context, self bool, msg *pubsub.Message) (pubsub.ValidationResult, string) {
if self {
return filec.validateLocalBlock(ctx, msg)
}
// track validation time
begin := build.Clock.Now()
defer func() {
log.Debugf("block validation time: %s", build.Clock.Since(begin))
}()
stats.Record(ctx, metrics.BlockReceived.M(1))
recordFailureFlagPeer := func(what string) {
// bv.Validate will flag the peer in that case
panic(what)
}
blk, what, err := filec.decodeAndCheckBlock(msg)
if err != nil {
log.Error("got invalid block over pubsub: ", err)
recordFailureFlagPeer(what)
return pubsub.ValidationReject, what
}
// validate the block meta: the Message CID in the header must match the included messages
err = filec.validateMsgMeta(ctx, blk)
if err != nil {
log.Warnf("error validating message metadata: %s", err)
recordFailureFlagPeer("invalid_block_meta")
return pubsub.ValidationReject, "invalid_block_meta"
}
reject, err := filec.validateBlockHeader(ctx, blk.Header)
if err != nil {
if reject == "" {
log.Warn("ignoring block msg: ", err)
return pubsub.ValidationIgnore, reject
}
recordFailureFlagPeer(reject)
return pubsub.ValidationReject, reject
}
// all good, accept the block
msg.ValidatorData = blk
stats.Record(ctx, metrics.BlockValidationSuccess.M(1))
return pubsub.ValidationAccept, ""
}
func (filec *FilecoinEC) validateLocalBlock(ctx context.Context, msg *pubsub.Message) (pubsub.ValidationResult, string) {
stats.Record(ctx, metrics.BlockPublished.M(1))
if size := msg.Size(); size > 1<<20-1<<15 {
log.Errorf("ignoring oversize block (%dB)", size)
return pubsub.ValidationIgnore, "oversize_block"
}
blk, what, err := filec.decodeAndCheckBlock(msg)
if err != nil {
log.Errorf("got invalid local block: %s", err)
return pubsub.ValidationIgnore, what
}
msg.ValidatorData = blk
stats.Record(ctx, metrics.BlockValidationSuccess.M(1))
return pubsub.ValidationAccept, ""
}
func (filec *FilecoinEC) decodeAndCheckBlock(msg *pubsub.Message) (*types.BlockMsg, string, error) {
blk, err := types.DecodeBlockMsg(msg.GetData())
if err != nil {
return nil, "invalid", xerrors.Errorf("error decoding block: %w", err)
}
if count := len(blk.BlsMessages) + len(blk.SecpkMessages); count > build.BlockMessageLimit {
return nil, "too_many_messages", fmt.Errorf("block contains too many messages (%d)", count)
}
// make sure we have a signature
if blk.Header.BlockSig == nil {
return nil, "missing_signature", fmt.Errorf("block without a signature")
}
return blk, "", nil
}
func (filec *FilecoinEC) validateMsgMeta(ctx context.Context, msg *types.BlockMsg) error {
// TODO there has to be a simpler way to do this without the blockstore dance
// block headers use adt0
store := blockadt.WrapStore(ctx, cbor.NewCborStore(bstore.NewMemory()))
bmArr := blockadt.MakeEmptyArray(store)
smArr := blockadt.MakeEmptyArray(store)
for i, m := range msg.BlsMessages {
c := cbg.CborCid(m)
if err := bmArr.Set(uint64(i), &c); err != nil {
return err
}
}
for i, m := range msg.SecpkMessages {
c := cbg.CborCid(m)
if err := smArr.Set(uint64(i), &c); err != nil {
return err
}
}
bmroot, err := bmArr.Root()
if err != nil {
return err
}
smroot, err := smArr.Root()
if err != nil {
return err
}
mrcid, err := store.Put(store.Context(), &types.MsgMeta{
BlsMessages: bmroot,
SecpkMessages: smroot,
})
if err != nil {
return err
}
if msg.Header.Messages != mrcid {
return fmt.Errorf("messages didn't match root cid in header")
}
return nil
}
func (filec *FilecoinEC) validateBlockHeader(ctx context.Context, b *types.BlockHeader) (rejectReason string, err error) {
// we want to ensure that it is a block from a known miner; we reject blocks from unknown miners // we want to ensure that it is a block from a known miner; we reject blocks from unknown miners
// to prevent spam attacks. // to prevent spam attacks.
@@ -520,27 +901,4 @@ func (filec *FilecoinEC) isChainNearSynced() bool {
return build.Clock.Since(timestampTime) < 6*time.Hour return build.Clock.Since(timestampTime) < 6*time.Hour
} }
func verifyBlockSignature(ctx context.Context, h *types.BlockHeader,
addr address.Address) error {
return sigs.CheckBlockSignature(ctx, h, addr)
}
func signBlock(ctx context.Context, w api.Wallet,
addr address.Address, next *types.BlockHeader) error {
nosigbytes, err := next.SigningBytes()
if err != nil {
return xerrors.Errorf("failed to get signing bytes for block: %w", err)
}
sig, err := w.WalletSign(ctx, addr, nosigbytes, api.MsgMeta{
Type: api.MTBlock,
})
if err != nil {
return xerrors.Errorf("failed to sign new block: %w", err)
}
next.BlockSig = sig
return nil
}
var _ consensus.Consensus = &FilecoinEC{} var _ consensus.Consensus = &FilecoinEC{}
+100 -4
View File
@@ -3,9 +3,13 @@ package filcns
import ( import (
"context" "context"
"github.com/ipfs/go-cid"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain"
"github.com/filecoin-project/lotus/chain/consensus" "github.com/filecoin-project/lotus/chain/consensus"
"github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
@@ -17,6 +21,11 @@ func (filec *FilecoinEC) CreateBlock(ctx context.Context, w api.Wallet, bt *api.
return nil, xerrors.Errorf("failed to load parent tipset: %w", err) return nil, xerrors.Errorf("failed to load parent tipset: %w", err)
} }
st, recpts, err := filec.sm.TipSetState(ctx, pts)
if err != nil {
return nil, xerrors.Errorf("failed to load tipset state: %w", err)
}
_, lbst, err := stmgr.GetLookbackTipSetForRound(ctx, filec.sm, pts, bt.Epoch) _, lbst, err := stmgr.GetLookbackTipSetForRound(ctx, filec.sm, pts, bt.Epoch)
if err != nil { if err != nil {
return nil, xerrors.Errorf("getting lookback miner actor state: %w", err) return nil, xerrors.Errorf("getting lookback miner actor state: %w", err)
@@ -27,15 +36,102 @@ func (filec *FilecoinEC) CreateBlock(ctx context.Context, w api.Wallet, bt *api.
return nil, xerrors.Errorf("failed to get miner worker: %w", err) return nil, xerrors.Errorf("failed to get miner worker: %w", err)
} }
next, blsMessages, secpkMessages, err := consensus.CreateBlockHeader(ctx, filec.sm, pts, bt) next := &types.BlockHeader{
if err != nil { Miner: bt.Miner,
return nil, xerrors.Errorf("failed to process messages from block template: %w", err) Parents: bt.Parents.Cids(),
Ticket: bt.Ticket,
ElectionProof: bt.Eproof,
BeaconEntries: bt.BeaconValues,
Height: bt.Epoch,
Timestamp: bt.Timestamp,
WinPoStProof: bt.WinningPoStProof,
ParentStateRoot: st,
ParentMessageReceipts: recpts,
} }
if err := signBlock(ctx, w, worker, next); err != nil { var blsMessages []*types.Message
var secpkMessages []*types.SignedMessage
var blsMsgCids, secpkMsgCids []cid.Cid
var blsSigs []crypto.Signature
nv := filec.sm.GetNetworkVersion(ctx, bt.Epoch)
for _, msg := range bt.Messages {
if msg.Signature.Type == crypto.SigTypeBLS {
blsSigs = append(blsSigs, msg.Signature)
blsMessages = append(blsMessages, &msg.Message)
c, err := filec.sm.ChainStore().PutMessage(ctx, &msg.Message)
if err != nil {
return nil, err
}
blsMsgCids = append(blsMsgCids, c)
} else if chain.IsValidSecpkSigType(nv, msg.Signature.Type) {
c, err := filec.sm.ChainStore().PutMessage(ctx, msg)
if err != nil {
return nil, err
}
secpkMsgCids = append(secpkMsgCids, c)
secpkMessages = append(secpkMessages, msg)
} else {
return nil, xerrors.Errorf("unknown sig type: %d", msg.Signature.Type)
}
}
store := filec.sm.ChainStore().ActorStore(ctx)
blsmsgroot, err := consensus.ToMessagesArray(store, blsMsgCids)
if err != nil {
return nil, xerrors.Errorf("building bls amt: %w", err)
}
secpkmsgroot, err := consensus.ToMessagesArray(store, secpkMsgCids)
if err != nil {
return nil, xerrors.Errorf("building secpk amt: %w", err)
}
mmcid, err := store.Put(store.Context(), &types.MsgMeta{
BlsMessages: blsmsgroot,
SecpkMessages: secpkmsgroot,
})
if err != nil {
return nil, err
}
next.Messages = mmcid
aggSig, err := consensus.AggregateSignatures(blsSigs)
if err != nil {
return nil, err
}
next.BLSAggregate = aggSig
pweight, err := filec.sm.ChainStore().Weight(ctx, pts)
if err != nil {
return nil, err
}
next.ParentWeight = pweight
baseFee, err := filec.sm.ChainStore().ComputeBaseFee(ctx, pts)
if err != nil {
return nil, xerrors.Errorf("computing base fee: %w", err)
}
next.ParentBaseFee = baseFee
nosigbytes, err := next.SigningBytes()
if err != nil {
return nil, xerrors.Errorf("failed to get signing bytes for block: %w", err)
}
sig, err := w.WalletSign(ctx, worker, nosigbytes, api.MsgMeta{
Type: api.MTBlock,
})
if err != nil {
return nil, xerrors.Errorf("failed to sign new block: %w", err) return nil, xerrors.Errorf("failed to sign new block: %w", err)
} }
next.BlockSig = sig
fullBlock := &types.FullBlock{ fullBlock := &types.FullBlock{
Header: next, Header: next,
BlsMessages: blsMessages, BlsMessages: blsMessages,
+12 -10
View File
@@ -533,11 +533,12 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *stmgr.StateManager, _ st
MessageReceipt: *stmgr.MakeFakeRct(), MessageReceipt: *stmgr.MakeFakeRct(),
ActorErr: nil, ActorErr: nil,
ExecutionTrace: types.ExecutionTrace{ ExecutionTrace: types.ExecutionTrace{
Msg: types.MessageTrace{ Msg: fakeMsg,
To: fakeMsg.To, MsgRct: stmgr.MakeFakeRct(),
From: fakeMsg.From, Error: "",
}, Duration: 0,
Subcalls: subcalls, GasCharges: nil,
Subcalls: subcalls,
}, },
Duration: 0, Duration: 0,
GasCosts: nil, GasCosts: nil,
@@ -710,11 +711,12 @@ func splitGenesisMultisig0(ctx context.Context, em stmgr.ExecMonitor, addr addre
MessageReceipt: *stmgr.MakeFakeRct(), MessageReceipt: *stmgr.MakeFakeRct(),
ActorErr: nil, ActorErr: nil,
ExecutionTrace: types.ExecutionTrace{ ExecutionTrace: types.ExecutionTrace{
Msg: types.MessageTrace{ Msg: fakeMsg,
From: fakeMsg.From, MsgRct: stmgr.MakeFakeRct(),
To: fakeMsg.To, Error: "",
}, Duration: 0,
Subcalls: subcalls, GasCharges: nil,
Subcalls: subcalls,
}, },
Duration: 0, Duration: 0,
GasCosts: nil, GasCosts: nil,
+2 -85
View File
@@ -4,100 +4,17 @@ import (
"context" "context"
pubsub "github.com/libp2p/go-libp2p-pubsub" pubsub "github.com/libp2p/go-libp2p-pubsub"
"go.opencensus.io/stats"
"github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors/builtin/reward"
"github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm"
"github.com/filecoin-project/lotus/metrics"
) )
type Consensus interface { type Consensus interface {
// ValidateBlockHeader is called by peers when they receive a new block through the network.
//
// This is a fast sanity-check validation performed by the PubSub protocol before delivering
// it to the syncer. It checks that the block has the right format and it performs
// other consensus-specific light verifications like ensuring that the block is signed by
// a valid miner, or that it includes all the data required for a full verification.
ValidateBlockHeader(ctx context.Context, b *types.BlockHeader) (rejectReason string, err error)
// ValidateBlock is called by the syncer to determine if to accept a block or not.
//
// It performs all the checks needed by the syncer to accept
// the block (signature verifications, VRF checks, message validity, etc.)
ValidateBlock(ctx context.Context, b *types.FullBlock) (err error) ValidateBlock(ctx context.Context, b *types.FullBlock) (err error)
ValidateBlockPubsub(ctx context.Context, self bool, msg *pubsub.Message) (pubsub.ValidationResult, string)
IsEpochBeyondCurrMax(epoch abi.ChainEpoch) bool
// IsEpochInConsensusRange returns true if the epoch is "in range" for consensus. That is:
// - It's not before finality.
// - It's not too far in the future.
IsEpochInConsensusRange(epoch abi.ChainEpoch) bool
// CreateBlock implements all the logic required to propose and assemble a new Filecoin block.
//
// This function encapsulate all the consensus-specific actions to propose a new block
// such as the ordering of transactions, the inclusion of consensus proofs, the signature
// of the block, etc.
CreateBlock(ctx context.Context, w api.Wallet, bt *api.BlockTemplate) (*types.FullBlock, error) CreateBlock(ctx context.Context, w api.Wallet, bt *api.BlockTemplate) (*types.FullBlock, error)
} }
// RewardFunc parametrizes the logic for rewards when a message is executed.
//
// Each consensus implementation can set their own reward function.
type RewardFunc func(ctx context.Context, vmi vm.Interface, em stmgr.ExecMonitor,
epoch abi.ChainEpoch, ts *types.TipSet, params *reward.AwardBlockRewardParams) error
// ValidateBlockPubsub implements the common checks performed by all consensus implementations
// when a block is received through the pubsub channel.
func ValidateBlockPubsub(ctx context.Context, cns Consensus, self bool, msg *pubsub.Message) (pubsub.ValidationResult, string) {
if self {
return validateLocalBlock(ctx, msg)
}
// track validation time
begin := build.Clock.Now()
defer func() {
log.Debugf("block validation time: %s", build.Clock.Since(begin))
}()
stats.Record(ctx, metrics.BlockReceived.M(1))
blk, what, err := decodeAndCheckBlock(msg)
if err != nil {
log.Error("got invalid block over pubsub: ", err)
return pubsub.ValidationReject, what
}
if !cns.IsEpochInConsensusRange(blk.Header.Height) {
// We ignore these blocks instead of rejecting to avoid breaking the network if
// we're recovering from an outage (e.g., where nobody agrees on where "head" is
// currently).
log.Warnf("received block outside of consensus range (%d)", blk.Header.Height)
return pubsub.ValidationIgnore, "invalid_block_height"
}
// validate the block meta: the Message CID in the header must match the included messages
err = validateMsgMeta(ctx, blk)
if err != nil {
log.Warnf("error validating message metadata: %s", err)
return pubsub.ValidationReject, "invalid_block_meta"
}
reject, err := cns.ValidateBlockHeader(ctx, blk.Header)
if err != nil {
if reject == "" {
log.Warn("ignoring block msg: ", err)
return pubsub.ValidationIgnore, reject
}
return pubsub.ValidationReject, reject
}
// all good, accept the block
msg.ValidatorData = blk
stats.Record(ctx, metrics.BlockValidationSuccess.M(1))
return pubsub.ValidationAccept, ""
}
+2 -2
View File
@@ -47,7 +47,7 @@ type Events struct {
*hcEvents *hcEvents
} }
func newEventsWithGCConfidence(ctx context.Context, api EventAPI, gcConfidence abi.ChainEpoch) (*Events, error) { func NewEventsWithConfidence(ctx context.Context, api EventAPI, gcConfidence abi.ChainEpoch) (*Events, error) {
cache := newCache(api, gcConfidence) cache := newCache(api, gcConfidence)
ob := newObserver(cache, gcConfidence) ob := newObserver(cache, gcConfidence)
@@ -63,5 +63,5 @@ func newEventsWithGCConfidence(ctx context.Context, api EventAPI, gcConfidence a
func NewEvents(ctx context.Context, api EventAPI) (*Events, error) { func NewEvents(ctx context.Context, api EventAPI) (*Events, error) {
gcConfidence := 2 * build.ForkLengthThreshold gcConfidence := 2 * build.ForkLengthThreshold
return newEventsWithGCConfidence(ctx, api, gcConfidence) return NewEventsWithConfidence(ctx, api, gcConfidence)
} }
+2 -5
View File
@@ -174,16 +174,13 @@ func (fcs *fakeCS) makeTs(t *testing.T, parents []cid.Cid, h abi.ChainEpoch, msg
}, },
}) })
require.NoError(t, err)
fcs.mu.Lock()
defer fcs.mu.Unlock()
if fcs.tipsets == nil { if fcs.tipsets == nil {
fcs.tipsets = map[types.TipSetKey]*types.TipSet{} fcs.tipsets = map[types.TipSetKey]*types.TipSet{}
} }
fcs.tipsets[ts.Key()] = ts fcs.tipsets[ts.Key()] = ts
require.NoError(t, err)
return ts return ts
} }
+9 -9
View File
@@ -4,7 +4,7 @@ import (
"context" "context"
"sync" "sync"
lru "github.com/hashicorp/golang-lru/v2" lru "github.com/hashicorp/golang-lru"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
"github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api"
@@ -14,14 +14,14 @@ type messageCache struct {
api EventAPI api EventAPI
blockMsgLk sync.Mutex blockMsgLk sync.Mutex
blockMsgCache *lru.ARCCache[cid.Cid, *api.BlockMessages] blockMsgCache *lru.ARCCache
} }
func newMessageCache(a EventAPI) *messageCache { func newMessageCache(api EventAPI) *messageCache {
blsMsgCache, _ := lru.NewARC[cid.Cid, *api.BlockMessages](500) blsMsgCache, _ := lru.NewARC(500)
return &messageCache{ return &messageCache{
api: a, api: api,
blockMsgCache: blsMsgCache, blockMsgCache: blsMsgCache,
} }
} }
@@ -30,14 +30,14 @@ func (c *messageCache) ChainGetBlockMessages(ctx context.Context, blkCid cid.Cid
c.blockMsgLk.Lock() c.blockMsgLk.Lock()
defer c.blockMsgLk.Unlock() defer c.blockMsgLk.Unlock()
msgs, ok := c.blockMsgCache.Get(blkCid) msgsI, ok := c.blockMsgCache.Get(blkCid)
var err error var err error
if !ok { if !ok {
msgs, err = c.api.ChainGetBlockMessages(ctx, blkCid) msgsI, err = c.api.ChainGetBlockMessages(ctx, blkCid)
if err != nil { if err != nil {
return nil, err return nil, err
} }
c.blockMsgCache.Add(blkCid, msgs) c.blockMsgCache.Add(blkCid, msgsI)
} }
return msgs, nil return msgsI.(*api.BlockMessages), nil
} }
+1 -1
View File
@@ -125,7 +125,7 @@ func (o *observer) listenHeadChangesOnce(ctx context.Context) error {
for changes := range notifs { for changes := range notifs {
if err := o.applyChanges(ctx, changes); err != nil { if err := o.applyChanges(ctx, changes); err != nil {
return xerrors.Errorf("failed to apply a change notification: %w", err) return err
} }
} }
+1 -1
View File
@@ -4,8 +4,8 @@ import (
"context" "context"
"sync" "sync"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
blocks "github.com/ipfs/go-libipfs/blocks"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
+4 -6
View File
@@ -5,7 +5,7 @@ import (
"context" "context"
"fmt" "fmt"
"io" "io"
"os" "io/ioutil"
"sync/atomic" "sync/atomic"
"time" "time"
@@ -31,10 +31,8 @@ import (
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/chain/actors/policy"
"github.com/filecoin-project/lotus/chain/beacon" "github.com/filecoin-project/lotus/chain/beacon"
"github.com/filecoin-project/lotus/chain/consensus"
"github.com/filecoin-project/lotus/chain/consensus/filcns" "github.com/filecoin-project/lotus/chain/consensus/filcns"
genesis2 "github.com/filecoin-project/lotus/chain/gen/genesis" genesis2 "github.com/filecoin-project/lotus/chain/gen/genesis"
"github.com/filecoin-project/lotus/chain/index"
"github.com/filecoin-project/lotus/chain/rand" "github.com/filecoin-project/lotus/chain/rand"
"github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/store"
@@ -168,7 +166,7 @@ func NewGeneratorWithSectorsAndUpgradeSchedule(numSectors int, us stmgr.UpgradeS
maddr1 := genesis2.MinerAddress(0) maddr1 := genesis2.MinerAddress(0)
m1temp, err := os.MkdirTemp("", "preseal") m1temp, err := ioutil.TempDir("", "preseal")
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -180,7 +178,7 @@ func NewGeneratorWithSectorsAndUpgradeSchedule(numSectors int, us stmgr.UpgradeS
maddr2 := genesis2.MinerAddress(1) maddr2 := genesis2.MinerAddress(1)
m2temp, err := os.MkdirTemp("", "preseal") m2temp, err := ioutil.TempDir("", "preseal")
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -257,7 +255,7 @@ func NewGeneratorWithSectorsAndUpgradeSchedule(numSectors int, us stmgr.UpgradeS
//return nil, xerrors.Errorf("creating drand beacon: %w", err) //return nil, xerrors.Errorf("creating drand beacon: %w", err)
//} //}
sm, err := stmgr.NewStateManager(cs, consensus.NewTipSetExecutor(filcns.RewardFunc), sys, us, beac, ds, index.DummyMsgIndex) sm, err := stmgr.NewStateManager(cs, filcns.NewTipSetExecutor(), sys, us, beac)
if err != nil { if err != nil {
return nil, xerrors.Errorf("initing stmgr: %w", err) return nil, xerrors.Errorf("initing stmgr: %w", err)
} }
+1 -1
View File
@@ -3,8 +3,8 @@ package genesis
import ( import (
"encoding/hex" "encoding/hex"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
blocks "github.com/ipfs/go-libipfs/blocks"
"github.com/multiformats/go-multihash" "github.com/multiformats/go-multihash"
) )
+2 -2
View File
@@ -38,7 +38,7 @@ import (
"github.com/filecoin-project/lotus/chain/actors/builtin/reward" "github.com/filecoin-project/lotus/chain/actors/builtin/reward"
"github.com/filecoin-project/lotus/chain/actors/builtin/system" "github.com/filecoin-project/lotus/chain/actors/builtin/system"
"github.com/filecoin-project/lotus/chain/actors/builtin/verifreg" "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
"github.com/filecoin-project/lotus/chain/consensus" "github.com/filecoin-project/lotus/chain/consensus/filcns"
"github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
@@ -486,7 +486,7 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, sys vm.Sysca
Epoch: 0, Epoch: 0,
Rand: &fakeRand{}, Rand: &fakeRand{},
Bstore: cs.StateBlockstore(), Bstore: cs.StateBlockstore(),
Actors: consensus.NewActorRegistry(), Actors: filcns.NewActorRegistry(),
Syscalls: mkFakedSigSyscalls(sys), Syscalls: mkFakedSigSyscalls(sys),
CircSupplyCalc: csc, CircSupplyCalc: csc,
NetworkVersion: nv, NetworkVersion: nv,
+2 -2
View File
@@ -42,7 +42,7 @@ import (
"github.com/filecoin-project/lotus/chain/actors/builtin/power" "github.com/filecoin-project/lotus/chain/actors/builtin/power"
"github.com/filecoin-project/lotus/chain/actors/builtin/reward" "github.com/filecoin-project/lotus/chain/actors/builtin/reward"
"github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/chain/actors/policy"
"github.com/filecoin-project/lotus/chain/consensus" "github.com/filecoin-project/lotus/chain/consensus/filcns"
"github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
@@ -96,7 +96,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sys vm.Syscal
Epoch: 0, Epoch: 0,
Rand: &fakeRand{}, Rand: &fakeRand{},
Bstore: cs.StateBlockstore(), Bstore: cs.StateBlockstore(),
Actors: consensus.NewActorRegistry(), Actors: filcns.NewActorRegistry(),
Syscalls: mkFakedSigSyscalls(sys), Syscalls: mkFakedSigSyscalls(sys),
CircSupplyCalc: csc, CircSupplyCalc: csc,
NetworkVersion: nv, NetworkVersion: nv,

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