Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
96a5e579cf |
+19
-164
@@ -5,7 +5,7 @@ orbs:
|
|||||||
executors:
|
executors:
|
||||||
golang:
|
golang:
|
||||||
docker:
|
docker:
|
||||||
- image: circleci/golang:1.14.6
|
- image: circleci/golang:1.14.2
|
||||||
resource_class: 2xlarge
|
resource_class: 2xlarge
|
||||||
ubuntu:
|
ubuntu:
|
||||||
docker:
|
docker:
|
||||||
@@ -34,7 +34,7 @@ commands:
|
|||||||
condition: << parameters.linux >>
|
condition: << parameters.linux >>
|
||||||
steps:
|
steps:
|
||||||
- run: sudo apt-get update
|
- run: sudo apt-get update
|
||||||
- run: sudo apt-get install ocl-icd-opencl-dev libhwloc-dev
|
- run: sudo apt-get install ocl-icd-opencl-dev
|
||||||
- run: git submodule sync
|
- run: git submodule sync
|
||||||
- run: git submodule update --init
|
- run: git submodule update --init
|
||||||
download-params:
|
download-params:
|
||||||
@@ -45,7 +45,7 @@ commands:
|
|||||||
- 'v25-2k-lotus-params'
|
- 'v25-2k-lotus-params'
|
||||||
paths:
|
paths:
|
||||||
- /var/tmp/filecoin-proof-parameters/
|
- /var/tmp/filecoin-proof-parameters/
|
||||||
- run: ./lotus fetch-params 2048
|
- run: ./lotus fetch-params --proving-params 2048
|
||||||
- save_cache:
|
- save_cache:
|
||||||
name: Save parameters cache
|
name: Save parameters cache
|
||||||
key: 'v25-2k-lotus-params'
|
key: 'v25-2k-lotus-params'
|
||||||
@@ -93,10 +93,10 @@ jobs:
|
|||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
path: lotus
|
path: lotus
|
||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
path: lotus-miner
|
path: lotus-storage-miner
|
||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
path: lotus-worker
|
path: lotus-seal-worker
|
||||||
- run: mkdir linux && mv lotus lotus-miner lotus-worker linux/
|
- run: mkdir linux && mv lotus lotus-storage-miner lotus-seal-worker linux/
|
||||||
- persist_to_workspace:
|
- persist_to_workspace:
|
||||||
root: "."
|
root: "."
|
||||||
paths:
|
paths:
|
||||||
@@ -113,7 +113,7 @@ jobs:
|
|||||||
test: &test
|
test: &test
|
||||||
description: |
|
description: |
|
||||||
Run tests with gotestsum.
|
Run tests with gotestsum.
|
||||||
parameters: &test-params
|
parameters:
|
||||||
executor:
|
executor:
|
||||||
type: executor
|
type: executor
|
||||||
default: golang
|
default: golang
|
||||||
@@ -134,7 +134,7 @@ jobs:
|
|||||||
description: Test suite name to report to CircleCI.
|
description: Test suite name to report to CircleCI.
|
||||||
gotestsum-format:
|
gotestsum-format:
|
||||||
type: string
|
type: string
|
||||||
default: pkgname-and-test-fails
|
default: short
|
||||||
description: gotestsum format. https://github.com/gotestyourself/gotestsum#format
|
description: gotestsum format. https://github.com/gotestyourself/gotestsum#format
|
||||||
coverage:
|
coverage:
|
||||||
type: string
|
type: string
|
||||||
@@ -156,28 +156,21 @@ jobs:
|
|||||||
- download-params
|
- download-params
|
||||||
- go/install-gotestsum:
|
- go/install-gotestsum:
|
||||||
gobin: $HOME/.local/bin
|
gobin: $HOME/.local/bin
|
||||||
version: 0.5.2
|
|
||||||
- run:
|
- run:
|
||||||
name: go test
|
name: go test
|
||||||
environment:
|
environment:
|
||||||
|
GOTESTSUM_JUNITFILE: /tmp/test-reports/<< parameters.test-suite-name >>/junit.xml
|
||||||
|
GOTESTSUM_FORMAT: << parameters.gotestsum-format >>
|
||||||
LOTUS_TEST_WINDOW_POST: << parameters.winpost-test >>
|
LOTUS_TEST_WINDOW_POST: << parameters.winpost-test >>
|
||||||
SKIP_CONFORMANCE: "1"
|
|
||||||
command: |
|
command: |
|
||||||
mkdir -p /tmp/test-reports/<< parameters.test-suite-name >>
|
mkdir -p /tmp/test-reports/<< parameters.test-suite-name >>
|
||||||
mkdir -p /tmp/test-artifacts
|
gotestsum -- \
|
||||||
gotestsum \
|
|
||||||
--format << parameters.gotestsum-format >> \
|
|
||||||
--junitfile /tmp/test-reports/<< parameters.test-suite-name >>/junit.xml \
|
|
||||||
--jsonfile /tmp/test-artifacts/<< parameters.test-suite-name >>.json \
|
|
||||||
-- \
|
|
||||||
<< parameters.coverage >> \
|
<< parameters.coverage >> \
|
||||||
<< parameters.go-test-flags >> \
|
<< parameters.go-test-flags >> \
|
||||||
<< parameters.packages >>
|
<< parameters.packages >>
|
||||||
no_output_timeout: 30m
|
no_output_timeout: 30m
|
||||||
- store_test_results:
|
- store_test_results:
|
||||||
path: /tmp/test-reports
|
path: /tmp/test-reports
|
||||||
- store_artifacts:
|
|
||||||
path: /tmp/test-artifacts/<< parameters.test-suite-name >>.json
|
|
||||||
- when:
|
- when:
|
||||||
condition: << parameters.codecov-upload >>
|
condition: << parameters.codecov-upload >>
|
||||||
steps:
|
steps:
|
||||||
@@ -188,99 +181,10 @@ jobs:
|
|||||||
command: |
|
command: |
|
||||||
bash <(curl -s https://codecov.io/bash)
|
bash <(curl -s https://codecov.io/bash)
|
||||||
|
|
||||||
test-chain:
|
|
||||||
<<: *test
|
|
||||||
test-node:
|
|
||||||
<<: *test
|
|
||||||
test-storage:
|
|
||||||
<<: *test
|
|
||||||
test-cli:
|
|
||||||
<<: *test
|
|
||||||
test-short:
|
test-short:
|
||||||
<<: *test
|
<<: *test
|
||||||
test-window-post:
|
test-window-post:
|
||||||
<<: *test
|
<<: *test
|
||||||
test-conformance:
|
|
||||||
description: |
|
|
||||||
Run tests using a corpus of interoperable test vectors for Filecoin
|
|
||||||
implementations to test their correctness and compliance with the Filecoin
|
|
||||||
specifications.
|
|
||||||
parameters:
|
|
||||||
<<: *test-params
|
|
||||||
vectors-branch:
|
|
||||||
type: string
|
|
||||||
default: ""
|
|
||||||
description: |
|
|
||||||
Branch on github.com/filecoin-project/test-vectors to checkout and
|
|
||||||
test with. If empty (the default) the commit defined by the git
|
|
||||||
submodule is used.
|
|
||||||
executor: << parameters.executor >>
|
|
||||||
steps:
|
|
||||||
- install-deps
|
|
||||||
- prepare
|
|
||||||
- run:
|
|
||||||
command: make deps lotus
|
|
||||||
no_output_timeout: 30m
|
|
||||||
- download-params
|
|
||||||
- when:
|
|
||||||
condition:
|
|
||||||
not:
|
|
||||||
equal: [ "", << parameters.vectors-branch >> ]
|
|
||||||
steps:
|
|
||||||
- run:
|
|
||||||
name: checkout vectors branch
|
|
||||||
command: |
|
|
||||||
cd extern/test-vectors
|
|
||||||
git fetch
|
|
||||||
git checkout origin/<< parameters.vectors-branch >>
|
|
||||||
- go/install-gotestsum:
|
|
||||||
gobin: $HOME/.local/bin
|
|
||||||
version: 0.5.2
|
|
||||||
- run:
|
|
||||||
name: install statediff globally
|
|
||||||
command: |
|
|
||||||
## statediff is optional; we succeed even if compilation fails.
|
|
||||||
mkdir -p /tmp/statediff
|
|
||||||
git clone https://github.com/filecoin-project/statediff.git /tmp/statediff
|
|
||||||
cd /tmp/statediff
|
|
||||||
go install ./cmd/statediff || exit 0
|
|
||||||
- run:
|
|
||||||
name: go test
|
|
||||||
environment:
|
|
||||||
SKIP_CONFORMANCE: "0"
|
|
||||||
command: |
|
|
||||||
mkdir -p /tmp/test-reports
|
|
||||||
mkdir -p /tmp/test-artifacts
|
|
||||||
gotestsum \
|
|
||||||
--format pkgname-and-test-fails \
|
|
||||||
--junitfile /tmp/test-reports/junit.xml \
|
|
||||||
-- \
|
|
||||||
-v -coverpkg ./chain/vm/,github.com/filecoin-project/specs-actors/... -coverprofile=/tmp/conformance.out ./conformance/
|
|
||||||
go tool cover -html=/tmp/conformance.out -o /tmp/test-artifacts/conformance-coverage.html
|
|
||||||
no_output_timeout: 30m
|
|
||||||
- store_test_results:
|
|
||||||
path: /tmp/test-reports
|
|
||||||
- store_artifacts:
|
|
||||||
path: /tmp/test-artifacts/conformance-coverage.html
|
|
||||||
build-lotus-soup:
|
|
||||||
description: |
|
|
||||||
Compile `lotus-soup` Testground test plan using the current version of Lotus.
|
|
||||||
parameters:
|
|
||||||
<<: *test-params
|
|
||||||
executor: << parameters.executor >>
|
|
||||||
steps:
|
|
||||||
- install-deps
|
|
||||||
- prepare
|
|
||||||
- run: cd extern/oni && git submodule sync
|
|
||||||
- run: cd extern/oni && git submodule update --init
|
|
||||||
- run: cd extern/filecoin-ffi && make
|
|
||||||
- run:
|
|
||||||
name: "replace lotus, filecoin-ffi, blst and fil-blst deps"
|
|
||||||
command: cd extern/oni/lotus-soup && go mod edit -replace github.com/filecoin-project/lotus=../../../ && go mod edit -replace github.com/filecoin-project/filecoin-ffi=../../filecoin-ffi && go mod edit -replace github.com/supranational/blst=../../blst
|
|
||||||
- run:
|
|
||||||
name: "build lotus-soup testplan"
|
|
||||||
command: pushd extern/oni/lotus-soup && go build -tags=testground .
|
|
||||||
|
|
||||||
|
|
||||||
build-macos:
|
build-macos:
|
||||||
description: build darwin lotus binary
|
description: build darwin lotus binary
|
||||||
@@ -319,10 +223,10 @@ jobs:
|
|||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
path: lotus
|
path: lotus
|
||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
path: lotus-miner
|
path: lotus-storage-miner
|
||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
path: lotus-worker
|
path: lotus-seal-worker
|
||||||
- run: mkdir darwin && mv lotus lotus-miner lotus-worker darwin/
|
- run: mkdir darwin && mv lotus lotus-storage-miner lotus-seal-worker darwin/
|
||||||
- persist_to_workspace:
|
- persist_to_workspace:
|
||||||
root: "."
|
root: "."
|
||||||
paths:
|
paths:
|
||||||
@@ -342,28 +246,6 @@ jobs:
|
|||||||
- run:
|
- run:
|
||||||
command: "! go fmt ./... 2>&1 | read"
|
command: "! go fmt ./... 2>&1 | read"
|
||||||
|
|
||||||
cbor-gen-check:
|
|
||||||
executor: golang
|
|
||||||
steps:
|
|
||||||
- install-deps
|
|
||||||
- prepare
|
|
||||||
- run: make deps
|
|
||||||
- run: go install golang.org/x/tools/cmd/goimports
|
|
||||||
- run: go install github.com/hannahhoward/cbor-gen-for
|
|
||||||
- run: go generate ./...
|
|
||||||
- run: git --no-pager diff
|
|
||||||
- run: git --no-pager diff --quiet
|
|
||||||
|
|
||||||
docs-check:
|
|
||||||
executor: golang
|
|
||||||
steps:
|
|
||||||
- install-deps
|
|
||||||
- prepare
|
|
||||||
- run: make deps
|
|
||||||
- run: make docsgen
|
|
||||||
- run: git --no-pager diff
|
|
||||||
- run: git --no-pager diff --quiet
|
|
||||||
|
|
||||||
lint: &lint
|
lint: &lint
|
||||||
description: |
|
description: |
|
||||||
Run golangci-lint.
|
Run golangci-lint.
|
||||||
@@ -400,6 +282,9 @@ jobs:
|
|||||||
command: |
|
command: |
|
||||||
$HOME/.local/bin/golangci-lint run -v --timeout 2m \
|
$HOME/.local/bin/golangci-lint run -v --timeout 2m \
|
||||||
--concurrency << parameters.concurrency >> << parameters.args >>
|
--concurrency << parameters.concurrency >> << parameters.args >>
|
||||||
|
lint-changes:
|
||||||
|
<<: *lint
|
||||||
|
|
||||||
lint-all:
|
lint-all:
|
||||||
<<: *lint
|
<<: *lint
|
||||||
|
|
||||||
@@ -428,51 +313,21 @@ workflows:
|
|||||||
version: 2.1
|
version: 2.1
|
||||||
ci:
|
ci:
|
||||||
jobs:
|
jobs:
|
||||||
- lint-all:
|
- lint-changes:
|
||||||
concurrency: "16" # expend all docker 2xlarge CPUs.
|
args: "--new-from-rev origin/next"
|
||||||
- mod-tidy-check
|
- mod-tidy-check
|
||||||
- gofmt
|
- gofmt
|
||||||
- cbor-gen-check
|
|
||||||
- docs-check
|
|
||||||
- test:
|
- test:
|
||||||
codecov-upload: true
|
codecov-upload: true
|
||||||
test-suite-name: full
|
|
||||||
- test-chain:
|
|
||||||
codecov-upload: true
|
|
||||||
test-suite-name: chain
|
|
||||||
packages: "./chain/..."
|
|
||||||
- test-node:
|
|
||||||
codecov-upload: true
|
|
||||||
test-suite-name: node
|
|
||||||
packages: "./node/..."
|
|
||||||
- test-storage:
|
|
||||||
codecov-upload: true
|
|
||||||
test-suite-name: storage
|
|
||||||
packages: "./storage/... ./extern/..."
|
|
||||||
- test-cli:
|
|
||||||
codecov-upload: true
|
|
||||||
test-suite-name: cli
|
|
||||||
packages: "./cli/... ./cmd/... ./api/..."
|
|
||||||
- test-window-post:
|
- test-window-post:
|
||||||
go-test-flags: "-run=TestWindowedPost"
|
go-test-flags: "-run=TestWindowedPost"
|
||||||
winpost-test: "1"
|
winpost-test: "1"
|
||||||
test-suite-name: window-post
|
|
||||||
- test-short:
|
- test-short:
|
||||||
go-test-flags: "--timeout 10m --short"
|
go-test-flags: "--timeout 10m --short"
|
||||||
test-suite-name: short
|
|
||||||
filters:
|
filters:
|
||||||
tags:
|
tags:
|
||||||
only:
|
only:
|
||||||
- /^v\d+\.\d+\.\d+$/
|
- /^v\d+\.\d+\.\d+$/
|
||||||
- test-conformance:
|
|
||||||
test-suite-name: conformance
|
|
||||||
packages: "./conformance"
|
|
||||||
- test-conformance:
|
|
||||||
name: test-conformance-bleeding-edge
|
|
||||||
test-suite-name: conformance-bleeding-edge
|
|
||||||
packages: "./conformance"
|
|
||||||
vectors-branch: master
|
|
||||||
- build-lotus-soup
|
|
||||||
- build-debug
|
- build-debug
|
||||||
- build-all:
|
- build-all:
|
||||||
requires:
|
requires:
|
||||||
|
|||||||
+1
-7
@@ -1,9 +1,3 @@
|
|||||||
comment: off
|
comment: off
|
||||||
ignore:
|
ignore:
|
||||||
- "**/cbor_gen.go"
|
- "cbor_gen.go"
|
||||||
- "api/test/**/*"
|
|
||||||
- "api/test/*"
|
|
||||||
- "gen/**/*"
|
|
||||||
- "gen/*"
|
|
||||||
github_checks:
|
|
||||||
annotations: false
|
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
## filecoin-project/lotus CODEOWNERS
|
|
||||||
## Refer to https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners.
|
|
||||||
##
|
|
||||||
## These users or groups will be automatically assigned as reviewers every time
|
|
||||||
## a PR is submitted that modifies code in the specified locations.
|
|
||||||
##
|
|
||||||
## The Lotus repo configuration requires that at least ONE codeowner approves
|
|
||||||
## the PR before merging.
|
|
||||||
|
|
||||||
### Global owners.
|
|
||||||
* @magik6k @whyrusleeping @Kubuxu
|
|
||||||
|
|
||||||
### Conformance testing.
|
|
||||||
conformance/ @raulk
|
|
||||||
extern/test-vectors @raulk
|
|
||||||
cmd/tvx @raulk
|
|
||||||
@@ -21,7 +21,7 @@ A clear and concise description of what you expected to happen.
|
|||||||
**Screenshots**
|
**Screenshots**
|
||||||
If applicable, add screenshots to help explain your problem.
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
**Version (run `lotus version`):**
|
**Version (run `lotus --version`):**
|
||||||
|
|
||||||
**Additional context**
|
**Additional context**
|
||||||
Add any other context about the problem here.
|
Add any other context about the problem here.
|
||||||
|
|||||||
@@ -17,27 +17,18 @@ A brief description of the problem you encountered while proving (sealing) a sec
|
|||||||
|
|
||||||
Including what commands you ran, and a description of your setup, is very helpful.
|
Including what commands you ran, and a description of your setup, is very helpful.
|
||||||
|
|
||||||
|
**Sectors list**
|
||||||
|
|
||||||
|
The output of `./lotus-storage-miner sectors list`.
|
||||||
|
|
||||||
**Sectors status**
|
**Sectors status**
|
||||||
|
|
||||||
The output of `lotus-miner sectors status --log <sectorId>` for the failed sector(s).
|
The output of `./lotus-storage-miner sectors status --log <sectorId>` for the failed sector(s).
|
||||||
|
|
||||||
**Lotus miner logs**
|
**Lotus storage miner logs**
|
||||||
|
|
||||||
Please go through the logs of your miner, and include screenshots of any error-like messages you find.
|
Please go through the logs of your storage miner, and include screenshots of any error-like messages you find.
|
||||||
|
|
||||||
Alternatively please upload full log files and share a link here
|
|
||||||
|
|
||||||
**Lotus miner diagnostic info**
|
|
||||||
|
|
||||||
Please collect the following diagnostic information, and share a link here
|
|
||||||
|
|
||||||
* lotus-miner diagnostic info `lotus-miner info all > allinfo`
|
|
||||||
|
|
||||||
** Code modifications **
|
|
||||||
|
|
||||||
If you have modified parts of lotus, please describe which areas were modified,
|
|
||||||
and the scope of those modifications
|
|
||||||
|
|
||||||
**Version**
|
**Version**
|
||||||
|
|
||||||
The output of `lotus --version`.
|
The output of `./lotus --version`.
|
||||||
|
|||||||
@@ -1,248 +0,0 @@
|
|||||||
###
|
|
||||||
### Special magic GitHub labels
|
|
||||||
### https://help.github.com/en/github/building-a-strong-community/encouraging-helpful-contributions-to-your-project-with-labels
|
|
||||||
#
|
|
||||||
- name: "good first issue"
|
|
||||||
color: 7057ff
|
|
||||||
description: "Good for newcomers"
|
|
||||||
- name: "help wanted"
|
|
||||||
color: 008672
|
|
||||||
description: "Extra attention is needed"
|
|
||||||
|
|
||||||
###
|
|
||||||
### Goals
|
|
||||||
#
|
|
||||||
- name: goal/incentives
|
|
||||||
color: ff004d
|
|
||||||
description: "Incentinet"
|
|
||||||
|
|
||||||
###
|
|
||||||
### Areas
|
|
||||||
#
|
|
||||||
- name: area/ux
|
|
||||||
color: 00A4E0
|
|
||||||
description: "Area: UX"
|
|
||||||
- name: area/chain/vm
|
|
||||||
color: 00A4E2
|
|
||||||
description: "Area: Chain/VM"
|
|
||||||
- name: area/chain/sync
|
|
||||||
color: 00A4E4
|
|
||||||
description: "Area: Chain/Sync"
|
|
||||||
- name: area/chain/misc
|
|
||||||
color: 00A4E6
|
|
||||||
description: "Area: Chain/Misc"
|
|
||||||
- name: area/markets
|
|
||||||
color: 00A4E8
|
|
||||||
description: "Area: Markets"
|
|
||||||
- name: area/sealing/fsm
|
|
||||||
color: 0bb1ed
|
|
||||||
description: "Area: Sealing/FSM"
|
|
||||||
- name: area/sealing/storage
|
|
||||||
color: 0EB4F0
|
|
||||||
description: "Area: Sealing/Storage"
|
|
||||||
- name: area/proving
|
|
||||||
color: 0EB4F0
|
|
||||||
description: "Area: Proving"
|
|
||||||
- name: area/mining
|
|
||||||
color: 10B6F2
|
|
||||||
description: "Area: Mining"
|
|
||||||
- name: area/client/storage
|
|
||||||
color: 13B9F5
|
|
||||||
description: "Area: Client/Storage"
|
|
||||||
- name: area/client/retrieval
|
|
||||||
color: 15BBF7
|
|
||||||
description: "Area: Client/Retrieval"
|
|
||||||
- name: area/wallet
|
|
||||||
color: 15BBF7
|
|
||||||
description: "Area: Wallet"
|
|
||||||
- name: area/payment-channel
|
|
||||||
color: ff6767
|
|
||||||
description: "Area: Payment Channel"
|
|
||||||
- name: area/multisig
|
|
||||||
color: fff0ff
|
|
||||||
description: "Area: Multisig"
|
|
||||||
- name: area/networking
|
|
||||||
color: 273f8a
|
|
||||||
description: "Area: Networking"
|
|
||||||
|
|
||||||
###
|
|
||||||
### Kinds
|
|
||||||
#
|
|
||||||
- name: kind/bug
|
|
||||||
color: c92712
|
|
||||||
description: "Kind: Bug"
|
|
||||||
- name: kind/chore
|
|
||||||
color: fcf0b5
|
|
||||||
description: "Kind: Chore"
|
|
||||||
- name: kind/feature
|
|
||||||
color: FFF3B8
|
|
||||||
description: "Kind: Feature"
|
|
||||||
- name: kind/improvement
|
|
||||||
color: FFF5BA
|
|
||||||
description: "Kind: Improvement"
|
|
||||||
- name: kind/test
|
|
||||||
color: FFF8BD
|
|
||||||
description: "Kind: Test"
|
|
||||||
- name: kind/question
|
|
||||||
color: FFFDC2
|
|
||||||
description: "Kind: Question"
|
|
||||||
- name: kind/enhancement
|
|
||||||
color: FFFFC5
|
|
||||||
description: "Kind: Enhancement"
|
|
||||||
- name: kind/discussion
|
|
||||||
color: FFFFC7
|
|
||||||
description: "Kind: Discussion"
|
|
||||||
|
|
||||||
###
|
|
||||||
### Difficulties
|
|
||||||
#
|
|
||||||
- name: dif/trivial
|
|
||||||
color: b2b7ff
|
|
||||||
description: "Can be confidently tackled by newcomers, who are widely unfamiliar with lotus"
|
|
||||||
- name: dif/easy
|
|
||||||
color: 7886d7
|
|
||||||
description: "An existing lotus user should be able to pick this up"
|
|
||||||
- name: dif/medium
|
|
||||||
color: 6574cd
|
|
||||||
description: "Prior development experience with lotus is likely helpful"
|
|
||||||
- name: dif/hard
|
|
||||||
color: 5661b3
|
|
||||||
description: "Suggests that having worked on the specific component affected by this issue is important"
|
|
||||||
- name: dif/expert
|
|
||||||
color: 2f365f
|
|
||||||
description: "Requires extensive knowledge of the history, implications, ramifications of the issue"
|
|
||||||
|
|
||||||
###
|
|
||||||
### Efforts
|
|
||||||
#
|
|
||||||
- name: effort/minutes
|
|
||||||
color: e8fffe
|
|
||||||
description: "Effort: Minutes"
|
|
||||||
- name: effort/hours
|
|
||||||
color: a0f0ed
|
|
||||||
description: "Effort: Hours"
|
|
||||||
- name: effort/day
|
|
||||||
color: 64d5ca
|
|
||||||
description: "Effort: One Day"
|
|
||||||
- name: effort/days
|
|
||||||
color: 4dc0b5
|
|
||||||
description: "Effort: Multiple Days"
|
|
||||||
- name: effort/week
|
|
||||||
color: 38a89d
|
|
||||||
description: "Effort: One Week"
|
|
||||||
- name: effort/weeks
|
|
||||||
color: 20504f
|
|
||||||
description: "Effort: Multiple Weeks"
|
|
||||||
|
|
||||||
###
|
|
||||||
### Impacts
|
|
||||||
#
|
|
||||||
- name: impact/regression
|
|
||||||
color: f1f5f8
|
|
||||||
description: "Impact: Regression"
|
|
||||||
- name: impact/api-breakage
|
|
||||||
color: ECF0F3
|
|
||||||
description: "Impact: API Breakage"
|
|
||||||
- name: impact/quality
|
|
||||||
color: E7EBEE
|
|
||||||
description: "Impact: Quality"
|
|
||||||
- name: impact/dx
|
|
||||||
color: E2E6E9
|
|
||||||
description: "Impact: Developer Experience"
|
|
||||||
- name: impact/test-flakiness
|
|
||||||
color: DDE1E4
|
|
||||||
description: "Impact: Test Flakiness"
|
|
||||||
- name: impact/consensus
|
|
||||||
color: b20014
|
|
||||||
description: "Impact: Consensus"
|
|
||||||
|
|
||||||
###
|
|
||||||
### Topics
|
|
||||||
#
|
|
||||||
- name: topic/interoperability
|
|
||||||
color: bf0f73
|
|
||||||
description: "Topic: Interoperability"
|
|
||||||
- name: topic/specs
|
|
||||||
color: CC1C80
|
|
||||||
description: "Topic: Specs"
|
|
||||||
- name: topic/docs
|
|
||||||
color: D9298D
|
|
||||||
description: "Topic: Documentation"
|
|
||||||
- name: topic/architecture
|
|
||||||
color: E53599
|
|
||||||
description: "Topic: Architecture"
|
|
||||||
|
|
||||||
###
|
|
||||||
### Priorities
|
|
||||||
###
|
|
||||||
- name: P0
|
|
||||||
color: dd362a
|
|
||||||
description: "P0: Critical Blocker"
|
|
||||||
- name: P1
|
|
||||||
color: ce8048
|
|
||||||
description: "P1: Must be resolved"
|
|
||||||
- name: P2
|
|
||||||
color: dbd81a
|
|
||||||
description: "P2: Should be resolved"
|
|
||||||
- name: P3
|
|
||||||
color: 9fea8f
|
|
||||||
description: "P3: Might get resolved"
|
|
||||||
|
|
||||||
###
|
|
||||||
### Hints
|
|
||||||
#
|
|
||||||
#- name: hint/good-first-issue
|
|
||||||
# color: 7057ff
|
|
||||||
# description: "Hint: Good First Issue"
|
|
||||||
#- name: hint/help-wanted
|
|
||||||
# color: 008672
|
|
||||||
# description: "Hint: Help Wanted"
|
|
||||||
- name: hint/needs-decision
|
|
||||||
color: 33B9A5
|
|
||||||
description: "Hint: Needs Decision"
|
|
||||||
- name: hint/needs-triage
|
|
||||||
color: 1AA08C
|
|
||||||
description: "Hint: Needs Triage"
|
|
||||||
- name: hint/needs-analysis
|
|
||||||
color: 26AC98
|
|
||||||
description: "Hint: Needs Analysis"
|
|
||||||
- name: hint/needs-author-input
|
|
||||||
color: 33B9A5
|
|
||||||
description: "Hint: Needs Author Input"
|
|
||||||
- name: hint/needs-team-input
|
|
||||||
color: 40C6B2
|
|
||||||
description: "Hint: Needs Team Input"
|
|
||||||
- name: hint/needs-community-input
|
|
||||||
color: 4DD3BF
|
|
||||||
description: "Hint: Needs Community Input"
|
|
||||||
- name: hint/needs-review
|
|
||||||
color: 5AE0CC
|
|
||||||
description: "Hint: Needs Review"
|
|
||||||
|
|
||||||
###
|
|
||||||
### Statuses
|
|
||||||
#
|
|
||||||
- name: status/done
|
|
||||||
color: edb3a6
|
|
||||||
description: "Status: Done"
|
|
||||||
- name: status/deferred
|
|
||||||
color: E0A699
|
|
||||||
description: "Status: Deferred"
|
|
||||||
- name: status/in-progress
|
|
||||||
color: D49A8D
|
|
||||||
description: "Status: In Progress"
|
|
||||||
- name: status/blocked
|
|
||||||
color: C78D80
|
|
||||||
description: "Status: Blocked"
|
|
||||||
- name: status/inactive
|
|
||||||
color: BA8073
|
|
||||||
description: "Status: Inactive"
|
|
||||||
- name: status/waiting
|
|
||||||
color: AD7366
|
|
||||||
description: "Status: Waiting"
|
|
||||||
- name: status/rotten
|
|
||||||
color: 7A4033
|
|
||||||
description: "Status: Rotten"
|
|
||||||
- name: status/discarded
|
|
||||||
color: 6D3326
|
|
||||||
description: "Status: Discarded / Won't fix"
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
|
|
||||||
name: Label syncer
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
paths:
|
|
||||||
- '.github/labels.yml'
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
name: Sync labels
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@1.0.0
|
|
||||||
- uses: micnncim/action-label-syncer@v1.0.0
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
+8
-13
@@ -1,24 +1,19 @@
|
|||||||
/lotus
|
/lotus
|
||||||
/lotus-miner
|
/lotus-storage-miner
|
||||||
/lotus-worker
|
/lotus-seal-worker
|
||||||
/lotus-seed
|
/lotus-seed
|
||||||
/lotus-health
|
/lotus-health
|
||||||
/lotus-chainwatch
|
|
||||||
/lotus-shed
|
/lotus-shed
|
||||||
/lotus-pond
|
/pond
|
||||||
/lotus-townhall
|
/townhall
|
||||||
/lotus-fountain
|
/fountain
|
||||||
/lotus-stats
|
/stats
|
||||||
/lotus-bench
|
/bench
|
||||||
/lotus-gateway
|
|
||||||
/lotus-pcr
|
|
||||||
/lotus-wallet
|
|
||||||
/bench.json
|
/bench.json
|
||||||
/lotuspond/front/node_modules
|
/lotuspond/front/node_modules
|
||||||
/lotuspond/front/build
|
/lotuspond/front/build
|
||||||
/cmd/lotus-townhall/townhall/node_modules
|
/cmd/lotus-townhall/townhall/node_modules
|
||||||
/cmd/lotus-townhall/townhall/build
|
/cmd/lotus-townhall/townhall/build
|
||||||
/cmd/lotus-townhall/townhall/package-lock.json
|
|
||||||
extern/filecoin-ffi/rust/target
|
extern/filecoin-ffi/rust/target
|
||||||
**/*.a
|
**/*.a
|
||||||
**/*.pc
|
**/*.pc
|
||||||
@@ -29,6 +24,7 @@ build/paramfetch.sh
|
|||||||
/vendor
|
/vendor
|
||||||
/blocks.dot
|
/blocks.dot
|
||||||
/blocks.svg
|
/blocks.svg
|
||||||
|
/chainwatch
|
||||||
/chainwatch.db
|
/chainwatch.db
|
||||||
/bundle
|
/bundle
|
||||||
/darwin
|
/darwin
|
||||||
@@ -39,4 +35,3 @@ build/paramfetch.sh
|
|||||||
bin/ipget
|
bin/ipget
|
||||||
bin/tmp/*
|
bin/tmp/*
|
||||||
.idea
|
.idea
|
||||||
scratchpad
|
|
||||||
|
|||||||
+2
-10
@@ -1,15 +1,7 @@
|
|||||||
[submodule "extern/filecoin-ffi"]
|
[submodule "extern/filecoin-ffi"]
|
||||||
path = extern/filecoin-ffi
|
path = extern/filecoin-ffi
|
||||||
url = https://github.com/filecoin-project/filecoin-ffi.git
|
url = https://github.com/filecoin-project/filecoin-ffi.git
|
||||||
|
branch = master
|
||||||
[submodule "extern/serialization-vectors"]
|
[submodule "extern/serialization-vectors"]
|
||||||
path = extern/serialization-vectors
|
path = extern/serialization-vectors
|
||||||
url = https://github.com/filecoin-project/serialization-vectors.git
|
url = https://github.com/filecoin-project/serialization-vectors
|
||||||
[submodule "extern/test-vectors"]
|
|
||||||
path = extern/test-vectors
|
|
||||||
url = https://github.com/filecoin-project/test-vectors.git
|
|
||||||
[submodule "extern/oni"]
|
|
||||||
path = extern/oni
|
|
||||||
url = https://github.com/filecoin-project/oni.git
|
|
||||||
[submodule "extern/blst"]
|
|
||||||
path = extern/blst
|
|
||||||
url = https://github.com/supranational/blst.git
|
|
||||||
|
|||||||
@@ -23,14 +23,6 @@ issues:
|
|||||||
- "Potential file inclusion via variable"
|
- "Potential file inclusion via variable"
|
||||||
- "should have( a package)? comment"
|
- "should have( a package)? comment"
|
||||||
- "Error return value of `logging.SetLogLevel` is not checked"
|
- "Error return value of `logging.SetLogLevel` is not checked"
|
||||||
- "comment on exported"
|
|
||||||
- "(func|method) \\w+ should be \\w+"
|
|
||||||
- "(type|var|struct field|(method|func) parameter) `\\w+` should be `\\w+`"
|
|
||||||
- "(G306|G301|G307|G108|G302|G204|G104)"
|
|
||||||
- "don't use ALL_CAPS in Go names"
|
|
||||||
- "string .* has .* occurrences, make it a constant"
|
|
||||||
- "a blank import should be only in a main or test package, or have a comment justifying it"
|
|
||||||
- "package comment should be of the form"
|
|
||||||
|
|
||||||
exclude-use-default: false
|
exclude-use-default: false
|
||||||
exclude-rules:
|
exclude-rules:
|
||||||
@@ -54,19 +46,6 @@ issues:
|
|||||||
linters:
|
linters:
|
||||||
- gosec
|
- gosec
|
||||||
|
|
||||||
- path: chain/vectors/gen/.*
|
|
||||||
linters:
|
|
||||||
- gosec
|
|
||||||
|
|
||||||
- path: cmd/lotus-bench/.*
|
|
||||||
linters:
|
|
||||||
- gosec
|
|
||||||
|
|
||||||
- path: api/test/.*
|
|
||||||
text: "context.Context should be the first parameter"
|
|
||||||
linters:
|
|
||||||
- golint
|
|
||||||
|
|
||||||
linters-settings:
|
linters-settings:
|
||||||
goconst:
|
goconst:
|
||||||
min-occurrences: 6
|
min-occurrences: 6
|
||||||
|
|||||||
+4
-1029
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@ all: build
|
|||||||
unexport GOFLAGS
|
unexport GOFLAGS
|
||||||
|
|
||||||
GOVERSION:=$(shell go version | cut -d' ' -f 3 | cut -d. -f 2)
|
GOVERSION:=$(shell go version | cut -d' ' -f 3 | cut -d. -f 2)
|
||||||
ifeq ($(shell expr $(GOVERSION) \< 14), 1)
|
ifeq ($(shell expr $(GOVERSION) \< 13), 1)
|
||||||
$(warning Your Golang version is go 1.$(GOVERSION))
|
$(warning Your Golang version is go 1.$(GOVERSION))
|
||||||
$(error Update Golang to version $(shell grep '^go' go.mod))
|
$(error Update Golang to version $(shell grep '^go' go.mod))
|
||||||
endif
|
endif
|
||||||
@@ -58,10 +58,10 @@ deps: $(BUILD_DEPS)
|
|||||||
.PHONY: deps
|
.PHONY: deps
|
||||||
|
|
||||||
debug: GOFLAGS+=-tags=debug
|
debug: GOFLAGS+=-tags=debug
|
||||||
debug: lotus lotus-miner lotus-worker lotus-seed
|
debug: lotus lotus-storage-miner lotus-seal-worker lotus-seed
|
||||||
|
|
||||||
2k: GOFLAGS+=-tags=2k
|
2k: GOFLAGS+=-tags=2k
|
||||||
2k: lotus lotus-miner lotus-worker lotus-seed
|
2k: lotus lotus-storage-miner lotus-seal-worker lotus-seed
|
||||||
|
|
||||||
lotus: $(BUILD_DEPS)
|
lotus: $(BUILD_DEPS)
|
||||||
rm -f lotus
|
rm -f lotus
|
||||||
@@ -71,19 +71,19 @@ lotus: $(BUILD_DEPS)
|
|||||||
.PHONY: lotus
|
.PHONY: lotus
|
||||||
BINS+=lotus
|
BINS+=lotus
|
||||||
|
|
||||||
lotus-miner: $(BUILD_DEPS)
|
lotus-storage-miner: $(BUILD_DEPS)
|
||||||
rm -f lotus-miner
|
rm -f lotus-storage-miner
|
||||||
go build $(GOFLAGS) -o lotus-miner ./cmd/lotus-storage-miner
|
go build $(GOFLAGS) -o lotus-storage-miner ./cmd/lotus-storage-miner
|
||||||
go run github.com/GeertJohan/go.rice/rice append --exec lotus-miner -i ./build
|
go run github.com/GeertJohan/go.rice/rice append --exec lotus-storage-miner -i ./build
|
||||||
.PHONY: lotus-miner
|
.PHONY: lotus-storage-miner
|
||||||
BINS+=lotus-miner
|
BINS+=lotus-storage-miner
|
||||||
|
|
||||||
lotus-worker: $(BUILD_DEPS)
|
lotus-seal-worker: $(BUILD_DEPS)
|
||||||
rm -f lotus-worker
|
rm -f lotus-seal-worker
|
||||||
go build $(GOFLAGS) -o lotus-worker ./cmd/lotus-seal-worker
|
go build $(GOFLAGS) -o lotus-seal-worker ./cmd/lotus-seal-worker
|
||||||
go run github.com/GeertJohan/go.rice/rice append --exec lotus-worker -i ./build
|
go run github.com/GeertJohan/go.rice/rice append --exec lotus-seal-worker -i ./build
|
||||||
.PHONY: lotus-worker
|
.PHONY: lotus-seal-worker
|
||||||
BINS+=lotus-worker
|
BINS+=lotus-seal-worker
|
||||||
|
|
||||||
lotus-shed: $(BUILD_DEPS)
|
lotus-shed: $(BUILD_DEPS)
|
||||||
rm -f lotus-shed
|
rm -f lotus-shed
|
||||||
@@ -92,28 +92,29 @@ lotus-shed: $(BUILD_DEPS)
|
|||||||
.PHONY: lotus-shed
|
.PHONY: lotus-shed
|
||||||
BINS+=lotus-shed
|
BINS+=lotus-shed
|
||||||
|
|
||||||
lotus-gateway: $(BUILD_DEPS)
|
build: lotus lotus-storage-miner lotus-seal-worker
|
||||||
rm -f lotus-gateway
|
|
||||||
go build $(GOFLAGS) -o lotus-gateway ./cmd/lotus-gateway
|
|
||||||
.PHONY: lotus-gateway
|
|
||||||
BINS+=lotus-gateway
|
|
||||||
|
|
||||||
build: lotus lotus-miner lotus-worker
|
|
||||||
@[[ $$(type -P "lotus") ]] && echo "Caution: you have \
|
@[[ $$(type -P "lotus") ]] && echo "Caution: you have \
|
||||||
an existing lotus binary in your PATH. This may cause problems if you don't run 'sudo make install'" || true
|
an existing lotus binary in your PATH. This may cause problems if you don't run 'sudo make install'" || true
|
||||||
|
|
||||||
.PHONY: build
|
.PHONY: build
|
||||||
|
|
||||||
install: install-daemon install-miner install-worker
|
install:
|
||||||
|
|
||||||
install-daemon:
|
|
||||||
install -C ./lotus /usr/local/bin/lotus
|
install -C ./lotus /usr/local/bin/lotus
|
||||||
|
install -C ./lotus-storage-miner /usr/local/bin/lotus-storage-miner
|
||||||
|
install -C ./lotus-seal-worker /usr/local/bin/lotus-seal-worker
|
||||||
|
|
||||||
install-miner:
|
install-services: install
|
||||||
install -C ./lotus-miner /usr/local/bin/lotus-miner
|
mkdir -p /usr/local/lib/systemd/system
|
||||||
|
install -C -m 0644 ./scripts/lotus-daemon.service /usr/local/lib/systemd/system/lotus-daemon.service
|
||||||
|
install -C -m 0644 ./scripts/lotus-miner.service /usr/local/lib/systemd/system/lotus-miner.service
|
||||||
|
systemctl daemon-reload
|
||||||
|
@echo
|
||||||
|
@echo "lotus and lotus-miner services installed. Don't forget to 'systemctl enable lotus|lotus-miner' for it to be enabled on startup."
|
||||||
|
|
||||||
install-worker:
|
clean-services:
|
||||||
install -C ./lotus-worker /usr/local/bin/lotus-worker
|
rm -f /usr/local/lib/systemd/system/lotus-daemon.service
|
||||||
|
rm -f /usr/local/lib/systemd/system/lotus-miner.service
|
||||||
|
systemctl daemon-reload
|
||||||
|
|
||||||
# TOOLS
|
# TOOLS
|
||||||
|
|
||||||
@@ -131,142 +132,55 @@ benchmarks:
|
|||||||
@curl -X POST 'http://benchmark.kittyhawk.wtf/benchmark' -d '@bench.json' -u "${benchmark_http_cred}"
|
@curl -X POST 'http://benchmark.kittyhawk.wtf/benchmark' -d '@bench.json' -u "${benchmark_http_cred}"
|
||||||
.PHONY: benchmarks
|
.PHONY: benchmarks
|
||||||
|
|
||||||
lotus-pond: 2k
|
pond: 2k
|
||||||
go build -o lotus-pond ./lotuspond
|
go build -o pond ./lotuspond
|
||||||
.PHONY: lotus-pond
|
|
||||||
BINS+=lotus-pond
|
|
||||||
|
|
||||||
lotus-pond-front:
|
|
||||||
(cd lotuspond/front && npm i && CI=false npm run build)
|
(cd lotuspond/front && npm i && CI=false npm run build)
|
||||||
.PHONY: lotus-pond-front
|
.PHONY: pond
|
||||||
|
BINS+=pond
|
||||||
|
|
||||||
lotus-pond-app: lotus-pond-front lotus-pond
|
townhall:
|
||||||
.PHONY: lotus-pond-app
|
rm -f townhall
|
||||||
|
go build -o townhall ./cmd/lotus-townhall
|
||||||
lotus-townhall:
|
|
||||||
rm -f lotus-townhall
|
|
||||||
go build -o lotus-townhall ./cmd/lotus-townhall
|
|
||||||
.PHONY: lotus-townhall
|
|
||||||
BINS+=lotus-townhall
|
|
||||||
|
|
||||||
lotus-townhall-front:
|
|
||||||
(cd ./cmd/lotus-townhall/townhall && npm i && npm run build)
|
(cd ./cmd/lotus-townhall/townhall && npm i && npm run build)
|
||||||
.PHONY: lotus-townhall-front
|
go run github.com/GeertJohan/go.rice/rice append --exec townhall -i ./cmd/lotus-townhall -i ./build
|
||||||
|
.PHONY: townhall
|
||||||
|
BINS+=townhall
|
||||||
|
|
||||||
lotus-townhall-app: lotus-touch lotus-townhall-front
|
fountain:
|
||||||
go run github.com/GeertJohan/go.rice/rice append --exec lotus-townhall -i ./cmd/lotus-townhall -i ./build
|
rm -f fountain
|
||||||
.PHONY: lotus-townhall-app
|
go build -o fountain ./cmd/lotus-fountain
|
||||||
|
go run github.com/GeertJohan/go.rice/rice append --exec fountain -i ./cmd/lotus-fountain -i ./build
|
||||||
|
.PHONY: fountain
|
||||||
|
BINS+=fountain
|
||||||
|
|
||||||
lotus-fountain:
|
chainwatch:
|
||||||
rm -f lotus-fountain
|
rm -f chainwatch
|
||||||
go build -o lotus-fountain ./cmd/lotus-fountain
|
go build -o chainwatch ./cmd/lotus-chainwatch
|
||||||
go run github.com/GeertJohan/go.rice/rice append --exec lotus-fountain -i ./cmd/lotus-fountain -i ./build
|
go run github.com/GeertJohan/go.rice/rice append --exec chainwatch -i ./cmd/lotus-chainwatch -i ./build
|
||||||
.PHONY: lotus-fountain
|
.PHONY: chainwatch
|
||||||
BINS+=lotus-fountain
|
BINS+=chainwatch
|
||||||
|
|
||||||
lotus-chainwatch:
|
bench:
|
||||||
rm -f lotus-chainwatch
|
rm -f bench
|
||||||
go build $(GOFLAGS) -o lotus-chainwatch ./cmd/lotus-chainwatch
|
go build -o bench ./cmd/lotus-bench
|
||||||
.PHONY: lotus-chainwatch
|
go run github.com/GeertJohan/go.rice/rice append --exec bench -i ./build
|
||||||
BINS+=lotus-chainwatch
|
.PHONY: bench
|
||||||
|
BINS+=bench
|
||||||
|
|
||||||
lotus-bench:
|
stats:
|
||||||
rm -f lotus-bench
|
rm -f stats
|
||||||
go build -o lotus-bench ./cmd/lotus-bench
|
go build -o stats ./tools/stats
|
||||||
go run github.com/GeertJohan/go.rice/rice append --exec lotus-bench -i ./build
|
go run github.com/GeertJohan/go.rice/rice append --exec stats -i ./build
|
||||||
.PHONY: lotus-bench
|
.PHONY: stats
|
||||||
BINS+=lotus-bench
|
BINS+=stats
|
||||||
|
|
||||||
lotus-stats:
|
health:
|
||||||
rm -f lotus-stats
|
|
||||||
go build $(GOFLAGS) -o lotus-stats ./cmd/lotus-stats
|
|
||||||
go run github.com/GeertJohan/go.rice/rice append --exec lotus-stats -i ./build
|
|
||||||
.PHONY: lotus-stats
|
|
||||||
BINS+=lotus-stats
|
|
||||||
|
|
||||||
lotus-pcr:
|
|
||||||
rm -f lotus-pcr
|
|
||||||
go build $(GOFLAGS) -o lotus-pcr ./cmd/lotus-pcr
|
|
||||||
go run github.com/GeertJohan/go.rice/rice append --exec lotus-pcr -i ./build
|
|
||||||
.PHONY: lotus-pcr
|
|
||||||
BINS+=lotus-pcr
|
|
||||||
|
|
||||||
lotus-health:
|
|
||||||
rm -f lotus-health
|
rm -f lotus-health
|
||||||
go build -o lotus-health ./cmd/lotus-health
|
go build -o lotus-health ./cmd/lotus-health
|
||||||
go run github.com/GeertJohan/go.rice/rice append --exec lotus-health -i ./build
|
go run github.com/GeertJohan/go.rice/rice append --exec lotus-health -i ./build
|
||||||
.PHONY: lotus-health
|
|
||||||
BINS+=lotus-health
|
|
||||||
|
|
||||||
lotus-wallet:
|
.PHONY: health
|
||||||
rm -f lotus-wallet
|
BINS+=health
|
||||||
go build -o lotus-wallet ./cmd/lotus-wallet
|
|
||||||
.PHONY: lotus-wallet
|
|
||||||
BINS+=lotus-wallet
|
|
||||||
|
|
||||||
testground:
|
|
||||||
go build -tags testground -o /dev/null ./cmd/lotus
|
|
||||||
.PHONY: testground
|
|
||||||
BINS+=testground
|
|
||||||
|
|
||||||
install-chainwatch: lotus-chainwatch
|
|
||||||
install -C ./lotus-chainwatch /usr/local/bin/lotus-chainwatch
|
|
||||||
|
|
||||||
# SYSTEMD
|
|
||||||
|
|
||||||
install-daemon-service: install-daemon
|
|
||||||
mkdir -p /etc/systemd/system
|
|
||||||
mkdir -p /var/log/lotus
|
|
||||||
install -C -m 0644 ./scripts/lotus-daemon.service /etc/systemd/system/lotus-daemon.service
|
|
||||||
systemctl daemon-reload
|
|
||||||
@echo
|
|
||||||
@echo "lotus-daemon service installed. Don't forget to run 'sudo systemctl start lotus-daemon' to start it and 'sudo systemctl enable lotus-daemon' for it to be enabled on startup."
|
|
||||||
|
|
||||||
install-miner-service: install-miner install-daemon-service
|
|
||||||
mkdir -p /etc/systemd/system
|
|
||||||
mkdir -p /var/log/lotus
|
|
||||||
install -C -m 0644 ./scripts/lotus-miner.service /etc/systemd/system/lotus-miner.service
|
|
||||||
systemctl daemon-reload
|
|
||||||
@echo
|
|
||||||
@echo "lotus-miner service installed. Don't forget to run 'sudo systemctl start lotus-miner' to start it and 'sudo systemctl enable lotus-miner' for it to be enabled on startup."
|
|
||||||
|
|
||||||
install-chainwatch-service: install-chainwatch install-daemon-service
|
|
||||||
mkdir -p /etc/systemd/system
|
|
||||||
mkdir -p /var/log/lotus
|
|
||||||
install -C -m 0644 ./scripts/lotus-chainwatch.service /etc/systemd/system/lotus-chainwatch.service
|
|
||||||
systemctl daemon-reload
|
|
||||||
@echo
|
|
||||||
@echo "chainwatch service installed. Don't forget to run 'sudo systemctl start lotus-chainwatch' to start it and 'sudo systemctl enable lotus-chainwatch' for it to be enabled on startup."
|
|
||||||
|
|
||||||
install-main-services: install-miner-service
|
|
||||||
|
|
||||||
install-all-services: install-main-services install-chainwatch-service
|
|
||||||
|
|
||||||
install-services: install-main-services
|
|
||||||
|
|
||||||
clean-daemon-service: clean-miner-service clean-chainwatch-service
|
|
||||||
-systemctl stop lotus-daemon
|
|
||||||
-systemctl disable lotus-daemon
|
|
||||||
rm -f /etc/systemd/system/lotus-daemon.service
|
|
||||||
systemctl daemon-reload
|
|
||||||
|
|
||||||
clean-miner-service:
|
|
||||||
-systemctl stop lotus-miner
|
|
||||||
-systemctl disable lotus-miner
|
|
||||||
rm -f /etc/systemd/system/lotus-miner.service
|
|
||||||
systemctl daemon-reload
|
|
||||||
|
|
||||||
clean-chainwatch-service:
|
|
||||||
-systemctl stop lotus-chainwatch
|
|
||||||
-systemctl disable lotus-chainwatch
|
|
||||||
rm -f /etc/systemd/system/lotus-chainwatch.service
|
|
||||||
systemctl daemon-reload
|
|
||||||
|
|
||||||
clean-main-services: clean-daemon-service
|
|
||||||
|
|
||||||
clean-all-services: clean-main-services
|
|
||||||
|
|
||||||
clean-services: clean-all-services
|
|
||||||
|
|
||||||
# MISC
|
# MISC
|
||||||
|
|
||||||
@@ -274,15 +188,15 @@ buildall: $(BINS)
|
|||||||
|
|
||||||
completions:
|
completions:
|
||||||
./scripts/make-completions.sh lotus
|
./scripts/make-completions.sh lotus
|
||||||
./scripts/make-completions.sh lotus-miner
|
./scripts/make-completions.sh lotus-storage-miner
|
||||||
.PHONY: completions
|
.PHONY: completions
|
||||||
|
|
||||||
install-completions:
|
install-completions:
|
||||||
mkdir -p /usr/share/bash-completion/completions /usr/local/share/zsh/site-functions/
|
mkdir -p /usr/share/bash-completion/completions /usr/local/share/zsh/site-functions/
|
||||||
install -C ./scripts/bash-completion/lotus /usr/share/bash-completion/completions/lotus
|
install -C ./scripts/bash-completion/lotus /usr/share/bash-completion/completions/lotus
|
||||||
install -C ./scripts/bash-completion/lotus-miner /usr/share/bash-completion/completions/lotus-miner
|
install -C ./scripts/bash-completion/lotus-storage-miner /usr/share/bash-completion/completions/lotus-storage-miner
|
||||||
install -C ./scripts/zsh-completion/lotus /usr/local/share/zsh/site-functions/_lotus
|
install -C ./scripts/zsh-completion/lotus /usr/local/share/zsh/site-functions/_lotus
|
||||||
install -C ./scripts/zsh-completion/lotus-miner /usr/local/share/zsh/site-functions/_lotus-miner
|
install -C ./scripts/zsh-completion/lotus-storage-miner /usr/local/share/zsh/site-functions/_lotus-storage-miner
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(CLEAN) $(BINS)
|
rm -rf $(CLEAN) $(BINS)
|
||||||
@@ -296,17 +210,11 @@ dist-clean:
|
|||||||
|
|
||||||
type-gen:
|
type-gen:
|
||||||
go run ./gen/main.go
|
go run ./gen/main.go
|
||||||
go generate ./...
|
|
||||||
|
|
||||||
method-gen:
|
method-gen:
|
||||||
(cd ./lotuspond/front/src/chain && go run ./methodgen.go)
|
(cd ./lotuspond/front/src/chain && go run ./methodgen.go)
|
||||||
|
|
||||||
gen: type-gen method-gen
|
gen: type-gen method-gen
|
||||||
|
|
||||||
docsgen:
|
|
||||||
go run ./api/docgen "api/api_full.go" "FullNode" > documentation/en/api-methods.md
|
|
||||||
go run ./api/docgen "api/api_storage.go" "StorageMiner" > documentation/en/api-methods-miner.md
|
|
||||||
go run ./api/docgen "api/api_worker.go" "WorkerAPI" > documentation/en/api-methods-worker.md
|
|
||||||
|
|
||||||
print-%:
|
print-%:
|
||||||
@echo $*=$($*)
|
@echo $*=$($*)
|
||||||
|
|||||||
@@ -1,47 +1,16 @@
|
|||||||
<p align="center">
|

|
||||||
<a href="https://docs.filecoin.io/" title="Filecoin Docs">
|
|
||||||
<img src="documentation/images/lotus_logo_h.png" alt="Project Lotus Logo" width="244" />
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h1 align="center">Project Lotus - 莲</h1>
|
# Project Lotus - 莲
|
||||||
|
|
||||||
<p align="center">
|
Lotus is an implementation of the Filecoin Distributed Storage Network. For more details about Filecoin, check out the [Filecoin Spec](https://github.com/filecoin-project/specs).
|
||||||
<a href="https://circleci.com/gh/filecoin-project/lotus"><img src="https://circleci.com/gh/filecoin-project/lotus.svg?style=svg"></a>
|
|
||||||
<a href="https://codecov.io/gh/filecoin-project/lotus"><img src="https://codecov.io/gh/filecoin-project/lotus/branch/master/graph/badge.svg"></a>
|
|
||||||
<a href="https://goreportcard.com/report/github.com/filecoin-project/lotus"><img src="https://goreportcard.com/badge/github.com/filecoin-project/lotus" /></a>
|
|
||||||
<a href=""><img src="https://img.shields.io/badge/golang-%3E%3D1.14.7-blue.svg" /></a>
|
|
||||||
<br>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
Lotus is an implementation of the Filecoin Distributed Storage Network. For more details about Filecoin, check out the [Filecoin Spec](https://spec.filecoin.io).
|
|
||||||
|
|
||||||
## Building & Documentation
|
|
||||||
|
|
||||||
For instructions on how to build, install and setup lotus, please visit [https://docs.filecoin.io/get-started/lotus](https://docs.filecoin.io/get-started/lotus/).
|
|
||||||
|
|
||||||
## Reporting a Vulnerability
|
|
||||||
|
|
||||||
Please send an email to security@filecoin.org. See our [security policy](SECURITY.md) for more details.
|
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
The main branches under development at the moment are:
|
All work is tracked via issues. An attempt at keeping an up-to-date view on remaining work is in the [lotus testnet github project board](https://github.com/filecoin-project/lotus/projects/1).
|
||||||
* [`master`](https://github.com/filecoin-project/lotus): current testnet.
|
|
||||||
* [`next`](https://github.com/filecoin-project/lotus/tree/next): working branch with chain-breaking changes.
|
|
||||||
* [`ntwk-calibration`](https://github.com/filecoin-project/lotus/tree/ntwk-calibration): devnet running one of `next` commits.
|
|
||||||
|
|
||||||
### Tracker
|
## Building & Documentation
|
||||||
|
|
||||||
All work is tracked via issues. An attempt at keeping an up-to-date view on remaining work towards Mainnet launch can be seen at the [lotus github project board](https://github.com/orgs/filecoin-project/projects/8). The issues labeled with `incentives` are there to identify the issues needed for Space Race launch.
|
For instructions on how to build lotus from source, please visit [https://docs.lotu.sh](https://docs.lotu.sh) or read the source [here](https://github.com/filecoin-project/lotus/tree/master/documentation).
|
||||||
|
|
||||||
### Packages
|
|
||||||
|
|
||||||
The lotus Filecoin implementation unfolds into the following packages:
|
|
||||||
|
|
||||||
- [This repo](https://github.com/filecoin-project/lotus)
|
|
||||||
- [go-fil-markets](https://github.com/filecoin-project/go-fil-markets) which has its own [kanban work tracker available here](https://app.zenhub.com/workspaces/markets-shared-components-5daa144a7046a60001c6e253/board)
|
|
||||||
- [spec-actors](https://github.com/filecoin-project/specs-actors) which has its own [kanban work tracker available here](https://app.zenhub.com/workspaces/actors-5ee6f3aa87591f0016c05685/board)
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
-23
@@ -1,23 +0,0 @@
|
|||||||
# Security Policy
|
|
||||||
|
|
||||||
## Reporting a Vulnerability
|
|
||||||
|
|
||||||
For *critical* bugs, please consult our Security Policy and Responsible Disclosure Program information at https://github.com/filecoin-project/community/blob/master/SECURITY.md
|
|
||||||
|
|
||||||
Please try to provide a clear description of any bugs reported, along with how to reproduce the bug if possible. More detailed bug reports (especially those with a PoC included) will help us move forward much faster. Additionally, please avoid reporting bugs that already have open issues. Take a moment to search the issue list of the related GitHub repositories before writing up a new report.
|
|
||||||
|
|
||||||
Here are some examples of bugs we would consider 'critical':
|
|
||||||
|
|
||||||
* If you can spend from a `multisig` wallet you do not control the keys for.
|
|
||||||
* If you can cause a miner to be slashed without them actually misbehaving.
|
|
||||||
* If you can maintain power without submitting windowed posts regularly.
|
|
||||||
* If you can craft a message that causes lotus nodes to panic.
|
|
||||||
* If you can cause your miner to win significantly more blocks than it should.
|
|
||||||
* If you can craft a message that causes a persistent fork in the network.
|
|
||||||
* If you can cause the total amount of Filecoin in the network to no longer be 2 billion.
|
|
||||||
|
|
||||||
This is not an exhaustive list, but should provide some idea of what we consider 'critical'.
|
|
||||||
|
|
||||||
## Reporting a non security bug
|
|
||||||
|
|
||||||
For non-critical bugs, please simply file a GitHub [issue](https://github.com/filecoin-project/lotus/issues/new?template=bug_report.md).
|
|
||||||
+4
-35
@@ -4,25 +4,20 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-jsonrpc/auth"
|
|
||||||
metrics "github.com/libp2p/go-libp2p-core/metrics"
|
|
||||||
"github.com/libp2p/go-libp2p-core/network"
|
"github.com/libp2p/go-libp2p-core/network"
|
||||||
"github.com/libp2p/go-libp2p-core/peer"
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
protocol "github.com/libp2p/go-libp2p-core/protocol"
|
|
||||||
|
"github.com/filecoin-project/go-jsonrpc/auth"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Common interface {
|
type Common interface {
|
||||||
|
// Auth
|
||||||
// MethodGroup: Auth
|
|
||||||
|
|
||||||
AuthVerify(ctx context.Context, token string) ([]auth.Permission, error)
|
AuthVerify(ctx context.Context, token string) ([]auth.Permission, error)
|
||||||
AuthNew(ctx context.Context, perms []auth.Permission) ([]byte, error)
|
AuthNew(ctx context.Context, perms []auth.Permission) ([]byte, error)
|
||||||
|
|
||||||
// MethodGroup: Net
|
// network
|
||||||
|
|
||||||
NetConnectedness(context.Context, peer.ID) (network.Connectedness, error)
|
NetConnectedness(context.Context, peer.ID) (network.Connectedness, error)
|
||||||
NetPeers(context.Context) ([]peer.AddrInfo, error)
|
NetPeers(context.Context) ([]peer.AddrInfo, error)
|
||||||
@@ -31,22 +26,6 @@ type Common interface {
|
|||||||
NetDisconnect(context.Context, peer.ID) error
|
NetDisconnect(context.Context, peer.ID) error
|
||||||
NetFindPeer(context.Context, peer.ID) (peer.AddrInfo, error)
|
NetFindPeer(context.Context, peer.ID) (peer.AddrInfo, error)
|
||||||
NetPubsubScores(context.Context) ([]PubsubScore, error)
|
NetPubsubScores(context.Context) ([]PubsubScore, error)
|
||||||
NetAutoNatStatus(context.Context) (NatInfo, error)
|
|
||||||
NetAgentVersion(ctx context.Context, p peer.ID) (string, error)
|
|
||||||
|
|
||||||
// NetBandwidthStats returns statistics about the nodes total bandwidth
|
|
||||||
// usage and current rate across all peers and protocols.
|
|
||||||
NetBandwidthStats(ctx context.Context) (metrics.Stats, error)
|
|
||||||
|
|
||||||
// NetBandwidthStatsByPeer returns statistics about the nodes bandwidth
|
|
||||||
// usage and current rate per peer
|
|
||||||
NetBandwidthStatsByPeer(ctx context.Context) (map[string]metrics.Stats, error)
|
|
||||||
|
|
||||||
// NetBandwidthStatsByProtocol returns statistics about the nodes bandwidth
|
|
||||||
// usage and current rate per protocol
|
|
||||||
NetBandwidthStatsByProtocol(ctx context.Context) (map[protocol.ID]metrics.Stats, error)
|
|
||||||
|
|
||||||
// MethodGroup: Common
|
|
||||||
|
|
||||||
// ID returns peerID of libp2p node backing this API
|
// ID returns peerID of libp2p node backing this API
|
||||||
ID(context.Context) (peer.ID, error)
|
ID(context.Context) (peer.ID, error)
|
||||||
@@ -59,11 +38,6 @@ type Common interface {
|
|||||||
|
|
||||||
// trigger graceful shutdown
|
// trigger graceful shutdown
|
||||||
Shutdown(context.Context) error
|
Shutdown(context.Context) error
|
||||||
|
|
||||||
// Session returns a random UUID of api provider session
|
|
||||||
Session(context.Context) (uuid.UUID, error)
|
|
||||||
|
|
||||||
Closing(context.Context) (<-chan struct{}, error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Version provides various build-time information
|
// Version provides various build-time information
|
||||||
@@ -85,8 +59,3 @@ type Version struct {
|
|||||||
func (v Version) String() string {
|
func (v Version) String() string {
|
||||||
return fmt.Sprintf("%s+api%s", v.Version, v.APIVersion.String())
|
return fmt.Sprintf("%s+api%s", v.Version, v.APIVersion.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
type NatInfo struct {
|
|
||||||
Reachability network.Reachability
|
|
||||||
PublicAddr string
|
|
||||||
}
|
|
||||||
|
|||||||
+106
-597
@@ -2,32 +2,23 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
datatransfer "github.com/filecoin-project/go-data-transfer"
|
|
||||||
"github.com/filecoin-project/go-state-types/network"
|
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
|
"github.com/ipfs/go-filestore"
|
||||||
"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-fil-markets/retrievalmarket"
|
|
||||||
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
||||||
"github.com/filecoin-project/go-multistore"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
||||||
"github.com/filecoin-project/go-state-types/big"
|
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||||
"github.com/filecoin-project/go-state-types/crypto"
|
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||||
"github.com/filecoin-project/go-state-types/dline"
|
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
|
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin/paych"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin/power"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
marketevents "github.com/filecoin-project/lotus/markets/loggers"
|
|
||||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -35,199 +26,60 @@ import (
|
|||||||
type FullNode interface {
|
type FullNode interface {
|
||||||
Common
|
Common
|
||||||
|
|
||||||
|
// TODO: TipSetKeys
|
||||||
|
|
||||||
// MethodGroup: Chain
|
// MethodGroup: Chain
|
||||||
// The Chain method group contains methods for interacting with the
|
// The Chain method group contains methods for interacting with the
|
||||||
// blockchain, but that do not require any form of state computation.
|
// blockchain, but that do not require any form of state computation
|
||||||
|
|
||||||
// ChainNotify returns channel with chain head updates.
|
// ChainNotify returns channel with chain head updates
|
||||||
// First message is guaranteed to be of len == 1, and type == 'current'.
|
// First message is guaranteed to be of len == 1, and type == 'current'
|
||||||
ChainNotify(context.Context) (<-chan []*HeadChange, error)
|
ChainNotify(context.Context) (<-chan []*HeadChange, error)
|
||||||
|
// ChainHead returns the current head of the chain
|
||||||
// ChainHead returns the current head of the chain.
|
|
||||||
ChainHead(context.Context) (*types.TipSet, error)
|
ChainHead(context.Context) (*types.TipSet, error)
|
||||||
|
// ChainGetRandomness is used to sample the chain for randomness
|
||||||
// ChainGetRandomnessFromTickets is used to sample the chain for randomness.
|
ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error)
|
||||||
ChainGetRandomnessFromTickets(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error)
|
// ChainGetBlock returns the block specified by the given CID
|
||||||
|
|
||||||
// ChainGetRandomnessFromBeacon is used to sample the beacon for randomness.
|
|
||||||
ChainGetRandomnessFromBeacon(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error)
|
|
||||||
|
|
||||||
// ChainGetBlock returns the block specified by the given CID.
|
|
||||||
ChainGetBlock(context.Context, cid.Cid) (*types.BlockHeader, error)
|
ChainGetBlock(context.Context, cid.Cid) (*types.BlockHeader, error)
|
||||||
// ChainGetTipSet returns the tipset specified by the given TipSetKey.
|
|
||||||
ChainGetTipSet(context.Context, types.TipSetKey) (*types.TipSet, error)
|
ChainGetTipSet(context.Context, types.TipSetKey) (*types.TipSet, error)
|
||||||
|
ChainGetBlockMessages(context.Context, cid.Cid) (*BlockMessages, error)
|
||||||
// ChainGetBlockMessages returns messages stored in the specified block.
|
ChainGetParentReceipts(context.Context, cid.Cid) ([]*types.MessageReceipt, error)
|
||||||
ChainGetBlockMessages(ctx context.Context, blockCid cid.Cid) (*BlockMessages, error)
|
ChainGetParentMessages(context.Context, cid.Cid) ([]Message, error)
|
||||||
|
|
||||||
// ChainGetParentReceipts returns receipts for messages in parent tipset of
|
|
||||||
// the specified block.
|
|
||||||
ChainGetParentReceipts(ctx context.Context, blockCid cid.Cid) ([]*types.MessageReceipt, error)
|
|
||||||
|
|
||||||
// ChainGetParentMessages returns messages stored in parent tipset of the
|
|
||||||
// specified block.
|
|
||||||
ChainGetParentMessages(ctx context.Context, blockCid cid.Cid) ([]Message, error)
|
|
||||||
|
|
||||||
// ChainGetTipSetByHeight looks back for a tipset at the specified epoch.
|
|
||||||
// If there are no blocks at the specified epoch, a tipset at an earlier epoch
|
|
||||||
// will be returned.
|
|
||||||
ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error)
|
ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error)
|
||||||
|
|
||||||
// ChainReadObj reads ipld nodes referenced by the specified CID from chain
|
|
||||||
// blockstore and returns raw bytes.
|
|
||||||
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
|
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
|
||||||
|
|
||||||
// ChainDeleteObj deletes node referenced by the given CID
|
|
||||||
ChainDeleteObj(context.Context, cid.Cid) error
|
|
||||||
|
|
||||||
// ChainHasObj checks if a given CID exists in the chain blockstore.
|
|
||||||
ChainHasObj(context.Context, cid.Cid) (bool, error)
|
ChainHasObj(context.Context, cid.Cid) (bool, error)
|
||||||
|
ChainStatObj(context.Context, cid.Cid, cid.Cid) (ObjStat, error)
|
||||||
// ChainStatObj returns statistics about the graph referenced by 'obj'.
|
|
||||||
// If 'base' is also specified, then the returned stat will be a diff
|
|
||||||
// between the two objects.
|
|
||||||
ChainStatObj(ctx context.Context, obj cid.Cid, base cid.Cid) (ObjStat, error)
|
|
||||||
|
|
||||||
// ChainSetHead forcefully sets current chain head. Use with caution.
|
|
||||||
ChainSetHead(context.Context, types.TipSetKey) error
|
ChainSetHead(context.Context, types.TipSetKey) error
|
||||||
|
|
||||||
// ChainGetGenesis returns the genesis tipset.
|
|
||||||
ChainGetGenesis(context.Context) (*types.TipSet, error)
|
ChainGetGenesis(context.Context) (*types.TipSet, error)
|
||||||
|
|
||||||
// ChainTipSetWeight computes weight for the specified tipset.
|
|
||||||
ChainTipSetWeight(context.Context, types.TipSetKey) (types.BigInt, error)
|
ChainTipSetWeight(context.Context, types.TipSetKey) (types.BigInt, error)
|
||||||
ChainGetNode(ctx context.Context, p string) (*IpldObject, error)
|
ChainGetNode(ctx context.Context, p string) (*IpldObject, error)
|
||||||
|
|
||||||
// ChainGetMessage reads a message referenced by the specified CID from the
|
|
||||||
// chain blockstore.
|
|
||||||
ChainGetMessage(context.Context, cid.Cid) (*types.Message, error)
|
ChainGetMessage(context.Context, cid.Cid) (*types.Message, error)
|
||||||
|
|
||||||
// ChainGetPath returns a set of revert/apply operations needed to get from
|
|
||||||
// one tipset to another, for example:
|
|
||||||
//```
|
|
||||||
// to
|
|
||||||
// ^
|
|
||||||
// from tAA
|
|
||||||
// ^ ^
|
|
||||||
// tBA tAB
|
|
||||||
// ^---*--^
|
|
||||||
// ^
|
|
||||||
// tRR
|
|
||||||
//```
|
|
||||||
// Would return `[revert(tBA), apply(tAB), apply(tAA)]`
|
|
||||||
ChainGetPath(ctx context.Context, from types.TipSetKey, to types.TipSetKey) ([]*HeadChange, error)
|
ChainGetPath(ctx context.Context, from types.TipSetKey, to types.TipSetKey) ([]*HeadChange, error)
|
||||||
|
ChainExport(context.Context, types.TipSetKey) (<-chan []byte, error)
|
||||||
// ChainExport returns a stream of bytes with CAR dump of chain data.
|
|
||||||
// The exported chain data includes the header chain from the given tipset
|
|
||||||
// back to genesis, the entire genesis state, and the most recent 'nroots'
|
|
||||||
// state trees.
|
|
||||||
// If oldmsgskip is set, messages from before the requested roots are also not included.
|
|
||||||
ChainExport(ctx context.Context, nroots abi.ChainEpoch, oldmsgskip bool, tsk types.TipSetKey) (<-chan []byte, error)
|
|
||||||
|
|
||||||
// MethodGroup: Beacon
|
|
||||||
// The Beacon method group contains methods for interacting with the random beacon (DRAND)
|
|
||||||
|
|
||||||
// BeaconGetEntry returns the beacon entry for the given filecoin epoch. If
|
|
||||||
// the entry has not yet been produced, the call will block until the entry
|
|
||||||
// becomes available
|
|
||||||
BeaconGetEntry(ctx context.Context, epoch abi.ChainEpoch) (*types.BeaconEntry, error)
|
|
||||||
|
|
||||||
// GasEstimateFeeCap estimates gas fee cap
|
|
||||||
GasEstimateFeeCap(context.Context, *types.Message, int64, types.TipSetKey) (types.BigInt, error)
|
|
||||||
|
|
||||||
// GasEstimateGasLimit estimates gas used by the message and returns it.
|
|
||||||
// It fails if message fails to execute.
|
|
||||||
GasEstimateGasLimit(context.Context, *types.Message, types.TipSetKey) (int64, error)
|
|
||||||
|
|
||||||
// GasEstimateGasPremium estimates what gas price should be used for a
|
|
||||||
// message to have high likelihood of inclusion in `nblocksincl` epochs.
|
|
||||||
|
|
||||||
GasEstimateGasPremium(_ context.Context, nblocksincl uint64,
|
|
||||||
sender address.Address, gaslimit int64, tsk types.TipSetKey) (types.BigInt, error)
|
|
||||||
|
|
||||||
// GasEstimateMessageGas estimates gas values for unset message gas fields
|
|
||||||
GasEstimateMessageGas(context.Context, *types.Message, *MessageSendSpec, types.TipSetKey) (*types.Message, error)
|
|
||||||
|
|
||||||
// MethodGroup: Sync
|
// MethodGroup: Sync
|
||||||
// The Sync method group contains methods for interacting with and
|
// The Sync method group contains methods for interacting with and
|
||||||
// observing the lotus sync service.
|
// observing the lotus sync service
|
||||||
|
|
||||||
// SyncState returns the current status of the lotus sync system.
|
// SyncState returns the current status of the lotus sync system
|
||||||
SyncState(context.Context) (*SyncState, error)
|
SyncState(context.Context) (*SyncState, error)
|
||||||
|
// SyncSubmitBlock can be used to submit a newly created block to the
|
||||||
// SyncSubmitBlock can be used to submit a newly created block to the.
|
|
||||||
// network through this node
|
// network through this node
|
||||||
SyncSubmitBlock(ctx context.Context, blk *types.BlockMsg) error
|
SyncSubmitBlock(ctx context.Context, blk *types.BlockMsg) error
|
||||||
|
|
||||||
// SyncIncomingBlocks returns a channel streaming incoming, potentially not
|
|
||||||
// yet synced block headers.
|
|
||||||
SyncIncomingBlocks(ctx context.Context) (<-chan *types.BlockHeader, error)
|
SyncIncomingBlocks(ctx context.Context) (<-chan *types.BlockHeader, error)
|
||||||
|
|
||||||
// SyncCheckpoint marks a blocks as checkpointed, meaning that it won't ever fork away from it.
|
|
||||||
SyncCheckpoint(ctx context.Context, tsk types.TipSetKey) error
|
|
||||||
|
|
||||||
// SyncMarkBad marks a blocks as bad, meaning that it won't ever by synced.
|
|
||||||
// Use with extreme caution.
|
|
||||||
SyncMarkBad(ctx context.Context, bcid cid.Cid) error
|
SyncMarkBad(ctx context.Context, bcid cid.Cid) error
|
||||||
|
|
||||||
// SyncUnmarkBad unmarks a blocks as bad, making it possible to be validated and synced again.
|
|
||||||
SyncUnmarkBad(ctx context.Context, bcid cid.Cid) error
|
|
||||||
|
|
||||||
// SyncUnmarkAllBad purges bad block cache, making it possible to sync to chains previously marked as bad
|
|
||||||
SyncUnmarkAllBad(ctx context.Context) error
|
|
||||||
|
|
||||||
// SyncCheckBad checks if a block was marked as bad, and if it was, returns
|
|
||||||
// the reason.
|
|
||||||
SyncCheckBad(ctx context.Context, bcid cid.Cid) (string, error)
|
SyncCheckBad(ctx context.Context, bcid cid.Cid) (string, error)
|
||||||
|
|
||||||
// SyncValidateTipset indicates whether the provided tipset is valid or not
|
|
||||||
SyncValidateTipset(ctx context.Context, tsk types.TipSetKey) (bool, error)
|
|
||||||
|
|
||||||
// MethodGroup: Mpool
|
// MethodGroup: Mpool
|
||||||
// The Mpool methods are for interacting with the message pool. The message pool
|
// The Mpool methods are for interacting with the message pool. The message pool
|
||||||
// manages all incoming and outgoing 'messages' going over the network.
|
// manages all incoming and outgoing 'messages' going over the network.
|
||||||
|
|
||||||
// MpoolPending returns pending mempool messages.
|
|
||||||
MpoolPending(context.Context, types.TipSetKey) ([]*types.SignedMessage, error)
|
MpoolPending(context.Context, types.TipSetKey) ([]*types.SignedMessage, error)
|
||||||
|
|
||||||
// MpoolSelect returns a list of pending messages for inclusion in the next block
|
|
||||||
MpoolSelect(context.Context, types.TipSetKey, float64) ([]*types.SignedMessage, error)
|
|
||||||
|
|
||||||
// MpoolPush pushes a signed message to mempool.
|
|
||||||
MpoolPush(context.Context, *types.SignedMessage) (cid.Cid, error)
|
MpoolPush(context.Context, *types.SignedMessage) (cid.Cid, error)
|
||||||
|
MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error) // get nonce, sign, push
|
||||||
// MpoolPushUntrusted pushes a signed message to mempool from untrusted sources.
|
|
||||||
MpoolPushUntrusted(context.Context, *types.SignedMessage) (cid.Cid, error)
|
|
||||||
|
|
||||||
// MpoolPushMessage atomically assigns a nonce, signs, and pushes a message
|
|
||||||
// to mempool.
|
|
||||||
// maxFee is only used when GasFeeCap/GasPremium fields aren't specified
|
|
||||||
//
|
|
||||||
// When maxFee is set to 0, MpoolPushMessage will guess appropriate fee
|
|
||||||
// based on current chain conditions
|
|
||||||
MpoolPushMessage(ctx context.Context, msg *types.Message, spec *MessageSendSpec) (*types.SignedMessage, error)
|
|
||||||
|
|
||||||
// MpoolBatchPush batch pushes a signed message to mempool.
|
|
||||||
MpoolBatchPush(context.Context, []*types.SignedMessage) ([]cid.Cid, error)
|
|
||||||
|
|
||||||
// MpoolBatchPushUntrusted batch pushes a signed message to mempool from untrusted sources.
|
|
||||||
MpoolBatchPushUntrusted(context.Context, []*types.SignedMessage) ([]cid.Cid, error)
|
|
||||||
|
|
||||||
// MpoolBatchPushMessage batch pushes a unsigned message to mempool.
|
|
||||||
MpoolBatchPushMessage(context.Context, []*types.Message, *MessageSendSpec) ([]*types.SignedMessage, error)
|
|
||||||
|
|
||||||
// MpoolGetNonce gets next nonce for the specified sender.
|
|
||||||
// Note that this method may not be atomic. Use MpoolPushMessage instead.
|
|
||||||
MpoolGetNonce(context.Context, address.Address) (uint64, error)
|
MpoolGetNonce(context.Context, address.Address) (uint64, error)
|
||||||
MpoolSub(context.Context) (<-chan MpoolUpdate, error)
|
MpoolSub(context.Context) (<-chan MpoolUpdate, error)
|
||||||
|
MpoolEstimateGasPrice(context.Context, uint64, address.Address, int64, types.TipSetKey) (types.BigInt, error)
|
||||||
// MpoolClear clears pending messages from the mpool
|
|
||||||
MpoolClear(context.Context, bool) error
|
|
||||||
|
|
||||||
// MpoolGetConfig returns (a copy of) the current mpool config
|
|
||||||
MpoolGetConfig(context.Context) (*types.MpoolConfig, error)
|
|
||||||
// MpoolSetConfig sets the mpool config to (a copy of) the supplied config
|
|
||||||
MpoolSetConfig(context.Context, *types.MpoolConfig) error
|
|
||||||
|
|
||||||
// MethodGroup: Miner
|
// MethodGroup: Miner
|
||||||
|
|
||||||
@@ -238,35 +90,18 @@ type FullNode interface {
|
|||||||
|
|
||||||
// MethodGroup: Wallet
|
// MethodGroup: Wallet
|
||||||
|
|
||||||
// WalletNew creates a new address in the wallet with the given sigType.
|
WalletNew(context.Context, crypto.SigType) (address.Address, error)
|
||||||
// Available key types: bls, secp256k1, secp256k1-ledger
|
|
||||||
// Support for numerical types: 1 - secp256k1, 2 - BLS is deprecated
|
|
||||||
WalletNew(context.Context, types.KeyType) (address.Address, error)
|
|
||||||
// WalletHas indicates whether the given address is in the wallet.
|
|
||||||
WalletHas(context.Context, address.Address) (bool, error)
|
WalletHas(context.Context, address.Address) (bool, error)
|
||||||
// WalletList lists all the addresses in the wallet.
|
|
||||||
WalletList(context.Context) ([]address.Address, error)
|
WalletList(context.Context) ([]address.Address, error)
|
||||||
// WalletBalance returns the balance of the given address at the current head of the chain.
|
|
||||||
WalletBalance(context.Context, address.Address) (types.BigInt, error)
|
WalletBalance(context.Context, address.Address) (types.BigInt, error)
|
||||||
// WalletSign signs the given bytes using the given address.
|
|
||||||
WalletSign(context.Context, address.Address, []byte) (*crypto.Signature, error)
|
WalletSign(context.Context, address.Address, []byte) (*crypto.Signature, error)
|
||||||
// WalletSignMessage signs the given message using the given address.
|
|
||||||
WalletSignMessage(context.Context, address.Address, *types.Message) (*types.SignedMessage, error)
|
WalletSignMessage(context.Context, address.Address, *types.Message) (*types.SignedMessage, error)
|
||||||
// WalletVerify takes an address, a signature, and some bytes, and indicates whether the signature is valid.
|
WalletVerify(context.Context, address.Address, []byte, *crypto.Signature) bool
|
||||||
// The address does not have to be in the wallet.
|
|
||||||
WalletVerify(context.Context, address.Address, []byte, *crypto.Signature) (bool, error)
|
|
||||||
// WalletDefaultAddress returns the address marked as default in the wallet.
|
|
||||||
WalletDefaultAddress(context.Context) (address.Address, error)
|
WalletDefaultAddress(context.Context) (address.Address, error)
|
||||||
// WalletSetDefault marks the given address as as the default one.
|
|
||||||
WalletSetDefault(context.Context, address.Address) error
|
WalletSetDefault(context.Context, address.Address) error
|
||||||
// WalletExport returns the private key of an address in the wallet.
|
|
||||||
WalletExport(context.Context, address.Address) (*types.KeyInfo, error)
|
WalletExport(context.Context, address.Address) (*types.KeyInfo, error)
|
||||||
// WalletImport receives a KeyInfo, which includes a private key, and imports it into the wallet.
|
|
||||||
WalletImport(context.Context, *types.KeyInfo) (address.Address, error)
|
WalletImport(context.Context, *types.KeyInfo) (address.Address, error)
|
||||||
// WalletDelete deletes an address from the wallet.
|
|
||||||
WalletDelete(context.Context, address.Address) error
|
WalletDelete(context.Context, address.Address) error
|
||||||
// WalletValidateAddress validates whether a given string can be decoded as a well-formed address
|
|
||||||
WalletValidateAddress(context.Context, string) (address.Address, error)
|
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
|
|
||||||
@@ -274,51 +109,19 @@ type FullNode interface {
|
|||||||
// The Client methods all have to do with interacting with the storage and
|
// The Client methods all have to do with interacting with the storage and
|
||||||
// retrieval markets as a client
|
// retrieval markets as a client
|
||||||
|
|
||||||
// ClientImport imports file under the specified path into filestore.
|
// ClientImport imports file under the specified path into filestore
|
||||||
ClientImport(ctx context.Context, ref FileRef) (*ImportRes, error)
|
ClientImport(ctx context.Context, ref FileRef) (cid.Cid, error)
|
||||||
// ClientRemoveImport removes file import
|
// ClientStartDeal proposes a deal with a miner
|
||||||
ClientRemoveImport(ctx context.Context, importID multistore.StoreID) error
|
|
||||||
// ClientStartDeal proposes a deal with a miner.
|
|
||||||
ClientStartDeal(ctx context.Context, params *StartDealParams) (*cid.Cid, error)
|
ClientStartDeal(ctx context.Context, params *StartDealParams) (*cid.Cid, error)
|
||||||
// ClientGetDealInfo returns the latest information about a given deal.
|
// ClientGetDeal info returns the latest information about a given deal
|
||||||
ClientGetDealInfo(context.Context, cid.Cid) (*DealInfo, error)
|
ClientGetDealInfo(context.Context, cid.Cid) (*DealInfo, error)
|
||||||
// ClientListDeals returns information about the deals made by the local client.
|
|
||||||
ClientListDeals(ctx context.Context) ([]DealInfo, error)
|
ClientListDeals(ctx context.Context) ([]DealInfo, error)
|
||||||
// ClientGetDealUpdates returns the status of updated deals
|
|
||||||
ClientGetDealUpdates(ctx context.Context) (<-chan DealInfo, error)
|
|
||||||
// ClientGetDealStatus returns status given a code
|
|
||||||
ClientGetDealStatus(ctx context.Context, statusCode uint64) (string, error)
|
|
||||||
// ClientHasLocal indicates whether a certain CID is locally stored.
|
|
||||||
ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error)
|
ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error)
|
||||||
// ClientFindData identifies peers that have a certain file, and returns QueryOffers (one per peer).
|
ClientFindData(ctx context.Context, root cid.Cid) ([]QueryOffer, error)
|
||||||
ClientFindData(ctx context.Context, root cid.Cid, piece *cid.Cid) ([]QueryOffer, error)
|
|
||||||
// ClientMinerQueryOffer returns a QueryOffer for the specific miner and file.
|
|
||||||
ClientMinerQueryOffer(ctx context.Context, miner address.Address, root cid.Cid, piece *cid.Cid) (QueryOffer, error)
|
|
||||||
// ClientRetrieve initiates the retrieval of a file, as specified in the order.
|
|
||||||
ClientRetrieve(ctx context.Context, order RetrievalOrder, ref *FileRef) error
|
ClientRetrieve(ctx context.Context, order RetrievalOrder, ref *FileRef) error
|
||||||
// ClientRetrieveWithEvents initiates the retrieval of a file, as specified in the order, and provides a channel
|
ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.SignedStorageAsk, error)
|
||||||
// of status updates.
|
ClientCalcCommP(ctx context.Context, inpath string, miner address.Address) (*CommPRet, error)
|
||||||
ClientRetrieveWithEvents(ctx context.Context, order RetrievalOrder, ref *FileRef) (<-chan marketevents.RetrievalEvent, error)
|
|
||||||
// ClientQueryAsk returns a signed StorageAsk from the specified miner.
|
|
||||||
ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.StorageAsk, error)
|
|
||||||
// ClientCalcCommP calculates the CommP and data size of the specified CID
|
|
||||||
ClientDealPieceCID(ctx context.Context, root cid.Cid) (DataCIDSize, error)
|
|
||||||
// ClientCalcCommP calculates the CommP for a specified file
|
|
||||||
ClientCalcCommP(ctx context.Context, inpath string) (*CommPRet, error)
|
|
||||||
// ClientGenCar generates a CAR file for the specified file.
|
|
||||||
ClientGenCar(ctx context.Context, ref FileRef, outpath string) error
|
ClientGenCar(ctx context.Context, ref FileRef, outpath string) error
|
||||||
// ClientDealSize calculates real deal data size
|
|
||||||
ClientDealSize(ctx context.Context, root cid.Cid) (DataSize, error)
|
|
||||||
// ClientListTransfers returns the status of all ongoing transfers of data
|
|
||||||
ClientListDataTransfers(ctx context.Context) ([]DataTransferChannel, error)
|
|
||||||
ClientDataTransferUpdates(ctx context.Context) (<-chan DataTransferChannel, error)
|
|
||||||
// ClientRestartDataTransfer attempts to restart a data transfer with the given transfer ID and other peer
|
|
||||||
ClientRestartDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error
|
|
||||||
// ClientCancelDataTransfer cancels a data transfer with the given transfer ID and other peer
|
|
||||||
ClientCancelDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error
|
|
||||||
// ClientRetrieveTryRestartInsufficientFunds attempts to restart stalled retrievals on a given payment channel
|
|
||||||
// which are stuck due to insufficient funds
|
|
||||||
ClientRetrieveTryRestartInsufficientFunds(ctx context.Context, paymentChannel address.Address) error
|
|
||||||
|
|
||||||
// ClientUnimport removes references to the specified file from filestore
|
// ClientUnimport removes references to the specified file from filestore
|
||||||
//ClientUnimport(path string)
|
//ClientUnimport(path string)
|
||||||
@@ -329,221 +132,74 @@ type FullNode interface {
|
|||||||
//ClientListAsks() []Ask
|
//ClientListAsks() []Ask
|
||||||
|
|
||||||
// MethodGroup: State
|
// MethodGroup: State
|
||||||
// The State methods are used to query, inspect, and interact with chain state.
|
// The State methods are used to query, inspect, and interact with chain state
|
||||||
// Most methods take a TipSetKey as a parameter. The state looked up is the state at that tipset.
|
|
||||||
// A nil TipSetKey can be provided as a param, this will cause the heaviest tipset in the chain to be used.
|
|
||||||
|
|
||||||
// StateCall runs the given message and returns its result without any persisted changes.
|
// if tipset is nil, we'll use heaviest
|
||||||
StateCall(context.Context, *types.Message, types.TipSetKey) (*InvocResult, error)
|
StateCall(context.Context, *types.Message, types.TipSetKey) (*InvocResult, error)
|
||||||
// StateReplay replays a given message, assuming it was included in a block in the specified tipset.
|
|
||||||
// If no tipset key is provided, the appropriate tipset is looked up.
|
|
||||||
StateReplay(context.Context, types.TipSetKey, cid.Cid) (*InvocResult, error)
|
StateReplay(context.Context, types.TipSetKey, cid.Cid) (*InvocResult, error)
|
||||||
// StateGetActor returns the indicated actor's nonce and balance.
|
|
||||||
StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error)
|
StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error)
|
||||||
// StateReadState returns the indicated actor's state.
|
StateReadState(ctx context.Context, act *types.Actor, tsk types.TipSetKey) (*ActorState, error)
|
||||||
StateReadState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*ActorState, error)
|
StateListMessages(ctx context.Context, match *types.Message, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error)
|
||||||
// StateListMessages looks back and returns all messages with a matching to or from address, stopping at the given height.
|
|
||||||
StateListMessages(ctx context.Context, match *MessageMatch, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error)
|
|
||||||
// StateDecodeParams attempts to decode the provided params, based on the recipient actor address and method number.
|
|
||||||
StateDecodeParams(ctx context.Context, toAddr address.Address, method abi.MethodNum, params []byte, tsk types.TipSetKey) (interface{}, error)
|
|
||||||
|
|
||||||
// StateNetworkName returns the name of the network the node is synced to
|
|
||||||
StateNetworkName(context.Context) (dtypes.NetworkName, error)
|
StateNetworkName(context.Context) (dtypes.NetworkName, error)
|
||||||
// StateMinerSectors returns info about the given miner's sectors. If the filter bitfield is nil, all sectors are included.
|
StateMinerSectors(context.Context, address.Address, *abi.BitField, bool, types.TipSetKey) ([]*ChainSectorInfo, error)
|
||||||
StateMinerSectors(context.Context, address.Address, *bitfield.BitField, types.TipSetKey) ([]*miner.SectorOnChainInfo, error)
|
StateMinerProvingSet(context.Context, address.Address, types.TipSetKey) ([]*ChainSectorInfo, error)
|
||||||
// StateMinerActiveSectors returns info about sectors that a given miner is actively proving.
|
StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*miner.DeadlineInfo, error)
|
||||||
StateMinerActiveSectors(context.Context, address.Address, types.TipSetKey) ([]*miner.SectorOnChainInfo, error)
|
|
||||||
// StateMinerProvingDeadline calculates the deadline at some epoch for a proving period
|
|
||||||
// and returns the deadline-related calculations.
|
|
||||||
StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*dline.Info, error)
|
|
||||||
// StateMinerPower returns the power of the indicated miner
|
|
||||||
StateMinerPower(context.Context, address.Address, types.TipSetKey) (*MinerPower, error)
|
StateMinerPower(context.Context, address.Address, types.TipSetKey) (*MinerPower, error)
|
||||||
// StateMinerInfo returns info about the indicated miner
|
|
||||||
StateMinerInfo(context.Context, address.Address, types.TipSetKey) (miner.MinerInfo, error)
|
StateMinerInfo(context.Context, address.Address, types.TipSetKey) (miner.MinerInfo, error)
|
||||||
// StateMinerDeadlines returns all the proving deadlines for the given miner
|
StateMinerDeadlines(context.Context, address.Address, types.TipSetKey) (*miner.Deadlines, error)
|
||||||
StateMinerDeadlines(context.Context, address.Address, types.TipSetKey) ([]Deadline, error)
|
StateMinerFaults(context.Context, address.Address, types.TipSetKey) (*abi.BitField, error)
|
||||||
// StateMinerPartitions returns all partitions in the specified deadline
|
// Returns all non-expired Faults that occur within lookback epochs of the given tipset
|
||||||
StateMinerPartitions(ctx context.Context, m address.Address, dlIdx uint64, tsk types.TipSetKey) ([]Partition, error)
|
|
||||||
// StateMinerFaults returns a bitfield indicating the faulty sectors of the given miner
|
|
||||||
StateMinerFaults(context.Context, address.Address, types.TipSetKey) (bitfield.BitField, error)
|
|
||||||
// StateAllMinerFaults returns all non-expired Faults that occur within lookback epochs of the given tipset
|
|
||||||
StateAllMinerFaults(ctx context.Context, lookback abi.ChainEpoch, ts types.TipSetKey) ([]*Fault, error)
|
StateAllMinerFaults(ctx context.Context, lookback abi.ChainEpoch, ts types.TipSetKey) ([]*Fault, error)
|
||||||
// StateMinerRecoveries returns a bitfield indicating the recovering sectors of the given miner
|
StateMinerRecoveries(context.Context, address.Address, types.TipSetKey) (*abi.BitField, error)
|
||||||
StateMinerRecoveries(context.Context, address.Address, types.TipSetKey) (bitfield.BitField, error)
|
StateMinerInitialPledgeCollateral(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (types.BigInt, error)
|
||||||
// StateMinerInitialPledgeCollateral returns the precommit deposit for the specified miner's sector
|
|
||||||
StateMinerPreCommitDepositForPower(context.Context, address.Address, miner.SectorPreCommitInfo, types.TipSetKey) (types.BigInt, error)
|
|
||||||
// StateMinerInitialPledgeCollateral returns the initial pledge collateral for the specified miner's sector
|
|
||||||
StateMinerInitialPledgeCollateral(context.Context, address.Address, miner.SectorPreCommitInfo, types.TipSetKey) (types.BigInt, error)
|
|
||||||
// StateMinerAvailableBalance returns the portion of a miner's balance that can be withdrawn or spent
|
|
||||||
StateMinerAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error)
|
StateMinerAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error)
|
||||||
// StateMinerSectorAllocated checks if a sector is allocated
|
|
||||||
StateMinerSectorAllocated(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (bool, error)
|
|
||||||
// StateSectorPreCommitInfo returns the PreCommit info for the specified miner's sector
|
|
||||||
StateSectorPreCommitInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error)
|
StateSectorPreCommitInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error)
|
||||||
// StateSectorGetInfo returns the on-chain info for the specified miner's sector. Returns null in case the sector info isn't found
|
|
||||||
// NOTE: returned info.Expiration may not be accurate in some cases, use StateSectorExpiration to get accurate
|
|
||||||
// expiration epoch
|
|
||||||
StateSectorGetInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorOnChainInfo, error)
|
StateSectorGetInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorOnChainInfo, error)
|
||||||
// StateSectorExpiration returns epoch at which given sector will expire
|
StatePledgeCollateral(context.Context, types.TipSetKey) (types.BigInt, error)
|
||||||
StateSectorExpiration(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorExpiration, error)
|
|
||||||
// StateSectorPartition finds deadline/partition with the specified sector
|
|
||||||
StateSectorPartition(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok types.TipSetKey) (*miner.SectorLocation, error)
|
|
||||||
// StateSearchMsg searches for a message in the chain, and returns its receipt and the tipset where it was executed
|
|
||||||
StateSearchMsg(context.Context, cid.Cid) (*MsgLookup, error)
|
|
||||||
// StateWaitMsg looks back in the chain for a message. If not found, it blocks until the
|
|
||||||
// message arrives on chain, and gets to the indicated confidence depth.
|
|
||||||
StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64) (*MsgLookup, error)
|
StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64) (*MsgLookup, error)
|
||||||
// StateWaitMsgLimited looks back up to limit epochs in the chain for a message.
|
StateSearchMsg(context.Context, cid.Cid) (*MsgLookup, error)
|
||||||
// If not found, it blocks until the message arrives on chain, and gets to the
|
|
||||||
// indicated confidence depth.
|
|
||||||
StateWaitMsgLimited(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch) (*MsgLookup, error)
|
|
||||||
// StateListMiners returns the addresses of every miner that has claimed power in the Power Actor
|
|
||||||
StateListMiners(context.Context, types.TipSetKey) ([]address.Address, error)
|
StateListMiners(context.Context, types.TipSetKey) ([]address.Address, error)
|
||||||
// StateListActors returns the addresses of every actor in the state
|
|
||||||
StateListActors(context.Context, types.TipSetKey) ([]address.Address, error)
|
StateListActors(context.Context, types.TipSetKey) ([]address.Address, error)
|
||||||
// StateMarketBalance looks up the Escrow and Locked balances of the given address in the Storage Market
|
|
||||||
StateMarketBalance(context.Context, address.Address, types.TipSetKey) (MarketBalance, error)
|
StateMarketBalance(context.Context, address.Address, types.TipSetKey) (MarketBalance, error)
|
||||||
// StateMarketParticipants returns the Escrow and Locked balances of every participant in the Storage Market
|
|
||||||
StateMarketParticipants(context.Context, types.TipSetKey) (map[string]MarketBalance, error)
|
StateMarketParticipants(context.Context, types.TipSetKey) (map[string]MarketBalance, error)
|
||||||
// StateMarketDeals returns information about every deal in the Storage Market
|
|
||||||
StateMarketDeals(context.Context, types.TipSetKey) (map[string]MarketDeal, error)
|
StateMarketDeals(context.Context, types.TipSetKey) (map[string]MarketDeal, error)
|
||||||
// StateMarketStorageDeal returns information about the indicated deal
|
|
||||||
StateMarketStorageDeal(context.Context, abi.DealID, types.TipSetKey) (*MarketDeal, error)
|
StateMarketStorageDeal(context.Context, abi.DealID, types.TipSetKey) (*MarketDeal, error)
|
||||||
// StateLookupID retrieves the ID address of the given address
|
|
||||||
StateLookupID(context.Context, address.Address, types.TipSetKey) (address.Address, error)
|
StateLookupID(context.Context, address.Address, types.TipSetKey) (address.Address, error)
|
||||||
// StateAccountKey returns the public key address of the given ID address
|
|
||||||
StateAccountKey(context.Context, address.Address, types.TipSetKey) (address.Address, error)
|
StateAccountKey(context.Context, address.Address, types.TipSetKey) (address.Address, error)
|
||||||
// StateChangedActors returns all the actors whose states change between the two given state CIDs
|
|
||||||
// TODO: Should this take tipset keys instead?
|
|
||||||
StateChangedActors(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error)
|
StateChangedActors(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error)
|
||||||
// StateGetReceipt returns the message receipt for the given message
|
|
||||||
StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error)
|
StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error)
|
||||||
// StateMinerSectorCount returns the number of sectors in a miner's sector set and proving set
|
|
||||||
StateMinerSectorCount(context.Context, address.Address, types.TipSetKey) (MinerSectors, error)
|
StateMinerSectorCount(context.Context, address.Address, types.TipSetKey) (MinerSectors, error)
|
||||||
// StateCompute is a flexible command that applies the given messages on the given tipset.
|
|
||||||
// The messages are run as though the VM were at the provided height.
|
|
||||||
StateCompute(context.Context, abi.ChainEpoch, []*types.Message, types.TipSetKey) (*ComputeStateOutput, error)
|
StateCompute(context.Context, abi.ChainEpoch, []*types.Message, types.TipSetKey) (*ComputeStateOutput, error)
|
||||||
// StateVerifierStatus returns the data cap for the given address.
|
|
||||||
// Returns nil if there is no entry in the data cap table for the
|
|
||||||
// address.
|
|
||||||
StateVerifierStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error)
|
|
||||||
// StateVerifiedClientStatus returns the data cap for the given address.
|
|
||||||
// Returns nil if there is no entry in the data cap table for the
|
|
||||||
// address.
|
|
||||||
StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error)
|
|
||||||
// StateVerifiedClientStatus returns the address of the Verified Registry's root key
|
|
||||||
StateVerifiedRegistryRootKey(ctx context.Context, tsk types.TipSetKey) (address.Address, error)
|
|
||||||
// StateDealProviderCollateralBounds returns the min and max collateral a storage provider
|
|
||||||
// can issue. It takes the deal size and verified status as parameters.
|
|
||||||
StateDealProviderCollateralBounds(context.Context, abi.PaddedPieceSize, bool, types.TipSetKey) (DealCollateralBounds, error)
|
|
||||||
|
|
||||||
// StateCirculatingSupply returns the exact circulating supply of Filecoin at the given tipset.
|
|
||||||
// This is not used anywhere in the protocol itself, and is only for external consumption.
|
|
||||||
StateCirculatingSupply(context.Context, types.TipSetKey) (abi.TokenAmount, error)
|
|
||||||
// StateVMCirculatingSupplyInternal returns an approximation of the circulating supply of Filecoin at the given tipset.
|
|
||||||
// This is the value reported by the runtime interface to actors code.
|
|
||||||
StateVMCirculatingSupplyInternal(context.Context, types.TipSetKey) (CirculatingSupply, error)
|
|
||||||
// StateNetworkVersion returns the network version at the given tipset
|
|
||||||
StateNetworkVersion(context.Context, types.TipSetKey) (network.Version, error)
|
|
||||||
|
|
||||||
// MethodGroup: Msig
|
// MethodGroup: Msig
|
||||||
// The Msig methods are used to interact with multisig wallets on the
|
// The Msig methods are used to interact with multisig wallets on the
|
||||||
// filecoin network
|
// filecoin network
|
||||||
|
|
||||||
// MsigGetAvailableBalance returns the portion of a multisig's balance that can be withdrawn or spent
|
|
||||||
MsigGetAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error)
|
MsigGetAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error)
|
||||||
// MsigGetVestingSchedule returns the vesting details of a given multisig.
|
MsigCreate(context.Context, int64, []address.Address, types.BigInt, address.Address, types.BigInt) (cid.Cid, error)
|
||||||
MsigGetVestingSchedule(context.Context, address.Address, types.TipSetKey) (MsigVesting, error)
|
|
||||||
// MsigGetVested returns the amount of FIL that vested in a multisig in a certain period.
|
|
||||||
// It takes the following params: <multisig address>, <start epoch>, <end epoch>
|
|
||||||
MsigGetVested(context.Context, address.Address, types.TipSetKey, types.TipSetKey) (types.BigInt, error)
|
|
||||||
// MsigCreate creates a multisig wallet
|
|
||||||
// It takes the following params: <required number of senders>, <approving addresses>, <unlock duration>
|
|
||||||
//<initial balance>, <sender address of the create msg>, <gas price>
|
|
||||||
MsigCreate(context.Context, uint64, []address.Address, abi.ChainEpoch, types.BigInt, address.Address, types.BigInt) (cid.Cid, error)
|
|
||||||
// MsigPropose proposes a multisig message
|
|
||||||
// It takes the following params: <multisig address>, <recipient address>, <value to transfer>,
|
|
||||||
// <sender address of the propose msg>, <method to call in the proposed message>, <params to include in the proposed message>
|
|
||||||
MsigPropose(context.Context, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error)
|
MsigPropose(context.Context, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error)
|
||||||
|
MsigApprove(context.Context, address.Address, uint64, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error)
|
||||||
|
MsigCancel(context.Context, address.Address, uint64, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error)
|
||||||
|
|
||||||
// MsigApprove approves a previously-proposed multisig message by transaction ID
|
MarketEnsureAvailable(context.Context, address.Address, address.Address, types.BigInt) (cid.Cid, error)
|
||||||
// It takes the following params: <multisig address>, <proposed transaction ID> <signer address>
|
// MarketFreeBalance
|
||||||
MsigApprove(context.Context, address.Address, uint64, address.Address) (cid.Cid, error)
|
|
||||||
|
|
||||||
// MsigApproveTxnHash approves a previously-proposed multisig message, specified
|
|
||||||
// using both transaction ID and a hash of the parameters used in the
|
|
||||||
// proposal. This method of approval can be used to ensure you only approve
|
|
||||||
// exactly the transaction you think you are.
|
|
||||||
// It takes the following params: <multisig address>, <proposed message ID>, <proposer address>, <recipient address>, <value to transfer>,
|
|
||||||
// <sender address of the approve msg>, <method to call in the proposed message>, <params to include in the proposed message>
|
|
||||||
MsigApproveTxnHash(context.Context, address.Address, uint64, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error)
|
|
||||||
|
|
||||||
// MsigCancel cancels a previously-proposed multisig message
|
|
||||||
// It takes the following params: <multisig address>, <proposed transaction ID>, <recipient address>, <value to transfer>,
|
|
||||||
// <sender address of the cancel msg>, <method to call in the proposed message>, <params to include in the proposed message>
|
|
||||||
MsigCancel(context.Context, address.Address, uint64, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error)
|
|
||||||
// MsigAddPropose proposes adding a signer in the multisig
|
|
||||||
// It takes the following params: <multisig address>, <sender address of the propose msg>,
|
|
||||||
// <new signer>, <whether the number of required signers should be increased>
|
|
||||||
MsigAddPropose(context.Context, address.Address, address.Address, address.Address, bool) (cid.Cid, error)
|
|
||||||
// MsigAddApprove approves a previously proposed AddSigner message
|
|
||||||
// It takes the following params: <multisig address>, <sender address of the approve msg>, <proposed message ID>,
|
|
||||||
// <proposer address>, <new signer>, <whether the number of required signers should be increased>
|
|
||||||
MsigAddApprove(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, bool) (cid.Cid, error)
|
|
||||||
// MsigAddCancel cancels a previously proposed AddSigner message
|
|
||||||
// It takes the following params: <multisig address>, <sender address of the cancel msg>, <proposed message ID>,
|
|
||||||
// <new signer>, <whether the number of required signers should be increased>
|
|
||||||
MsigAddCancel(context.Context, address.Address, address.Address, uint64, address.Address, bool) (cid.Cid, error)
|
|
||||||
// MsigSwapPropose proposes swapping 2 signers in the multisig
|
|
||||||
// It takes the following params: <multisig address>, <sender address of the propose msg>,
|
|
||||||
// <old signer>, <new signer>
|
|
||||||
MsigSwapPropose(context.Context, address.Address, address.Address, address.Address, address.Address) (cid.Cid, error)
|
|
||||||
// MsigSwapApprove approves a previously proposed SwapSigner
|
|
||||||
// It takes the following params: <multisig address>, <sender address of the approve msg>, <proposed message ID>,
|
|
||||||
// <proposer address>, <old signer>, <new signer>
|
|
||||||
MsigSwapApprove(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, address.Address) (cid.Cid, error)
|
|
||||||
// MsigSwapCancel cancels a previously proposed SwapSigner message
|
|
||||||
// It takes the following params: <multisig address>, <sender address of the cancel msg>, <proposed message ID>,
|
|
||||||
// <old signer>, <new signer>
|
|
||||||
MsigSwapCancel(context.Context, address.Address, address.Address, uint64, address.Address, address.Address) (cid.Cid, error)
|
|
||||||
|
|
||||||
// MsigRemoveSigner proposes the removal of a signer from the multisig.
|
|
||||||
// It accepts the multisig to make the change on, the proposer address to
|
|
||||||
// send the message from, the address to be removed, and a boolean
|
|
||||||
// indicating whether or not the signing threshold should be lowered by one
|
|
||||||
// along with the address removal.
|
|
||||||
MsigRemoveSigner(ctx context.Context, msig address.Address, proposer address.Address, toRemove address.Address, decrease bool) (cid.Cid, error)
|
|
||||||
|
|
||||||
// MarketReserveFunds reserves funds for a deal
|
|
||||||
MarketReserveFunds(ctx context.Context, wallet address.Address, addr address.Address, amt types.BigInt) (cid.Cid, error)
|
|
||||||
// MarketReleaseFunds releases funds reserved by MarketReserveFunds
|
|
||||||
MarketReleaseFunds(ctx context.Context, addr address.Address, amt types.BigInt) error
|
|
||||||
|
|
||||||
// MethodGroup: Paych
|
// MethodGroup: Paych
|
||||||
// The Paych methods are for interacting with and managing payment channels
|
// The Paych methods are for interacting with and managing payment channels
|
||||||
|
|
||||||
PaychGet(ctx context.Context, from, to address.Address, amt types.BigInt) (*ChannelInfo, error)
|
PaychGet(ctx context.Context, from, to address.Address, ensureFunds types.BigInt) (*ChannelInfo, error)
|
||||||
PaychGetWaitReady(context.Context, cid.Cid) (address.Address, error)
|
|
||||||
PaychAvailableFunds(ctx context.Context, ch address.Address) (*ChannelAvailableFunds, error)
|
|
||||||
PaychAvailableFundsByFromTo(ctx context.Context, from, to address.Address) (*ChannelAvailableFunds, error)
|
|
||||||
PaychList(context.Context) ([]address.Address, error)
|
PaychList(context.Context) ([]address.Address, error)
|
||||||
PaychStatus(context.Context, address.Address) (*PaychStatus, error)
|
PaychStatus(context.Context, address.Address) (*PaychStatus, error)
|
||||||
PaychSettle(context.Context, address.Address) (cid.Cid, error)
|
PaychClose(context.Context, address.Address) (cid.Cid, error)
|
||||||
PaychCollect(context.Context, address.Address) (cid.Cid, error)
|
|
||||||
PaychAllocateLane(ctx context.Context, ch address.Address) (uint64, error)
|
PaychAllocateLane(ctx context.Context, ch address.Address) (uint64, error)
|
||||||
PaychNewPayment(ctx context.Context, from, to address.Address, vouchers []VoucherSpec) (*PaymentInfo, error)
|
PaychNewPayment(ctx context.Context, from, to address.Address, vouchers []VoucherSpec) (*PaymentInfo, error)
|
||||||
PaychVoucherCheckValid(context.Context, address.Address, *paych.SignedVoucher) error
|
PaychVoucherCheckValid(context.Context, address.Address, *paych.SignedVoucher) error
|
||||||
PaychVoucherCheckSpendable(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (bool, error)
|
PaychVoucherCheckSpendable(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (bool, error)
|
||||||
PaychVoucherCreate(context.Context, address.Address, types.BigInt, uint64) (*VoucherCreateResult, error)
|
PaychVoucherCreate(context.Context, address.Address, types.BigInt, uint64) (*paych.SignedVoucher, error)
|
||||||
PaychVoucherAdd(context.Context, address.Address, *paych.SignedVoucher, []byte, types.BigInt) (types.BigInt, error)
|
PaychVoucherAdd(context.Context, address.Address, *paych.SignedVoucher, []byte, types.BigInt) (types.BigInt, error)
|
||||||
PaychVoucherList(context.Context, address.Address) ([]*paych.SignedVoucher, error)
|
PaychVoucherList(context.Context, address.Address) ([]*paych.SignedVoucher, error)
|
||||||
PaychVoucherSubmit(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (cid.Cid, error)
|
PaychVoucherSubmit(context.Context, address.Address, *paych.SignedVoucher) (cid.Cid, error)
|
||||||
|
|
||||||
// CreateBackup creates node backup onder the specified file name. The
|
|
||||||
// method requires that the lotus daemon is running with the
|
|
||||||
// LOTUS_BACKUP_BASE_PATH environment variable set to some path, and that
|
|
||||||
// the path specified when calling CreateBackup is within the base path
|
|
||||||
CreateBackup(ctx context.Context, fpath string) error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type FileRef struct {
|
type FileRef struct {
|
||||||
@@ -552,26 +208,15 @@ type FileRef struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type MinerSectors struct {
|
type MinerSectors struct {
|
||||||
// Live sectors that should be proven.
|
Sset uint64
|
||||||
Live uint64
|
Pset uint64
|
||||||
// Sectors actively contributing to power.
|
|
||||||
Active uint64
|
|
||||||
// Sectors with failed proofs.
|
|
||||||
Faulty uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
type ImportRes struct {
|
|
||||||
Root cid.Cid
|
|
||||||
ImportID multistore.StoreID
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Import struct {
|
type Import struct {
|
||||||
Key multistore.StoreID
|
Status filestore.Status
|
||||||
Err string
|
Key cid.Cid
|
||||||
|
|
||||||
Root *cid.Cid
|
|
||||||
Source string
|
|
||||||
FilePath string
|
FilePath string
|
||||||
|
Size uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
type DealInfo struct {
|
type DealInfo struct {
|
||||||
@@ -580,7 +225,6 @@ type DealInfo struct {
|
|||||||
Message string // more information about deal state, particularly errors
|
Message string // more information about deal state, particularly errors
|
||||||
Provider address.Address
|
Provider address.Address
|
||||||
|
|
||||||
DataRef *storagemarket.DataRef
|
|
||||||
PieceCID cid.Cid
|
PieceCID cid.Cid
|
||||||
Size uint64
|
Size uint64
|
||||||
|
|
||||||
@@ -588,32 +232,13 @@ type DealInfo struct {
|
|||||||
Duration uint64
|
Duration uint64
|
||||||
|
|
||||||
DealID abi.DealID
|
DealID abi.DealID
|
||||||
|
|
||||||
CreationTime time.Time
|
|
||||||
Verified bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type MsgLookup struct {
|
type MsgLookup struct {
|
||||||
Message cid.Cid // Can be different than requested, in case it was replaced, but only gas values changed
|
Receipt types.MessageReceipt
|
||||||
Receipt types.MessageReceipt
|
TipSet *types.TipSet
|
||||||
ReturnDec interface{}
|
|
||||||
TipSet types.TipSetKey
|
|
||||||
Height abi.ChainEpoch
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type MsgGasCost struct {
|
|
||||||
Message cid.Cid // Can be different than requested, in case it was replaced, but only gas values changed
|
|
||||||
GasUsed abi.TokenAmount
|
|
||||||
BaseFeeBurn abi.TokenAmount
|
|
||||||
OverEstimationBurn abi.TokenAmount
|
|
||||||
MinerPenalty abi.TokenAmount
|
|
||||||
MinerTip abi.TokenAmount
|
|
||||||
Refund abi.TokenAmount
|
|
||||||
TotalCost abi.TokenAmount
|
|
||||||
}
|
|
||||||
|
|
||||||
// BlsMessages[x].cid = Cids[x]
|
|
||||||
// SecpkMessages[y].cid = Cids[BlsMessages.length + y]
|
|
||||||
type BlockMessages struct {
|
type BlockMessages struct {
|
||||||
BlsMessages []*types.Message
|
BlsMessages []*types.Message
|
||||||
SecpkMessages []*types.SignedMessage
|
SecpkMessages []*types.SignedMessage
|
||||||
@@ -626,6 +251,11 @@ type Message struct {
|
|||||||
Message *types.Message
|
Message *types.Message
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ChainSectorInfo struct {
|
||||||
|
Info miner.SectorOnChainInfo
|
||||||
|
ID abi.SectorNumber
|
||||||
|
}
|
||||||
|
|
||||||
type ActorState struct {
|
type ActorState struct {
|
||||||
Balance types.BigInt
|
Balance types.BigInt
|
||||||
State interface{}
|
State interface{}
|
||||||
@@ -645,36 +275,14 @@ type PaychStatus struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ChannelInfo struct {
|
type ChannelInfo struct {
|
||||||
Channel address.Address
|
Channel address.Address
|
||||||
WaitSentinel cid.Cid
|
ChannelMessage cid.Cid
|
||||||
}
|
|
||||||
|
|
||||||
type ChannelAvailableFunds struct {
|
|
||||||
// Channel is the address of the channel
|
|
||||||
Channel *address.Address
|
|
||||||
// From is the from address of the channel (channel creator)
|
|
||||||
From address.Address
|
|
||||||
// To is the to address of the channel
|
|
||||||
To address.Address
|
|
||||||
// ConfirmedAmt is the amount of funds that have been confirmed on-chain
|
|
||||||
// for the channel
|
|
||||||
ConfirmedAmt types.BigInt
|
|
||||||
// PendingAmt is the amount of funds that are pending confirmation on-chain
|
|
||||||
PendingAmt types.BigInt
|
|
||||||
// PendingWaitSentinel can be used with PaychGetWaitReady to wait for
|
|
||||||
// confirmation of pending funds
|
|
||||||
PendingWaitSentinel *cid.Cid
|
|
||||||
// QueuedAmt is the amount that is queued up behind a pending request
|
|
||||||
QueuedAmt types.BigInt
|
|
||||||
// VoucherRedeemedAmt is the amount that is redeemed by vouchers on-chain
|
|
||||||
// and in the local datastore
|
|
||||||
VoucherReedeemedAmt types.BigInt
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type PaymentInfo struct {
|
type PaymentInfo struct {
|
||||||
Channel address.Address
|
Channel address.Address
|
||||||
WaitSentinel cid.Cid
|
ChannelMessage *cid.Cid
|
||||||
Vouchers []*paych.SignedVoucher
|
Vouchers []*paych.SignedVoucher
|
||||||
}
|
}
|
||||||
|
|
||||||
type VoucherSpec struct {
|
type VoucherSpec struct {
|
||||||
@@ -686,50 +294,35 @@ type VoucherSpec struct {
|
|||||||
Extra *paych.ModVerifyParams
|
Extra *paych.ModVerifyParams
|
||||||
}
|
}
|
||||||
|
|
||||||
// VoucherCreateResult is the response to calling PaychVoucherCreate
|
|
||||||
type VoucherCreateResult struct {
|
|
||||||
// Voucher that was created, or nil if there was an error or if there
|
|
||||||
// were insufficient funds in the channel
|
|
||||||
Voucher *paych.SignedVoucher
|
|
||||||
// Shortfall is the additional amount that would be needed in the channel
|
|
||||||
// in order to be able to create the voucher
|
|
||||||
Shortfall types.BigInt
|
|
||||||
}
|
|
||||||
|
|
||||||
type MinerPower struct {
|
type MinerPower struct {
|
||||||
MinerPower power.Claim
|
MinerPower power.Claim
|
||||||
TotalPower power.Claim
|
TotalPower power.Claim
|
||||||
HasMinPower bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type QueryOffer struct {
|
type QueryOffer struct {
|
||||||
Err string
|
Err string
|
||||||
|
|
||||||
Root cid.Cid
|
Root cid.Cid
|
||||||
Piece *cid.Cid
|
|
||||||
|
|
||||||
Size uint64
|
Size uint64
|
||||||
MinPrice types.BigInt
|
MinPrice types.BigInt
|
||||||
UnsealPrice types.BigInt
|
|
||||||
PaymentInterval uint64
|
PaymentInterval uint64
|
||||||
PaymentIntervalIncrease uint64
|
PaymentIntervalIncrease uint64
|
||||||
Miner address.Address
|
Miner address.Address
|
||||||
MinerPeer retrievalmarket.RetrievalPeer
|
MinerPeerID peer.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *QueryOffer) Order(client address.Address) RetrievalOrder {
|
func (o *QueryOffer) Order(client address.Address) RetrievalOrder {
|
||||||
return RetrievalOrder{
|
return RetrievalOrder{
|
||||||
Root: o.Root,
|
Root: o.Root,
|
||||||
Piece: o.Piece,
|
|
||||||
Size: o.Size,
|
Size: o.Size,
|
||||||
Total: o.MinPrice,
|
Total: o.MinPrice,
|
||||||
UnsealPrice: o.UnsealPrice,
|
|
||||||
PaymentInterval: o.PaymentInterval,
|
PaymentInterval: o.PaymentInterval,
|
||||||
PaymentIntervalIncrease: o.PaymentIntervalIncrease,
|
PaymentIntervalIncrease: o.PaymentIntervalIncrease,
|
||||||
Client: client,
|
Client: client,
|
||||||
|
|
||||||
Miner: o.Miner,
|
Miner: o.Miner,
|
||||||
MinerPeer: o.MinerPeer,
|
MinerPeerID: o.MinerPeerID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -745,27 +338,23 @@ type MarketDeal struct {
|
|||||||
|
|
||||||
type RetrievalOrder struct {
|
type RetrievalOrder struct {
|
||||||
// TODO: make this less unixfs specific
|
// TODO: make this less unixfs specific
|
||||||
Root cid.Cid
|
Root cid.Cid
|
||||||
Piece *cid.Cid
|
Size uint64
|
||||||
Size uint64
|
|
||||||
// TODO: support offset
|
// TODO: support offset
|
||||||
Total types.BigInt
|
Total types.BigInt
|
||||||
UnsealPrice types.BigInt
|
|
||||||
PaymentInterval uint64
|
PaymentInterval uint64
|
||||||
PaymentIntervalIncrease uint64
|
PaymentIntervalIncrease uint64
|
||||||
Client address.Address
|
Client address.Address
|
||||||
Miner address.Address
|
Miner address.Address
|
||||||
MinerPeer retrievalmarket.RetrievalPeer
|
MinerPeerID peer.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
type InvocResult struct {
|
type InvocResult struct {
|
||||||
MsgCid cid.Cid
|
Msg *types.Message
|
||||||
Msg *types.Message
|
MsgRct *types.MessageReceipt
|
||||||
MsgRct *types.MessageReceipt
|
InternalExecutions []*types.ExecutionResult
|
||||||
GasCost MsgGasCost
|
Error string
|
||||||
ExecutionTrace types.ExecutionTrace
|
Duration time.Duration
|
||||||
Error string
|
|
||||||
Duration time.Duration
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type MethodCall struct {
|
type MethodCall struct {
|
||||||
@@ -774,15 +363,12 @@ type MethodCall struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type StartDealParams struct {
|
type StartDealParams struct {
|
||||||
Data *storagemarket.DataRef
|
Data *storagemarket.DataRef
|
||||||
Wallet address.Address
|
Wallet address.Address
|
||||||
Miner address.Address
|
Miner address.Address
|
||||||
EpochPrice types.BigInt
|
EpochPrice types.BigInt
|
||||||
MinBlocksDuration uint64
|
MinBlocksDuration uint64
|
||||||
ProviderCollateral big.Int
|
DealStartEpoch abi.ChainEpoch
|
||||||
DealStartEpoch abi.ChainEpoch
|
|
||||||
FastRetrieval bool
|
|
||||||
VerifiedDeal bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type IpldObject struct {
|
type IpldObject struct {
|
||||||
@@ -791,9 +377,8 @@ type IpldObject struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ActiveSync struct {
|
type ActiveSync struct {
|
||||||
WorkerID uint64
|
Base *types.TipSet
|
||||||
Base *types.TipSet
|
Target *types.TipSet
|
||||||
Target *types.TipSet
|
|
||||||
|
|
||||||
Stage SyncStateStage
|
Stage SyncStateStage
|
||||||
Height abi.ChainEpoch
|
Height abi.ChainEpoch
|
||||||
@@ -805,8 +390,6 @@ type ActiveSync struct {
|
|||||||
|
|
||||||
type SyncState struct {
|
type SyncState struct {
|
||||||
ActiveSyncs []ActiveSync
|
ActiveSyncs []ActiveSync
|
||||||
|
|
||||||
VMApplied uint64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type SyncStateStage int
|
type SyncStateStage int
|
||||||
@@ -818,28 +401,8 @@ const (
|
|||||||
StageMessages
|
StageMessages
|
||||||
StageSyncComplete
|
StageSyncComplete
|
||||||
StageSyncErrored
|
StageSyncErrored
|
||||||
StageFetchingMessages
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (v SyncStateStage) String() string {
|
|
||||||
switch v {
|
|
||||||
case StageHeaders:
|
|
||||||
return "header sync"
|
|
||||||
case StagePersistHeaders:
|
|
||||||
return "persisting headers"
|
|
||||||
case StageMessages:
|
|
||||||
return "message sync"
|
|
||||||
case StageSyncComplete:
|
|
||||||
return "complete"
|
|
||||||
case StageSyncErrored:
|
|
||||||
return "error"
|
|
||||||
case StageFetchingMessages:
|
|
||||||
return "fetching messages"
|
|
||||||
default:
|
|
||||||
return fmt.Sprintf("<unknown: %d>", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type MpoolChange int
|
type MpoolChange int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -857,28 +420,14 @@ type ComputeStateOutput struct {
|
|||||||
Trace []*InvocResult
|
Trace []*InvocResult
|
||||||
}
|
}
|
||||||
|
|
||||||
type DealCollateralBounds struct {
|
|
||||||
Min abi.TokenAmount
|
|
||||||
Max abi.TokenAmount
|
|
||||||
}
|
|
||||||
|
|
||||||
type CirculatingSupply struct {
|
|
||||||
FilVested abi.TokenAmount
|
|
||||||
FilMined abi.TokenAmount
|
|
||||||
FilBurnt abi.TokenAmount
|
|
||||||
FilLocked abi.TokenAmount
|
|
||||||
FilCirculating abi.TokenAmount
|
|
||||||
}
|
|
||||||
|
|
||||||
type MiningBaseInfo struct {
|
type MiningBaseInfo struct {
|
||||||
MinerPower types.BigInt
|
MinerPower types.BigInt
|
||||||
NetworkPower types.BigInt
|
NetworkPower types.BigInt
|
||||||
Sectors []builtin.SectorInfo
|
Sectors []abi.SectorInfo
|
||||||
WorkerKey address.Address
|
WorkerKey address.Address
|
||||||
SectorSize abi.SectorSize
|
SectorSize abi.SectorSize
|
||||||
PrevBeaconEntry types.BeaconEntry
|
PrevBeaconEntry types.BeaconEntry
|
||||||
BeaconEntries []types.BeaconEntry
|
BeaconEntries []types.BeaconEntry
|
||||||
EligibleForMining bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type BlockTemplate struct {
|
type BlockTemplate struct {
|
||||||
@@ -890,18 +439,7 @@ type BlockTemplate struct {
|
|||||||
Messages []*types.SignedMessage
|
Messages []*types.SignedMessage
|
||||||
Epoch abi.ChainEpoch
|
Epoch abi.ChainEpoch
|
||||||
Timestamp uint64
|
Timestamp uint64
|
||||||
WinningPoStProof []builtin.PoStProof
|
WinningPoStProof []abi.PoStProof
|
||||||
}
|
|
||||||
|
|
||||||
type DataSize struct {
|
|
||||||
PayloadSize int64
|
|
||||||
PieceSize abi.PaddedPieceSize
|
|
||||||
}
|
|
||||||
|
|
||||||
type DataCIDSize struct {
|
|
||||||
PayloadSize int64
|
|
||||||
PieceSize abi.PaddedPieceSize
|
|
||||||
PieceCID cid.Cid
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type CommPRet struct {
|
type CommPRet struct {
|
||||||
@@ -920,36 +458,7 @@ const (
|
|||||||
MsigCancel
|
MsigCancel
|
||||||
)
|
)
|
||||||
|
|
||||||
type Deadline struct {
|
|
||||||
PostSubmissions bitfield.BitField
|
|
||||||
}
|
|
||||||
|
|
||||||
type Partition struct {
|
|
||||||
AllSectors bitfield.BitField
|
|
||||||
FaultySectors bitfield.BitField
|
|
||||||
RecoveringSectors bitfield.BitField
|
|
||||||
LiveSectors bitfield.BitField
|
|
||||||
ActiveSectors bitfield.BitField
|
|
||||||
}
|
|
||||||
|
|
||||||
type Fault struct {
|
type Fault struct {
|
||||||
Miner address.Address
|
Miner address.Address
|
||||||
Epoch abi.ChainEpoch
|
Epoch abi.ChainEpoch
|
||||||
}
|
}
|
||||||
|
|
||||||
var EmptyVesting = MsigVesting{
|
|
||||||
InitialBalance: types.EmptyInt,
|
|
||||||
StartEpoch: -1,
|
|
||||||
UnlockDuration: -1,
|
|
||||||
}
|
|
||||||
|
|
||||||
type MsigVesting struct {
|
|
||||||
InitialBalance abi.TokenAmount
|
|
||||||
StartEpoch abi.ChainEpoch
|
|
||||||
UnlockDuration abi.ChainEpoch
|
|
||||||
}
|
|
||||||
|
|
||||||
type MessageMatch struct {
|
|
||||||
To address.Address
|
|
||||||
From address.Address
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
package api
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/filecoin-project/go-state-types/dline"
|
|
||||||
"github.com/filecoin-project/go-state-types/network"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
type GatewayAPI interface {
|
|
||||||
ChainHasObj(context.Context, cid.Cid) (bool, error)
|
|
||||||
ChainHead(ctx context.Context) (*types.TipSet, error)
|
|
||||||
ChainGetBlockMessages(context.Context, cid.Cid) (*BlockMessages, error)
|
|
||||||
ChainGetMessage(ctx context.Context, mc cid.Cid) (*types.Message, error)
|
|
||||||
ChainGetTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error)
|
|
||||||
ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error)
|
|
||||||
ChainNotify(context.Context) (<-chan []*HeadChange, error)
|
|
||||||
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
|
|
||||||
GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *MessageSendSpec, tsk types.TipSetKey) (*types.Message, error)
|
|
||||||
MpoolPush(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error)
|
|
||||||
MsigGetAvailableBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error)
|
|
||||||
MsigGetVested(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error)
|
|
||||||
StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
|
|
||||||
StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (DealCollateralBounds, error)
|
|
||||||
StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error)
|
|
||||||
StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error)
|
|
||||||
StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error)
|
|
||||||
StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
|
|
||||||
StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (MarketBalance, error)
|
|
||||||
StateMarketStorageDeal(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*MarketDeal, error)
|
|
||||||
StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (miner.MinerInfo, error)
|
|
||||||
StateMinerProvingDeadline(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*dline.Info, error)
|
|
||||||
StateMinerPower(context.Context, address.Address, types.TipSetKey) (*MinerPower, error)
|
|
||||||
StateNetworkVersion(context.Context, types.TipSetKey) (network.Version, error)
|
|
||||||
StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error)
|
|
||||||
StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*MsgLookup, error)
|
|
||||||
}
|
|
||||||
+19
-95
@@ -3,22 +3,15 @@ package api
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"time"
|
|
||||||
|
|
||||||
datatransfer "github.com/filecoin-project/go-data-transfer"
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"github.com/libp2p/go-libp2p-core/peer"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-fil-markets/piecestore"
|
|
||||||
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
|
|
||||||
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/fsutil"
|
"github.com/filecoin-project/sector-storage/stores"
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
|
"github.com/filecoin-project/sector-storage/storiface"
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
)
|
)
|
||||||
|
|
||||||
// StorageMiner is a low-level interface to the Filecoin network storage miner node
|
// StorageMiner is a low-level interface to the Filecoin network storage miner node
|
||||||
@@ -35,87 +28,34 @@ type StorageMiner interface {
|
|||||||
PledgeSector(context.Context) error
|
PledgeSector(context.Context) error
|
||||||
|
|
||||||
// Get the status of a given sector by ID
|
// Get the status of a given sector by ID
|
||||||
SectorsStatus(ctx context.Context, sid abi.SectorNumber, showOnChainInfo bool) (SectorInfo, error)
|
SectorsStatus(context.Context, abi.SectorNumber) (SectorInfo, error)
|
||||||
|
|
||||||
// List all staged sectors
|
// List all staged sectors
|
||||||
SectorsList(context.Context) ([]abi.SectorNumber, error)
|
SectorsList(context.Context) ([]abi.SectorNumber, error)
|
||||||
|
|
||||||
SectorsRefs(context.Context) (map[string][]SealedRef, error)
|
SectorsRefs(context.Context) (map[string][]SealedRef, error)
|
||||||
|
|
||||||
// SectorStartSealing can be called on sectors in Empty or WaitDeals states
|
|
||||||
// to trigger sealing early
|
|
||||||
SectorStartSealing(context.Context, abi.SectorNumber) error
|
|
||||||
// SectorSetSealDelay sets the time that a newly-created sector
|
|
||||||
// waits for more deals before it starts sealing
|
|
||||||
SectorSetSealDelay(context.Context, time.Duration) error
|
|
||||||
// SectorGetSealDelay gets the time that a newly-created sector
|
|
||||||
// waits for more deals before it starts sealing
|
|
||||||
SectorGetSealDelay(context.Context) (time.Duration, error)
|
|
||||||
// SectorSetExpectedSealDuration sets the expected time for a sector to seal
|
|
||||||
SectorSetExpectedSealDuration(context.Context, time.Duration) error
|
|
||||||
// SectorGetExpectedSealDuration gets the expected time for a sector to seal
|
|
||||||
SectorGetExpectedSealDuration(context.Context) (time.Duration, error)
|
|
||||||
SectorsUpdate(context.Context, abi.SectorNumber, SectorState) error
|
SectorsUpdate(context.Context, abi.SectorNumber, SectorState) error
|
||||||
SectorRemove(context.Context, abi.SectorNumber) error
|
|
||||||
SectorMarkForUpgrade(ctx context.Context, id abi.SectorNumber) error
|
|
||||||
|
|
||||||
StorageList(ctx context.Context) (map[stores.ID][]stores.Decl, error)
|
StorageList(ctx context.Context) (map[stores.ID][]stores.Decl, error)
|
||||||
StorageLocal(ctx context.Context) (map[stores.ID]string, error)
|
StorageLocal(ctx context.Context) (map[stores.ID]string, error)
|
||||||
StorageStat(ctx context.Context, id stores.ID) (fsutil.FsStat, error)
|
StorageStat(ctx context.Context, id stores.ID) (stores.FsStat, error)
|
||||||
|
|
||||||
// WorkerConnect tells the node to connect to workers RPC
|
// WorkerConnect tells the node to connect to workers RPC
|
||||||
WorkerConnect(context.Context, string) error
|
WorkerConnect(context.Context, string) error
|
||||||
WorkerStats(context.Context) (map[uuid.UUID]storiface.WorkerStats, error)
|
WorkerStats(context.Context) (map[uint64]storiface.WorkerStats, error)
|
||||||
WorkerJobs(context.Context) (map[uuid.UUID][]storiface.WorkerJob, error)
|
|
||||||
storiface.WorkerReturn
|
|
||||||
|
|
||||||
// SealingSchedDiag dumps internal sealing scheduler state
|
|
||||||
SealingSchedDiag(ctx context.Context, doSched bool) (interface{}, error)
|
|
||||||
SealingAbort(ctx context.Context, call storiface.CallID) error
|
|
||||||
|
|
||||||
stores.SectorIndex
|
stores.SectorIndex
|
||||||
|
|
||||||
MarketImportDealData(ctx context.Context, propcid cid.Cid, path string) error
|
MarketImportDealData(ctx context.Context, propcid cid.Cid, path string) error
|
||||||
MarketListDeals(ctx context.Context) ([]MarketDeal, error)
|
MarketListDeals(ctx context.Context) ([]storagemarket.StorageDeal, error)
|
||||||
MarketListRetrievalDeals(ctx context.Context) ([]retrievalmarket.ProviderDealState, error)
|
|
||||||
MarketGetDealUpdates(ctx context.Context) (<-chan storagemarket.MinerDeal, error)
|
|
||||||
MarketListIncompleteDeals(ctx context.Context) ([]storagemarket.MinerDeal, error)
|
MarketListIncompleteDeals(ctx context.Context) ([]storagemarket.MinerDeal, error)
|
||||||
MarketSetAsk(ctx context.Context, price types.BigInt, verifiedPrice types.BigInt, duration abi.ChainEpoch, minPieceSize abi.PaddedPieceSize, maxPieceSize abi.PaddedPieceSize) error
|
MarketSetPrice(context.Context, types.BigInt) error
|
||||||
MarketGetAsk(ctx context.Context) (*storagemarket.SignedStorageAsk, error)
|
|
||||||
MarketSetRetrievalAsk(ctx context.Context, rask *retrievalmarket.Ask) error
|
|
||||||
MarketGetRetrievalAsk(ctx context.Context) (*retrievalmarket.Ask, error)
|
|
||||||
MarketListDataTransfers(ctx context.Context) ([]DataTransferChannel, error)
|
|
||||||
MarketDataTransferUpdates(ctx context.Context) (<-chan DataTransferChannel, error)
|
|
||||||
// MinerRestartDataTransfer attempts to restart a data transfer with the given transfer ID and other peer
|
|
||||||
MarketRestartDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error
|
|
||||||
// ClientCancelDataTransfer cancels a data transfer with the given transfer ID and other peer
|
|
||||||
MarketCancelDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error
|
|
||||||
|
|
||||||
DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error
|
DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error
|
||||||
DealsList(ctx context.Context) ([]MarketDeal, error)
|
DealsList(ctx context.Context) ([]storagemarket.StorageDeal, error)
|
||||||
DealsConsiderOnlineStorageDeals(context.Context) (bool, error)
|
|
||||||
DealsSetConsiderOnlineStorageDeals(context.Context, bool) error
|
|
||||||
DealsConsiderOnlineRetrievalDeals(context.Context) (bool, error)
|
|
||||||
DealsSetConsiderOnlineRetrievalDeals(context.Context, bool) error
|
|
||||||
DealsPieceCidBlocklist(context.Context) ([]cid.Cid, error)
|
|
||||||
DealsSetPieceCidBlocklist(context.Context, []cid.Cid) error
|
|
||||||
DealsConsiderOfflineStorageDeals(context.Context) (bool, error)
|
|
||||||
DealsSetConsiderOfflineStorageDeals(context.Context, bool) error
|
|
||||||
DealsConsiderOfflineRetrievalDeals(context.Context) (bool, error)
|
|
||||||
DealsSetConsiderOfflineRetrievalDeals(context.Context, bool) error
|
|
||||||
|
|
||||||
StorageAddLocal(ctx context.Context, path string) error
|
StorageAddLocal(ctx context.Context, path string) error
|
||||||
|
|
||||||
PiecesListPieces(ctx context.Context) ([]cid.Cid, error)
|
|
||||||
PiecesListCidInfos(ctx context.Context) ([]cid.Cid, error)
|
|
||||||
PiecesGetPieceInfo(ctx context.Context, pieceCid cid.Cid) (*piecestore.PieceInfo, error)
|
|
||||||
PiecesGetCIDInfo(ctx context.Context, payloadCid cid.Cid) (*piecestore.CIDInfo, error)
|
|
||||||
|
|
||||||
// CreateBackup creates node backup onder the specified file name. The
|
|
||||||
// method requires that the lotus-miner is running with the
|
|
||||||
// LOTUS_BACKUP_BASE_PATH environment variable set to some path, and that
|
|
||||||
// the path specified when calling CreateBackup is within the base path
|
|
||||||
CreateBackup(ctx context.Context, fpath string) error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type SealRes struct {
|
type SealRes struct {
|
||||||
@@ -135,40 +75,24 @@ type SectorLog struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SectorInfo struct {
|
type SectorInfo struct {
|
||||||
SectorID abi.SectorNumber
|
SectorID abi.SectorNumber
|
||||||
State SectorState
|
State SectorState
|
||||||
CommD *cid.Cid
|
CommD *cid.Cid
|
||||||
CommR *cid.Cid
|
CommR *cid.Cid
|
||||||
Proof []byte
|
Proof []byte
|
||||||
Deals []abi.DealID
|
Deals []abi.DealID
|
||||||
Ticket SealTicket
|
Ticket SealTicket
|
||||||
Seed SealSeed
|
Seed SealSeed
|
||||||
PreCommitMsg *cid.Cid
|
Retries uint64
|
||||||
CommitMsg *cid.Cid
|
|
||||||
Retries uint64
|
|
||||||
ToUpgrade bool
|
|
||||||
|
|
||||||
LastErr string
|
LastErr string
|
||||||
|
|
||||||
Log []SectorLog
|
Log []SectorLog
|
||||||
|
|
||||||
// On Chain Info
|
|
||||||
SealProof abi.RegisteredSealProof // The seal proof type implies the PoSt proof/s
|
|
||||||
Activation abi.ChainEpoch // Epoch during which the sector proof was accepted
|
|
||||||
Expiration abi.ChainEpoch // Epoch during which the sector expires
|
|
||||||
DealWeight abi.DealWeight // Integral of active deals over sector lifetime
|
|
||||||
VerifiedDealWeight abi.DealWeight // Integral of active verified deals over sector lifetime
|
|
||||||
InitialPledge abi.TokenAmount // Pledge collected to commit this sector
|
|
||||||
// Expiration Info
|
|
||||||
OnTime abi.ChainEpoch
|
|
||||||
// non-zero if sector is faulty, epoch at which it will be permanently
|
|
||||||
// removed if it doesn't recover
|
|
||||||
Early abi.ChainEpoch
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type SealedRef struct {
|
type SealedRef struct {
|
||||||
SectorID abi.SectorNumber
|
SectorID abi.SectorNumber
|
||||||
Offset abi.PaddedPieceSize
|
Offset uint64
|
||||||
Size abi.UnpaddedPieceSize
|
Size abi.UnpaddedPieceSize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,12 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"reflect"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func goCmd() string {
|
func goCmd() string {
|
||||||
@@ -36,68 +32,3 @@ func TestDoesntDependOnFFI(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReturnTypes(t *testing.T) {
|
|
||||||
errType := reflect.TypeOf(new(error)).Elem()
|
|
||||||
bareIface := reflect.TypeOf(new(interface{})).Elem()
|
|
||||||
jmarsh := reflect.TypeOf(new(json.Marshaler)).Elem()
|
|
||||||
|
|
||||||
tst := func(api interface{}) func(t *testing.T) {
|
|
||||||
return func(t *testing.T) {
|
|
||||||
ra := reflect.TypeOf(api).Elem()
|
|
||||||
for i := 0; i < ra.NumMethod(); i++ {
|
|
||||||
m := ra.Method(i)
|
|
||||||
switch m.Type.NumOut() {
|
|
||||||
case 1: // if 1 return value, it must be an error
|
|
||||||
require.Equal(t, errType, m.Type.Out(0), m.Name)
|
|
||||||
|
|
||||||
case 2: // if 2 return values, first cant be an interface/function, second must be an error
|
|
||||||
seen := map[reflect.Type]struct{}{}
|
|
||||||
todo := []reflect.Type{m.Type.Out(0)}
|
|
||||||
for len(todo) > 0 {
|
|
||||||
typ := todo[len(todo)-1]
|
|
||||||
todo = todo[:len(todo)-1]
|
|
||||||
|
|
||||||
if _, ok := seen[typ]; ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
seen[typ] = struct{}{}
|
|
||||||
|
|
||||||
if typ.Kind() == reflect.Interface && typ != bareIface && !typ.Implements(jmarsh) {
|
|
||||||
t.Error("methods can't return interfaces", m.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
switch typ.Kind() {
|
|
||||||
case reflect.Ptr:
|
|
||||||
fallthrough
|
|
||||||
case reflect.Array:
|
|
||||||
fallthrough
|
|
||||||
case reflect.Slice:
|
|
||||||
fallthrough
|
|
||||||
case reflect.Chan:
|
|
||||||
todo = append(todo, typ.Elem())
|
|
||||||
case reflect.Map:
|
|
||||||
todo = append(todo, typ.Elem())
|
|
||||||
todo = append(todo, typ.Key())
|
|
||||||
case reflect.Struct:
|
|
||||||
for i := 0; i < typ.NumField(); i++ {
|
|
||||||
todo = append(todo, typ.Field(i).Type)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
require.NotEqual(t, reflect.Func.String(), m.Type.Out(0).Kind().String(), m.Name)
|
|
||||||
require.Equal(t, errType, m.Type.Out(1), m.Name)
|
|
||||||
|
|
||||||
default:
|
|
||||||
t.Error("methods can only have 1 or 2 return values", m.Name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Run("common", tst(new(Common)))
|
|
||||||
t.Run("full", tst(new(FullNode)))
|
|
||||||
t.Run("miner", tst(new(StorageMiner)))
|
|
||||||
t.Run("worker", tst(new(WorkerAPI)))
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
package api
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/crypto"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
type MsgType string
|
|
||||||
|
|
||||||
const (
|
|
||||||
MTUnknown = "unknown"
|
|
||||||
|
|
||||||
// Signing message CID. MsgMeta.Extra contains raw cbor message bytes
|
|
||||||
MTChainMsg = "message"
|
|
||||||
|
|
||||||
// Signing a blockheader. signing raw cbor block bytes (MsgMeta.Extra is empty)
|
|
||||||
MTBlock = "block"
|
|
||||||
|
|
||||||
// Signing a deal proposal. signing raw cbor proposal bytes (MsgMeta.Extra is empty)
|
|
||||||
MTDealProposal = "dealproposal"
|
|
||||||
|
|
||||||
// TODO: Deals, Vouchers, VRF
|
|
||||||
)
|
|
||||||
|
|
||||||
type MsgMeta struct {
|
|
||||||
Type MsgType
|
|
||||||
|
|
||||||
// Additional data related to what is signed. Should be verifiable with the
|
|
||||||
// signed bytes (e.g. CID(Extra).Bytes() == toSign)
|
|
||||||
Extra []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
type WalletAPI interface {
|
|
||||||
WalletNew(context.Context, types.KeyType) (address.Address, error)
|
|
||||||
WalletHas(context.Context, address.Address) (bool, error)
|
|
||||||
WalletList(context.Context) ([]address.Address, error)
|
|
||||||
|
|
||||||
WalletSign(ctx context.Context, signer address.Address, toSign []byte, meta MsgMeta) (*crypto.Signature, error)
|
|
||||||
|
|
||||||
WalletExport(context.Context, address.Address) (*types.KeyInfo, error)
|
|
||||||
WalletImport(context.Context, *types.KeyInfo) (address.Address, error)
|
|
||||||
WalletDelete(context.Context, address.Address) error
|
|
||||||
}
|
|
||||||
+13
-23
@@ -2,13 +2,15 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"io"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/ipfs/go-cid"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/sector-storage/sealtasks"
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/sealtasks"
|
"github.com/filecoin-project/sector-storage/stores"
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
|
"github.com/filecoin-project/sector-storage/storiface"
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
|
"github.com/filecoin-project/specs-storage/storage"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
)
|
)
|
||||||
@@ -21,26 +23,14 @@ type WorkerAPI interface {
|
|||||||
Paths(context.Context) ([]stores.StoragePath, error)
|
Paths(context.Context) ([]stores.StoragePath, error)
|
||||||
Info(context.Context) (storiface.WorkerInfo, error)
|
Info(context.Context) (storiface.WorkerInfo, error)
|
||||||
|
|
||||||
storiface.WorkerCalls
|
storage.Sealer
|
||||||
|
|
||||||
// Storage / Other
|
MoveStorage(ctx context.Context, sector abi.SectorID) error
|
||||||
Remove(ctx context.Context, sector abi.SectorID) error
|
|
||||||
|
|
||||||
StorageAddLocal(ctx context.Context, path string) error
|
UnsealPiece(context.Context, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) error
|
||||||
|
ReadPiece(context.Context, io.Writer, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize) error
|
||||||
|
|
||||||
// SetEnabled marks the worker as enabled/disabled. Not that this setting
|
Fetch(context.Context, abi.SectorID, stores.SectorFileType, stores.PathType, stores.AcquireMode) error
|
||||||
// may take a few seconds to propagate to task scheduler
|
|
||||||
SetEnabled(ctx context.Context, enabled bool) error
|
|
||||||
|
|
||||||
Enabled(ctx context.Context) (bool, error)
|
Closing(context.Context) (<-chan struct{}, error)
|
||||||
|
|
||||||
// WaitQuiet blocks until there are no tasks running
|
|
||||||
WaitQuiet(ctx context.Context) error
|
|
||||||
|
|
||||||
// returns a random UUID of worker session, generated randomly when worker
|
|
||||||
// process starts
|
|
||||||
ProcessSession(context.Context) (uuid.UUID, error)
|
|
||||||
|
|
||||||
// Like ProcessSession, but returns an error when worker is disabled
|
|
||||||
Session(context.Context) (uuid.UUID, error)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,8 @@ import (
|
|||||||
|
|
||||||
blocks "github.com/ipfs/go-block-format"
|
blocks "github.com/ipfs/go-block-format"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
|
blockstore "github.com/ipfs/go-ipfs-blockstore"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/lib/blockstore"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type ChainIO interface {
|
type ChainIO interface {
|
||||||
|
|||||||
@@ -36,9 +36,3 @@ func PermissionedWorkerAPI(a api.WorkerAPI) api.WorkerAPI {
|
|||||||
auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.Internal)
|
auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.Internal)
|
||||||
return &out
|
return &out
|
||||||
}
|
}
|
||||||
|
|
||||||
func PermissionedWalletAPI(a api.WalletAPI) api.WalletAPI {
|
|
||||||
var out WalletStruct
|
|
||||||
auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.Internal)
|
|
||||||
return &out
|
|
||||||
}
|
|
||||||
|
|||||||
+232
-1042
File diff suppressed because it is too large
Load Diff
+51
-51
@@ -6,8 +6,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
abi "github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
paych "github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
xerrors "golang.org/x/xerrors"
|
xerrors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
@@ -33,7 +33,7 @@ func (t *PaymentInfo) MarshalCBOR(w io.Writer) error {
|
|||||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("Channel"))); err != nil {
|
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("Channel"))); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := io.WriteString(w, string("Channel")); err != nil {
|
if _, err := io.WriteString(w, "Channel"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,20 +41,26 @@ func (t *PaymentInfo) MarshalCBOR(w io.Writer) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// t.WaitSentinel (cid.Cid) (struct)
|
// t.ChannelMessage (cid.Cid) (struct)
|
||||||
if len("WaitSentinel") > cbg.MaxLength {
|
if len("ChannelMessage") > cbg.MaxLength {
|
||||||
return xerrors.Errorf("Value in field \"WaitSentinel\" was too long")
|
return xerrors.Errorf("Value in field \"ChannelMessage\" was too long")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("WaitSentinel"))); err != nil {
|
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("ChannelMessage"))); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := io.WriteString(w, string("WaitSentinel")); err != nil {
|
if _, err := io.WriteString(w, "ChannelMessage"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := cbg.WriteCidBuf(scratch, w, t.WaitSentinel); err != nil {
|
if t.ChannelMessage == nil {
|
||||||
return xerrors.Errorf("failed to write cid field t.WaitSentinel: %w", err)
|
if _, err := w.Write(cbg.CborNull); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err := cbg.WriteCidBuf(scratch, w, *t.ChannelMessage); err != nil {
|
||||||
|
return xerrors.Errorf("failed to write cid field t.ChannelMessage: %w", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// t.Vouchers ([]*paych.SignedVoucher) (slice)
|
// t.Vouchers ([]*paych.SignedVoucher) (slice)
|
||||||
@@ -65,7 +71,7 @@ func (t *PaymentInfo) MarshalCBOR(w io.Writer) error {
|
|||||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("Vouchers"))); err != nil {
|
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("Vouchers"))); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := io.WriteString(w, string("Vouchers")); err != nil {
|
if _, err := io.WriteString(w, "Vouchers"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,8 +91,6 @@ func (t *PaymentInfo) MarshalCBOR(w io.Writer) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *PaymentInfo) UnmarshalCBOR(r io.Reader) error {
|
func (t *PaymentInfo) UnmarshalCBOR(r io.Reader) error {
|
||||||
*t = PaymentInfo{}
|
|
||||||
|
|
||||||
br := cbg.GetPeeker(r)
|
br := cbg.GetPeeker(r)
|
||||||
scratch := make([]byte, 8)
|
scratch := make([]byte, 8)
|
||||||
|
|
||||||
@@ -127,17 +131,29 @@ func (t *PaymentInfo) UnmarshalCBOR(r io.Reader) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// t.WaitSentinel (cid.Cid) (struct)
|
// t.ChannelMessage (cid.Cid) (struct)
|
||||||
case "WaitSentinel":
|
case "ChannelMessage":
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
c, err := cbg.ReadCid(br)
|
pb, err := br.PeekByte()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("failed to read cid field t.WaitSentinel: %w", err)
|
return err
|
||||||
}
|
}
|
||||||
|
if pb == cbg.CborNull[0] {
|
||||||
|
var nbuf [1]byte
|
||||||
|
if _, err := br.Read(nbuf[:]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
t.WaitSentinel = c
|
c, err := cbg.ReadCid(br)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("failed to read cid field t.ChannelMessage: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.ChannelMessage = &c
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// t.Vouchers ([]*paych.SignedVoucher) (slice)
|
// t.Vouchers ([]*paych.SignedVoucher) (slice)
|
||||||
@@ -196,7 +212,7 @@ func (t *SealedRef) MarshalCBOR(w io.Writer) error {
|
|||||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("SectorID"))); err != nil {
|
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("SectorID"))); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := io.WriteString(w, string("SectorID")); err != nil {
|
if _, err := io.WriteString(w, "SectorID"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,7 +220,7 @@ func (t *SealedRef) MarshalCBOR(w io.Writer) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// t.Offset (abi.PaddedPieceSize) (uint64)
|
// t.Offset (uint64) (uint64)
|
||||||
if len("Offset") > cbg.MaxLength {
|
if len("Offset") > cbg.MaxLength {
|
||||||
return xerrors.Errorf("Value in field \"Offset\" was too long")
|
return xerrors.Errorf("Value in field \"Offset\" was too long")
|
||||||
}
|
}
|
||||||
@@ -212,7 +228,7 @@ func (t *SealedRef) MarshalCBOR(w io.Writer) error {
|
|||||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("Offset"))); err != nil {
|
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("Offset"))); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := io.WriteString(w, string("Offset")); err != nil {
|
if _, err := io.WriteString(w, "Offset"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,7 +244,7 @@ func (t *SealedRef) MarshalCBOR(w io.Writer) error {
|
|||||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("Size"))); err != nil {
|
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("Size"))); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := io.WriteString(w, string("Size")); err != nil {
|
if _, err := io.WriteString(w, "Size"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,8 +256,6 @@ func (t *SealedRef) MarshalCBOR(w io.Writer) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *SealedRef) UnmarshalCBOR(r io.Reader) error {
|
func (t *SealedRef) UnmarshalCBOR(r io.Reader) error {
|
||||||
*t = SealedRef{}
|
|
||||||
|
|
||||||
br := cbg.GetPeeker(r)
|
br := cbg.GetPeeker(r)
|
||||||
scratch := make([]byte, 8)
|
scratch := make([]byte, 8)
|
||||||
|
|
||||||
@@ -287,7 +301,7 @@ func (t *SealedRef) UnmarshalCBOR(r io.Reader) error {
|
|||||||
t.SectorID = abi.SectorNumber(extra)
|
t.SectorID = abi.SectorNumber(extra)
|
||||||
|
|
||||||
}
|
}
|
||||||
// t.Offset (abi.PaddedPieceSize) (uint64)
|
// t.Offset (uint64) (uint64)
|
||||||
case "Offset":
|
case "Offset":
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -299,7 +313,7 @@ func (t *SealedRef) UnmarshalCBOR(r io.Reader) 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.Offset = abi.PaddedPieceSize(extra)
|
t.Offset = uint64(extra)
|
||||||
|
|
||||||
}
|
}
|
||||||
// t.Size (abi.UnpaddedPieceSize) (uint64)
|
// t.Size (abi.UnpaddedPieceSize) (uint64)
|
||||||
@@ -344,7 +358,7 @@ func (t *SealedRefs) MarshalCBOR(w io.Writer) error {
|
|||||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("Refs"))); err != nil {
|
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("Refs"))); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := io.WriteString(w, string("Refs")); err != nil {
|
if _, err := io.WriteString(w, "Refs"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,8 +378,6 @@ func (t *SealedRefs) MarshalCBOR(w io.Writer) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *SealedRefs) UnmarshalCBOR(r io.Reader) error {
|
func (t *SealedRefs) UnmarshalCBOR(r io.Reader) error {
|
||||||
*t = SealedRefs{}
|
|
||||||
|
|
||||||
br := cbg.GetPeeker(r)
|
br := cbg.GetPeeker(r)
|
||||||
scratch := make([]byte, 8)
|
scratch := make([]byte, 8)
|
||||||
|
|
||||||
@@ -452,7 +464,7 @@ func (t *SealTicket) MarshalCBOR(w io.Writer) error {
|
|||||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("Value"))); err != nil {
|
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("Value"))); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := io.WriteString(w, string("Value")); err != nil {
|
if _, err := io.WriteString(w, "Value"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -464,7 +476,7 @@ func (t *SealTicket) MarshalCBOR(w io.Writer) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := w.Write(t.Value[:]); err != nil {
|
if _, err := w.Write(t.Value); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -476,7 +488,7 @@ func (t *SealTicket) MarshalCBOR(w io.Writer) error {
|
|||||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("Epoch"))); err != nil {
|
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("Epoch"))); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := io.WriteString(w, string("Epoch")); err != nil {
|
if _, err := io.WriteString(w, "Epoch"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -493,8 +505,6 @@ func (t *SealTicket) MarshalCBOR(w io.Writer) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *SealTicket) UnmarshalCBOR(r io.Reader) error {
|
func (t *SealTicket) UnmarshalCBOR(r io.Reader) error {
|
||||||
*t = SealTicket{}
|
|
||||||
|
|
||||||
br := cbg.GetPeeker(r)
|
br := cbg.GetPeeker(r)
|
||||||
scratch := make([]byte, 8)
|
scratch := make([]byte, 8)
|
||||||
|
|
||||||
@@ -539,12 +549,8 @@ func (t *SealTicket) UnmarshalCBOR(r io.Reader) error {
|
|||||||
if maj != cbg.MajByteString {
|
if maj != cbg.MajByteString {
|
||||||
return fmt.Errorf("expected byte array")
|
return fmt.Errorf("expected byte array")
|
||||||
}
|
}
|
||||||
|
t.Value = make([]byte, extra)
|
||||||
if extra > 0 {
|
if _, err := io.ReadFull(br, t.Value); err != nil {
|
||||||
t.Value = make([]uint8, extra)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := io.ReadFull(br, t.Value[:]); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// t.Epoch (abi.ChainEpoch) (int64)
|
// t.Epoch (abi.ChainEpoch) (int64)
|
||||||
@@ -600,7 +606,7 @@ func (t *SealSeed) MarshalCBOR(w io.Writer) error {
|
|||||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("Value"))); err != nil {
|
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("Value"))); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := io.WriteString(w, string("Value")); err != nil {
|
if _, err := io.WriteString(w, "Value"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -612,7 +618,7 @@ func (t *SealSeed) MarshalCBOR(w io.Writer) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := w.Write(t.Value[:]); err != nil {
|
if _, err := w.Write(t.Value); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -624,7 +630,7 @@ func (t *SealSeed) MarshalCBOR(w io.Writer) error {
|
|||||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("Epoch"))); err != nil {
|
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("Epoch"))); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := io.WriteString(w, string("Epoch")); err != nil {
|
if _, err := io.WriteString(w, "Epoch"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -641,8 +647,6 @@ func (t *SealSeed) MarshalCBOR(w io.Writer) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *SealSeed) UnmarshalCBOR(r io.Reader) error {
|
func (t *SealSeed) UnmarshalCBOR(r io.Reader) error {
|
||||||
*t = SealSeed{}
|
|
||||||
|
|
||||||
br := cbg.GetPeeker(r)
|
br := cbg.GetPeeker(r)
|
||||||
scratch := make([]byte, 8)
|
scratch := make([]byte, 8)
|
||||||
|
|
||||||
@@ -687,12 +691,8 @@ func (t *SealSeed) UnmarshalCBOR(r io.Reader) error {
|
|||||||
if maj != cbg.MajByteString {
|
if maj != cbg.MajByteString {
|
||||||
return fmt.Errorf("expected byte array")
|
return fmt.Errorf("expected byte array")
|
||||||
}
|
}
|
||||||
|
t.Value = make([]byte, extra)
|
||||||
if extra > 0 {
|
if _, err := io.ReadFull(br, t.Value); err != nil {
|
||||||
t.Value = make([]uint8, extra)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := io.ReadFull(br, t.Value[:]); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// t.Epoch (abi.ChainEpoch) (int64)
|
// t.Epoch (abi.ChainEpoch) (int64)
|
||||||
|
|||||||
+9
-58
@@ -1,23 +1,18 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
|
||||||
"path"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-jsonrpc"
|
"github.com/filecoin-project/go-jsonrpc"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/api/apistruct"
|
"github.com/filecoin-project/lotus/api/apistruct"
|
||||||
"github.com/filecoin-project/lotus/lib/rpcenc"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewCommonRPC creates a new http jsonrpc client.
|
// NewCommonRPC creates a new http jsonrpc client.
|
||||||
func NewCommonRPC(ctx context.Context, addr string, requestHeader http.Header) (api.Common, jsonrpc.ClientCloser, error) {
|
func NewCommonRPC(addr string, requestHeader http.Header) (api.Common, jsonrpc.ClientCloser, error) {
|
||||||
var res apistruct.CommonStruct
|
var res apistruct.CommonStruct
|
||||||
closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin",
|
closer, err := jsonrpc.NewMergeClient(addr, "Filecoin",
|
||||||
[]interface{}{
|
[]interface{}{
|
||||||
&res.Internal,
|
&res.Internal,
|
||||||
},
|
},
|
||||||
@@ -28,9 +23,9 @@ func NewCommonRPC(ctx context.Context, addr string, requestHeader http.Header) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewFullNodeRPC creates a new http jsonrpc client.
|
// NewFullNodeRPC creates a new http jsonrpc client.
|
||||||
func NewFullNodeRPC(ctx context.Context, addr string, requestHeader http.Header) (api.FullNode, jsonrpc.ClientCloser, error) {
|
func NewFullNodeRPC(addr string, requestHeader http.Header) (api.FullNode, jsonrpc.ClientCloser, error) {
|
||||||
var res apistruct.FullNodeStruct
|
var res apistruct.FullNodeStruct
|
||||||
closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin",
|
closer, err := jsonrpc.NewMergeClient(addr, "Filecoin",
|
||||||
[]interface{}{
|
[]interface{}{
|
||||||
&res.CommonStruct.Internal,
|
&res.CommonStruct.Internal,
|
||||||
&res.Internal,
|
&res.Internal,
|
||||||
@@ -39,67 +34,23 @@ func NewFullNodeRPC(ctx context.Context, addr string, requestHeader http.Header)
|
|||||||
return &res, closer, err
|
return &res, closer, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewStorageMinerRPC creates a new http jsonrpc client for miner
|
// NewStorageMinerRPC creates a new http jsonrpc client for storage miner
|
||||||
func NewStorageMinerRPC(ctx context.Context, addr string, requestHeader http.Header, opts ...jsonrpc.Option) (api.StorageMiner, jsonrpc.ClientCloser, error) {
|
func NewStorageMinerRPC(addr string, requestHeader http.Header) (api.StorageMiner, jsonrpc.ClientCloser, error) {
|
||||||
var res apistruct.StorageMinerStruct
|
var res apistruct.StorageMinerStruct
|
||||||
closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin",
|
closer, err := jsonrpc.NewMergeClient(addr, "Filecoin",
|
||||||
[]interface{}{
|
[]interface{}{
|
||||||
&res.CommonStruct.Internal,
|
&res.CommonStruct.Internal,
|
||||||
&res.Internal,
|
&res.Internal,
|
||||||
},
|
},
|
||||||
requestHeader,
|
requestHeader,
|
||||||
opts...,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return &res, closer, err
|
return &res, closer, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewWorkerRPC(ctx context.Context, addr string, requestHeader http.Header) (api.WorkerAPI, jsonrpc.ClientCloser, error) {
|
func NewWorkerRPC(addr string, requestHeader http.Header) (api.WorkerAPI, jsonrpc.ClientCloser, error) {
|
||||||
u, err := url.Parse(addr)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
switch u.Scheme {
|
|
||||||
case "ws":
|
|
||||||
u.Scheme = "http"
|
|
||||||
case "wss":
|
|
||||||
u.Scheme = "https"
|
|
||||||
}
|
|
||||||
///rpc/v0 -> /rpc/streams/v0/push
|
|
||||||
|
|
||||||
u.Path = path.Join(u.Path, "../streams/v0/push")
|
|
||||||
|
|
||||||
var res apistruct.WorkerStruct
|
var res apistruct.WorkerStruct
|
||||||
closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin",
|
closer, err := jsonrpc.NewMergeClient(addr, "Filecoin",
|
||||||
[]interface{}{
|
|
||||||
&res.Internal,
|
|
||||||
},
|
|
||||||
requestHeader,
|
|
||||||
rpcenc.ReaderParamEncoder(u.String()),
|
|
||||||
jsonrpc.WithNoReconnect(),
|
|
||||||
jsonrpc.WithTimeout(30*time.Second),
|
|
||||||
)
|
|
||||||
|
|
||||||
return &res, closer, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewGatewayRPC creates a new http jsonrpc client for a gateway node.
|
|
||||||
func NewGatewayRPC(ctx context.Context, addr string, requestHeader http.Header, opts ...jsonrpc.Option) (api.GatewayAPI, jsonrpc.ClientCloser, error) {
|
|
||||||
var res apistruct.GatewayStruct
|
|
||||||
closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin",
|
|
||||||
[]interface{}{
|
|
||||||
&res.Internal,
|
|
||||||
},
|
|
||||||
requestHeader,
|
|
||||||
opts...,
|
|
||||||
)
|
|
||||||
|
|
||||||
return &res, closer, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewWalletRPC(ctx context.Context, addr string, requestHeader http.Header) (api.WalletAPI, jsonrpc.ClientCloser, error) {
|
|
||||||
var res apistruct.WalletStruct
|
|
||||||
closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin",
|
|
||||||
[]interface{}{
|
[]interface{}{
|
||||||
&res.Internal,
|
&res.Internal,
|
||||||
},
|
},
|
||||||
|
|||||||
+40
-216
@@ -6,44 +6,27 @@ import (
|
|||||||
"go/ast"
|
"go/ast"
|
||||||
"go/parser"
|
"go/parser"
|
||||||
"go/token"
|
"go/token"
|
||||||
"os"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
"github.com/ipfs/go-filestore"
|
|
||||||
metrics "github.com/libp2p/go-libp2p-core/metrics"
|
|
||||||
"github.com/libp2p/go-libp2p-core/network"
|
|
||||||
"github.com/libp2p/go-libp2p-core/peer"
|
|
||||||
protocol "github.com/libp2p/go-libp2p-core/protocol"
|
|
||||||
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
|
||||||
"github.com/multiformats/go-multiaddr"
|
|
||||||
|
|
||||||
"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"
|
|
||||||
filestore2 "github.com/filecoin-project/go-fil-markets/filestore"
|
|
||||||
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
|
|
||||||
"github.com/filecoin-project/go-jsonrpc/auth"
|
"github.com/filecoin-project/go-jsonrpc/auth"
|
||||||
"github.com/filecoin-project/go-multistore"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/filecoin-project/go-state-types/crypto"
|
|
||||||
"github.com/filecoin-project/go-state-types/exitcode"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/api/apistruct"
|
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/sealtasks"
|
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
|
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
|
|
||||||
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
|
|
||||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
"github.com/ipfs/go-filestore"
|
||||||
|
"github.com/libp2p/go-libp2p-core/network"
|
||||||
|
peer "github.com/libp2p/go-libp2p-peer"
|
||||||
|
"github.com/multiformats/go-multiaddr"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ExampleValues = map[reflect.Type]interface{}{
|
var ExampleValues = map[reflect.Type]interface{}{
|
||||||
@@ -82,23 +65,17 @@ func init() {
|
|||||||
|
|
||||||
ExampleValues[reflect.TypeOf(addr)] = addr
|
ExampleValues[reflect.TypeOf(addr)] = addr
|
||||||
|
|
||||||
pid, err := peer.Decode("12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf")
|
pid, err := peer.IDB58Decode("12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
addExample(pid)
|
addExample(pid)
|
||||||
addExample(&pid)
|
|
||||||
|
|
||||||
addExample(bitfield.NewFromSet([]uint64{5}))
|
addExample(bitfield.NewFromSet([]uint64{5}))
|
||||||
addExample(abi.RegisteredSealProof_StackedDrg32GiBV1)
|
addExample(abi.RegisteredProof_StackedDRG32GiBPoSt)
|
||||||
addExample(abi.RegisteredPoStProof_StackedDrgWindow32GiBV1)
|
|
||||||
addExample(abi.ChainEpoch(10101))
|
addExample(abi.ChainEpoch(10101))
|
||||||
addExample(crypto.SigTypeBLS)
|
addExample(crypto.SigTypeBLS)
|
||||||
addExample(types.KTBLS)
|
|
||||||
addExample(int64(9))
|
addExample(int64(9))
|
||||||
addExample(12.3)
|
|
||||||
addExample(123)
|
|
||||||
addExample(uintptr(0))
|
|
||||||
addExample(abi.MethodNum(1))
|
addExample(abi.MethodNum(1))
|
||||||
addExample(exitcode.ExitCode(0))
|
addExample(exitcode.ExitCode(0))
|
||||||
addExample(crypto.DomainSeparationTag_ElectionProofProduction)
|
addExample(crypto.DomainSeparationTag_ElectionProofProduction)
|
||||||
@@ -113,52 +90,21 @@ func init() {
|
|||||||
addExample(network.Connected)
|
addExample(network.Connected)
|
||||||
addExample(dtypes.NetworkName("lotus"))
|
addExample(dtypes.NetworkName("lotus"))
|
||||||
addExample(api.SyncStateStage(1))
|
addExample(api.SyncStateStage(1))
|
||||||
addExample(build.FullAPIVersion)
|
addExample(build.APIVersion)
|
||||||
addExample(api.PCHInbound)
|
addExample(api.PCHInbound)
|
||||||
addExample(time.Minute)
|
addExample(time.Minute)
|
||||||
addExample(datatransfer.TransferID(3))
|
addExample(&types.ExecutionResult{
|
||||||
addExample(datatransfer.Ongoing)
|
Msg: exampleValue(reflect.TypeOf(&types.Message{})).(*types.Message),
|
||||||
addExample(multistore.StoreID(50))
|
MsgRct: exampleValue(reflect.TypeOf(&types.MessageReceipt{})).(*types.MessageReceipt),
|
||||||
addExample(retrievalmarket.ClientEventDealAccepted)
|
|
||||||
addExample(retrievalmarket.DealStatusNew)
|
|
||||||
addExample(network.ReachabilityPublic)
|
|
||||||
addExample(build.NewestNetworkVersion)
|
|
||||||
addExample(&types.ExecutionTrace{
|
|
||||||
Msg: exampleValue("init", reflect.TypeOf(&types.Message{}), nil).(*types.Message),
|
|
||||||
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(reflect.TypeOf(types.Actor{})).(types.Actor),
|
||||||
})
|
})
|
||||||
addExample(map[string]api.MarketDeal{
|
addExample(map[string]api.MarketDeal{
|
||||||
"t026363": exampleValue("init", reflect.TypeOf(api.MarketDeal{}), nil).(api.MarketDeal),
|
"t026363": exampleValue(reflect.TypeOf(api.MarketDeal{})).(api.MarketDeal),
|
||||||
})
|
})
|
||||||
addExample(map[string]api.MarketBalance{
|
addExample(map[string]api.MarketBalance{
|
||||||
"t026363": exampleValue("init", reflect.TypeOf(api.MarketBalance{}), nil).(api.MarketBalance),
|
"t026363": exampleValue(reflect.TypeOf(api.MarketBalance{})).(api.MarketBalance),
|
||||||
})
|
|
||||||
addExample(map[string]*pubsub.TopicScoreSnapshot{
|
|
||||||
"/blocks": {
|
|
||||||
TimeInMesh: time.Minute,
|
|
||||||
FirstMessageDeliveries: 122,
|
|
||||||
MeshMessageDeliveries: 1234,
|
|
||||||
InvalidMessageDeliveries: 3,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
addExample(map[string]metrics.Stats{
|
|
||||||
"12D3KooWSXmXLJmBR1M7i9RW9GQPNUhZSzXKzxDHWtAgNuJAbyEJ": {
|
|
||||||
RateIn: 100,
|
|
||||||
RateOut: 50,
|
|
||||||
TotalIn: 174000,
|
|
||||||
TotalOut: 12500,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
addExample(map[protocol.ID]metrics.Stats{
|
|
||||||
"/fil/hello/1.0.0": {
|
|
||||||
RateIn: 100,
|
|
||||||
RateOut: 50,
|
|
||||||
TotalIn: 174000,
|
|
||||||
TotalOut: 12500,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
||||||
maddr, err := multiaddr.NewMultiaddr("/ip4/52.36.61.156/tcp/1347/p2p/12D3KooWFETiESTf1v4PGUvtnxMAcEFMzLZbJGg4tjWfGEimYior")
|
maddr, err := multiaddr.NewMultiaddr("/ip4/52.36.61.156/tcp/1347/p2p/12D3KooWFETiESTf1v4PGUvtnxMAcEFMzLZbJGg4tjWfGEimYior")
|
||||||
@@ -169,80 +115,9 @@ func init() {
|
|||||||
// because reflect.TypeOf(maddr) returns the concrete type...
|
// because reflect.TypeOf(maddr) returns the concrete type...
|
||||||
ExampleValues[reflect.TypeOf(struct{ A multiaddr.Multiaddr }{}).Field(0).Type] = maddr
|
ExampleValues[reflect.TypeOf(struct{ A multiaddr.Multiaddr }{}).Field(0).Type] = maddr
|
||||||
|
|
||||||
// miner specific
|
|
||||||
addExample(filestore2.Path(".lotusminer/fstmp123"))
|
|
||||||
si := multistore.StoreID(12)
|
|
||||||
addExample(&si)
|
|
||||||
addExample(retrievalmarket.DealID(5))
|
|
||||||
addExample(abi.ActorID(1000))
|
|
||||||
addExample(map[string][]api.SealedRef{
|
|
||||||
"98000": {
|
|
||||||
api.SealedRef{
|
|
||||||
SectorID: 100,
|
|
||||||
Offset: 10 << 20,
|
|
||||||
Size: 1 << 20,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
addExample(api.SectorState(sealing.Proving))
|
|
||||||
addExample(stores.ID("76f1988b-ef30-4d7e-b3ec-9a627f4ba5a8"))
|
|
||||||
addExample(storiface.FTUnsealed)
|
|
||||||
addExample(storiface.PathSealing)
|
|
||||||
addExample(map[stores.ID][]stores.Decl{
|
|
||||||
"76f1988b-ef30-4d7e-b3ec-9a627f4ba5a8": {
|
|
||||||
{
|
|
||||||
SectorID: abi.SectorID{Miner: 1000, Number: 100},
|
|
||||||
SectorFileType: storiface.FTSealed,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
addExample(map[stores.ID]string{
|
|
||||||
"76f1988b-ef30-4d7e-b3ec-9a627f4ba5a8": "/data/path",
|
|
||||||
})
|
|
||||||
addExample(map[uuid.UUID][]storiface.WorkerJob{
|
|
||||||
uuid.MustParse("ef8d99a2-6865-4189-8ffa-9fef0f806eee"): {
|
|
||||||
{
|
|
||||||
ID: storiface.CallID{
|
|
||||||
Sector: abi.SectorID{Miner: 1000, Number: 100},
|
|
||||||
ID: uuid.MustParse("76081ba0-61bd-45a5-bc08-af05f1c26e5d"),
|
|
||||||
},
|
|
||||||
Sector: abi.SectorID{Miner: 1000, Number: 100},
|
|
||||||
Task: sealtasks.TTPreCommit2,
|
|
||||||
RunWait: 0,
|
|
||||||
Start: time.Unix(1605172927, 0).UTC(),
|
|
||||||
Hostname: "host",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
addExample(map[uuid.UUID]storiface.WorkerStats{
|
|
||||||
uuid.MustParse("ef8d99a2-6865-4189-8ffa-9fef0f806eee"): {
|
|
||||||
Info: storiface.WorkerInfo{
|
|
||||||
Hostname: "host",
|
|
||||||
Resources: storiface.WorkerResources{
|
|
||||||
MemPhysical: 256 << 30,
|
|
||||||
MemSwap: 120 << 30,
|
|
||||||
MemReserved: 2 << 30,
|
|
||||||
CPUs: 64,
|
|
||||||
GPUs: []string{"aGPU 1337"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Enabled: true,
|
|
||||||
MemUsedMin: 0,
|
|
||||||
MemUsedMax: 0,
|
|
||||||
GpuUsed: false,
|
|
||||||
CpuUse: 0,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
// worker specific
|
|
||||||
addExample(storiface.AcquireMove)
|
|
||||||
addExample(storiface.UnpaddedByteIndex(abi.PaddedPieceSize(1 << 20).Unpadded()))
|
|
||||||
addExample(map[sealtasks.TaskType]struct{}{
|
|
||||||
sealtasks.TTPreCommit2: {},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func exampleValue(method string, t, parent reflect.Type) interface{} {
|
func exampleValue(t reflect.Type) interface{} {
|
||||||
v, ok := ExampleValues[t]
|
v, ok := ExampleValues[t]
|
||||||
if ok {
|
if ok {
|
||||||
return v
|
return v
|
||||||
@@ -251,25 +126,25 @@ func exampleValue(method string, t, parent reflect.Type) interface{} {
|
|||||||
switch t.Kind() {
|
switch t.Kind() {
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
out := reflect.New(t).Elem()
|
out := reflect.New(t).Elem()
|
||||||
reflect.Append(out, reflect.ValueOf(exampleValue(method, t.Elem(), t)))
|
reflect.Append(out, reflect.ValueOf(exampleValue(t.Elem())))
|
||||||
return out.Interface()
|
return out.Interface()
|
||||||
case reflect.Chan:
|
case reflect.Chan:
|
||||||
return exampleValue(method, t.Elem(), nil)
|
return exampleValue(t.Elem())
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
es := exampleStruct(method, t, parent)
|
es := exampleStruct(t)
|
||||||
v := reflect.ValueOf(es).Elem().Interface()
|
v := reflect.ValueOf(es).Elem().Interface()
|
||||||
ExampleValues[t] = v
|
ExampleValues[t] = v
|
||||||
return v
|
return v
|
||||||
case reflect.Array:
|
case reflect.Array:
|
||||||
out := reflect.New(t).Elem()
|
out := reflect.New(t).Elem()
|
||||||
for i := 0; i < t.Len(); i++ {
|
for i := 0; i < t.Len(); i++ {
|
||||||
out.Index(i).Set(reflect.ValueOf(exampleValue(method, t.Elem(), t)))
|
out.Index(i).Set(reflect.ValueOf(exampleValue(t.Elem())))
|
||||||
}
|
}
|
||||||
return out.Interface()
|
return out.Interface()
|
||||||
|
|
||||||
case reflect.Ptr:
|
case reflect.Ptr:
|
||||||
if t.Elem().Kind() == reflect.Struct {
|
if t.Elem().Kind() == reflect.Struct {
|
||||||
es := exampleStruct(method, t.Elem(), t)
|
es := exampleStruct(t.Elem())
|
||||||
//ExampleValues[t] = es
|
//ExampleValues[t] = es
|
||||||
return es
|
return es
|
||||||
}
|
}
|
||||||
@@ -277,18 +152,15 @@ func exampleValue(method string, t, parent reflect.Type) interface{} {
|
|||||||
return struct{}{}
|
return struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
panic(fmt.Sprintf("No example value for type: %s (method '%s')", t, method))
|
panic(fmt.Sprintf("No example value for type: %s", t))
|
||||||
}
|
}
|
||||||
|
|
||||||
func exampleStruct(method string, t, parent reflect.Type) interface{} {
|
func exampleStruct(t reflect.Type) interface{} {
|
||||||
ns := reflect.New(t)
|
ns := reflect.New(t)
|
||||||
for i := 0; i < t.NumField(); i++ {
|
for i := 0; i < t.NumField(); i++ {
|
||||||
f := t.Field(i)
|
f := t.Field(i)
|
||||||
if f.Type == parent {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if strings.Title(f.Name) == f.Name {
|
if strings.Title(f.Name) == f.Name {
|
||||||
ns.Elem().Field(i).Set(reflect.ValueOf(exampleValue(method, f.Type, t)))
|
ns.Elem().Field(i).Set(reflect.ValueOf(exampleValue(f.Type)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,7 +168,6 @@ func exampleStruct(method string, t, parent reflect.Type) interface{} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Visitor struct {
|
type Visitor struct {
|
||||||
Root string
|
|
||||||
Methods map[string]ast.Node
|
Methods map[string]ast.Node
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,7 +177,7 @@ func (v *Visitor) Visit(node ast.Node) ast.Visitor {
|
|||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
if st.Name.Name != v.Root {
|
if st.Name.Name != "FullNode" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,7 +193,7 @@ func (v *Visitor) Visit(node ast.Node) ast.Visitor {
|
|||||||
|
|
||||||
const noComment = "There are not yet any comments for this method."
|
const noComment = "There are not yet any comments for this method."
|
||||||
|
|
||||||
func parseApiASTInfo(apiFile, iface string) (map[string]string, map[string]string) { //nolint:golint
|
func parseApiASTInfo() (map[string]string, map[string]string) { //nolint:golint
|
||||||
fset := token.NewFileSet()
|
fset := token.NewFileSet()
|
||||||
pkgs, err := parser.ParseDir(fset, "./api", nil, parser.AllErrors|parser.ParseComments)
|
pkgs, err := parser.ParseDir(fset, "./api", nil, parser.AllErrors|parser.ParseComments)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -331,11 +202,11 @@ func parseApiASTInfo(apiFile, iface string) (map[string]string, map[string]strin
|
|||||||
|
|
||||||
ap := pkgs["api"]
|
ap := pkgs["api"]
|
||||||
|
|
||||||
f := ap.Files[apiFile]
|
f := ap.Files["api/api_full.go"]
|
||||||
|
|
||||||
cmap := ast.NewCommentMap(fset, f, f.Comments)
|
cmap := ast.NewCommentMap(fset, f, f.Comments)
|
||||||
|
|
||||||
v := &Visitor{iface, make(map[string]ast.Node)}
|
v := &Visitor{make(map[string]ast.Node)}
|
||||||
ast.Walk(v, pkgs["api"])
|
ast.Walk(v, pkgs["api"])
|
||||||
|
|
||||||
groupDocs := make(map[string]string)
|
groupDocs := make(map[string]string)
|
||||||
@@ -391,30 +262,13 @@ func methodGroupFromName(mn string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
comments, groupComments := parseApiASTInfo(os.Args[1], os.Args[2])
|
|
||||||
|
comments, groupComments := parseApiASTInfo()
|
||||||
|
|
||||||
groups := make(map[string]*MethodGroup)
|
groups := make(map[string]*MethodGroup)
|
||||||
|
|
||||||
var t reflect.Type
|
var api struct{ api.FullNode }
|
||||||
var permStruct, commonPermStruct reflect.Type
|
t := reflect.TypeOf(api)
|
||||||
|
|
||||||
switch os.Args[2] {
|
|
||||||
case "FullNode":
|
|
||||||
t = reflect.TypeOf(new(struct{ api.FullNode })).Elem()
|
|
||||||
permStruct = reflect.TypeOf(apistruct.FullNodeStruct{}.Internal)
|
|
||||||
commonPermStruct = reflect.TypeOf(apistruct.CommonStruct{}.Internal)
|
|
||||||
case "StorageMiner":
|
|
||||||
t = reflect.TypeOf(new(struct{ api.StorageMiner })).Elem()
|
|
||||||
permStruct = reflect.TypeOf(apistruct.StorageMinerStruct{}.Internal)
|
|
||||||
commonPermStruct = reflect.TypeOf(apistruct.CommonStruct{}.Internal)
|
|
||||||
case "WorkerAPI":
|
|
||||||
t = reflect.TypeOf(new(struct{ api.WorkerAPI })).Elem()
|
|
||||||
permStruct = reflect.TypeOf(apistruct.WorkerStruct{}.Internal)
|
|
||||||
commonPermStruct = reflect.TypeOf(apistruct.WorkerStruct{}.Internal)
|
|
||||||
default:
|
|
||||||
panic("unknown type")
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < t.NumMethod(); i++ {
|
for i := 0; i < t.NumMethod(); i++ {
|
||||||
m := t.Method(i)
|
m := t.Method(i)
|
||||||
|
|
||||||
@@ -432,17 +286,17 @@ func main() {
|
|||||||
ft := m.Func.Type()
|
ft := m.Func.Type()
|
||||||
for j := 2; j < ft.NumIn(); j++ {
|
for j := 2; j < ft.NumIn(); j++ {
|
||||||
inp := ft.In(j)
|
inp := ft.In(j)
|
||||||
args = append(args, exampleValue(m.Name, inp, nil))
|
args = append(args, exampleValue(inp))
|
||||||
}
|
}
|
||||||
|
|
||||||
v, err := json.MarshalIndent(args, "", " ")
|
v, err := json.Marshal(args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
outv := exampleValue(m.Name, ft.Out(0), nil)
|
outv := exampleValue(ft.Out(0))
|
||||||
|
|
||||||
ov, err := json.MarshalIndent(outv, "", " ")
|
ov, err := json.Marshal(outv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@@ -464,15 +318,6 @@ func main() {
|
|||||||
return groupslice[i].GroupName < groupslice[j].GroupName
|
return groupslice[i].GroupName < groupslice[j].GroupName
|
||||||
})
|
})
|
||||||
|
|
||||||
fmt.Printf("# Groups\n")
|
|
||||||
|
|
||||||
for _, g := range groupslice {
|
|
||||||
fmt.Printf("* [%s](#%s)\n", g.GroupName, g.GroupName)
|
|
||||||
for _, method := range g.Methods {
|
|
||||||
fmt.Printf(" * [%s](#%s)\n", method.Name, method.Name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, g := range groupslice {
|
for _, g := range groupslice {
|
||||||
g := g
|
g := g
|
||||||
fmt.Printf("## %s\n", g.GroupName)
|
fmt.Printf("## %s\n", g.GroupName)
|
||||||
@@ -486,29 +331,8 @@ func main() {
|
|||||||
fmt.Printf("### %s\n", m.Name)
|
fmt.Printf("### %s\n", m.Name)
|
||||||
fmt.Printf("%s\n\n", m.Comment)
|
fmt.Printf("%s\n\n", m.Comment)
|
||||||
|
|
||||||
meth, ok := permStruct.FieldByName(m.Name)
|
fmt.Printf("Inputs: `%s`\n\n", m.InputExample)
|
||||||
if !ok {
|
fmt.Printf("Response: `%s`\n\n", m.ResponseExample)
|
||||||
meth, ok = commonPermStruct.FieldByName(m.Name)
|
|
||||||
if !ok {
|
|
||||||
panic("no perms for method: " + m.Name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
perms := meth.Tag.Get("perm")
|
|
||||||
|
|
||||||
fmt.Printf("Perms: %s\n\n", perms)
|
|
||||||
|
|
||||||
if strings.Count(m.InputExample, "\n") > 0 {
|
|
||||||
fmt.Printf("Inputs:\n```json\n%s\n```\n\n", m.InputExample)
|
|
||||||
} else {
|
|
||||||
fmt.Printf("Inputs: `%s`\n\n", m.InputExample)
|
|
||||||
}
|
|
||||||
|
|
||||||
if strings.Count(m.ResponseExample, "\n") > 0 {
|
|
||||||
fmt.Printf("Response:\n```json\n%s\n```\n\n", m.ResponseExample)
|
|
||||||
} else {
|
|
||||||
fmt.Printf("Response: `%s`\n\n", m.ResponseExample)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"sync/atomic"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/filecoin-project/lotus/miner"
|
|
||||||
)
|
|
||||||
|
|
||||||
type BlockMiner struct {
|
|
||||||
ctx context.Context
|
|
||||||
t *testing.T
|
|
||||||
miner TestStorageNode
|
|
||||||
blocktime time.Duration
|
|
||||||
mine int64
|
|
||||||
nulls int64
|
|
||||||
done chan struct{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewBlockMiner(ctx context.Context, t *testing.T, miner TestStorageNode, blocktime time.Duration) *BlockMiner {
|
|
||||||
return &BlockMiner{
|
|
||||||
ctx: ctx,
|
|
||||||
t: t,
|
|
||||||
miner: miner,
|
|
||||||
blocktime: blocktime,
|
|
||||||
mine: int64(1),
|
|
||||||
done: make(chan struct{}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bm *BlockMiner) MineBlocks() {
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
go func() {
|
|
||||||
defer close(bm.done)
|
|
||||||
for atomic.LoadInt64(&bm.mine) == 1 {
|
|
||||||
select {
|
|
||||||
case <-bm.ctx.Done():
|
|
||||||
return
|
|
||||||
case <-time.After(bm.blocktime):
|
|
||||||
}
|
|
||||||
|
|
||||||
nulls := atomic.SwapInt64(&bm.nulls, 0)
|
|
||||||
if err := bm.miner.MineOne(bm.ctx, miner.MineReq{
|
|
||||||
InjectNulls: abi.ChainEpoch(nulls),
|
|
||||||
Done: func(bool, abi.ChainEpoch, error) {},
|
|
||||||
}); err != nil {
|
|
||||||
bm.t.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bm *BlockMiner) Stop() {
|
|
||||||
atomic.AddInt64(&bm.mine, -1)
|
|
||||||
fmt.Println("shutting down mining")
|
|
||||||
<-bm.done
|
|
||||||
}
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"sync/atomic"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
"github.com/filecoin-project/lotus/node/impl"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
|
||||||
for _, height := range []abi.ChainEpoch{
|
|
||||||
1, // before
|
|
||||||
162, // while sealing
|
|
||||||
520, // after upgrade deal
|
|
||||||
5000, // after
|
|
||||||
} {
|
|
||||||
height := height // make linters happy by copying
|
|
||||||
t.Run(fmt.Sprintf("upgrade-%d", height), func(t *testing.T) {
|
|
||||||
testCCUpgrade(t, b, blocktime, height)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration, upgradeHeight abi.ChainEpoch) {
|
|
||||||
ctx := context.Background()
|
|
||||||
n, sn := b(t, []FullNodeOpts{FullNodeWithUpgradeAt(upgradeHeight)}, OneMiner)
|
|
||||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
|
||||||
miner := sn[0]
|
|
||||||
|
|
||||||
addrinfo, err := client.NetAddrsListen(ctx)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := miner.NetConnect(ctx, addrinfo); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
|
|
||||||
mine := int64(1)
|
|
||||||
done := make(chan struct{})
|
|
||||||
go func() {
|
|
||||||
defer close(done)
|
|
||||||
for atomic.LoadInt64(&mine) == 1 {
|
|
||||||
time.Sleep(blocktime)
|
|
||||||
if err := sn[0].MineOne(ctx, MineNext); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
maddr, err := miner.ActorAddress(ctx)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
CC := abi.SectorNumber(GenesisPreseals + 1)
|
|
||||||
Upgraded := CC + 1
|
|
||||||
|
|
||||||
pledgeSectors(t, ctx, miner, 1, 0, nil)
|
|
||||||
|
|
||||||
sl, err := miner.SectorsList(ctx)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if len(sl) != 1 {
|
|
||||||
t.Fatal("expected 1 sector")
|
|
||||||
}
|
|
||||||
|
|
||||||
if sl[0] != CC {
|
|
||||||
t.Fatal("bad")
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
si, err := client.StateSectorGetInfo(ctx, maddr, CC, types.EmptyTSK)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Less(t, 50000, int(si.Expiration))
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := miner.SectorMarkForUpgrade(ctx, sl[0]); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
MakeDeal(t, ctx, 6, client, miner, false, false)
|
|
||||||
|
|
||||||
// Validate upgrade
|
|
||||||
|
|
||||||
{
|
|
||||||
exp, err := client.StateSectorExpiration(ctx, maddr, CC, types.EmptyTSK)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NotNil(t, exp)
|
|
||||||
require.Greater(t, 50000, int(exp.OnTime))
|
|
||||||
}
|
|
||||||
{
|
|
||||||
exp, err := client.StateSectorExpiration(ctx, maddr, Upgraded, types.EmptyTSK)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Less(t, 50000, int(exp.OnTime))
|
|
||||||
}
|
|
||||||
|
|
||||||
dlInfo, err := client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
// Sector should expire.
|
|
||||||
for {
|
|
||||||
// Wait for the sector to expire.
|
|
||||||
status, err := miner.SectorsStatus(ctx, CC, true)
|
|
||||||
require.NoError(t, err)
|
|
||||||
if status.OnTime == 0 && status.Early == 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
t.Log("waiting for sector to expire")
|
|
||||||
// wait one deadline per loop.
|
|
||||||
time.Sleep(time.Duration(dlInfo.WPoStChallengeWindow) * blocktime)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("shutting down mining")
|
|
||||||
atomic.AddInt64(&mine, -1)
|
|
||||||
<-done
|
|
||||||
}
|
|
||||||
+37
-241
@@ -8,20 +8,18 @@ import (
|
|||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sync/atomic"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
|
|
||||||
files "github.com/ipfs/go-ipfs-files"
|
files "github.com/ipfs/go-ipfs-files"
|
||||||
|
logging "github.com/ipfs/go-log/v2"
|
||||||
"github.com/ipld/go-car"
|
"github.com/ipld/go-car"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
|
|
||||||
dag "github.com/ipfs/go-merkledag"
|
dag "github.com/ipfs/go-merkledag"
|
||||||
dstest "github.com/ipfs/go-merkledag/test"
|
dstest "github.com/ipfs/go-merkledag/test"
|
||||||
unixfile "github.com/ipfs/go-unixfs/file"
|
unixfile "github.com/ipfs/go-unixfs/file"
|
||||||
@@ -31,10 +29,16 @@ import (
|
|||||||
ipld "github.com/ipfs/go-ipld-format"
|
ipld "github.com/ipfs/go-ipld-format"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, carExport, fastRet bool) {
|
func init() {
|
||||||
|
logging.SetAllLoggers(logging.LevelInfo)
|
||||||
|
build.InsecurePoStValidation = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, carExport bool) {
|
||||||
|
_ = os.Setenv("BELLMAN_NO_GPU", "1")
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
n, sn := b(t, OneFull, OneMiner)
|
n, sn := b(t, 1, oneMiner)
|
||||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||||
miner := sn[0]
|
miner := sn[0]
|
||||||
|
|
||||||
@@ -48,29 +52,30 @@ func TestDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, carExport
|
|||||||
}
|
}
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
|
|
||||||
mine := int64(1)
|
mine := true
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
defer close(done)
|
defer close(done)
|
||||||
for atomic.LoadInt64(&mine) == 1 {
|
for mine {
|
||||||
time.Sleep(blocktime)
|
time.Sleep(blocktime)
|
||||||
if err := sn[0].MineOne(ctx, MineNext); err != nil {
|
if err := sn[0].MineOne(ctx, func(bool) {}); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
MakeDeal(t, ctx, 6, client, miner, carExport, fastRet)
|
makeDeal(t, ctx, 6, client, miner, carExport)
|
||||||
|
|
||||||
atomic.AddInt64(&mine, -1)
|
mine = false
|
||||||
fmt.Println("shutting down mining")
|
fmt.Println("shutting down mining")
|
||||||
<-done
|
<-done
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDoubleDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
func TestDoubleDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||||
|
_ = os.Setenv("BELLMAN_NO_GPU", "1")
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
n, sn := b(t, OneFull, OneMiner)
|
n, sn := b(t, 1, oneMiner)
|
||||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||||
miner := sn[0]
|
miner := sn[0]
|
||||||
|
|
||||||
@@ -84,103 +89,31 @@ func TestDoubleDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
|||||||
}
|
}
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
|
|
||||||
mine := int64(1)
|
mine := true
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer close(done)
|
defer close(done)
|
||||||
for atomic.LoadInt64(&mine) == 1 {
|
for mine {
|
||||||
time.Sleep(blocktime)
|
time.Sleep(blocktime)
|
||||||
if err := sn[0].MineOne(ctx, MineNext); err != nil {
|
if err := sn[0].MineOne(ctx, func(bool) {}); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
MakeDeal(t, ctx, 6, client, miner, false, false)
|
makeDeal(t, ctx, 6, client, miner, false)
|
||||||
MakeDeal(t, ctx, 7, client, miner, false, false)
|
makeDeal(t, ctx, 7, client, miner, false)
|
||||||
|
|
||||||
atomic.AddInt64(&mine, -1)
|
mine = false
|
||||||
fmt.Println("shutting down mining")
|
fmt.Println("shutting down mining")
|
||||||
<-done
|
<-done
|
||||||
}
|
}
|
||||||
|
|
||||||
func MakeDeal(t *testing.T, ctx context.Context, rseed int, client api.FullNode, miner TestStorageNode, carExport, fastRet bool) {
|
func makeDeal(t *testing.T, ctx context.Context, rseed int, client *impl.FullNodeAPI, miner TestStorageNode, carExport bool) {
|
||||||
res, data, err := CreateClientFile(ctx, client, rseed)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fcid := res.Root
|
|
||||||
fmt.Println("FILE CID: ", fcid)
|
|
||||||
|
|
||||||
deal := startDeal(t, ctx, miner, client, fcid, fastRet)
|
|
||||||
|
|
||||||
// TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
waitDealSealed(t, ctx, miner, client, deal, false)
|
|
||||||
|
|
||||||
// Retrieval
|
|
||||||
info, err := client.ClientGetDealInfo(ctx, *deal)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
testRetrieval(t, ctx, client, fcid, &info.PieceCID, carExport, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateClientFile(ctx context.Context, client api.FullNode, rseed int) (*api.ImportRes, []byte, error) {
|
|
||||||
data := make([]byte, 1600)
|
data := make([]byte, 1600)
|
||||||
rand.New(rand.NewSource(int64(rseed))).Read(data)
|
rand.New(rand.NewSource(int64(rseed))).Read(data)
|
||||||
|
|
||||||
dir, err := ioutil.TempDir(os.TempDir(), "test-make-deal-")
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
path := filepath.Join(dir, "sourcefile.dat")
|
|
||||||
err = ioutil.WriteFile(path, data, 0644)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
res, err := client.ClientImport(ctx, api.FileRef{Path: path})
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
return res, data, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFastRetrievalDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
|
||||||
|
|
||||||
ctx := context.Background()
|
|
||||||
n, sn := b(t, OneFull, OneMiner)
|
|
||||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
|
||||||
miner := sn[0]
|
|
||||||
|
|
||||||
addrinfo, err := client.NetAddrsListen(ctx)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := miner.NetConnect(ctx, addrinfo); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
|
|
||||||
mine := int64(1)
|
|
||||||
done := make(chan struct{})
|
|
||||||
go func() {
|
|
||||||
defer close(done)
|
|
||||||
for atomic.LoadInt64(&mine) == 1 {
|
|
||||||
time.Sleep(blocktime)
|
|
||||||
if err := sn[0].MineOne(ctx, MineNext); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
data := make([]byte, 1600)
|
|
||||||
rand.New(rand.NewSource(int64(8))).Read(data)
|
|
||||||
|
|
||||||
r := bytes.NewReader(data)
|
r := bytes.NewReader(data)
|
||||||
fcid, err := client.ClientImportLocal(ctx, r)
|
fcid, err := client.ClientImportLocal(ctx, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -189,96 +122,18 @@ func TestFastRetrievalDealFlow(t *testing.T, b APIBuilder, blocktime time.Durati
|
|||||||
|
|
||||||
fmt.Println("FILE CID: ", fcid)
|
fmt.Println("FILE CID: ", fcid)
|
||||||
|
|
||||||
deal := startDeal(t, ctx, miner, client, fcid, true)
|
deal := startDeal(t, ctx, miner, client, fcid)
|
||||||
|
|
||||||
waitDealPublished(t, ctx, miner, deal)
|
// TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this
|
||||||
fmt.Println("deal published, retrieving")
|
|
||||||
// Retrieval
|
|
||||||
info, err := client.ClientGetDealInfo(ctx, *deal)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
testRetrieval(t, ctx, client, fcid, &info.PieceCID, false, data)
|
|
||||||
atomic.AddInt64(&mine, -1)
|
|
||||||
fmt.Println("shutting down mining")
|
|
||||||
<-done
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSenondDealRetrieval(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
|
||||||
|
|
||||||
ctx := context.Background()
|
|
||||||
n, sn := b(t, OneFull, OneMiner)
|
|
||||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
|
||||||
miner := sn[0]
|
|
||||||
|
|
||||||
addrinfo, err := client.NetAddrsListen(ctx)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := miner.NetConnect(ctx, addrinfo); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
|
waitDealSealed(t, ctx, client, deal)
|
||||||
|
|
||||||
mine := int64(1)
|
// Retrieval
|
||||||
done := make(chan struct{})
|
|
||||||
|
|
||||||
go func() {
|
testRetrieval(t, ctx, err, client, fcid, carExport, data)
|
||||||
defer close(done)
|
|
||||||
for atomic.LoadInt64(&mine) == 1 {
|
|
||||||
time.Sleep(blocktime)
|
|
||||||
if err := sn[0].MineOne(ctx, MineNext); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
{
|
|
||||||
data1 := make([]byte, 800)
|
|
||||||
rand.New(rand.NewSource(int64(3))).Read(data1)
|
|
||||||
r := bytes.NewReader(data1)
|
|
||||||
|
|
||||||
fcid1, err := client.ClientImportLocal(ctx, r)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
data2 := make([]byte, 800)
|
|
||||||
rand.New(rand.NewSource(int64(9))).Read(data2)
|
|
||||||
r2 := bytes.NewReader(data2)
|
|
||||||
|
|
||||||
fcid2, err := client.ClientImportLocal(ctx, r2)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
deal1 := startDeal(t, ctx, miner, client, fcid1, true)
|
|
||||||
|
|
||||||
// TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
waitDealSealed(t, ctx, miner, client, deal1, true)
|
|
||||||
|
|
||||||
deal2 := startDeal(t, ctx, miner, client, fcid2, true)
|
|
||||||
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
waitDealSealed(t, ctx, miner, client, deal2, false)
|
|
||||||
|
|
||||||
// Retrieval
|
|
||||||
info, err := client.ClientGetDealInfo(ctx, *deal2)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
rf, _ := miner.SectorsRefs(ctx)
|
|
||||||
fmt.Printf("refs: %+v\n", rf)
|
|
||||||
|
|
||||||
testRetrieval(t, ctx, client, fcid2, &info.PieceCID, false, data2)
|
|
||||||
}
|
|
||||||
|
|
||||||
atomic.AddInt64(&mine, -1)
|
|
||||||
fmt.Println("shutting down mining")
|
|
||||||
<-done
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func startDeal(t *testing.T, ctx context.Context, miner TestStorageNode, client api.FullNode, fcid cid.Cid, fastRet bool) *cid.Cid {
|
func startDeal(t *testing.T, ctx context.Context, miner TestStorageNode, client *impl.FullNodeAPI, fcid cid.Cid) *cid.Cid {
|
||||||
maddr, err := miner.ActorAddress(ctx)
|
maddr, err := miner.ActorAddress(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -289,15 +144,11 @@ func startDeal(t *testing.T, ctx context.Context, miner TestStorageNode, client
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
deal, err := client.ClientStartDeal(ctx, &api.StartDealParams{
|
deal, err := client.ClientStartDeal(ctx, &api.StartDealParams{
|
||||||
Data: &storagemarket.DataRef{
|
Data: &storagemarket.DataRef{Root: fcid},
|
||||||
TransferType: storagemarket.TTGraphsync,
|
|
||||||
Root: fcid,
|
|
||||||
},
|
|
||||||
Wallet: addr,
|
Wallet: addr,
|
||||||
Miner: maddr,
|
Miner: maddr,
|
||||||
EpochPrice: types.NewInt(1000000),
|
EpochPrice: types.NewInt(1000000),
|
||||||
MinBlocksDuration: uint64(build.MinDealDuration),
|
MinBlocksDuration: 100,
|
||||||
FastRetrieval: fastRet,
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("%+v", err)
|
t.Fatalf("%+v", err)
|
||||||
@@ -305,7 +156,7 @@ func startDeal(t *testing.T, ctx context.Context, miner TestStorageNode, client
|
|||||||
return deal
|
return deal
|
||||||
}
|
}
|
||||||
|
|
||||||
func waitDealSealed(t *testing.T, ctx context.Context, miner TestStorageNode, client api.FullNode, deal *cid.Cid, noseal bool) {
|
func waitDealSealed(t *testing.T, ctx context.Context, client *impl.FullNodeAPI, deal *cid.Cid) {
|
||||||
loop:
|
loop:
|
||||||
for {
|
for {
|
||||||
di, err := client.ClientGetDealInfo(ctx, *deal)
|
di, err := client.ClientGetDealInfo(ctx, *deal)
|
||||||
@@ -313,11 +164,6 @@ loop:
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
switch di.State {
|
switch di.State {
|
||||||
case storagemarket.StorageDealSealing:
|
|
||||||
if noseal {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
startSealingWaiting(t, ctx, miner)
|
|
||||||
case storagemarket.StorageDealProposalRejected:
|
case storagemarket.StorageDealProposalRejected:
|
||||||
t.Fatal("deal rejected")
|
t.Fatal("deal rejected")
|
||||||
case storagemarket.StorageDealFailing:
|
case storagemarket.StorageDealFailing:
|
||||||
@@ -333,53 +179,8 @@ loop:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func waitDealPublished(t *testing.T, ctx context.Context, miner TestStorageNode, deal *cid.Cid) {
|
func testRetrieval(t *testing.T, ctx context.Context, err error, client *impl.FullNodeAPI, fcid cid.Cid, carExport bool, data []byte) {
|
||||||
subCtx, cancel := context.WithCancel(ctx)
|
offers, err := client.ClientFindData(ctx, fcid)
|
||||||
defer cancel()
|
|
||||||
updates, err := miner.MarketGetDealUpdates(subCtx)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
t.Fatal("context timeout")
|
|
||||||
case di := <-updates:
|
|
||||||
if deal.Equals(di.ProposalCid) {
|
|
||||||
switch di.State {
|
|
||||||
case storagemarket.StorageDealProposalRejected:
|
|
||||||
t.Fatal("deal rejected")
|
|
||||||
case storagemarket.StorageDealFailing:
|
|
||||||
t.Fatal("deal failed")
|
|
||||||
case storagemarket.StorageDealError:
|
|
||||||
t.Fatal("deal errored", di.Message)
|
|
||||||
case storagemarket.StorageDealFinalizing, storagemarket.StorageDealSealing, storagemarket.StorageDealActive:
|
|
||||||
fmt.Println("COMPLETE", di)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
fmt.Println("Deal state: ", storagemarket.DealStates[di.State])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func startSealingWaiting(t *testing.T, ctx context.Context, miner TestStorageNode) {
|
|
||||||
snums, err := miner.SectorsList(ctx)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
for _, snum := range snums {
|
|
||||||
si, err := miner.SectorsStatus(ctx, snum, false)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
t.Logf("Sector state: %s", si.State)
|
|
||||||
if si.State == api.SectorState(sealing.WaitDeals) {
|
|
||||||
require.NoError(t, miner.SectorStartSealing(ctx, snum))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testRetrieval(t *testing.T, ctx context.Context, client api.FullNode, fcid cid.Cid, piece *cid.Cid, carExport bool, data []byte) {
|
|
||||||
offers, err := client.ClientFindData(ctx, fcid, piece)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -403,14 +204,9 @@ func testRetrieval(t *testing.T, ctx context.Context, client api.FullNode, fcid
|
|||||||
Path: filepath.Join(rpath, "ret"),
|
Path: filepath.Join(rpath, "ret"),
|
||||||
IsCAR: carExport,
|
IsCAR: carExport,
|
||||||
}
|
}
|
||||||
updates, err := client.ClientRetrieveWithEvents(ctx, offers[0].Order(caddr), ref)
|
err = client.ClientRetrieve(ctx, offers[0].Order(caddr), ref)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatalf("%+v", err)
|
||||||
}
|
|
||||||
for update := range updates {
|
|
||||||
if update.Err != "" {
|
|
||||||
t.Fatalf("retrieval failed: %s", update.Err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rdata, err := ioutil.ReadFile(filepath.Join(rpath, "ret"))
|
rdata, err := ioutil.ReadFile(filepath.Join(rpath, "ret"))
|
||||||
|
|||||||
+60
-62
@@ -5,45 +5,43 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"os"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
logging "github.com/ipfs/go-log/v2"
|
logging "github.com/ipfs/go-log/v2"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
"github.com/filecoin-project/lotus/miner"
|
|
||||||
"github.com/filecoin-project/lotus/node/impl"
|
"github.com/filecoin-project/lotus/node/impl"
|
||||||
)
|
)
|
||||||
|
|
||||||
//nolint:deadcode,varcheck
|
|
||||||
var log = logging.Logger("apitest")
|
var log = logging.Logger("apitest")
|
||||||
|
|
||||||
func (ts *testSuite) testMining(t *testing.T) {
|
func (ts *testSuite) testMining(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
apis, sn := ts.makeNodes(t, OneFull, OneMiner)
|
apis, sn := ts.makeNodes(t, 1, oneMiner)
|
||||||
api := apis[0]
|
api := apis[0]
|
||||||
|
|
||||||
newHeads, err := api.ChainNotify(ctx)
|
|
||||||
require.NoError(t, err)
|
|
||||||
initHead := (<-newHeads)[0]
|
|
||||||
baseHeight := initHead.Val.Height()
|
|
||||||
|
|
||||||
h1, err := api.ChainHead(ctx)
|
h1, err := api.ChainHead(ctx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, int64(h1.Height()), int64(baseHeight))
|
require.Equal(t, abi.ChainEpoch(0), h1.Height())
|
||||||
|
|
||||||
MineUntilBlock(ctx, t, apis[0], sn[0], nil)
|
newHeads, err := api.ChainNotify(ctx)
|
||||||
|
require.NoError(t, err)
|
||||||
|
<-newHeads
|
||||||
|
|
||||||
|
err = sn[0].MineOne(ctx, func(bool) {})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
<-newHeads
|
<-newHeads
|
||||||
|
|
||||||
h2, err := api.ChainHead(ctx)
|
h2, err := api.ChainHead(ctx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Greater(t, int64(h2.Height()), int64(h1.Height()))
|
require.Equal(t, abi.ChainEpoch(1), h2.Height())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ts *testSuite) testMiningReal(t *testing.T) {
|
func (ts *testSuite) testMiningReal(t *testing.T) {
|
||||||
@@ -53,43 +51,45 @@ func (ts *testSuite) testMiningReal(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
apis, sn := ts.makeNodes(t, OneFull, OneMiner)
|
apis, sn := ts.makeNodes(t, 1, oneMiner)
|
||||||
api := apis[0]
|
api := apis[0]
|
||||||
|
|
||||||
newHeads, err := api.ChainNotify(ctx)
|
|
||||||
require.NoError(t, err)
|
|
||||||
at := (<-newHeads)[0].Val.Height()
|
|
||||||
|
|
||||||
h1, err := api.ChainHead(ctx)
|
h1, err := api.ChainHead(ctx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, int64(at), int64(h1.Height()))
|
require.Equal(t, abi.ChainEpoch(0), h1.Height())
|
||||||
|
|
||||||
MineUntilBlock(ctx, t, apis[0], sn[0], nil)
|
newHeads, err := api.ChainNotify(ctx)
|
||||||
|
require.NoError(t, err)
|
||||||
|
<-newHeads
|
||||||
|
|
||||||
|
err = sn[0].MineOne(ctx, func(bool) {})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
<-newHeads
|
<-newHeads
|
||||||
|
|
||||||
h2, err := api.ChainHead(ctx)
|
h2, err := api.ChainHead(ctx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Greater(t, int64(h2.Height()), int64(h1.Height()))
|
require.Equal(t, abi.ChainEpoch(1), h2.Height())
|
||||||
|
|
||||||
MineUntilBlock(ctx, t, apis[0], sn[0], nil)
|
err = sn[0].MineOne(ctx, func(bool) {})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
<-newHeads
|
<-newHeads
|
||||||
|
|
||||||
h3, err := api.ChainHead(ctx)
|
h2, err = api.ChainHead(ctx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Greater(t, int64(h3.Height()), int64(h2.Height()))
|
require.Equal(t, abi.ChainEpoch(2), h2.Height())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDealMining(t *testing.T, b APIBuilder, blocktime time.Duration, carExport bool) {
|
func TestDealMining(t *testing.T, b APIBuilder, blocktime time.Duration, carExport bool) {
|
||||||
|
_ = os.Setenv("BELLMAN_NO_GPU", "1")
|
||||||
|
|
||||||
// test making a deal with a fresh miner, and see if it starts to mine
|
// test making a deal with a fresh miner, and see if it starts to mine
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
n, sn := b(t, OneFull, []StorageMiner{
|
n, sn := b(t, 1, []StorageMiner{
|
||||||
{Full: 0, Preseal: PresealGenesis},
|
{Full: 0, Preseal: PresealGenesis},
|
||||||
{Full: 0, Preseal: 0}, // TODO: Add support for miners on non-first full node
|
{Full: 0, Preseal: 0}, // TODO: Add support for storage miners on non-first full node
|
||||||
})
|
})
|
||||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||||
provider := sn[1]
|
provider := sn[1]
|
||||||
@@ -125,30 +125,27 @@ func TestDealMining(t *testing.T, b APIBuilder, blocktime time.Duration, carExpo
|
|||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
minedTwo := make(chan struct{})
|
minedTwo := make(chan struct{})
|
||||||
|
|
||||||
m2addr, err := sn[1].ActorAddress(context.TODO())
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer close(done)
|
defer close(done)
|
||||||
|
|
||||||
complChan := minedTwo
|
prevExpect := 0
|
||||||
for atomic.LoadInt32(&mine) != 0 {
|
for atomic.LoadInt32(&mine) != 0 {
|
||||||
wait := make(chan int)
|
wait := make(chan int, 2)
|
||||||
mdone := func(mined bool, _ abi.ChainEpoch, err error) {
|
mdone := func(mined bool) {
|
||||||
n := 0
|
go func() {
|
||||||
if mined {
|
n := 0
|
||||||
n = 1
|
if mined {
|
||||||
}
|
n = 1
|
||||||
wait <- n
|
}
|
||||||
|
wait <- n
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := sn[0].MineOne(ctx, miner.MineReq{Done: mdone}); err != nil {
|
if err := sn[0].MineOne(ctx, mdone); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := sn[1].MineOne(ctx, miner.MineReq{Done: mdone}); err != nil {
|
if err := sn[1].MineOne(ctx, mdone); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,42 +153,43 @@ func TestDealMining(t *testing.T, b APIBuilder, blocktime time.Duration, carExpo
|
|||||||
expect += <-wait
|
expect += <-wait
|
||||||
|
|
||||||
time.Sleep(blocktime)
|
time.Sleep(blocktime)
|
||||||
if expect == 0 {
|
|
||||||
// null block
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
var nodeOneMined bool
|
for {
|
||||||
for _, node := range sn {
|
n := 0
|
||||||
mb, err := node.MiningBase(ctx)
|
for i, node := range sn {
|
||||||
if err != nil {
|
mb, err := node.MiningBase(ctx)
|
||||||
t.Error(err)
|
if err != nil {
|
||||||
return
|
t.Error(err)
|
||||||
}
|
return
|
||||||
|
|
||||||
for _, b := range mb.Blocks() {
|
|
||||||
if b.Miner == m2addr {
|
|
||||||
nodeOneMined = true
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(mb.Cids()) != expect {
|
||||||
|
log.Warnf("node %d mining base not complete (%d, want %d)", i, len(mb.Cids()), expect)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
n++
|
||||||
}
|
}
|
||||||
|
if n == len(sn) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
time.Sleep(blocktime)
|
||||||
}
|
}
|
||||||
|
|
||||||
if nodeOneMined && complChan != nil {
|
if prevExpect == 2 && expect == 2 && minedTwo != nil {
|
||||||
close(complChan)
|
close(minedTwo)
|
||||||
complChan = nil
|
minedTwo = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prevExpect = expect
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
deal := startDeal(t, ctx, provider, client, fcid, false)
|
deal := startDeal(t, ctx, provider, client, fcid)
|
||||||
|
|
||||||
// TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this
|
// TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
|
|
||||||
waitDealSealed(t, ctx, provider, client, deal, false)
|
waitDealSealed(t, ctx, client, deal)
|
||||||
|
|
||||||
<-minedTwo
|
<-minedTwo
|
||||||
|
|
||||||
|
|||||||
@@ -1,312 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"sync/atomic"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/filecoin-project/go-state-types/big"
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
|
||||||
"github.com/filecoin-project/lotus/api/apibstore"
|
|
||||||
"github.com/filecoin-project/lotus/build"
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin/paych"
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
|
||||||
"github.com/filecoin-project/lotus/chain/events"
|
|
||||||
"github.com/filecoin-project/lotus/chain/events/state"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
|
||||||
ctx := context.Background()
|
|
||||||
n, sn := b(t, TwoFull, OneMiner)
|
|
||||||
|
|
||||||
paymentCreator := n[0]
|
|
||||||
paymentReceiver := n[1]
|
|
||||||
miner := sn[0]
|
|
||||||
|
|
||||||
// get everyone connected
|
|
||||||
addrs, err := paymentCreator.NetAddrsListen(ctx)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := paymentReceiver.NetConnect(ctx, addrs); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := miner.NetConnect(ctx, addrs); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// start mining blocks
|
|
||||||
bm := NewBlockMiner(ctx, t, miner, blocktime)
|
|
||||||
bm.MineBlocks()
|
|
||||||
|
|
||||||
// send some funds to register the receiver
|
|
||||||
receiverAddr, err := paymentReceiver.WalletNew(ctx, types.KTSecp256k1)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
SendFunds(ctx, t, paymentCreator, receiverAddr, abi.NewTokenAmount(1e18))
|
|
||||||
|
|
||||||
// setup the payment channel
|
|
||||||
createrAddr, err := paymentCreator.WalletDefaultAddress(ctx)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
channelAmt := int64(7000)
|
|
||||||
channelInfo, err := paymentCreator.PaychGet(ctx, createrAddr, receiverAddr, abi.NewTokenAmount(channelAmt))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
channel, err := paymentCreator.PaychGetWaitReady(ctx, channelInfo.WaitSentinel)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// allocate three lanes
|
|
||||||
var lanes []uint64
|
|
||||||
for i := 0; i < 3; i++ {
|
|
||||||
lane, err := paymentCreator.PaychAllocateLane(ctx, channel)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
lanes = append(lanes, lane)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make two vouchers each for each lane, then save on the other side
|
|
||||||
// Note that the voucher with a value of 2000 has a higher nonce, so it
|
|
||||||
// supersedes the voucher with a value of 1000
|
|
||||||
for _, lane := range lanes {
|
|
||||||
vouch1, err := paymentCreator.PaychVoucherCreate(ctx, channel, abi.NewTokenAmount(1000), lane)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if vouch1.Voucher == nil {
|
|
||||||
t.Fatal(fmt.Errorf("Not enough funds to create voucher: missing %d", vouch1.Shortfall))
|
|
||||||
}
|
|
||||||
vouch2, err := paymentCreator.PaychVoucherCreate(ctx, channel, abi.NewTokenAmount(2000), lane)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if vouch2.Voucher == nil {
|
|
||||||
t.Fatal(fmt.Errorf("Not enough funds to create voucher: missing %d", vouch2.Shortfall))
|
|
||||||
}
|
|
||||||
delta1, err := paymentReceiver.PaychVoucherAdd(ctx, channel, vouch1.Voucher, nil, abi.NewTokenAmount(1000))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if !delta1.Equals(abi.NewTokenAmount(1000)) {
|
|
||||||
t.Fatal("voucher didn't have the right amount")
|
|
||||||
}
|
|
||||||
delta2, err := paymentReceiver.PaychVoucherAdd(ctx, channel, vouch2.Voucher, nil, abi.NewTokenAmount(1000))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if !delta2.Equals(abi.NewTokenAmount(1000)) {
|
|
||||||
t.Fatal("voucher didn't have the right amount")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// settle the payment channel
|
|
||||||
settleMsgCid, err := paymentCreator.PaychSettle(ctx, channel)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
res := waitForMessage(ctx, t, paymentCreator, settleMsgCid, time.Second*10, "settle")
|
|
||||||
if res.Receipt.ExitCode != 0 {
|
|
||||||
t.Fatal("Unable to settle payment channel")
|
|
||||||
}
|
|
||||||
|
|
||||||
creatorStore := adt.WrapStore(ctx, cbor.NewCborStore(apibstore.NewAPIBlockstore(paymentCreator)))
|
|
||||||
|
|
||||||
// wait for the receiver to submit their vouchers
|
|
||||||
ev := events.NewEvents(ctx, paymentCreator)
|
|
||||||
preds := state.NewStatePredicates(paymentCreator)
|
|
||||||
finished := make(chan struct{})
|
|
||||||
err = ev.StateChanged(func(ts *types.TipSet) (done bool, more bool, err error) {
|
|
||||||
act, err := paymentCreator.StateGetActor(ctx, channel, ts.Key())
|
|
||||||
if err != nil {
|
|
||||||
return false, false, err
|
|
||||||
}
|
|
||||||
state, err := paych.Load(creatorStore, act)
|
|
||||||
if err != nil {
|
|
||||||
return false, false, err
|
|
||||||
}
|
|
||||||
toSend, err := state.ToSend()
|
|
||||||
if err != nil {
|
|
||||||
return false, false, err
|
|
||||||
}
|
|
||||||
if toSend.GreaterThanEqual(abi.NewTokenAmount(6000)) {
|
|
||||||
return true, false, nil
|
|
||||||
}
|
|
||||||
return false, true, nil
|
|
||||||
}, func(oldTs, newTs *types.TipSet, states events.StateChange, curH abi.ChainEpoch) (more bool, err error) {
|
|
||||||
toSendChange := states.(*state.PayChToSendChange)
|
|
||||||
if toSendChange.NewToSend.GreaterThanEqual(abi.NewTokenAmount(6000)) {
|
|
||||||
close(finished)
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
return true, nil
|
|
||||||
}, func(ctx context.Context, ts *types.TipSet) error {
|
|
||||||
return nil
|
|
||||||
}, int(build.MessageConfidence)+1, build.Finality, func(oldTs, newTs *types.TipSet) (bool, events.StateChange, error) {
|
|
||||||
return preds.OnPaymentChannelActorChanged(channel, preds.OnToSendAmountChanges())(ctx, oldTs.Key(), newTs.Key())
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-finished:
|
|
||||||
case <-time.After(time.Second):
|
|
||||||
t.Fatal("Timed out waiting for receiver to submit vouchers")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a new voucher now that some vouchers have already been submitted
|
|
||||||
vouchRes, err := paymentCreator.PaychVoucherCreate(ctx, channel, abi.NewTokenAmount(1000), 3)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if vouchRes.Voucher == nil {
|
|
||||||
t.Fatal(fmt.Errorf("Not enough funds to create voucher: missing %d", vouchRes.Shortfall))
|
|
||||||
}
|
|
||||||
vdelta, err := paymentReceiver.PaychVoucherAdd(ctx, channel, vouchRes.Voucher, nil, abi.NewTokenAmount(1000))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if !vdelta.Equals(abi.NewTokenAmount(1000)) {
|
|
||||||
t.Fatal("voucher didn't have the right amount")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a new voucher whose value would exceed the channel balance
|
|
||||||
excessAmt := abi.NewTokenAmount(1000)
|
|
||||||
vouchRes, err = paymentCreator.PaychVoucherCreate(ctx, channel, excessAmt, 4)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if vouchRes.Voucher != nil {
|
|
||||||
t.Fatal("Expected not to be able to create voucher whose value would exceed channel balance")
|
|
||||||
}
|
|
||||||
if !vouchRes.Shortfall.Equals(excessAmt) {
|
|
||||||
t.Fatal(fmt.Errorf("Expected voucher shortfall of %d, got %d", excessAmt, vouchRes.Shortfall))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add a voucher whose value would exceed the channel balance
|
|
||||||
vouch := &paych.SignedVoucher{ChannelAddr: channel, Amount: excessAmt, Lane: 4, Nonce: 1}
|
|
||||||
vb, err := vouch.SigningBytes()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
sig, err := paymentCreator.WalletSign(ctx, createrAddr, vb)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
vouch.Signature = sig
|
|
||||||
_, err = paymentReceiver.PaychVoucherAdd(ctx, channel, vouch, nil, abi.NewTokenAmount(1000))
|
|
||||||
if err == nil {
|
|
||||||
t.Fatal(fmt.Errorf("Expected shortfall error of %d", excessAmt))
|
|
||||||
}
|
|
||||||
|
|
||||||
// wait for the settlement period to pass before collecting
|
|
||||||
waitForBlocks(ctx, t, bm, paymentReceiver, receiverAddr, policy.PaychSettleDelay)
|
|
||||||
|
|
||||||
creatorPreCollectBalance, err := paymentCreator.WalletBalance(ctx, createrAddr)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// collect funds (from receiver, though either party can do it)
|
|
||||||
collectMsg, err := paymentReceiver.PaychCollect(ctx, channel)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
res, err = paymentReceiver.StateWaitMsg(ctx, collectMsg, 3)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if res.Receipt.ExitCode != 0 {
|
|
||||||
t.Fatal("unable to collect on payment channel")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finally, check the balance for the creator
|
|
||||||
currentCreatorBalance, err := paymentCreator.WalletBalance(ctx, createrAddr)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The highest nonce voucher that the creator sent on each lane is 2000
|
|
||||||
totalVouchers := int64(len(lanes) * 2000)
|
|
||||||
|
|
||||||
// When receiver submits the tokens to the chain, creator should get a
|
|
||||||
// refund on the remaining balance, which is
|
|
||||||
// channel amount - total voucher value
|
|
||||||
expectedRefund := channelAmt - totalVouchers
|
|
||||||
delta := big.Sub(currentCreatorBalance, creatorPreCollectBalance)
|
|
||||||
if !delta.Equals(abi.NewTokenAmount(expectedRefund)) {
|
|
||||||
t.Fatalf("did not send correct funds from creator: expected %d, got %d", expectedRefund, delta)
|
|
||||||
}
|
|
||||||
|
|
||||||
// shut down mining
|
|
||||||
bm.Stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
func waitForBlocks(ctx context.Context, t *testing.T, bm *BlockMiner, paymentReceiver TestNode, receiverAddr address.Address, count int) {
|
|
||||||
// We need to add null blocks in batches, if we add too many the chain can't sync
|
|
||||||
batchSize := 60
|
|
||||||
for i := 0; i < count; i += batchSize {
|
|
||||||
size := batchSize
|
|
||||||
if i > count {
|
|
||||||
size = count - i
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add a batch of null blocks
|
|
||||||
atomic.StoreInt64(&bm.nulls, int64(size-1))
|
|
||||||
|
|
||||||
// Add a real block
|
|
||||||
m, err := paymentReceiver.MpoolPushMessage(ctx, &types.Message{
|
|
||||||
To: builtin.BurntFundsActorAddr,
|
|
||||||
From: receiverAddr,
|
|
||||||
Value: types.NewInt(0),
|
|
||||||
}, nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = paymentReceiver.StateWaitMsg(ctx, m.Cid(), 1)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func waitForMessage(ctx context.Context, t *testing.T, paymentCreator TestNode, msgCid cid.Cid, duration time.Duration, desc string) *api.MsgLookup {
|
|
||||||
ctx, cancel := context.WithTimeout(ctx, duration)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
fmt.Println("Waiting for", desc)
|
|
||||||
res, err := paymentCreator.StateWaitMsg(ctx, msgCid, 1)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error waiting for", desc, err)
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if res.Receipt.ExitCode != 0 {
|
|
||||||
t.Fatalf("did not successfully send %s", desc)
|
|
||||||
}
|
|
||||||
fmt.Println("Confirmed", desc)
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/filecoin-project/go-state-types/network"
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
|
||||||
"github.com/filecoin-project/lotus/build"
|
|
||||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
|
||||||
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
|
|
||||||
"github.com/filecoin-project/lotus/node"
|
|
||||||
"github.com/filecoin-project/lotus/node/impl"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestTapeFix(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
|
||||||
t.Run("before", func(t *testing.T) { testTapeFix(t, b, blocktime, false) })
|
|
||||||
t.Run("after", func(t *testing.T) { testTapeFix(t, b, blocktime, true) })
|
|
||||||
}
|
|
||||||
func testTapeFix(t *testing.T, b APIBuilder, blocktime time.Duration, after bool) {
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
upgradeSchedule := stmgr.UpgradeSchedule{{
|
|
||||||
Network: build.ActorUpgradeNetworkVersion,
|
|
||||||
Height: 1,
|
|
||||||
Migration: stmgr.UpgradeActorsV2,
|
|
||||||
}}
|
|
||||||
if after {
|
|
||||||
upgradeSchedule = append(upgradeSchedule, stmgr.Upgrade{
|
|
||||||
Network: network.Version5,
|
|
||||||
Height: 2,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
n, sn := b(t, []FullNodeOpts{{Opts: func(_ []TestNode) node.Option {
|
|
||||||
return node.Override(new(stmgr.UpgradeSchedule), upgradeSchedule)
|
|
||||||
}}}, OneMiner)
|
|
||||||
|
|
||||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
|
||||||
miner := sn[0]
|
|
||||||
|
|
||||||
addrinfo, err := client.NetAddrsListen(ctx)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := miner.NetConnect(ctx, addrinfo); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
build.Clock.Sleep(time.Second)
|
|
||||||
|
|
||||||
done := make(chan struct{})
|
|
||||||
go func() {
|
|
||||||
defer close(done)
|
|
||||||
for ctx.Err() == nil {
|
|
||||||
build.Clock.Sleep(blocktime)
|
|
||||||
if err := sn[0].MineOne(ctx, MineNext); err != nil {
|
|
||||||
if ctx.Err() != nil {
|
|
||||||
// context was canceled, ignore the error.
|
|
||||||
return
|
|
||||||
}
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
defer func() {
|
|
||||||
cancel()
|
|
||||||
<-done
|
|
||||||
}()
|
|
||||||
|
|
||||||
err = miner.PledgeSector(ctx)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
// Wait till done.
|
|
||||||
var sectorNo abi.SectorNumber
|
|
||||||
for {
|
|
||||||
s, err := miner.SectorsList(ctx) // Note - the test builder doesn't import genesis sectors into FSM
|
|
||||||
require.NoError(t, err)
|
|
||||||
fmt.Printf("Sectors: %d\n", len(s))
|
|
||||||
if len(s) == 1 {
|
|
||||||
sectorNo = s[0]
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
build.Clock.Sleep(100 * time.Millisecond)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("All sectors is fsm\n")
|
|
||||||
|
|
||||||
// If before, we expect the precommit to fail
|
|
||||||
successState := api.SectorState(sealing.CommitFailed)
|
|
||||||
failureState := api.SectorState(sealing.Proving)
|
|
||||||
if after {
|
|
||||||
// otherwise, it should succeed.
|
|
||||||
successState, failureState = failureState, successState
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
|
||||||
st, err := miner.SectorsStatus(ctx, sectorNo, false)
|
|
||||||
require.NoError(t, err)
|
|
||||||
if st.State == successState {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
require.NotEqual(t, failureState, st.State)
|
|
||||||
build.Clock.Sleep(100 * time.Millisecond)
|
|
||||||
fmt.Println("WaitSeal")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
+6
-123
@@ -2,79 +2,40 @@ package test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
|
|
||||||
logging "github.com/ipfs/go-log/v2"
|
|
||||||
"github.com/multiformats/go-multiaddr"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/filecoin-project/go-state-types/big"
|
|
||||||
"github.com/filecoin-project/go-state-types/network"
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
"github.com/filecoin-project/lotus/miner"
|
|
||||||
"github.com/filecoin-project/lotus/node"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
|
||||||
logging.SetAllLoggers(logging.LevelInfo)
|
|
||||||
err := os.Setenv("BELLMAN_NO_GPU", "1")
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("failed to set BELLMAN_NO_GPU env variable: %s", err))
|
|
||||||
}
|
|
||||||
build.InsecurePoStValidation = true
|
|
||||||
}
|
|
||||||
|
|
||||||
type TestNode struct {
|
type TestNode struct {
|
||||||
api.FullNode
|
api.FullNode
|
||||||
// ListenAddr is the address on which an API server is listening, if an
|
|
||||||
// API server is created for this Node
|
|
||||||
ListenAddr multiaddr.Multiaddr
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type TestStorageNode struct {
|
type TestStorageNode struct {
|
||||||
api.StorageMiner
|
api.StorageMiner
|
||||||
// ListenAddr is the address on which an API server is listening, if an
|
|
||||||
// API server is created for this Node
|
|
||||||
ListenAddr multiaddr.Multiaddr
|
|
||||||
|
|
||||||
MineOne func(context.Context, miner.MineReq) error
|
MineOne func(context.Context, func(bool)) error
|
||||||
}
|
}
|
||||||
|
|
||||||
var PresealGenesis = -1
|
var PresealGenesis = -1
|
||||||
|
|
||||||
const GenesisPreseals = 2
|
const GenesisPreseals = 2
|
||||||
|
|
||||||
// Options for setting up a mock storage miner
|
|
||||||
type StorageMiner struct {
|
type StorageMiner struct {
|
||||||
Full int
|
Full int
|
||||||
Preseal int
|
Preseal int
|
||||||
}
|
}
|
||||||
|
|
||||||
type OptionGenerator func([]TestNode) node.Option
|
|
||||||
|
|
||||||
// Options for setting up a mock full node
|
|
||||||
type FullNodeOpts struct {
|
|
||||||
Lite bool // run node in "lite" mode
|
|
||||||
Opts OptionGenerator // generate dependency injection options
|
|
||||||
}
|
|
||||||
|
|
||||||
// APIBuilder is a function which is invoked in test suite to provide
|
// APIBuilder is a function which is invoked in test suite to provide
|
||||||
// test nodes and networks
|
// test nodes and networks
|
||||||
//
|
//
|
||||||
// fullOpts array defines options for each full node
|
|
||||||
// storage array defines storage nodes, numbers in the array specify full node
|
// storage array defines storage nodes, numbers in the array specify full node
|
||||||
// index the storage node 'belongs' to
|
// index the storage node 'belongs' to
|
||||||
type APIBuilder func(t *testing.T, full []FullNodeOpts, storage []StorageMiner) ([]TestNode, []TestStorageNode)
|
type APIBuilder func(t *testing.T, nFull int, storage []StorageMiner) ([]TestNode, []TestStorageNode)
|
||||||
type testSuite struct {
|
type testSuite struct {
|
||||||
makeNodes APIBuilder
|
makeNodes APIBuilder
|
||||||
}
|
}
|
||||||
@@ -90,48 +51,13 @@ func TestApis(t *testing.T, b APIBuilder) {
|
|||||||
t.Run("testConnectTwo", ts.testConnectTwo)
|
t.Run("testConnectTwo", ts.testConnectTwo)
|
||||||
t.Run("testMining", ts.testMining)
|
t.Run("testMining", ts.testMining)
|
||||||
t.Run("testMiningReal", ts.testMiningReal)
|
t.Run("testMiningReal", ts.testMiningReal)
|
||||||
t.Run("testSearchMsg", ts.testSearchMsg)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func DefaultFullOpts(nFull int) []FullNodeOpts {
|
var oneMiner = []StorageMiner{{Full: 0, Preseal: PresealGenesis}}
|
||||||
full := make([]FullNodeOpts, nFull)
|
|
||||||
for i := range full {
|
|
||||||
full[i] = FullNodeOpts{
|
|
||||||
Opts: func(nodes []TestNode) node.Option {
|
|
||||||
return node.Options()
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return full
|
|
||||||
}
|
|
||||||
|
|
||||||
var OneMiner = []StorageMiner{{Full: 0, Preseal: PresealGenesis}}
|
|
||||||
var OneFull = DefaultFullOpts(1)
|
|
||||||
var TwoFull = DefaultFullOpts(2)
|
|
||||||
|
|
||||||
var FullNodeWithUpgradeAt = func(upgradeHeight abi.ChainEpoch) FullNodeOpts {
|
|
||||||
return FullNodeOpts{
|
|
||||||
Opts: func(nodes []TestNode) node.Option {
|
|
||||||
return node.Override(new(stmgr.UpgradeSchedule), stmgr.UpgradeSchedule{{
|
|
||||||
// Skip directly to tape height so precommits work.
|
|
||||||
Network: network.Version5,
|
|
||||||
Height: upgradeHeight,
|
|
||||||
Migration: stmgr.UpgradeActorsV2,
|
|
||||||
}})
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var MineNext = miner.MineReq{
|
|
||||||
InjectNulls: 0,
|
|
||||||
Done: func(bool, abi.ChainEpoch, error) {},
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ts *testSuite) testVersion(t *testing.T) {
|
func (ts *testSuite) testVersion(t *testing.T) {
|
||||||
build.RunningNodeType = build.NodeFull
|
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
apis, _ := ts.makeNodes(t, OneFull, OneMiner)
|
apis, _ := ts.makeNodes(t, 1, oneMiner)
|
||||||
api := apis[0]
|
api := apis[0]
|
||||||
|
|
||||||
v, err := api.Version(ctx)
|
v, err := api.Version(ctx)
|
||||||
@@ -141,52 +67,9 @@ func (ts *testSuite) testVersion(t *testing.T) {
|
|||||||
require.Equal(t, v.Version, build.BuildVersion)
|
require.Equal(t, v.Version, build.BuildVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ts *testSuite) testSearchMsg(t *testing.T) {
|
|
||||||
apis, miners := ts.makeNodes(t, OneFull, OneMiner)
|
|
||||||
|
|
||||||
api := apis[0]
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
|
||||||
defer cancel()
|
|
||||||
senderAddr, err := api.WalletDefaultAddress(ctx)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
msg := &types.Message{
|
|
||||||
From: senderAddr,
|
|
||||||
To: senderAddr,
|
|
||||||
Value: big.Zero(),
|
|
||||||
}
|
|
||||||
bm := NewBlockMiner(ctx, t, miners[0], 100*time.Millisecond)
|
|
||||||
bm.MineBlocks()
|
|
||||||
defer bm.Stop()
|
|
||||||
|
|
||||||
sm, err := api.MpoolPushMessage(ctx, msg, nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
res, err := api.StateWaitMsg(ctx, sm.Cid(), 1)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if res.Receipt.ExitCode != 0 {
|
|
||||||
t.Fatal("did not successfully send message")
|
|
||||||
}
|
|
||||||
|
|
||||||
searchRes, err := api.StateSearchMsg(ctx, sm.Cid())
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if searchRes.TipSet != res.TipSet {
|
|
||||||
t.Fatalf("search ts: %s, different from wait ts: %s", searchRes.TipSet, res.TipSet)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ts *testSuite) testID(t *testing.T) {
|
func (ts *testSuite) testID(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
apis, _ := ts.makeNodes(t, OneFull, OneMiner)
|
apis, _ := ts.makeNodes(t, 1, oneMiner)
|
||||||
api := apis[0]
|
api := apis[0]
|
||||||
|
|
||||||
id, err := api.ID(ctx)
|
id, err := api.ID(ctx)
|
||||||
@@ -198,7 +81,7 @@ func (ts *testSuite) testID(t *testing.T) {
|
|||||||
|
|
||||||
func (ts *testSuite) testConnectTwo(t *testing.T) {
|
func (ts *testSuite) testConnectTwo(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
apis, _ := ts.makeNodes(t, TwoFull, OneMiner)
|
apis, _ := ts.makeNodes(t, 2, oneMiner)
|
||||||
|
|
||||||
p, err := apis[0].NetPeers(ctx)
|
p, err := apis[0].NetPeers(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -1,86 +0,0 @@
|
|||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
"github.com/filecoin-project/lotus/miner"
|
|
||||||
)
|
|
||||||
|
|
||||||
func SendFunds(ctx context.Context, t *testing.T, sender TestNode, addr address.Address, amount abi.TokenAmount) {
|
|
||||||
senderAddr, err := sender.WalletDefaultAddress(ctx)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
msg := &types.Message{
|
|
||||||
From: senderAddr,
|
|
||||||
To: addr,
|
|
||||||
Value: amount,
|
|
||||||
}
|
|
||||||
|
|
||||||
sm, err := sender.MpoolPushMessage(ctx, msg, nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
res, err := sender.StateWaitMsg(ctx, sm.Cid(), 1)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if res.Receipt.ExitCode != 0 {
|
|
||||||
t.Fatal("did not successfully send money")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func MineUntilBlock(ctx context.Context, t *testing.T, fn TestNode, sn TestStorageNode, cb func(abi.ChainEpoch)) {
|
|
||||||
for i := 0; i < 1000; i++ {
|
|
||||||
var success bool
|
|
||||||
var err error
|
|
||||||
var epoch abi.ChainEpoch
|
|
||||||
wait := make(chan struct{})
|
|
||||||
mineErr := sn.MineOne(ctx, miner.MineReq{
|
|
||||||
Done: func(win bool, ep abi.ChainEpoch, e error) {
|
|
||||||
success = win
|
|
||||||
err = e
|
|
||||||
epoch = ep
|
|
||||||
wait <- struct{}{}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if mineErr != nil {
|
|
||||||
t.Fatal(mineErr)
|
|
||||||
}
|
|
||||||
<-wait
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if success {
|
|
||||||
// Wait until it shows up on the given full nodes ChainHead
|
|
||||||
nloops := 50
|
|
||||||
for i := 0; i < nloops; i++ {
|
|
||||||
ts, err := fn.ChainHead(ctx)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if ts.Height() == epoch {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if i == nloops-1 {
|
|
||||||
t.Fatal("block never managed to sync to node")
|
|
||||||
}
|
|
||||||
time.Sleep(time.Millisecond * 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
if cb != nil {
|
|
||||||
cb(epoch)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
t.Log("did not mine block, trying again", i)
|
|
||||||
}
|
|
||||||
t.Fatal("failed to mine 1000 times in a row...")
|
|
||||||
}
|
|
||||||
+39
-206
@@ -3,31 +3,27 @@ package test
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync/atomic"
|
"github.com/filecoin-project/lotus/api"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
miner2 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/mock"
|
sealing "github.com/filecoin-project/storage-fsm"
|
||||||
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
|
||||||
"github.com/filecoin-project/lotus/build"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
bminer "github.com/filecoin-project/lotus/miner"
|
|
||||||
"github.com/filecoin-project/lotus/node/impl"
|
"github.com/filecoin-project/lotus/node/impl"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPledgeSector(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int) {
|
func TestPledgeSector(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int) {
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
os.Setenv("BELLMAN_NO_GPU", "1")
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
n, sn := b(t, OneFull, OneMiner)
|
ctx := context.Background()
|
||||||
|
n, sn := b(t, 1, oneMiner)
|
||||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||||
miner := sn[0]
|
miner := sn[0]
|
||||||
|
|
||||||
@@ -39,46 +35,41 @@ func TestPledgeSector(t *testing.T, b APIBuilder, blocktime time.Duration, nSect
|
|||||||
if err := miner.NetConnect(ctx, addrinfo); err != nil {
|
if err := miner.NetConnect(ctx, addrinfo); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
build.Clock.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
|
|
||||||
mine := int64(1)
|
mine := true
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
defer close(done)
|
defer close(done)
|
||||||
for atomic.LoadInt64(&mine) != 0 {
|
for mine {
|
||||||
build.Clock.Sleep(blocktime)
|
time.Sleep(blocktime)
|
||||||
if err := sn[0].MineOne(ctx, bminer.MineReq{Done: func(bool, abi.ChainEpoch, error) {
|
if err := sn[0].MineOne(ctx, func(bool) {}); err != nil {
|
||||||
|
|
||||||
}}); err != nil {
|
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
pledgeSectors(t, ctx, miner, nSectors, 0, nil)
|
pledgeSectors(t, ctx, miner, nSectors)
|
||||||
|
|
||||||
atomic.StoreInt64(&mine, 0)
|
mine = false
|
||||||
<-done
|
<-done
|
||||||
}
|
}
|
||||||
|
|
||||||
func pledgeSectors(t *testing.T, ctx context.Context, miner TestStorageNode, n, existing int, blockNotif <-chan struct{}) {
|
func pledgeSectors(t *testing.T, ctx context.Context, miner TestStorageNode, n int) {
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
err := miner.PledgeSector(ctx)
|
err := miner.PledgeSector(ctx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
if i%3 == 0 && blockNotif != nil {
|
|
||||||
<-blockNotif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
s, err := miner.SectorsList(ctx) // Note - the test builder doesn't import genesis sectors into FSM
|
s, err := miner.SectorsList(ctx) // Note - the test builder doesn't import genesis sectors into FSM
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
fmt.Printf("Sectors: %d\n", len(s))
|
fmt.Printf("Sectors: %d\n", len(s))
|
||||||
if len(s) >= n+existing {
|
if len(s) >= n {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
build.Clock.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("All sectors is fsm\n")
|
fmt.Printf("All sectors is fsm\n")
|
||||||
@@ -93,7 +84,7 @@ func pledgeSectors(t *testing.T, ctx context.Context, miner TestStorageNode, n,
|
|||||||
|
|
||||||
for len(toCheck) > 0 {
|
for len(toCheck) > 0 {
|
||||||
for n := range toCheck {
|
for n := range toCheck {
|
||||||
st, err := miner.SectorsStatus(ctx, n, false)
|
st, err := miner.SectorsStatus(ctx, n)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
if st.State == api.SectorState(sealing.Proving) {
|
if st.State == api.SectorState(sealing.Proving) {
|
||||||
delete(toCheck, n)
|
delete(toCheck, n)
|
||||||
@@ -103,31 +94,16 @@ func pledgeSectors(t *testing.T, ctx context.Context, miner TestStorageNode, n,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
build.Clock.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
fmt.Printf("WaitSeal: %d\n", len(s))
|
fmt.Printf("WaitSeal: %d\n", len(s))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int) {
|
func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int) {
|
||||||
for _, height := range []abi.ChainEpoch{
|
os.Setenv("BELLMAN_NO_GPU", "1")
|
||||||
1, // before
|
|
||||||
162, // while sealing
|
|
||||||
5000, // while proving
|
|
||||||
} {
|
|
||||||
height := height // copy to satisfy lints
|
|
||||||
t.Run(fmt.Sprintf("upgrade-%d", height), func(t *testing.T) {
|
|
||||||
testWindowPostUpgrade(t, b, blocktime, nSectors, height)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
func testWindowPostUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int,
|
|
||||||
upgradeHeight abi.ChainEpoch) {
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
n, sn := b(t, []FullNodeOpts{FullNodeWithUpgradeAt(upgradeHeight)}, OneMiner)
|
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
n, sn := b(t, 1, oneMiner)
|
||||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||||
miner := sn[0]
|
miner := sn[0]
|
||||||
|
|
||||||
@@ -139,28 +115,21 @@ func testWindowPostUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration,
|
|||||||
if err := miner.NetConnect(ctx, addrinfo); err != nil {
|
if err := miner.NetConnect(ctx, addrinfo); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
build.Clock.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
|
|
||||||
|
mine := true
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
defer close(done)
|
defer close(done)
|
||||||
for ctx.Err() == nil {
|
for mine {
|
||||||
build.Clock.Sleep(blocktime)
|
time.Sleep(blocktime)
|
||||||
if err := sn[0].MineOne(ctx, MineNext); err != nil {
|
if err := sn[0].MineOne(ctx, func(bool) {}); err != nil {
|
||||||
if ctx.Err() != nil {
|
|
||||||
// context was canceled, ignore the error.
|
|
||||||
return
|
|
||||||
}
|
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
defer func() {
|
|
||||||
cancel()
|
|
||||||
<-done
|
|
||||||
}()
|
|
||||||
|
|
||||||
pledgeSectors(t, ctx, miner, nSectors, 0, nil)
|
pledgeSectors(t, ctx, miner, nSectors)
|
||||||
|
|
||||||
maddr, err := miner.ActorAddress(ctx)
|
maddr, err := miner.ActorAddress(ctx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -168,21 +137,20 @@ func testWindowPostUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration,
|
|||||||
di, err := client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK)
|
di, err := client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
mid, err := address.IDFromAddress(maddr)
|
fmt.Printf("Running one proving periods\n")
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
fmt.Printf("Running one proving period\n")
|
|
||||||
fmt.Printf("End for head.Height > %d\n", di.PeriodStart+di.WPoStProvingPeriod+2)
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
head, err := client.ChainHead(ctx)
|
head, err := client.ChainHead(ctx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
if head.Height() > di.PeriodStart+di.WPoStProvingPeriod+2 {
|
if head.Height() > di.PeriodStart+(miner2.WPoStProvingPeriod)+2 {
|
||||||
fmt.Printf("Now head.Height = %d\n", head.Height())
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
build.Clock.Sleep(blocktime)
|
|
||||||
|
if head.Height()%100 == 0 {
|
||||||
|
fmt.Printf("@%d\n", head.Height())
|
||||||
|
}
|
||||||
|
time.Sleep(blocktime)
|
||||||
}
|
}
|
||||||
|
|
||||||
p, err := client.StateMinerPower(ctx, maddr, types.EmptyTSK)
|
p, err := client.StateMinerPower(ctx, maddr, types.EmptyTSK)
|
||||||
@@ -194,143 +162,8 @@ func testWindowPostUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration,
|
|||||||
require.Equal(t, p.MinerPower, p.TotalPower)
|
require.Equal(t, p.MinerPower, p.TotalPower)
|
||||||
require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz)*uint64(nSectors+GenesisPreseals)))
|
require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz)*uint64(nSectors+GenesisPreseals)))
|
||||||
|
|
||||||
fmt.Printf("Drop some sectors\n")
|
// TODO: Inject faults here
|
||||||
|
|
||||||
// Drop 2 sectors from deadline 2 partition 0 (full partition / deadline)
|
mine = false
|
||||||
{
|
<-done
|
||||||
parts, err := client.StateMinerPartitions(ctx, maddr, 2, types.EmptyTSK)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Greater(t, len(parts), 0)
|
|
||||||
|
|
||||||
secs := parts[0].AllSectors
|
|
||||||
n, err := secs.Count()
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, uint64(2), n)
|
|
||||||
|
|
||||||
// Drop the partition
|
|
||||||
err = secs.ForEach(func(sid uint64) error {
|
|
||||||
return miner.StorageMiner.(*impl.StorageMinerAPI).IStorageMgr.(*mock.SectorMgr).MarkCorrupted(abi.SectorID{
|
|
||||||
Miner: abi.ActorID(mid),
|
|
||||||
Number: abi.SectorNumber(sid),
|
|
||||||
}, true)
|
|
||||||
})
|
|
||||||
require.NoError(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var s abi.SectorID
|
|
||||||
|
|
||||||
// Drop 1 sectors from deadline 3 partition 0
|
|
||||||
{
|
|
||||||
parts, err := client.StateMinerPartitions(ctx, maddr, 3, types.EmptyTSK)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Greater(t, len(parts), 0)
|
|
||||||
|
|
||||||
secs := parts[0].AllSectors
|
|
||||||
n, err := secs.Count()
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, uint64(2), n)
|
|
||||||
|
|
||||||
// Drop the sector
|
|
||||||
sn, err := secs.First()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
all, err := secs.All(2)
|
|
||||||
require.NoError(t, err)
|
|
||||||
fmt.Println("the sectors", all)
|
|
||||||
|
|
||||||
s = abi.SectorID{
|
|
||||||
Miner: abi.ActorID(mid),
|
|
||||||
Number: abi.SectorNumber(sn),
|
|
||||||
}
|
|
||||||
|
|
||||||
err = miner.StorageMiner.(*impl.StorageMinerAPI).IStorageMgr.(*mock.SectorMgr).MarkFailed(s, true)
|
|
||||||
require.NoError(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
di, err = client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
fmt.Printf("Go through another PP, wait for sectors to become faulty\n")
|
|
||||||
fmt.Printf("End for head.Height > %d\n", di.PeriodStart+di.WPoStProvingPeriod+2)
|
|
||||||
|
|
||||||
for {
|
|
||||||
head, err := client.ChainHead(ctx)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
if head.Height() > di.PeriodStart+(di.WPoStProvingPeriod)+2 {
|
|
||||||
fmt.Printf("Now head.Height = %d\n", head.Height())
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
build.Clock.Sleep(blocktime)
|
|
||||||
}
|
|
||||||
|
|
||||||
p, err = client.StateMinerPower(ctx, maddr, types.EmptyTSK)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
require.Equal(t, p.MinerPower, p.TotalPower)
|
|
||||||
|
|
||||||
sectors := p.MinerPower.RawBytePower.Uint64() / uint64(ssz)
|
|
||||||
require.Equal(t, nSectors+GenesisPreseals-3, int(sectors)) // -3 just removed sectors
|
|
||||||
|
|
||||||
fmt.Printf("Recover one sector\n")
|
|
||||||
|
|
||||||
err = miner.StorageMiner.(*impl.StorageMinerAPI).IStorageMgr.(*mock.SectorMgr).MarkFailed(s, false)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
di, err = client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
fmt.Printf("End for head.Height > %d\n", di.PeriodStart+di.WPoStProvingPeriod+2)
|
|
||||||
|
|
||||||
for {
|
|
||||||
head, err := client.ChainHead(ctx)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
if head.Height() > di.PeriodStart+di.WPoStProvingPeriod+2 {
|
|
||||||
fmt.Printf("Now head.Height = %d\n", head.Height())
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
build.Clock.Sleep(blocktime)
|
|
||||||
}
|
|
||||||
|
|
||||||
p, err = client.StateMinerPower(ctx, maddr, types.EmptyTSK)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
require.Equal(t, p.MinerPower, p.TotalPower)
|
|
||||||
|
|
||||||
sectors = p.MinerPower.RawBytePower.Uint64() / uint64(ssz)
|
|
||||||
require.Equal(t, nSectors+GenesisPreseals-2, int(sectors)) // -2 not recovered sectors
|
|
||||||
|
|
||||||
// pledge a sector after recovery
|
|
||||||
|
|
||||||
pledgeSectors(t, ctx, miner, 1, nSectors, nil)
|
|
||||||
|
|
||||||
{
|
|
||||||
// Wait until proven.
|
|
||||||
di, err = client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
waitUntil := di.PeriodStart + di.WPoStProvingPeriod + 2
|
|
||||||
fmt.Printf("End for head.Height > %d\n", waitUntil)
|
|
||||||
|
|
||||||
for {
|
|
||||||
head, err := client.ChainHead(ctx)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
if head.Height() > waitUntil {
|
|
||||||
fmt.Printf("Now head.Height = %d\n", head.Height())
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p, err = client.StateMinerPower(ctx, maddr, types.EmptyTSK)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
require.Equal(t, p.MinerPower, p.TotalPower)
|
|
||||||
|
|
||||||
sectors = p.MinerPower.RawBytePower.Uint64() / uint64(ssz)
|
|
||||||
require.Equal(t, nSectors+GenesisPreseals-2+1, int(sectors)) // -2 not recovered sectors + 1 just pledged
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-69
@@ -2,15 +2,8 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
datatransfer "github.com/filecoin-project/go-data-transfer"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/filecoin-project/lotus/build"
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
|
|
||||||
"github.com/libp2p/go-libp2p-core/peer"
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
|
||||||
ma "github.com/multiformats/go-multiaddr"
|
ma "github.com/multiformats/go-multiaddr"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -44,66 +37,5 @@ type ObjStat struct {
|
|||||||
|
|
||||||
type PubsubScore struct {
|
type PubsubScore struct {
|
||||||
ID peer.ID
|
ID peer.ID
|
||||||
Score *pubsub.PeerScoreSnapshot
|
Score float64
|
||||||
}
|
|
||||||
|
|
||||||
type MessageSendSpec struct {
|
|
||||||
MaxFee abi.TokenAmount
|
|
||||||
}
|
|
||||||
|
|
||||||
var DefaultMessageSendSpec = MessageSendSpec{
|
|
||||||
// MaxFee of 0.1FIL
|
|
||||||
MaxFee: abi.NewTokenAmount(int64(build.FilecoinPrecision) / 10),
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ms *MessageSendSpec) Get() MessageSendSpec {
|
|
||||||
if ms == nil {
|
|
||||||
return DefaultMessageSendSpec
|
|
||||||
}
|
|
||||||
|
|
||||||
return *ms
|
|
||||||
}
|
|
||||||
|
|
||||||
type DataTransferChannel struct {
|
|
||||||
TransferID datatransfer.TransferID
|
|
||||||
Status datatransfer.Status
|
|
||||||
BaseCID cid.Cid
|
|
||||||
IsInitiator bool
|
|
||||||
IsSender bool
|
|
||||||
Voucher string
|
|
||||||
Message string
|
|
||||||
OtherPeer peer.ID
|
|
||||||
Transferred uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewDataTransferChannel constructs an API DataTransferChannel type from full channel state snapshot and a host id
|
|
||||||
func NewDataTransferChannel(hostID peer.ID, channelState datatransfer.ChannelState) DataTransferChannel {
|
|
||||||
channel := DataTransferChannel{
|
|
||||||
TransferID: channelState.TransferID(),
|
|
||||||
Status: channelState.Status(),
|
|
||||||
BaseCID: channelState.BaseCID(),
|
|
||||||
IsSender: channelState.Sender() == hostID,
|
|
||||||
Message: channelState.Message(),
|
|
||||||
}
|
|
||||||
stringer, ok := channelState.Voucher().(fmt.Stringer)
|
|
||||||
if ok {
|
|
||||||
channel.Voucher = stringer.String()
|
|
||||||
} else {
|
|
||||||
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 {
|
|
||||||
channel.IsInitiator = !channelState.IsPull()
|
|
||||||
channel.Transferred = channelState.Sent()
|
|
||||||
channel.OtherPeer = channelState.Recipient()
|
|
||||||
} else {
|
|
||||||
channel.IsInitiator = channelState.IsPull()
|
|
||||||
channel.Transferred = channelState.Received()
|
|
||||||
channel.OtherPeer = channelState.Sender()
|
|
||||||
}
|
|
||||||
return channel
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-state-types/crypto"
|
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SignFunc = func(context.Context, []byte) (*crypto.Signature, error)
|
type SignFunc = func(context.Context, []byte) (*crypto.Signature, error)
|
||||||
|
|||||||
+9
-4
@@ -13,10 +13,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func BuiltinBootstrap() ([]peer.AddrInfo, error) {
|
func BuiltinBootstrap() ([]peer.AddrInfo, error) {
|
||||||
if DisableBuiltinAssets {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var out []peer.AddrInfo
|
var out []peer.AddrInfo
|
||||||
|
|
||||||
b := rice.MustFindBox("bootstrap")
|
b := rice.MustFindBox("bootstrap")
|
||||||
@@ -38,3 +34,12 @@ func BuiltinBootstrap() ([]peer.AddrInfo, error) {
|
|||||||
})
|
})
|
||||||
return out, err
|
return out, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DrandBootstrap() ([]peer.AddrInfo, error) {
|
||||||
|
addrs := []string{
|
||||||
|
"/dnsaddr/pl-eu.testnet.drand.sh/",
|
||||||
|
"/dnsaddr/pl-us.testnet.drand.sh/",
|
||||||
|
"/dnsaddr/pl-sin.testnet.drand.sh/",
|
||||||
|
}
|
||||||
|
return addrutil.ParseAddresses(context.TODO(), addrs)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,15 +1,6 @@
|
|||||||
/dns4/bootstrap-0.mainnet.filops.net/tcp/1347/p2p/12D3KooWCVe8MmsEMes2FzgTpt9fXtmCY7wrq91GRiaC8PHSCCBj
|
/dns4/t01000.miner.interopnet.kittyhawk.wtf/tcp/1347/p2p/12D3KooWLVgeFhXA7ztuSS1uvk4NVzZwRZLxg8PBy1mJuHfc8J6E
|
||||||
/dns4/bootstrap-1.mainnet.filops.net/tcp/1347/p2p/12D3KooWCwevHg1yLCvktf2nvLu7L9894mcrJR4MsBCcm4syShVc
|
/ip4/34.217.110.132/tcp/1347/p2p/12D3KooWLVgeFhXA7ztuSS1uvk4NVzZwRZLxg8PBy1mJuHfc8J6E
|
||||||
/dns4/bootstrap-2.mainnet.filops.net/tcp/1347/p2p/12D3KooWEWVwHGn2yR36gKLozmb4YjDJGerotAPGxmdWZx2nxMC4
|
/dns4/peer0.interopnet.kittyhawk.wtf/tcp/1347/p2p/12D3KooWBkXWpT1hLHXz7VzR8ZHCJ42P6c9Nb9532ATSguBpLTKJ
|
||||||
/dns4/bootstrap-3.mainnet.filops.net/tcp/1347/p2p/12D3KooWKhgq8c7NQ9iGjbyK7v7phXvG6492HQfiDaGHLHLQjk7R
|
/ip4/54.187.182.170/tcp/1347/p2p/12D3KooWBkXWpT1hLHXz7VzR8ZHCJ42P6c9Nb9532ATSguBpLTKJ
|
||||||
/dns4/bootstrap-4.mainnet.filops.net/tcp/1347/p2p/12D3KooWL6PsFNPhYftrJzGgF5U18hFoaVhfGk7xwzD8yVrHJ3Uc
|
/dns4/peer1.interopnet.kittyhawk.wtf/tcp/1347/p2p/12D3KooWJk5hQHNdCsidtX4jhKQMBXKJdo2kjhrNHUZBPmCZKwKt
|
||||||
/dns4/bootstrap-5.mainnet.filops.net/tcp/1347/p2p/12D3KooWLFynvDQiUpXoHroV1YxKHhPJgysQGH2k3ZGwtWzR4dFH
|
/ip4/52.24.84.39/tcp/1347/p2p/12D3KooWJk5hQHNdCsidtX4jhKQMBXKJdo2kjhrNHUZBPmCZKwKt
|
||||||
/dns4/bootstrap-6.mainnet.filops.net/tcp/1347/p2p/12D3KooWP5MwCiqdMETF9ub1P3MbCvQCcfconnYHbWg6sUJcDRQQ
|
|
||||||
/dns4/bootstrap-7.mainnet.filops.net/tcp/1347/p2p/12D3KooWRs3aY1p3juFjPy8gPN95PEQChm2QKGUCAdcDCC4EBMKf
|
|
||||||
/dns4/bootstrap-8.mainnet.filops.net/tcp/1347/p2p/12D3KooWScFR7385LTyR4zU1bYdzSiiAb5rnNABfVahPvVSzyTkR
|
|
||||||
/dns4/lotus-bootstrap.forceup.cn/tcp/41778/p2p/12D3KooWFQsv3nRMUevZNWWsY1Wu6NUzUbawnWU5NcRhgKuJA37C
|
|
||||||
/dns4/bootstrap-0.starpool.in/tcp/12757/p2p/12D3KooWGHpBMeZbestVEWkfdnC9u7p6uFHXL1n7m1ZBqsEmiUzz
|
|
||||||
/dns4/bootstrap-1.starpool.in/tcp/12757/p2p/12D3KooWQZrGH1PxSNZPum99M1zNvjNFM33d1AAu5DcvdHptuU7u
|
|
||||||
/dns4/node.glif.io/tcp/1235/p2p/12D3KooWBF8cpp65hp2u9LK5mh19x67ftAam84z9LsfaquTDSBpt
|
|
||||||
/dns4/bootstrap-0.ipfsmain.cn/tcp/34721/p2p/12D3KooWQnwEGNqcM2nAcPtRR9rAX8Hrg4k9kJLCHoTR5chJfz6d
|
|
||||||
/dns4/bootstrap-1.ipfsmain.cn/tcp/34723/p2p/12D3KooWMKxMkD5DMpSWsW7dBddKxKT7L2GgbNuckz9otxvkvByP
|
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
package build
|
|
||||||
|
|
||||||
import "github.com/raulk/clock"
|
|
||||||
|
|
||||||
// Clock is the global clock for the system. In standard builds,
|
|
||||||
// we use a real-time clock, which maps to the `time` package.
|
|
||||||
//
|
|
||||||
// Tests that need control of time can replace this variable with
|
|
||||||
// clock.NewMock(). Always use real time for socket/stream deadlines.
|
|
||||||
var Clock = clock.New()
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
package build
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sort"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
|
||||||
)
|
|
||||||
|
|
||||||
type DrandEnum int
|
|
||||||
|
|
||||||
func DrandConfigSchedule() dtypes.DrandSchedule {
|
|
||||||
out := dtypes.DrandSchedule{}
|
|
||||||
for start, config := range DrandSchedule {
|
|
||||||
out = append(out, dtypes.DrandPoint{Start: start, Config: DrandConfigs[config]})
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Slice(out, func(i, j int) bool {
|
|
||||||
return out[i].Start < out[j].Start
|
|
||||||
})
|
|
||||||
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
DrandMainnet DrandEnum = iota + 1
|
|
||||||
DrandTestnet
|
|
||||||
DrandDevnet
|
|
||||||
DrandLocalnet
|
|
||||||
DrandIncentinet
|
|
||||||
)
|
|
||||||
|
|
||||||
var DrandConfigs = map[DrandEnum]dtypes.DrandConfig{
|
|
||||||
DrandMainnet: {
|
|
||||||
Servers: []string{
|
|
||||||
"https://api.drand.sh",
|
|
||||||
"https://api2.drand.sh",
|
|
||||||
"https://api3.drand.sh",
|
|
||||||
"https://drand.cloudflare.com",
|
|
||||||
},
|
|
||||||
Relays: []string{
|
|
||||||
"/dnsaddr/api.drand.sh/",
|
|
||||||
"/dnsaddr/api2.drand.sh/",
|
|
||||||
"/dnsaddr/api3.drand.sh/",
|
|
||||||
},
|
|
||||||
ChainInfoJSON: `{"public_key":"868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31","period":30,"genesis_time":1595431050,"hash":"8990e7a9aaed2ffed73dbd7092123d6f289930540d7651336225dc172e51b2ce","groupHash":"176f93498eac9ca337150b46d21dd58673ea4e3581185f869672e59fa4cb390a"}`,
|
|
||||||
},
|
|
||||||
DrandTestnet: {
|
|
||||||
Servers: []string{
|
|
||||||
"https://pl-eu.testnet.drand.sh",
|
|
||||||
"https://pl-us.testnet.drand.sh",
|
|
||||||
"https://pl-sin.testnet.drand.sh",
|
|
||||||
},
|
|
||||||
Relays: []string{
|
|
||||||
"/dnsaddr/pl-eu.testnet.drand.sh/",
|
|
||||||
"/dnsaddr/pl-us.testnet.drand.sh/",
|
|
||||||
"/dnsaddr/pl-sin.testnet.drand.sh/",
|
|
||||||
},
|
|
||||||
ChainInfoJSON: `{"public_key":"922a2e93828ff83345bae533f5172669a26c02dc76d6bf59c80892e12ab1455c229211886f35bb56af6d5bea981024df","period":25,"genesis_time":1590445175,"hash":"84b2234fb34e835dccd048255d7ad3194b81af7d978c3bf157e3469592ae4e02","groupHash":"4dd408e5fdff9323c76a9b6f087ba8fdc5a6da907bd9217d9d10f2287d081957"}`,
|
|
||||||
},
|
|
||||||
DrandDevnet: {
|
|
||||||
Servers: []string{
|
|
||||||
"https://dev1.drand.sh",
|
|
||||||
"https://dev2.drand.sh",
|
|
||||||
},
|
|
||||||
Relays: []string{
|
|
||||||
"/dnsaddr/dev1.drand.sh/",
|
|
||||||
"/dnsaddr/dev2.drand.sh/",
|
|
||||||
},
|
|
||||||
ChainInfoJSON: `{"public_key":"8cda589f88914aa728fd183f383980b35789ce81b274e5daee1f338b77d02566ef4d3fb0098af1f844f10f9c803c1827","period":25,"genesis_time":1595348225,"hash":"e73b7dc3c4f6a236378220c0dd6aa110eb16eed26c11259606e07ee122838d4f","groupHash":"567d4785122a5a3e75a9bc9911d7ea807dd85ff76b78dc4ff06b075712898607"}`,
|
|
||||||
},
|
|
||||||
DrandIncentinet: {
|
|
||||||
ChainInfoJSON: `{"public_key":"8cad0c72c606ab27d36ee06de1d5b2db1faf92e447025ca37575ab3a8aac2eaae83192f846fc9e158bc738423753d000","period":30,"genesis_time":1595873820,"hash":"80c8b872c714f4c00fdd3daa465d5514049f457f01f85a4caf68cdcd394ba039","groupHash":"d9406aaed487f7af71851b4399448e311f2328923d454e971536c05398ce2d9b"}`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
package build
|
|
||||||
|
|
||||||
// DisableBuiltinAssets disables the resolution of go.rice boxes that store
|
|
||||||
// built-in assets, such as proof parameters, bootstrap peers, genesis blocks,
|
|
||||||
// etc.
|
|
||||||
//
|
|
||||||
// When this value is set to true, it is expected that the user will
|
|
||||||
// provide any such configurations through the Lotus API itself.
|
|
||||||
//
|
|
||||||
// This is useful when you're using Lotus as a library, such as to orchestrate
|
|
||||||
// test scenarios, or for other purposes where you don't need to use the
|
|
||||||
// defaults shipped with the binary.
|
|
||||||
//
|
|
||||||
// For this flag to be effective, it must be enabled _before_ instantiating Lotus.
|
|
||||||
var DisableBuiltinAssets = false
|
|
||||||
Binary file not shown.
+12
-33
@@ -3,46 +3,27 @@
|
|||||||
package build
|
package build
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
"os"
|
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||||
)
|
)
|
||||||
|
|
||||||
const UpgradeBreezeHeight = -1
|
|
||||||
const BreezeGasTampingDuration = 0
|
|
||||||
|
|
||||||
const UpgradeSmokeHeight = -1
|
|
||||||
const UpgradeIgnitionHeight = -2
|
|
||||||
const UpgradeRefuelHeight = -3
|
|
||||||
const UpgradeTapeHeight = -4
|
|
||||||
|
|
||||||
var UpgradeActorsV2Height = abi.ChainEpoch(10)
|
|
||||||
var UpgradeLiftoffHeight = abi.ChainEpoch(-5)
|
|
||||||
|
|
||||||
const UpgradeKumquatHeight = 15
|
|
||||||
|
|
||||||
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
|
||||||
0: DrandMainnet,
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
|
power.ConsensusMinerMinPower = big.NewInt(2048)
|
||||||
policy.SetConsensusMinerMinPower(abi.NewStoragePower(2048))
|
miner.SupportedProofTypes = map[abi.RegisteredProof]struct{}{
|
||||||
policy.SetMinVerifiedDealSize(abi.NewStoragePower(256))
|
abi.RegisteredProof_StackedDRG2KiBSeal: {},
|
||||||
|
|
||||||
if os.Getenv("LOTUS_DISABLE_V2_ACTOR_MIGRATION") == "1" {
|
|
||||||
UpgradeActorsV2Height = math.MaxInt64
|
|
||||||
UpgradeLiftoffHeight = 11
|
|
||||||
}
|
}
|
||||||
|
verifreg.MinVerifiedDealSize = big.NewInt(256)
|
||||||
|
|
||||||
BuildType |= Build2k
|
BuildType |= Build2k
|
||||||
}
|
}
|
||||||
|
|
||||||
const BlockDelaySecs = uint64(4)
|
// Seconds
|
||||||
|
const BlockDelay = 2
|
||||||
|
|
||||||
const PropagationDelaySecs = uint64(1)
|
const PropagationDelay = 3
|
||||||
|
|
||||||
// SlashablePowerDelay is the number of epochs after ElectionPeriodStart, after
|
// SlashablePowerDelay is the number of epochs after ElectionPeriodStart, after
|
||||||
// which the miner is slashed
|
// which the miner is slashed
|
||||||
@@ -52,5 +33,3 @@ const SlashablePowerDelay = 20
|
|||||||
|
|
||||||
// Epochs
|
// Epochs
|
||||||
const InteractivePoRepConfidence = 6
|
const InteractivePoRepConfidence = 6
|
||||||
|
|
||||||
const BootstrapPeerThreshold = 1
|
|
||||||
|
|||||||
@@ -1,63 +0,0 @@
|
|||||||
// +build !debug
|
|
||||||
// +build !2k
|
|
||||||
// +build !testground
|
|
||||||
|
|
||||||
package build
|
|
||||||
|
|
||||||
import (
|
|
||||||
"math"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
|
||||||
)
|
|
||||||
|
|
||||||
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
|
||||||
0: DrandIncentinet,
|
|
||||||
UpgradeSmokeHeight: DrandMainnet,
|
|
||||||
}
|
|
||||||
|
|
||||||
const UpgradeBreezeHeight = 41280
|
|
||||||
const BreezeGasTampingDuration = 120
|
|
||||||
|
|
||||||
const UpgradeSmokeHeight = 51000
|
|
||||||
|
|
||||||
const UpgradeIgnitionHeight = 94000
|
|
||||||
const UpgradeRefuelHeight = 130800
|
|
||||||
|
|
||||||
var UpgradeActorsV2Height = abi.ChainEpoch(138720)
|
|
||||||
|
|
||||||
const UpgradeTapeHeight = 140760
|
|
||||||
|
|
||||||
// This signals our tentative epoch for mainnet launch. Can make it later, but not earlier.
|
|
||||||
// Miners, clients, developers, custodians all need time to prepare.
|
|
||||||
// We still have upgrades and state changes to do, but can happen after signaling timing here.
|
|
||||||
const UpgradeLiftoffHeight = 148888
|
|
||||||
|
|
||||||
const UpgradeKumquatHeight = 170000
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
policy.SetConsensusMinerMinPower(abi.NewStoragePower(10 << 40))
|
|
||||||
policy.SetSupportedProofTypes(
|
|
||||||
abi.RegisteredSealProof_StackedDrg32GiBV1,
|
|
||||||
abi.RegisteredSealProof_StackedDrg64GiBV1,
|
|
||||||
)
|
|
||||||
|
|
||||||
if os.Getenv("LOTUS_USE_TEST_ADDRESSES") != "1" {
|
|
||||||
SetAddressNetwork(address.Mainnet)
|
|
||||||
}
|
|
||||||
|
|
||||||
if os.Getenv("LOTUS_DISABLE_V2_ACTOR_MIGRATION") == "1" {
|
|
||||||
UpgradeActorsV2Height = math.MaxInt64
|
|
||||||
}
|
|
||||||
|
|
||||||
Devnet = false
|
|
||||||
}
|
|
||||||
|
|
||||||
const BlockDelaySecs = uint64(builtin2.EpochDurationSeconds)
|
|
||||||
|
|
||||||
const PropagationDelaySecs = uint64(6)
|
|
||||||
|
|
||||||
const BootstrapPeerThreshold = 4
|
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
package build
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
"github.com/libp2p/go-libp2p-core/protocol"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
|
)
|
||||||
|
|
||||||
|
func DefaultSectorSize() abi.SectorSize {
|
||||||
|
szs := make([]abi.SectorSize, 0, len(miner.SupportedProofTypes))
|
||||||
|
for spt := range miner.SupportedProofTypes {
|
||||||
|
ss, err := spt.SectorSize()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
szs = append(szs, ss)
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Slice(szs, func(i, j int) bool {
|
||||||
|
return szs[i] < szs[j]
|
||||||
|
})
|
||||||
|
|
||||||
|
return szs[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Core network constants
|
||||||
|
|
||||||
|
func BlocksTopic(netName dtypes.NetworkName) string { return "/fil/blocks/" + string(netName) }
|
||||||
|
func MessagesTopic(netName dtypes.NetworkName) string { return "/fil/msgs/" + string(netName) }
|
||||||
|
func DhtProtocolName(netName dtypes.NetworkName) protocol.ID {
|
||||||
|
return protocol.ID("/fil/kad/" + string(netName))
|
||||||
|
}
|
||||||
|
|
||||||
|
// /////
|
||||||
|
// Storage
|
||||||
|
|
||||||
|
const UnixfsChunkSize uint64 = 1 << 20
|
||||||
|
const UnixfsLinksPerLevel = 1024
|
||||||
|
|
||||||
|
// /////
|
||||||
|
// Consensus / Network
|
||||||
|
|
||||||
|
// Seconds
|
||||||
|
const AllowableClockDrift = 1
|
||||||
|
|
||||||
|
// Epochs
|
||||||
|
const ForkLengthThreshold = Finality
|
||||||
|
|
||||||
|
// Blocks (e)
|
||||||
|
var BlocksPerEpoch = uint64(builtin.ExpectedLeadersPerEpoch)
|
||||||
|
|
||||||
|
// Epochs
|
||||||
|
const Finality = miner.ChainFinalityish
|
||||||
|
const MessageConfidence = 5
|
||||||
|
|
||||||
|
// constants for Weight calculation
|
||||||
|
// The ratio of weight contributed by short-term vs long-term factors in a given round
|
||||||
|
const WRatioNum = int64(1)
|
||||||
|
const WRatioDen = 2
|
||||||
|
|
||||||
|
// /////
|
||||||
|
// Proofs
|
||||||
|
|
||||||
|
// Epochs
|
||||||
|
const SealRandomnessLookback = Finality
|
||||||
|
|
||||||
|
// Epochs
|
||||||
|
const SealRandomnessLookbackLimit = SealRandomnessLookback + 2000 // TODO: Get from spec specs-actors
|
||||||
|
|
||||||
|
// Maximum lookback that randomness can be sourced from for a seal proof submission
|
||||||
|
const MaxSealLookback = SealRandomnessLookbackLimit + 2000 // TODO: Get from specs-actors
|
||||||
|
|
||||||
|
// /////
|
||||||
|
// Mining
|
||||||
|
|
||||||
|
// Epochs
|
||||||
|
const TicketRandomnessLookback = 1
|
||||||
|
|
||||||
|
const WinningPoStSectorSetLookback = 10
|
||||||
|
|
||||||
|
// /////
|
||||||
|
// Devnet settings
|
||||||
|
|
||||||
|
const TotalFilecoin = 2_000_000_000
|
||||||
|
const MiningRewardTotal = 1_400_000_000
|
||||||
|
|
||||||
|
const FilecoinPrecision = 1_000_000_000_000_000_000
|
||||||
|
|
||||||
|
var InitialRewardBalance *big.Int
|
||||||
|
|
||||||
|
// TODO: Move other important consts here
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
InitialRewardBalance = big.NewInt(MiningRewardTotal)
|
||||||
|
InitialRewardBalance = InitialRewardBalance.Mul(InitialRewardBalance, big.NewInt(FilecoinPrecision))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sync
|
||||||
|
const BadBlockCacheSize = 1 << 15
|
||||||
|
|
||||||
|
// assuming 4000 messages per round, this lets us not lose any messages across a
|
||||||
|
// 10 block reorg.
|
||||||
|
const BlsSignatureCacheSize = 40000
|
||||||
|
|
||||||
|
// Size of signature verification cache
|
||||||
|
// 32k keeps the cache around 10MB in size, max
|
||||||
|
const VerifSigCacheSize = 32000
|
||||||
|
|
||||||
|
// ///////
|
||||||
|
// Limits
|
||||||
|
|
||||||
|
// TODO: If this is gonna stay, it should move to specs-actors
|
||||||
|
const BlockMessageLimit = 512
|
||||||
|
const BlockGasLimit = 100_000_000_000
|
||||||
|
|
||||||
|
var DrandChain = `{"public_key":"922a2e93828ff83345bae533f5172669a26c02dc76d6bf59c80892e12ab1455c229211886f35bb56af6d5bea981024df","period":25,"genesis_time":1590445175,"hash":"138a324aa6540f93d0dad002aa89454b1bec2b6e948682cde6bd4db40f4b7c9b"}`
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
package build
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
|
|
||||||
"github.com/libp2p/go-libp2p-core/protocol"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Core network constants
|
|
||||||
|
|
||||||
func BlocksTopic(netName dtypes.NetworkName) string { return "/fil/blocks/" + string(netName) }
|
|
||||||
func MessagesTopic(netName dtypes.NetworkName) string { return "/fil/msgs/" + string(netName) }
|
|
||||||
func DhtProtocolName(netName dtypes.NetworkName) protocol.ID {
|
|
||||||
return protocol.ID("/fil/kad/" + string(netName))
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetAddressNetwork(n address.Network) {
|
|
||||||
address.CurrentNetwork = n
|
|
||||||
}
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
// +build !testground
|
|
||||||
|
|
||||||
package build
|
|
||||||
|
|
||||||
import (
|
|
||||||
"math/big"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/filecoin-project/go-state-types/network"
|
|
||||||
|
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
|
||||||
)
|
|
||||||
|
|
||||||
// /////
|
|
||||||
// Storage
|
|
||||||
|
|
||||||
const UnixfsChunkSize uint64 = 1 << 20
|
|
||||||
const UnixfsLinksPerLevel = 1024
|
|
||||||
|
|
||||||
// /////
|
|
||||||
// Consensus / Network
|
|
||||||
|
|
||||||
const AllowableClockDriftSecs = uint64(1)
|
|
||||||
const NewestNetworkVersion = network.Version6
|
|
||||||
const ActorUpgradeNetworkVersion = network.Version4
|
|
||||||
|
|
||||||
// Epochs
|
|
||||||
const ForkLengthThreshold = Finality
|
|
||||||
|
|
||||||
// Blocks (e)
|
|
||||||
var BlocksPerEpoch = uint64(builtin2.ExpectedLeadersPerEpoch)
|
|
||||||
|
|
||||||
// Epochs
|
|
||||||
const Finality = policy.ChainFinality
|
|
||||||
const MessageConfidence = uint64(5)
|
|
||||||
|
|
||||||
// constants for Weight calculation
|
|
||||||
// The ratio of weight contributed by short-term vs long-term factors in a given round
|
|
||||||
const WRatioNum = int64(1)
|
|
||||||
const WRatioDen = uint64(2)
|
|
||||||
|
|
||||||
// /////
|
|
||||||
// Proofs
|
|
||||||
|
|
||||||
// Epochs
|
|
||||||
// TODO: unused
|
|
||||||
const SealRandomnessLookback = policy.SealRandomnessLookback
|
|
||||||
|
|
||||||
// /////
|
|
||||||
// Mining
|
|
||||||
|
|
||||||
// Epochs
|
|
||||||
const TicketRandomnessLookback = abi.ChainEpoch(1)
|
|
||||||
|
|
||||||
// /////
|
|
||||||
// Address
|
|
||||||
|
|
||||||
const AddressMainnetEnvVar = "_mainnet_"
|
|
||||||
|
|
||||||
// /////
|
|
||||||
// Devnet settings
|
|
||||||
|
|
||||||
var Devnet = true
|
|
||||||
|
|
||||||
const FilBase = uint64(2_000_000_000)
|
|
||||||
const FilAllocStorageMining = uint64(1_100_000_000)
|
|
||||||
|
|
||||||
const FilecoinPrecision = uint64(1_000_000_000_000_000_000)
|
|
||||||
const FilReserved = uint64(300_000_000)
|
|
||||||
|
|
||||||
var InitialRewardBalance *big.Int
|
|
||||||
var InitialFilReserved *big.Int
|
|
||||||
|
|
||||||
// TODO: Move other important consts here
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
InitialRewardBalance = big.NewInt(int64(FilAllocStorageMining))
|
|
||||||
InitialRewardBalance = InitialRewardBalance.Mul(InitialRewardBalance, big.NewInt(int64(FilecoinPrecision)))
|
|
||||||
|
|
||||||
InitialFilReserved = big.NewInt(int64(FilReserved))
|
|
||||||
InitialFilReserved = InitialFilReserved.Mul(InitialFilReserved, big.NewInt(int64(FilecoinPrecision)))
|
|
||||||
|
|
||||||
if os.Getenv("LOTUS_ADDRESS_TYPE") == AddressMainnetEnvVar {
|
|
||||||
SetAddressNetwork(address.Mainnet)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sync
|
|
||||||
const BadBlockCacheSize = 1 << 15
|
|
||||||
|
|
||||||
// assuming 4000 messages per round, this lets us not lose any messages across a
|
|
||||||
// 10 block reorg.
|
|
||||||
const BlsSignatureCacheSize = 40000
|
|
||||||
|
|
||||||
// Size of signature verification cache
|
|
||||||
// 32k keeps the cache around 10MB in size, max
|
|
||||||
const VerifSigCacheSize = 32000
|
|
||||||
|
|
||||||
// ///////
|
|
||||||
// Limits
|
|
||||||
|
|
||||||
// TODO: If this is gonna stay, it should move to specs-actors
|
|
||||||
const BlockMessageLimit = 10000
|
|
||||||
|
|
||||||
const BlockGasLimit = 10_000_000_000
|
|
||||||
const BlockGasTarget = BlockGasLimit / 2
|
|
||||||
const BaseFeeMaxChangeDenom = 8 // 12.5%
|
|
||||||
const InitialBaseFee = 100e6
|
|
||||||
const MinimumBaseFee = 100
|
|
||||||
const PackingEfficiencyNum = 4
|
|
||||||
const PackingEfficiencyDenom = 5
|
|
||||||
|
|
||||||
// Actor consts
|
|
||||||
// TODO: Pull from actors when its made not private
|
|
||||||
var MinDealDuration = abi.ChainEpoch(180 * builtin2.EpochsInDay)
|
|
||||||
@@ -1,102 +0,0 @@
|
|||||||
// +build testground
|
|
||||||
|
|
||||||
// This file makes hardcoded parameters (const) configurable as vars.
|
|
||||||
//
|
|
||||||
// Its purpose is to unlock various degrees of flexibility and parametrization
|
|
||||||
// when writing Testground plans for Lotus.
|
|
||||||
//
|
|
||||||
package build
|
|
||||||
|
|
||||||
import (
|
|
||||||
"math/big"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/filecoin-project/go-state-types/network"
|
|
||||||
|
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
UnixfsChunkSize = uint64(1 << 20)
|
|
||||||
UnixfsLinksPerLevel = 1024
|
|
||||||
|
|
||||||
BlocksPerEpoch = uint64(builtin2.ExpectedLeadersPerEpoch)
|
|
||||||
BlockMessageLimit = 512
|
|
||||||
BlockGasLimit = int64(100_000_000_000)
|
|
||||||
BlockGasTarget = int64(BlockGasLimit / 2)
|
|
||||||
BaseFeeMaxChangeDenom = int64(8) // 12.5%
|
|
||||||
InitialBaseFee = int64(100e6)
|
|
||||||
MinimumBaseFee = int64(100)
|
|
||||||
BlockDelaySecs = uint64(builtin2.EpochDurationSeconds)
|
|
||||||
PropagationDelaySecs = uint64(6)
|
|
||||||
|
|
||||||
AllowableClockDriftSecs = uint64(1)
|
|
||||||
|
|
||||||
Finality = policy.ChainFinality
|
|
||||||
ForkLengthThreshold = Finality
|
|
||||||
|
|
||||||
SlashablePowerDelay = 20
|
|
||||||
InteractivePoRepConfidence = 6
|
|
||||||
|
|
||||||
MessageConfidence uint64 = 5
|
|
||||||
|
|
||||||
WRatioNum = int64(1)
|
|
||||||
WRatioDen = uint64(2)
|
|
||||||
|
|
||||||
BadBlockCacheSize = 1 << 15
|
|
||||||
BlsSignatureCacheSize = 40000
|
|
||||||
VerifSigCacheSize = 32000
|
|
||||||
|
|
||||||
SealRandomnessLookback = policy.SealRandomnessLookback
|
|
||||||
|
|
||||||
TicketRandomnessLookback = abi.ChainEpoch(1)
|
|
||||||
|
|
||||||
FilBase uint64 = 2_000_000_000
|
|
||||||
FilAllocStorageMining uint64 = 1_400_000_000
|
|
||||||
FilReserved uint64 = 300_000_000
|
|
||||||
|
|
||||||
FilecoinPrecision uint64 = 1_000_000_000_000_000_000
|
|
||||||
|
|
||||||
InitialRewardBalance = func() *big.Int {
|
|
||||||
v := big.NewInt(int64(FilAllocStorageMining))
|
|
||||||
v = v.Mul(v, big.NewInt(int64(FilecoinPrecision)))
|
|
||||||
return v
|
|
||||||
}()
|
|
||||||
|
|
||||||
InitialFilReserved = func() *big.Int {
|
|
||||||
v := big.NewInt(int64(FilReserved))
|
|
||||||
v = v.Mul(v, big.NewInt(int64(FilecoinPrecision)))
|
|
||||||
return v
|
|
||||||
}()
|
|
||||||
|
|
||||||
// Actor consts
|
|
||||||
// TODO: Pull from actors when its made not private
|
|
||||||
MinDealDuration = abi.ChainEpoch(180 * builtin2.EpochsInDay)
|
|
||||||
|
|
||||||
PackingEfficiencyNum int64 = 4
|
|
||||||
PackingEfficiencyDenom int64 = 5
|
|
||||||
|
|
||||||
UpgradeBreezeHeight abi.ChainEpoch = -1
|
|
||||||
BreezeGasTampingDuration abi.ChainEpoch = 0
|
|
||||||
|
|
||||||
UpgradeSmokeHeight abi.ChainEpoch = -1
|
|
||||||
UpgradeIgnitionHeight abi.ChainEpoch = -2
|
|
||||||
UpgradeRefuelHeight abi.ChainEpoch = -3
|
|
||||||
UpgradeTapeHeight abi.ChainEpoch = -4
|
|
||||||
UpgradeActorsV2Height abi.ChainEpoch = 10
|
|
||||||
UpgradeLiftoffHeight abi.ChainEpoch = -5
|
|
||||||
UpgradeKumquatHeight abi.ChainEpoch = -6
|
|
||||||
|
|
||||||
DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
|
||||||
0: DrandMainnet,
|
|
||||||
}
|
|
||||||
|
|
||||||
NewestNetworkVersion = network.Version5
|
|
||||||
ActorUpgradeNetworkVersion = network.Version4
|
|
||||||
|
|
||||||
Devnet = true
|
|
||||||
)
|
|
||||||
|
|
||||||
const BootstrapPeerThreshold = 1
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
// +build !debug
|
||||||
|
// +build !2k
|
||||||
|
|
||||||
|
package build
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
power.ConsensusMinerMinPower = big.NewInt(1024 << 20)
|
||||||
|
miner.SupportedProofTypes = map[abi.RegisteredProof]struct{}{
|
||||||
|
abi.RegisteredProof_StackedDRG512MiBSeal: {},
|
||||||
|
abi.RegisteredProof_StackedDRG32GiBSeal: {},
|
||||||
|
abi.RegisteredProof_StackedDRG64GiBSeal: {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seconds
|
||||||
|
const BlockDelay = builtin.EpochDurationSeconds
|
||||||
|
|
||||||
|
const PropagationDelay = 6
|
||||||
@@ -1,152 +1,152 @@
|
|||||||
{
|
{
|
||||||
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0170db1f394b35d995252228ee359194b13199d259380541dc529fb0099096b0.params": {
|
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0170db1f394b35d995252228ee359194b13199d259380541dc529fb0099096b0.params": {
|
||||||
"cid": "QmVxjFRyhmyQaZEtCh7nk2abc7LhFkzhnRX4rcHqCCpikR",
|
"cid": "QmYkygifkXnrnsN4MJsjBFHTQJHx294CyikDgDK8nYxdGh",
|
||||||
"digest": "7610b9f82bfc88405b7a832b651ce2f6",
|
"digest": "df3f30442a6d6b4192f5071fb17e820c",
|
||||||
"sector_size": 2048
|
"sector_size": 2048
|
||||||
},
|
},
|
||||||
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0170db1f394b35d995252228ee359194b13199d259380541dc529fb0099096b0.vk": {
|
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0170db1f394b35d995252228ee359194b13199d259380541dc529fb0099096b0.vk": {
|
||||||
"cid": "QmcS5JZs8X3TdtkEBpHAdUYjdNDqcL7fWQFtQz69mpnu2X",
|
"cid": "QmdXyqbmy2bkJA9Kyhh6z25GrTCq48LwX6c1mxPsm54wi7",
|
||||||
"digest": "0e0958009936b9d5e515ec97b8cb792d",
|
"digest": "0bea3951abf9557a3569f68e52a30c6c",
|
||||||
"sector_size": 2048
|
"sector_size": 2048
|
||||||
},
|
},
|
||||||
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0cfb4f178bbb71cf2ecfcd42accce558b27199ab4fb59cb78f2483fe21ef36d9.params": {
|
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0cfb4f178bbb71cf2ecfcd42accce558b27199ab4fb59cb78f2483fe21ef36d9.params": {
|
||||||
"cid": "QmUiRx71uxfmUE8V3H9sWAsAXoM88KR4eo1ByvvcFNeTLR",
|
"cid": "Qmf5XZZtP5VcYTf65MbKjLVabcS6cYMbr2rFShmfJzh5e5",
|
||||||
"digest": "1a7d4a9c8a502a497ed92a54366af33f",
|
"digest": "655e6277638edc8c658094f6f0b33d54",
|
||||||
"sector_size": 536870912
|
"sector_size": 536870912
|
||||||
},
|
},
|
||||||
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0cfb4f178bbb71cf2ecfcd42accce558b27199ab4fb59cb78f2483fe21ef36d9.vk": {
|
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0cfb4f178bbb71cf2ecfcd42accce558b27199ab4fb59cb78f2483fe21ef36d9.vk": {
|
||||||
"cid": "QmfCeddjFpWtavzfEzZpJfzSajGNwfL4RjFXWAvA9TSnTV",
|
"cid": "QmPuhdWnAXBks43emnkqi9FQzyU1gASKyz23zrD27BPGs8",
|
||||||
"digest": "4dae975de4f011f101f5a2f86d1daaba",
|
"digest": "57690e3a6a94c3f704802a674b34f36b",
|
||||||
"sector_size": 536870912
|
"sector_size": 536870912
|
||||||
},
|
},
|
||||||
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-3ea05428c9d11689f23529cde32fd30aabd50f7d2c93657c1d3650bca3e8ea9e.params": {
|
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-3ea05428c9d11689f23529cde32fd30aabd50f7d2c93657c1d3650bca3e8ea9e.params": {
|
||||||
"cid": "QmcSTqDcFVLGGVYz1njhUZ7B6fkKtBumsLUwx4nkh22TzS",
|
"cid": "QmPNVgTN7N5vDtD5u7ERMTLcvUtrKRBfYVUDr6uW3pKhX7",
|
||||||
"digest": "82c88066be968bb550a05e30ff6c2413",
|
"digest": "3d390654f58e603b896ac70c653f5676",
|
||||||
"sector_size": 2048
|
"sector_size": 2048
|
||||||
},
|
},
|
||||||
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-3ea05428c9d11689f23529cde32fd30aabd50f7d2c93657c1d3650bca3e8ea9e.vk": {
|
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-3ea05428c9d11689f23529cde32fd30aabd50f7d2c93657c1d3650bca3e8ea9e.vk": {
|
||||||
"cid": "QmSTCXF2ipGA3f6muVo6kHc2URSx6PzZxGUqu7uykaH5KU",
|
"cid": "Qmbj61Zez7v5xA7nSCnmWbyLYznWJDWeusz7Yg8EcgVdoN",
|
||||||
"digest": "ffd79788d614d27919ae5bd2d94eacb6",
|
"digest": "8c170a164743c39576a7f47a1b51e6f3",
|
||||||
"sector_size": 2048
|
"sector_size": 2048
|
||||||
},
|
},
|
||||||
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-50c7368dea9593ed0989e70974d28024efa9d156d585b7eea1be22b2e753f331.params": {
|
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-50c7368dea9593ed0989e70974d28024efa9d156d585b7eea1be22b2e753f331.params": {
|
||||||
"cid": "QmU9SBzJNrcjRFDiFc4GcApqdApN6z9X7MpUr66mJ2kAJP",
|
"cid": "QmRApb8RZoBK3cqicT7V3ydXg8yVvqPFMPrQNXP33aBihp",
|
||||||
"digest": "700171ecf7334e3199437c930676af82",
|
"digest": "b1b58ff9a297b82885e8a7dfb035f83c",
|
||||||
"sector_size": 8388608
|
"sector_size": 8388608
|
||||||
},
|
},
|
||||||
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-50c7368dea9593ed0989e70974d28024efa9d156d585b7eea1be22b2e753f331.vk": {
|
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-50c7368dea9593ed0989e70974d28024efa9d156d585b7eea1be22b2e753f331.vk": {
|
||||||
"cid": "QmbmUMa3TbbW3X5kFhExs6WgC4KeWT18YivaVmXDkB6ANG",
|
"cid": "QmcytF1dTdqMFoyXi931j1RgmGtLfR9LLLaBznRt1tPQyD",
|
||||||
"digest": "79ebb55f56fda427743e35053edad8fc",
|
"digest": "1a09e00c641f192f55af3433a028f050",
|
||||||
"sector_size": 8388608
|
"sector_size": 8388608
|
||||||
},
|
},
|
||||||
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-5294475db5237a2e83c3e52fd6c2b03859a1831d45ed08c4f35dbf9a803165a9.params": {
|
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-5294475db5237a2e83c3e52fd6c2b03859a1831d45ed08c4f35dbf9a803165a9.params": {
|
||||||
"cid": "QmdNEL2RtqL52GQNuj8uz6mVj5Z34NVnbaJ1yMyh1oXtBx",
|
"cid": "QmPvr54tWaVeP4WnekivzUAJitTqsQfvikBvAHNEaDNQSw",
|
||||||
"digest": "c49499bb76a0762884896f9683403f55",
|
"digest": "9380e41368ed4083dbc922b290d3b786",
|
||||||
"sector_size": 8388608
|
"sector_size": 8388608
|
||||||
},
|
},
|
||||||
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-5294475db5237a2e83c3e52fd6c2b03859a1831d45ed08c4f35dbf9a803165a9.vk": {
|
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-5294475db5237a2e83c3e52fd6c2b03859a1831d45ed08c4f35dbf9a803165a9.vk": {
|
||||||
"cid": "QmUiVYCQUgr6Y13pZFr8acWpSM4xvTXUdcvGmxyuHbKhsc",
|
"cid": "QmXyVLVDRCcxA9SjT7PeK8HFtyxZ2ZH3SHa8KoGLw8VGJt",
|
||||||
"digest": "34d4feeacd9abf788d69ef1bb4d8fd00",
|
"digest": "f0731a7e20f90704bd38fc5d27882f6d",
|
||||||
"sector_size": 8388608
|
"sector_size": 8388608
|
||||||
},
|
},
|
||||||
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-7d739b8cf60f1b0709eeebee7730e297683552e4b69cab6984ec0285663c5781.params": {
|
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-7d739b8cf60f1b0709eeebee7730e297683552e4b69cab6984ec0285663c5781.params": {
|
||||||
"cid": "QmVgCsJFRXKLuuUhT3aMYwKVGNA9rDeR6DCrs7cAe8riBT",
|
"cid": "Qmf5f6ko3dqj7qauzXpZqxM9B2x2sL977K6gE2ppNwuJPv",
|
||||||
"digest": "827359440349fe8f5a016e7598993b79",
|
"digest": "273ebb8c896326b7c292bee8b775fd38",
|
||||||
"sector_size": 536870912
|
"sector_size": 536870912
|
||||||
},
|
},
|
||||||
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-7d739b8cf60f1b0709eeebee7730e297683552e4b69cab6984ec0285663c5781.vk": {
|
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-7d739b8cf60f1b0709eeebee7730e297683552e4b69cab6984ec0285663c5781.vk": {
|
||||||
"cid": "QmfA31fbCWojSmhSGvvfxmxaYCpMoXP95zEQ9sLvBGHNaN",
|
"cid": "QmfP3MQe8koW63n5MkDENENVHxib78MJYYyZvbneCsuze8",
|
||||||
"digest": "bd2cd62f65c1ab84f19ca27e97b7c731",
|
"digest": "3dd94da9da64e51b3445bc528d84e76d",
|
||||||
"sector_size": 536870912
|
"sector_size": 536870912
|
||||||
},
|
},
|
||||||
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-0377ded656c6f524f1618760bffe4e0a1c51d5a70c4509eedae8a27555733edc.params": {
|
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-0377ded656c6f524f1618760bffe4e0a1c51d5a70c4509eedae8a27555733edc.params": {
|
||||||
"cid": "QmaUmfcJt6pozn8ndq1JVBzLRjRJdHMTPd4foa8iw5sjBZ",
|
"cid": "QmYEeeCE8uT2bsVkxcqqUYeMmMEbe6rfmo8wQCv7jFHqqm",
|
||||||
"digest": "2cf49eb26f1fee94c85781a390ddb4c8",
|
"digest": "c947f2021304ed43b7216f7a8436e294",
|
||||||
"sector_size": 34359738368
|
"sector_size": 34359738368
|
||||||
},
|
},
|
||||||
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-0377ded656c6f524f1618760bffe4e0a1c51d5a70c4509eedae8a27555733edc.vk": {
|
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-0377ded656c6f524f1618760bffe4e0a1c51d5a70c4509eedae8a27555733edc.vk": {
|
||||||
"cid": "QmR9i9KL3vhhAqTBGj1bPPC7LvkptxrH9RvxJxLN1vvsBE",
|
"cid": "QmXB63ExriFjB4ywWnXTnFwCcLFfCeEP3h15qtL5i7F4aX",
|
||||||
"digest": "0f8ec542485568fa3468c066e9fed82b",
|
"digest": "ab20d7b253e7e9a0d2ccdf7599ec8ec3",
|
||||||
"sector_size": 34359738368
|
"sector_size": 34359738368
|
||||||
},
|
},
|
||||||
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-559e581f022bb4e4ec6e719e563bf0e026ad6de42e56c18714a2c692b1b88d7e.params": {
|
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-559e581f022bb4e4ec6e719e563bf0e026ad6de42e56c18714a2c692b1b88d7e.params": {
|
||||||
"cid": "Qmdtczp7p4wrbDofmHdGhiixn9irAcN77mV9AEHZBaTt1i",
|
"cid": "QmW5Yxg3L1NSzuQVcRMHMbG3uvVoi4dTLzVaDpnEUPQpnA",
|
||||||
"digest": "d84f79a16fe40e9e25a36e2107bb1ba0",
|
"digest": "079ba19645828ae42b22b0e3f4866e8d",
|
||||||
"sector_size": 34359738368
|
"sector_size": 34359738368
|
||||||
},
|
},
|
||||||
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-559e581f022bb4e4ec6e719e563bf0e026ad6de42e56c18714a2c692b1b88d7e.vk": {
|
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-559e581f022bb4e4ec6e719e563bf0e026ad6de42e56c18714a2c692b1b88d7e.vk": {
|
||||||
"cid": "QmZCvxKcKP97vDAk8Nxs9R1fWtqpjQrAhhfXPoCi1nkDoF",
|
"cid": "QmQzZ5dJ11tcSBees38WX41tZLXS9BqpEti253m5QcnTNs",
|
||||||
"digest": "fc02943678dd119e69e7fab8420e8819",
|
"digest": "c76125a50a7de315165de359b5174ae4",
|
||||||
"sector_size": 34359738368
|
"sector_size": 34359738368
|
||||||
},
|
},
|
||||||
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-2627e4006b67f99cef990c0a47d5426cb7ab0a0ad58fc1061547bf2d28b09def.params": {
|
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-2627e4006b67f99cef990c0a47d5426cb7ab0a0ad58fc1061547bf2d28b09def.params": {
|
||||||
"cid": "QmeAN4vuANhXsF8xP2Lx5j2L6yMSdogLzpcvqCJThRGK1V",
|
"cid": "QmNk3wga1tS53FUu1QnkK8ehWA2cqpCnSEAPv3KLxdJxNa",
|
||||||
"digest": "3810b7780ac0e299b22ae70f1f94c9bc",
|
"digest": "421e4790c0b80e0107a7ff67acf14084",
|
||||||
"sector_size": 68719476736
|
"sector_size": 68719476736
|
||||||
},
|
},
|
||||||
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-2627e4006b67f99cef990c0a47d5426cb7ab0a0ad58fc1061547bf2d28b09def.vk": {
|
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-2627e4006b67f99cef990c0a47d5426cb7ab0a0ad58fc1061547bf2d28b09def.vk": {
|
||||||
"cid": "QmWV8rqZLxs1oQN9jxNWmnT1YdgLwCcscv94VARrhHf1T7",
|
"cid": "QmVQCHGsrUtbn9RjHs1e6GXfeXDW5m9w4ge48PSX3Z2as2",
|
||||||
"digest": "59d2bf1857adc59a4f08fcf2afaa916b",
|
"digest": "8b60e9cc1470a6729c687d6cf0a1f79c",
|
||||||
"sector_size": 68719476736
|
"sector_size": 68719476736
|
||||||
},
|
},
|
||||||
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-b62098629d07946e9028127e70295ed996fe3ed25b0f9f88eb610a0ab4385a3c.params": {
|
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-b62098629d07946e9028127e70295ed996fe3ed25b0f9f88eb610a0ab4385a3c.params": {
|
||||||
"cid": "QmVkrXc1SLcpgcudK5J25HH93QvR9tNsVhVTYHm5UymXAz",
|
"cid": "QmTL3VvydaMFWKvE5VzxjgKsJYgL9JMM4JVYNtQxdj9JK1",
|
||||||
"digest": "2170a91ad5bae22ea61f2ea766630322",
|
"digest": "2685f31124b22ea6b2857e5a5e87ffa3",
|
||||||
"sector_size": 68719476736
|
"sector_size": 68719476736
|
||||||
},
|
},
|
||||||
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-b62098629d07946e9028127e70295ed996fe3ed25b0f9f88eb610a0ab4385a3c.vk": {
|
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-b62098629d07946e9028127e70295ed996fe3ed25b0f9f88eb610a0ab4385a3c.vk": {
|
||||||
"cid": "QmbfQjPD7EpzjhWGmvWAsyN2mAZ4PcYhsf3ujuhU9CSuBm",
|
"cid": "QmSVWbLqQYbUbbJyfsRMzEib2rfSqMtnPks1Nw22omcBQm",
|
||||||
"digest": "6d3789148fb6466d07ee1e24d6292fd6",
|
"digest": "efe703cd2839597c7ca5c2a906b74296",
|
||||||
"sector_size": 68719476736
|
"sector_size": 68719476736
|
||||||
},
|
},
|
||||||
"v28-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-032d3138d22506ec0082ed72b2dcba18df18477904e35bafee82b3793b06832f.params": {
|
"v26-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-032d3138d22506ec0082ed72b2dcba18df18477904e35bafee82b3793b06832f.params": {
|
||||||
"cid": "QmWceMgnWYLopMuM4AoGMvGEau7tNe5UK83XFjH5V9B17h",
|
"cid": "QmU9dH31nZZUJnsogR4Ld4ySUcH6wm2RgmGiujwnqtbU6k",
|
||||||
"digest": "434fb1338ecfaf0f59256f30dde4968f",
|
"digest": "fcef8e87ae2afd7a28aae44347b804cf",
|
||||||
"sector_size": 2048
|
"sector_size": 2048
|
||||||
},
|
},
|
||||||
"v28-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-032d3138d22506ec0082ed72b2dcba18df18477904e35bafee82b3793b06832f.vk": {
|
"v26-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-032d3138d22506ec0082ed72b2dcba18df18477904e35bafee82b3793b06832f.vk": {
|
||||||
"cid": "QmamahpFCstMUqHi2qGtVoDnRrsXhid86qsfvoyCTKJqHr",
|
"cid": "QmdJ15DMGPooye5NaPcRfXUdHUDibcN7hKjbmTGuu1K4AQ",
|
||||||
"digest": "dc1ade9929ade1708238f155343044ac",
|
"digest": "2ee2b3518229680db15161d4f582af37",
|
||||||
"sector_size": 2048
|
"sector_size": 2048
|
||||||
},
|
},
|
||||||
"v28-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-6babf46ce344ae495d558e7770a585b2382d54f225af8ed0397b8be7c3fcd472.params": {
|
"v26-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-6babf46ce344ae495d558e7770a585b2382d54f225af8ed0397b8be7c3fcd472.params": {
|
||||||
"cid": "QmYBpTt7LWNAWr1JXThV5VxX7wsQFLd1PHrGYVbrU1EZjC",
|
"cid": "QmZgtxcY3tMXXQxZTA7ZTUDXLVUnfxNcerXgeW4gG2NnfP",
|
||||||
"digest": "6c77597eb91ab936c1cef4cf19eba1b3",
|
"digest": "3273c7135cb75684248b475781b738ee",
|
||||||
"sector_size": 536870912
|
"sector_size": 536870912
|
||||||
},
|
},
|
||||||
"v28-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-6babf46ce344ae495d558e7770a585b2382d54f225af8ed0397b8be7c3fcd472.vk": {
|
"v26-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-6babf46ce344ae495d558e7770a585b2382d54f225af8ed0397b8be7c3fcd472.vk": {
|
||||||
"cid": "QmWionkqH2B6TXivzBSQeSyBxojaiAFbzhjtwYRrfwd8nH",
|
"cid": "QmSS6ZkAV2aGZcgKgdPpEEgihXF1ryZX8PSAZDWSoeL1d4",
|
||||||
"digest": "065179da19fbe515507267677f02823e",
|
"digest": "1519b5f61d9044a59f2bdc57537c094b",
|
||||||
"sector_size": 536870912
|
"sector_size": 536870912
|
||||||
},
|
},
|
||||||
"v28-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-ecd683648512ab1765faa2a5f14bab48f676e633467f0aa8aad4b55dcb0652bb.params": {
|
"v26-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-ecd683648512ab1765faa2a5f14bab48f676e633467f0aa8aad4b55dcb0652bb.params": {
|
||||||
"cid": "QmPXAPPuQtuQz7Zz3MHMAMEtsYwqM1o9H1csPLeiMUQwZH",
|
"cid": "QmQBGXeiNn6hVwbR6qFarQqiNGDdKk4h9ucfyvcXyfYz2N",
|
||||||
"digest": "09e612e4eeb7a0eb95679a88404f960c",
|
"digest": "7d5f896f435c38e93bcda6dd168d860b",
|
||||||
"sector_size": 8388608
|
"sector_size": 8388608
|
||||||
},
|
},
|
||||||
"v28-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-ecd683648512ab1765faa2a5f14bab48f676e633467f0aa8aad4b55dcb0652bb.vk": {
|
"v26-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-ecd683648512ab1765faa2a5f14bab48f676e633467f0aa8aad4b55dcb0652bb.vk": {
|
||||||
"cid": "QmYCuipFyvVW1GojdMrjK1JnMobXtT4zRCZs1CGxjizs99",
|
"cid": "QmPrZgBVGMckEAeu5eSJnLmiAwcPQjKjZe5ir6VaQ5AxKs",
|
||||||
"digest": "b687beb9adbd9dabe265a7e3620813e4",
|
"digest": "fe6d2de44580a0db5a4934688899b92f",
|
||||||
"sector_size": 8388608
|
"sector_size": 8388608
|
||||||
},
|
},
|
||||||
"v28-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-0-sha256_hasher-82a357d2f2ca81dc61bb45f4a762807aedee1b0a53fd6c4e77b46a01bfef7820.params": {
|
"v26-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-0-sha256_hasher-82a357d2f2ca81dc61bb45f4a762807aedee1b0a53fd6c4e77b46a01bfef7820.params": {
|
||||||
"cid": "QmengpM684XLQfG8754ToonszgEg2bQeAGUan5uXTHUQzJ",
|
"cid": "QmZL2cq45XJn5BFzagAZwgFmLrcM1W6CXoiEF9C5j5tjEF",
|
||||||
"digest": "6a388072a518cf46ebd661f5cc46900a",
|
"digest": "acdfed9f0512bc85a01a9fb871d475d5",
|
||||||
"sector_size": 34359738368
|
"sector_size": 34359738368
|
||||||
},
|
},
|
||||||
"v28-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-0-sha256_hasher-82a357d2f2ca81dc61bb45f4a762807aedee1b0a53fd6c4e77b46a01bfef7820.vk": {
|
"v26-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-0-sha256_hasher-82a357d2f2ca81dc61bb45f4a762807aedee1b0a53fd6c4e77b46a01bfef7820.vk": {
|
||||||
"cid": "Qmf93EMrADXAK6CyiSfE8xx45fkMfR3uzKEPCvZC1n2kzb",
|
"cid": "QmQ4zB7nNa1tDYNifBkExRnZtwtxZw775iaqvVsZyRi6Q2",
|
||||||
"digest": "0c7b4aac1c40fdb7eb82bc355b41addf",
|
"digest": "524a2f3e9d6826593caebc41bb545c40",
|
||||||
"sector_size": 34359738368
|
"sector_size": 34359738368
|
||||||
},
|
},
|
||||||
"v28-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-2-sha256_hasher-96f1b4a04c5c51e4759bbf224bbc2ef5a42c7100f16ec0637123f16a845ddfb2.params": {
|
"v26-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-2-sha256_hasher-96f1b4a04c5c51e4759bbf224bbc2ef5a42c7100f16ec0637123f16a845ddfb2.params": {
|
||||||
"cid": "QmS7ye6Ri2MfFzCkcUJ7FQ6zxDKuJ6J6B8k5PN7wzSR9sX",
|
"cid": "QmY7DitNKXFeLQt9QoVQkfjM1EvRnprqUVxjmkTXkHDNka",
|
||||||
"digest": "1801f8a6e1b00bceb00cc27314bb5ce3",
|
"digest": "f27271c0537ba65ade2ec045f8fbd069",
|
||||||
"sector_size": 68719476736
|
"sector_size": 68719476736
|
||||||
},
|
},
|
||||||
"v28-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-2-sha256_hasher-96f1b4a04c5c51e4759bbf224bbc2ef5a42c7100f16ec0637123f16a845ddfb2.vk": {
|
"v26-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-2-sha256_hasher-96f1b4a04c5c51e4759bbf224bbc2ef5a42c7100f16ec0637123f16a845ddfb2.vk": {
|
||||||
"cid": "QmehSmC6BhrgRZakPDta2ewoH9nosNzdjCqQRXsNFNUkLN",
|
"cid": "QmUJsvoCuQ4LszPmeRVAkMYb5qY95ctz3UXKhu8xLzyFKo",
|
||||||
"digest": "a89884252c04c298d0b3c81bfd884164",
|
"digest": "576b292938c6c9d0a0e721bd867a543b",
|
||||||
"sector_size": 68719476736
|
"sector_size": 68719476736
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+4
-37
@@ -1,10 +1,6 @@
|
|||||||
package build
|
package build
|
||||||
|
|
||||||
import (
|
import "fmt"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
)
|
|
||||||
|
|
||||||
var CurrentCommit string
|
var CurrentCommit string
|
||||||
var BuildType int
|
var BuildType int
|
||||||
@@ -29,7 +25,7 @@ func buildType() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// BuildVersion is the local build version, set by build system
|
// BuildVersion is the local build version, set by build system
|
||||||
const BuildVersion = "1.1.3"
|
const BuildVersion = "0.4.0"
|
||||||
|
|
||||||
func UserVersion() string {
|
func UserVersion() string {
|
||||||
return BuildVersion + buildType() + CurrentCommit
|
return BuildVersion + buildType() + CurrentCommit
|
||||||
@@ -56,37 +52,8 @@ func (ve Version) EqMajorMinor(v2 Version) bool {
|
|||||||
return ve&minorMask == v2&minorMask
|
return ve&minorMask == v2&minorMask
|
||||||
}
|
}
|
||||||
|
|
||||||
type NodeType int
|
// APIVersion is a semver version of the rpc api exposed
|
||||||
|
var APIVersion Version = newVer(0, 3, 0)
|
||||||
const (
|
|
||||||
NodeUnknown NodeType = iota
|
|
||||||
|
|
||||||
NodeFull
|
|
||||||
NodeMiner
|
|
||||||
NodeWorker
|
|
||||||
)
|
|
||||||
|
|
||||||
var RunningNodeType NodeType
|
|
||||||
|
|
||||||
func VersionForType(nodeType NodeType) (Version, error) {
|
|
||||||
switch nodeType {
|
|
||||||
case NodeFull:
|
|
||||||
return FullAPIVersion, nil
|
|
||||||
case NodeMiner:
|
|
||||||
return MinerAPIVersion, nil
|
|
||||||
case NodeWorker:
|
|
||||||
return WorkerAPIVersion, nil
|
|
||||||
default:
|
|
||||||
return Version(0), xerrors.Errorf("unknown node type %d", nodeType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// semver versions of the rpc api exposed
|
|
||||||
var (
|
|
||||||
FullAPIVersion = newVer(0, 17, 0)
|
|
||||||
MinerAPIVersion = newVer(0, 17, 0)
|
|
||||||
WorkerAPIVersion = newVer(0, 16, 0)
|
|
||||||
)
|
|
||||||
|
|
||||||
//nolint:varcheck,deadcode
|
//nolint:varcheck,deadcode
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -1,76 +0,0 @@
|
|||||||
package adt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/filecoin-project/go-state-types/cbor"
|
|
||||||
"github.com/filecoin-project/go-state-types/network"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors"
|
|
||||||
|
|
||||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
|
||||||
adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Map interface {
|
|
||||||
Root() (cid.Cid, error)
|
|
||||||
|
|
||||||
Put(k abi.Keyer, v cbor.Marshaler) error
|
|
||||||
Get(k abi.Keyer, v cbor.Unmarshaler) (bool, error)
|
|
||||||
Delete(k abi.Keyer) error
|
|
||||||
|
|
||||||
ForEach(v cbor.Unmarshaler, fn func(key string) error) error
|
|
||||||
}
|
|
||||||
|
|
||||||
func AsMap(store Store, root cid.Cid, version actors.Version) (Map, error) {
|
|
||||||
switch version {
|
|
||||||
case actors.Version0:
|
|
||||||
return adt0.AsMap(store, root)
|
|
||||||
case actors.Version2:
|
|
||||||
return adt2.AsMap(store, root)
|
|
||||||
}
|
|
||||||
return nil, xerrors.Errorf("unknown network version: %d", version)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewMap(store Store, version actors.Version) (Map, error) {
|
|
||||||
switch version {
|
|
||||||
case actors.Version0:
|
|
||||||
return adt0.MakeEmptyMap(store), nil
|
|
||||||
case actors.Version2:
|
|
||||||
return adt2.MakeEmptyMap(store), nil
|
|
||||||
}
|
|
||||||
return nil, xerrors.Errorf("unknown network version: %d", version)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Array interface {
|
|
||||||
Root() (cid.Cid, error)
|
|
||||||
|
|
||||||
Set(idx uint64, v cbor.Marshaler) error
|
|
||||||
Get(idx uint64, v cbor.Unmarshaler) (bool, error)
|
|
||||||
Delete(idx uint64) error
|
|
||||||
Length() uint64
|
|
||||||
|
|
||||||
ForEach(v cbor.Unmarshaler, fn func(idx int64) error) error
|
|
||||||
}
|
|
||||||
|
|
||||||
func AsArray(store Store, root cid.Cid, version network.Version) (Array, error) {
|
|
||||||
switch actors.VersionForNetwork(version) {
|
|
||||||
case actors.Version0:
|
|
||||||
return adt0.AsArray(store, root)
|
|
||||||
case actors.Version2:
|
|
||||||
return adt2.AsArray(store, root)
|
|
||||||
}
|
|
||||||
return nil, xerrors.Errorf("unknown network version: %d", version)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewArray(store Store, version actors.Version) (Array, error) {
|
|
||||||
switch version {
|
|
||||||
case actors.Version0:
|
|
||||||
return adt0.MakeEmptyArray(store), nil
|
|
||||||
case actors.Version2:
|
|
||||||
return adt2.MakeEmptyArray(store), nil
|
|
||||||
}
|
|
||||||
return nil, xerrors.Errorf("unknown network version: %d", version)
|
|
||||||
}
|
|
||||||
@@ -1,122 +0,0 @@
|
|||||||
package adt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
typegen "github.com/whyrusleeping/cbor-gen"
|
|
||||||
)
|
|
||||||
|
|
||||||
// AdtArrayDiff generalizes adt.Array diffing by accepting a Deferred type that can unmarshalled to its corresponding struct
|
|
||||||
// in an interface implantation.
|
|
||||||
// Add should be called when a new k,v is added to the array
|
|
||||||
// Modify should be called when a value is modified in the array
|
|
||||||
// Remove should be called when a value is removed from the array
|
|
||||||
type AdtArrayDiff interface {
|
|
||||||
Add(key uint64, val *typegen.Deferred) error
|
|
||||||
Modify(key uint64, from, to *typegen.Deferred) error
|
|
||||||
Remove(key uint64, val *typegen.Deferred) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO Performance can be improved by diffing the underlying IPLD graph, e.g. https://github.com/ipfs/go-merkledag/blob/749fd8717d46b4f34c9ce08253070079c89bc56d/dagutils/diff.go#L104
|
|
||||||
// CBOR Marshaling will likely be the largest performance bottleneck here.
|
|
||||||
|
|
||||||
// DiffAdtArray accepts two *adt.Array's and an AdtArrayDiff implementation. It does the following:
|
|
||||||
// - All values that exist in preArr and not in curArr are passed to AdtArrayDiff.Remove()
|
|
||||||
// - All values that exist in curArr nnd not in prevArr are passed to adtArrayDiff.Add()
|
|
||||||
// - All values that exist in preArr and in curArr are passed to AdtArrayDiff.Modify()
|
|
||||||
// - It is the responsibility of AdtArrayDiff.Modify() to determine if the values it was passed have been modified.
|
|
||||||
func DiffAdtArray(preArr, curArr Array, out AdtArrayDiff) error {
|
|
||||||
notNew := make(map[int64]struct{}, curArr.Length())
|
|
||||||
prevVal := new(typegen.Deferred)
|
|
||||||
if err := preArr.ForEach(prevVal, func(i int64) error {
|
|
||||||
curVal := new(typegen.Deferred)
|
|
||||||
found, err := curArr.Get(uint64(i), curVal)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if !found {
|
|
||||||
if err := out.Remove(uint64(i), prevVal); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// no modification
|
|
||||||
if !bytes.Equal(prevVal.Raw, curVal.Raw) {
|
|
||||||
if err := out.Modify(uint64(i), prevVal, curVal); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
notNew[i] = struct{}{}
|
|
||||||
return nil
|
|
||||||
}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
curVal := new(typegen.Deferred)
|
|
||||||
return curArr.ForEach(curVal, func(i int64) error {
|
|
||||||
if _, ok := notNew[i]; ok {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return out.Add(uint64(i), curVal)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO Performance can be improved by diffing the underlying IPLD graph, e.g. https://github.com/ipfs/go-merkledag/blob/749fd8717d46b4f34c9ce08253070079c89bc56d/dagutils/diff.go#L104
|
|
||||||
// CBOR Marshaling will likely be the largest performance bottleneck here.
|
|
||||||
|
|
||||||
// AdtMapDiff generalizes adt.Map diffing by accepting a Deferred type that can unmarshalled to its corresponding struct
|
|
||||||
// in an interface implantation.
|
|
||||||
// AsKey should return the Keyer implementation specific to the map
|
|
||||||
// Add should be called when a new k,v is added to the map
|
|
||||||
// Modify should be called when a value is modified in the map
|
|
||||||
// Remove should be called when a value is removed from the map
|
|
||||||
type AdtMapDiff interface {
|
|
||||||
AsKey(key string) (abi.Keyer, error)
|
|
||||||
Add(key string, val *typegen.Deferred) error
|
|
||||||
Modify(key string, from, to *typegen.Deferred) error
|
|
||||||
Remove(key string, val *typegen.Deferred) error
|
|
||||||
}
|
|
||||||
|
|
||||||
func DiffAdtMap(preMap, curMap Map, out AdtMapDiff) error {
|
|
||||||
notNew := make(map[string]struct{})
|
|
||||||
prevVal := new(typegen.Deferred)
|
|
||||||
if err := preMap.ForEach(prevVal, func(key string) error {
|
|
||||||
curVal := new(typegen.Deferred)
|
|
||||||
k, err := out.AsKey(key)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
found, err := curMap.Get(k, curVal)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if !found {
|
|
||||||
if err := out.Remove(key, prevVal); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// no modification
|
|
||||||
if !bytes.Equal(prevVal.Raw, curVal.Raw) {
|
|
||||||
if err := out.Modify(key, prevVal, curVal); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
notNew[key] = struct{}{}
|
|
||||||
return nil
|
|
||||||
}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
curVal := new(typegen.Deferred)
|
|
||||||
return curMap.ForEach(curVal, func(key string) error {
|
|
||||||
if _, ok := notNew[key]; ok {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return out.Add(key, curVal)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,301 +0,0 @@
|
|||||||
package adt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"context"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
|
|
||||||
cbornode "github.com/ipfs/go-ipld-cbor"
|
|
||||||
typegen "github.com/whyrusleeping/cbor-gen"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
|
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
|
||||||
adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt"
|
|
||||||
|
|
||||||
bstore "github.com/filecoin-project/lotus/lib/blockstore"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestDiffAdtArray(t *testing.T) {
|
|
||||||
ctxstoreA := newContextStore()
|
|
||||||
ctxstoreB := newContextStore()
|
|
||||||
|
|
||||||
arrA := adt2.MakeEmptyArray(ctxstoreA)
|
|
||||||
arrB := adt2.MakeEmptyArray(ctxstoreB)
|
|
||||||
|
|
||||||
require.NoError(t, arrA.Set(0, builtin2.CBORBytes([]byte{0}))) // delete
|
|
||||||
|
|
||||||
require.NoError(t, arrA.Set(1, builtin2.CBORBytes([]byte{0}))) // modify
|
|
||||||
require.NoError(t, arrB.Set(1, builtin2.CBORBytes([]byte{1})))
|
|
||||||
|
|
||||||
require.NoError(t, arrA.Set(2, builtin2.CBORBytes([]byte{1}))) // delete
|
|
||||||
|
|
||||||
require.NoError(t, arrA.Set(3, builtin2.CBORBytes([]byte{0}))) // noop
|
|
||||||
require.NoError(t, arrB.Set(3, builtin2.CBORBytes([]byte{0})))
|
|
||||||
|
|
||||||
require.NoError(t, arrA.Set(4, builtin2.CBORBytes([]byte{0}))) // modify
|
|
||||||
require.NoError(t, arrB.Set(4, builtin2.CBORBytes([]byte{6})))
|
|
||||||
|
|
||||||
require.NoError(t, arrB.Set(5, builtin2.CBORBytes{8})) // add
|
|
||||||
require.NoError(t, arrB.Set(6, builtin2.CBORBytes{9})) // add
|
|
||||||
|
|
||||||
changes := new(TestDiffArray)
|
|
||||||
|
|
||||||
assert.NoError(t, DiffAdtArray(arrA, arrB, changes))
|
|
||||||
assert.NotNil(t, changes)
|
|
||||||
|
|
||||||
assert.Equal(t, 2, len(changes.Added))
|
|
||||||
// keys 5 and 6 were added
|
|
||||||
assert.EqualValues(t, uint64(5), changes.Added[0].key)
|
|
||||||
assert.EqualValues(t, []byte{8}, changes.Added[0].val)
|
|
||||||
assert.EqualValues(t, uint64(6), changes.Added[1].key)
|
|
||||||
assert.EqualValues(t, []byte{9}, changes.Added[1].val)
|
|
||||||
|
|
||||||
assert.Equal(t, 2, len(changes.Modified))
|
|
||||||
// keys 1 and 4 were modified
|
|
||||||
assert.EqualValues(t, uint64(1), changes.Modified[0].From.key)
|
|
||||||
assert.EqualValues(t, []byte{0}, changes.Modified[0].From.val)
|
|
||||||
assert.EqualValues(t, uint64(1), changes.Modified[0].To.key)
|
|
||||||
assert.EqualValues(t, []byte{1}, changes.Modified[0].To.val)
|
|
||||||
assert.EqualValues(t, uint64(4), changes.Modified[1].From.key)
|
|
||||||
assert.EqualValues(t, []byte{0}, changes.Modified[1].From.val)
|
|
||||||
assert.EqualValues(t, uint64(4), changes.Modified[1].To.key)
|
|
||||||
assert.EqualValues(t, []byte{6}, changes.Modified[1].To.val)
|
|
||||||
|
|
||||||
assert.Equal(t, 2, len(changes.Removed))
|
|
||||||
// keys 0 and 2 were deleted
|
|
||||||
assert.EqualValues(t, uint64(0), changes.Removed[0].key)
|
|
||||||
assert.EqualValues(t, []byte{0}, changes.Removed[0].val)
|
|
||||||
assert.EqualValues(t, uint64(2), changes.Removed[1].key)
|
|
||||||
assert.EqualValues(t, []byte{1}, changes.Removed[1].val)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDiffAdtMap(t *testing.T) {
|
|
||||||
ctxstoreA := newContextStore()
|
|
||||||
ctxstoreB := newContextStore()
|
|
||||||
|
|
||||||
mapA := adt2.MakeEmptyMap(ctxstoreA)
|
|
||||||
mapB := adt2.MakeEmptyMap(ctxstoreB)
|
|
||||||
|
|
||||||
require.NoError(t, mapA.Put(abi.UIntKey(0), builtin2.CBORBytes([]byte{0}))) // delete
|
|
||||||
|
|
||||||
require.NoError(t, mapA.Put(abi.UIntKey(1), builtin2.CBORBytes([]byte{0}))) // modify
|
|
||||||
require.NoError(t, mapB.Put(abi.UIntKey(1), builtin2.CBORBytes([]byte{1})))
|
|
||||||
|
|
||||||
require.NoError(t, mapA.Put(abi.UIntKey(2), builtin2.CBORBytes([]byte{1}))) // delete
|
|
||||||
|
|
||||||
require.NoError(t, mapA.Put(abi.UIntKey(3), builtin2.CBORBytes([]byte{0}))) // noop
|
|
||||||
require.NoError(t, mapB.Put(abi.UIntKey(3), builtin2.CBORBytes([]byte{0})))
|
|
||||||
|
|
||||||
require.NoError(t, mapA.Put(abi.UIntKey(4), builtin2.CBORBytes([]byte{0}))) // modify
|
|
||||||
require.NoError(t, mapB.Put(abi.UIntKey(4), builtin2.CBORBytes([]byte{6})))
|
|
||||||
|
|
||||||
require.NoError(t, mapB.Put(abi.UIntKey(5), builtin2.CBORBytes{8})) // add
|
|
||||||
require.NoError(t, mapB.Put(abi.UIntKey(6), builtin2.CBORBytes{9})) // add
|
|
||||||
|
|
||||||
changes := new(TestDiffMap)
|
|
||||||
|
|
||||||
assert.NoError(t, DiffAdtMap(mapA, mapB, changes))
|
|
||||||
assert.NotNil(t, changes)
|
|
||||||
|
|
||||||
assert.Equal(t, 2, len(changes.Added))
|
|
||||||
// keys 5 and 6 were added
|
|
||||||
assert.EqualValues(t, uint64(6), changes.Added[0].key)
|
|
||||||
assert.EqualValues(t, []byte{9}, changes.Added[0].val)
|
|
||||||
assert.EqualValues(t, uint64(5), changes.Added[1].key)
|
|
||||||
assert.EqualValues(t, []byte{8}, changes.Added[1].val)
|
|
||||||
|
|
||||||
assert.Equal(t, 2, len(changes.Modified))
|
|
||||||
// keys 1 and 4 were modified
|
|
||||||
assert.EqualValues(t, uint64(1), changes.Modified[0].From.key)
|
|
||||||
assert.EqualValues(t, []byte{0}, changes.Modified[0].From.val)
|
|
||||||
assert.EqualValues(t, uint64(1), changes.Modified[0].To.key)
|
|
||||||
assert.EqualValues(t, []byte{1}, changes.Modified[0].To.val)
|
|
||||||
assert.EqualValues(t, uint64(4), changes.Modified[1].From.key)
|
|
||||||
assert.EqualValues(t, []byte{0}, changes.Modified[1].From.val)
|
|
||||||
assert.EqualValues(t, uint64(4), changes.Modified[1].To.key)
|
|
||||||
assert.EqualValues(t, []byte{6}, changes.Modified[1].To.val)
|
|
||||||
|
|
||||||
assert.Equal(t, 2, len(changes.Removed))
|
|
||||||
// keys 0 and 2 were deleted
|
|
||||||
assert.EqualValues(t, uint64(0), changes.Removed[0].key)
|
|
||||||
assert.EqualValues(t, []byte{0}, changes.Removed[0].val)
|
|
||||||
assert.EqualValues(t, uint64(2), changes.Removed[1].key)
|
|
||||||
assert.EqualValues(t, []byte{1}, changes.Removed[1].val)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
type TestDiffMap struct {
|
|
||||||
Added []adtMapDiffResult
|
|
||||||
Modified []TestAdtMapDiffModified
|
|
||||||
Removed []adtMapDiffResult
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ AdtMapDiff = &TestDiffMap{}
|
|
||||||
|
|
||||||
func (t *TestDiffMap) AsKey(key string) (abi.Keyer, error) {
|
|
||||||
k, err := abi.ParseUIntKey(key)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return abi.UIntKey(k), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *TestDiffMap) Add(key string, val *typegen.Deferred) error {
|
|
||||||
v := new(builtin2.CBORBytes)
|
|
||||||
err := v.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
k, err := abi.ParseUIntKey(key)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
t.Added = append(t.Added, adtMapDiffResult{
|
|
||||||
key: k,
|
|
||||||
val: *v,
|
|
||||||
})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *TestDiffMap) Modify(key string, from, to *typegen.Deferred) error {
|
|
||||||
vFrom := new(builtin2.CBORBytes)
|
|
||||||
err := vFrom.UnmarshalCBOR(bytes.NewReader(from.Raw))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
vTo := new(builtin2.CBORBytes)
|
|
||||||
err = vTo.UnmarshalCBOR(bytes.NewReader(to.Raw))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
k, err := abi.ParseUIntKey(key)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !bytes.Equal(*vFrom, *vTo) {
|
|
||||||
t.Modified = append(t.Modified, TestAdtMapDiffModified{
|
|
||||||
From: adtMapDiffResult{
|
|
||||||
key: k,
|
|
||||||
val: *vFrom,
|
|
||||||
},
|
|
||||||
To: adtMapDiffResult{
|
|
||||||
key: k,
|
|
||||||
val: *vTo,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *TestDiffMap) Remove(key string, val *typegen.Deferred) error {
|
|
||||||
v := new(builtin2.CBORBytes)
|
|
||||||
err := v.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
k, err := abi.ParseUIntKey(key)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
t.Removed = append(t.Removed, adtMapDiffResult{
|
|
||||||
key: k,
|
|
||||||
val: *v,
|
|
||||||
})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type adtMapDiffResult struct {
|
|
||||||
key uint64
|
|
||||||
val builtin2.CBORBytes
|
|
||||||
}
|
|
||||||
|
|
||||||
type TestAdtMapDiffModified struct {
|
|
||||||
From adtMapDiffResult
|
|
||||||
To adtMapDiffResult
|
|
||||||
}
|
|
||||||
|
|
||||||
type adtArrayDiffResult struct {
|
|
||||||
key uint64
|
|
||||||
val builtin2.CBORBytes
|
|
||||||
}
|
|
||||||
|
|
||||||
type TestDiffArray struct {
|
|
||||||
Added []adtArrayDiffResult
|
|
||||||
Modified []TestAdtArrayDiffModified
|
|
||||||
Removed []adtArrayDiffResult
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ AdtArrayDiff = &TestDiffArray{}
|
|
||||||
|
|
||||||
type TestAdtArrayDiffModified struct {
|
|
||||||
From adtArrayDiffResult
|
|
||||||
To adtArrayDiffResult
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *TestDiffArray) Add(key uint64, val *typegen.Deferred) error {
|
|
||||||
v := new(builtin2.CBORBytes)
|
|
||||||
err := v.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
t.Added = append(t.Added, adtArrayDiffResult{
|
|
||||||
key: key,
|
|
||||||
val: *v,
|
|
||||||
})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *TestDiffArray) Modify(key uint64, from, to *typegen.Deferred) error {
|
|
||||||
vFrom := new(builtin2.CBORBytes)
|
|
||||||
err := vFrom.UnmarshalCBOR(bytes.NewReader(from.Raw))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
vTo := new(builtin2.CBORBytes)
|
|
||||||
err = vTo.UnmarshalCBOR(bytes.NewReader(to.Raw))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !bytes.Equal(*vFrom, *vTo) {
|
|
||||||
t.Modified = append(t.Modified, TestAdtArrayDiffModified{
|
|
||||||
From: adtArrayDiffResult{
|
|
||||||
key: key,
|
|
||||||
val: *vFrom,
|
|
||||||
},
|
|
||||||
To: adtArrayDiffResult{
|
|
||||||
key: key,
|
|
||||||
val: *vTo,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *TestDiffArray) Remove(key uint64, val *typegen.Deferred) error {
|
|
||||||
v := new(builtin2.CBORBytes)
|
|
||||||
err := v.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
t.Removed = append(t.Removed, adtArrayDiffResult{
|
|
||||||
key: key,
|
|
||||||
val: *v,
|
|
||||||
})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func newContextStore() Store {
|
|
||||||
ctx := context.Background()
|
|
||||||
bs := bstore.NewTemporarySync()
|
|
||||||
store := cbornode.NewCborStore(bs)
|
|
||||||
return WrapStore(ctx, store)
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
package adt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
adt "github.com/filecoin-project/specs-actors/actors/util/adt"
|
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Store interface {
|
|
||||||
Context() context.Context
|
|
||||||
cbor.IpldStore
|
|
||||||
}
|
|
||||||
|
|
||||||
func WrapStore(ctx context.Context, store cbor.IpldStore) Store {
|
|
||||||
return adt.WrapStore(ctx, store)
|
|
||||||
}
|
|
||||||
@@ -3,7 +3,7 @@ package aerrors
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/exitcode"
|
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ package aerrors_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/exitcode"
|
|
||||||
. "github.com/filecoin-project/lotus/chain/actors/aerrors"
|
. "github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/exitcode"
|
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
# Actors
|
|
||||||
|
|
||||||
This package contains shims for abstracting over different actor versions.
|
|
||||||
|
|
||||||
## Design
|
|
||||||
|
|
||||||
Shims in this package follow a few common design principles.
|
|
||||||
|
|
||||||
### Structure Agnostic
|
|
||||||
|
|
||||||
Shims interfaces defined in this package should (ideally) not change even if the
|
|
||||||
structure of the underlying data changes. For example:
|
|
||||||
|
|
||||||
* All shims store an internal "store" object. That way, state can be moved into
|
|
||||||
a separate object without needing to add a store to the function signature.
|
|
||||||
* All functions must return an error, even if unused for now.
|
|
||||||
|
|
||||||
### Minimal
|
|
||||||
|
|
||||||
These interfaces should be expanded only as necessary to reduce maintenance burden.
|
|
||||||
|
|
||||||
### Queries, not field assessors.
|
|
||||||
|
|
||||||
When possible, functions should query the state instead of simply acting as
|
|
||||||
field assessors. These queries are more likely to remain stable across
|
|
||||||
specs-actor upgrades than specific state fields.
|
|
||||||
|
|
||||||
Note: there is a trade-off here. Avoid implementing _complicated_ query logic
|
|
||||||
inside these shims, as it will need to be replicated in every shim.
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
package account
|
|
||||||
|
|
||||||
import (
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/cbor"
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
|
|
||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
builtin.RegisterActorState(builtin0.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
|
||||||
return load0(store, root)
|
|
||||||
})
|
|
||||||
builtin.RegisterActorState(builtin2.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
|
||||||
return load2(store, root)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
var Methods = builtin2.MethodsAccount
|
|
||||||
|
|
||||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
|
||||||
switch act.Code {
|
|
||||||
case builtin0.AccountActorCodeID:
|
|
||||||
return load0(store, act.Head)
|
|
||||||
case builtin2.AccountActorCodeID:
|
|
||||||
return load2(store, act.Head)
|
|
||||||
}
|
|
||||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
|
||||||
}
|
|
||||||
|
|
||||||
type State interface {
|
|
||||||
cbor.Marshaler
|
|
||||||
|
|
||||||
PubkeyAddress() (address.Address, error)
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package account
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
||||||
|
|
||||||
account0 "github.com/filecoin-project/specs-actors/actors/builtin/account"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ State = (*state0)(nil)
|
|
||||||
|
|
||||||
func load0(store adt.Store, root cid.Cid) (State, error) {
|
|
||||||
out := state0{store: store}
|
|
||||||
err := store.Get(store.Context(), root, &out)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type state0 struct {
|
|
||||||
account0.State
|
|
||||||
store adt.Store
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) PubkeyAddress() (address.Address, error) {
|
|
||||||
return s.Address, nil
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package account
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
||||||
|
|
||||||
account2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/account"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ State = (*state2)(nil)
|
|
||||||
|
|
||||||
func load2(store adt.Store, root cid.Cid) (State, error) {
|
|
||||||
out := state2{store: store}
|
|
||||||
err := store.Get(store.Context(), root, &out)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type state2 struct {
|
|
||||||
account2.State
|
|
||||||
store adt.Store
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) PubkeyAddress() (address.Address, error) {
|
|
||||||
return s.Address, nil
|
|
||||||
}
|
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
package builtin
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
|
||||||
smoothing2 "github.com/filecoin-project/specs-actors/v2/actors/util/smoothing"
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/filecoin-project/go-state-types/cbor"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
|
|
||||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
|
||||||
proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof"
|
|
||||||
smoothing0 "github.com/filecoin-project/specs-actors/actors/util/smoothing"
|
|
||||||
)
|
|
||||||
|
|
||||||
var SystemActorAddr = builtin0.SystemActorAddr
|
|
||||||
var BurntFundsActorAddr = builtin0.BurntFundsActorAddr
|
|
||||||
var CronActorAddr = builtin0.CronActorAddr
|
|
||||||
var SaftAddress = makeAddress("t0122")
|
|
||||||
var ReserveAddress = makeAddress("t090")
|
|
||||||
var RootVerifierAddress = makeAddress("t080")
|
|
||||||
|
|
||||||
var (
|
|
||||||
ExpectedLeadersPerEpoch = builtin0.ExpectedLeadersPerEpoch
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
EpochDurationSeconds = builtin0.EpochDurationSeconds
|
|
||||||
EpochsInDay = builtin0.EpochsInDay
|
|
||||||
SecondsInDay = builtin0.SecondsInDay
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
MethodSend = builtin2.MethodSend
|
|
||||||
MethodConstructor = builtin2.MethodConstructor
|
|
||||||
)
|
|
||||||
|
|
||||||
// TODO: Why does actors have 2 different versions of this?
|
|
||||||
type SectorInfo = proof0.SectorInfo
|
|
||||||
type PoStProof = proof0.PoStProof
|
|
||||||
type FilterEstimate = smoothing0.FilterEstimate
|
|
||||||
|
|
||||||
func FromV0FilterEstimate(v0 smoothing0.FilterEstimate) FilterEstimate {
|
|
||||||
return (FilterEstimate)(v0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Doesn't change between actors v0 and v1
|
|
||||||
func QAPowerForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight, verifiedWeight abi.DealWeight) abi.StoragePower {
|
|
||||||
return miner0.QAPowerForWeight(size, duration, dealWeight, verifiedWeight)
|
|
||||||
}
|
|
||||||
|
|
||||||
func FromV2FilterEstimate(v1 smoothing2.FilterEstimate) FilterEstimate {
|
|
||||||
return (FilterEstimate)(v1)
|
|
||||||
}
|
|
||||||
|
|
||||||
type ActorStateLoader func(store adt.Store, root cid.Cid) (cbor.Marshaler, error)
|
|
||||||
|
|
||||||
var ActorStateLoaders = make(map[cid.Cid]ActorStateLoader)
|
|
||||||
|
|
||||||
func RegisterActorState(code cid.Cid, loader ActorStateLoader) {
|
|
||||||
ActorStateLoaders[code] = loader
|
|
||||||
}
|
|
||||||
|
|
||||||
func Load(store adt.Store, act *types.Actor) (cbor.Marshaler, error) {
|
|
||||||
loader, found := ActorStateLoaders[act.Code]
|
|
||||||
if !found {
|
|
||||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
|
||||||
}
|
|
||||||
return loader(store, act.Head)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ActorNameByCode(c cid.Cid) string {
|
|
||||||
switch {
|
|
||||||
case builtin0.IsBuiltinActor(c):
|
|
||||||
return builtin0.ActorNameByCode(c)
|
|
||||||
case builtin2.IsBuiltinActor(c):
|
|
||||||
return builtin2.ActorNameByCode(c)
|
|
||||||
default:
|
|
||||||
return "<unknown>"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func IsBuiltinActor(c cid.Cid) bool {
|
|
||||||
return builtin0.IsBuiltinActor(c) || builtin2.IsBuiltinActor(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
func IsAccountActor(c cid.Cid) bool {
|
|
||||||
return c == builtin0.AccountActorCodeID || c == builtin2.AccountActorCodeID
|
|
||||||
}
|
|
||||||
|
|
||||||
func IsStorageMinerActor(c cid.Cid) bool {
|
|
||||||
return c == builtin0.StorageMinerActorCodeID || c == builtin2.StorageMinerActorCodeID
|
|
||||||
}
|
|
||||||
|
|
||||||
func IsMultisigActor(c cid.Cid) bool {
|
|
||||||
return c == builtin0.MultisigActorCodeID || c == builtin2.MultisigActorCodeID
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func IsPaymentChannelActor(c cid.Cid) bool {
|
|
||||||
return c == builtin0.PaymentChannelActorCodeID || c == builtin2.PaymentChannelActorCodeID
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeAddress(addr string) address.Address {
|
|
||||||
ret, err := address.NewFromString(addr)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
package cron
|
|
||||||
|
|
||||||
import (
|
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
Address = builtin2.CronActorAddr
|
|
||||||
Methods = builtin2.MethodsCron
|
|
||||||
)
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
package init
|
|
||||||
|
|
||||||
import (
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/filecoin-project/go-state-types/cbor"
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
|
||||||
|
|
||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
builtin.RegisterActorState(builtin0.InitActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
|
||||||
return load0(store, root)
|
|
||||||
})
|
|
||||||
builtin.RegisterActorState(builtin2.InitActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
|
||||||
return load2(store, root)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
Address = builtin2.InitActorAddr
|
|
||||||
Methods = builtin2.MethodsInit
|
|
||||||
)
|
|
||||||
|
|
||||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
|
||||||
switch act.Code {
|
|
||||||
case builtin0.InitActorCodeID:
|
|
||||||
return load0(store, act.Head)
|
|
||||||
case builtin2.InitActorCodeID:
|
|
||||||
return load2(store, act.Head)
|
|
||||||
}
|
|
||||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
|
||||||
}
|
|
||||||
|
|
||||||
type State interface {
|
|
||||||
cbor.Marshaler
|
|
||||||
|
|
||||||
ResolveAddress(address address.Address) (address.Address, bool, error)
|
|
||||||
MapAddressToNewID(address address.Address) (address.Address, error)
|
|
||||||
NetworkName() (dtypes.NetworkName, error)
|
|
||||||
|
|
||||||
ForEachActor(func(id abi.ActorID, address address.Address) error) error
|
|
||||||
|
|
||||||
// Remove exists to support tooling that manipulates state for testing.
|
|
||||||
// It should not be used in production code, as init actor entries are
|
|
||||||
// immutable.
|
|
||||||
Remove(addrs ...address.Address) error
|
|
||||||
|
|
||||||
// Sets the network's name. This should only be used on upgrade/fork.
|
|
||||||
SetNetworkName(name string) error
|
|
||||||
}
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
package init
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
||||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
|
||||||
|
|
||||||
init0 "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
|
||||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ State = (*state0)(nil)
|
|
||||||
|
|
||||||
func load0(store adt.Store, root cid.Cid) (State, error) {
|
|
||||||
out := state0{store: store}
|
|
||||||
err := store.Get(store.Context(), root, &out)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type state0 struct {
|
|
||||||
init0.State
|
|
||||||
store adt.Store
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) ResolveAddress(address address.Address) (address.Address, bool, error) {
|
|
||||||
return s.State.ResolveAddress(s.store, address)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) MapAddressToNewID(address address.Address) (address.Address, error) {
|
|
||||||
return s.State.MapAddressToNewID(s.store, address)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) ForEachActor(cb func(id abi.ActorID, address address.Address) error) error {
|
|
||||||
addrs, err := adt0.AsMap(s.store, s.State.AddressMap)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var actorID cbg.CborInt
|
|
||||||
return addrs.ForEach(&actorID, func(key string) error {
|
|
||||||
addr, err := address.NewFromBytes([]byte(key))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return cb(abi.ActorID(actorID), addr)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) NetworkName() (dtypes.NetworkName, error) {
|
|
||||||
return dtypes.NetworkName(s.State.NetworkName), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) SetNetworkName(name string) error {
|
|
||||||
s.State.NetworkName = name
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) Remove(addrs ...address.Address) (err error) {
|
|
||||||
m, err := adt0.AsMap(s.store, s.State.AddressMap)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, addr := range addrs {
|
|
||||||
if err = m.Delete(abi.AddrKey(addr)); err != nil {
|
|
||||||
return xerrors.Errorf("failed to delete entry for address: %s; err: %w", addr, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
amr, err := m.Root()
|
|
||||||
if err != nil {
|
|
||||||
return xerrors.Errorf("failed to get address map root: %w", err)
|
|
||||||
}
|
|
||||||
s.State.AddressMap = amr
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
package init
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
||||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
|
||||||
|
|
||||||
init2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/init"
|
|
||||||
adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ State = (*state2)(nil)
|
|
||||||
|
|
||||||
func load2(store adt.Store, root cid.Cid) (State, error) {
|
|
||||||
out := state2{store: store}
|
|
||||||
err := store.Get(store.Context(), root, &out)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type state2 struct {
|
|
||||||
init2.State
|
|
||||||
store adt.Store
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) ResolveAddress(address address.Address) (address.Address, bool, error) {
|
|
||||||
return s.State.ResolveAddress(s.store, address)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) MapAddressToNewID(address address.Address) (address.Address, error) {
|
|
||||||
return s.State.MapAddressToNewID(s.store, address)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) ForEachActor(cb func(id abi.ActorID, address address.Address) error) error {
|
|
||||||
addrs, err := adt2.AsMap(s.store, s.State.AddressMap)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var actorID cbg.CborInt
|
|
||||||
return addrs.ForEach(&actorID, func(key string) error {
|
|
||||||
addr, err := address.NewFromBytes([]byte(key))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return cb(abi.ActorID(actorID), addr)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) NetworkName() (dtypes.NetworkName, error) {
|
|
||||||
return dtypes.NetworkName(s.State.NetworkName), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) SetNetworkName(name string) error {
|
|
||||||
s.State.NetworkName = name
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) Remove(addrs ...address.Address) (err error) {
|
|
||||||
m, err := adt2.AsMap(s.store, s.State.AddressMap)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, addr := range addrs {
|
|
||||||
if err = m.Delete(abi.AddrKey(addr)); err != nil {
|
|
||||||
return xerrors.Errorf("failed to delete entry for address: %s; err: %w", addr, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
amr, err := m.Root()
|
|
||||||
if err != nil {
|
|
||||||
return xerrors.Errorf("failed to get address map root: %w", err)
|
|
||||||
}
|
|
||||||
s.State.AddressMap = amr
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
package market
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
|
||||||
)
|
|
||||||
|
|
||||||
func DiffDealProposals(pre, cur DealProposals) (*DealProposalChanges, error) {
|
|
||||||
results := new(DealProposalChanges)
|
|
||||||
if err := adt.DiffAdtArray(pre.array(), cur.array(), &marketProposalsDiffer{results, pre, cur}); err != nil {
|
|
||||||
return nil, fmt.Errorf("diffing deal states: %w", err)
|
|
||||||
}
|
|
||||||
return results, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type marketProposalsDiffer struct {
|
|
||||||
Results *DealProposalChanges
|
|
||||||
pre, cur DealProposals
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *marketProposalsDiffer) Add(key uint64, val *cbg.Deferred) error {
|
|
||||||
dp, err := d.cur.decode(val)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
d.Results.Added = append(d.Results.Added, ProposalIDState{abi.DealID(key), *dp})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *marketProposalsDiffer) Modify(key uint64, from, to *cbg.Deferred) error {
|
|
||||||
// short circuit, DealProposals are static
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *marketProposalsDiffer) Remove(key uint64, val *cbg.Deferred) error {
|
|
||||||
dp, err := d.pre.decode(val)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
d.Results.Removed = append(d.Results.Removed, ProposalIDState{abi.DealID(key), *dp})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func DiffDealStates(pre, cur DealStates) (*DealStateChanges, error) {
|
|
||||||
results := new(DealStateChanges)
|
|
||||||
if err := adt.DiffAdtArray(pre.array(), cur.array(), &marketStatesDiffer{results, pre, cur}); err != nil {
|
|
||||||
return nil, fmt.Errorf("diffing deal states: %w", err)
|
|
||||||
}
|
|
||||||
return results, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type marketStatesDiffer struct {
|
|
||||||
Results *DealStateChanges
|
|
||||||
pre, cur DealStates
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *marketStatesDiffer) Add(key uint64, val *cbg.Deferred) error {
|
|
||||||
ds, err := d.cur.decode(val)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
d.Results.Added = append(d.Results.Added, DealIDState{abi.DealID(key), *ds})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *marketStatesDiffer) Modify(key uint64, from, to *cbg.Deferred) error {
|
|
||||||
dsFrom, err := d.pre.decode(from)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
dsTo, err := d.cur.decode(to)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if *dsFrom != *dsTo {
|
|
||||||
d.Results.Modified = append(d.Results.Modified, DealStateChange{abi.DealID(key), dsFrom, dsTo})
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *marketStatesDiffer) Remove(key uint64, val *cbg.Deferred) error {
|
|
||||||
ds, err := d.pre.decode(val)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
d.Results.Removed = append(d.Results.Removed, DealIDState{abi.DealID(key), *ds})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,142 +0,0 @@
|
|||||||
package market
|
|
||||||
|
|
||||||
import (
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/filecoin-project/go-state-types/cbor"
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
|
||||||
|
|
||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
|
||||||
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
|
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
builtin.RegisterActorState(builtin0.StorageMarketActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
|
||||||
return load0(store, root)
|
|
||||||
})
|
|
||||||
builtin.RegisterActorState(builtin2.StorageMarketActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
|
||||||
return load2(store, root)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
Address = builtin2.StorageMarketActorAddr
|
|
||||||
Methods = builtin2.MethodsMarket
|
|
||||||
)
|
|
||||||
|
|
||||||
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
|
||||||
switch act.Code {
|
|
||||||
case builtin0.StorageMarketActorCodeID:
|
|
||||||
return load0(store, act.Head)
|
|
||||||
case builtin2.StorageMarketActorCodeID:
|
|
||||||
return load2(store, act.Head)
|
|
||||||
}
|
|
||||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
|
||||||
}
|
|
||||||
|
|
||||||
type State interface {
|
|
||||||
cbor.Marshaler
|
|
||||||
BalancesChanged(State) (bool, error)
|
|
||||||
EscrowTable() (BalanceTable, error)
|
|
||||||
LockedTable() (BalanceTable, error)
|
|
||||||
TotalLocked() (abi.TokenAmount, error)
|
|
||||||
StatesChanged(State) (bool, error)
|
|
||||||
States() (DealStates, error)
|
|
||||||
ProposalsChanged(State) (bool, error)
|
|
||||||
Proposals() (DealProposals, error)
|
|
||||||
VerifyDealsForActivation(
|
|
||||||
minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch,
|
|
||||||
) (weight, verifiedWeight abi.DealWeight, err error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type BalanceTable interface {
|
|
||||||
ForEach(cb func(address.Address, abi.TokenAmount) error) error
|
|
||||||
Get(key address.Address) (abi.TokenAmount, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type DealStates interface {
|
|
||||||
ForEach(cb func(id abi.DealID, ds DealState) error) error
|
|
||||||
Get(id abi.DealID) (*DealState, bool, error)
|
|
||||||
|
|
||||||
array() adt.Array
|
|
||||||
decode(*cbg.Deferred) (*DealState, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type DealProposals interface {
|
|
||||||
ForEach(cb func(id abi.DealID, dp DealProposal) error) error
|
|
||||||
Get(id abi.DealID) (*DealProposal, bool, error)
|
|
||||||
|
|
||||||
array() adt.Array
|
|
||||||
decode(*cbg.Deferred) (*DealProposal, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type PublishStorageDealsParams = market0.PublishStorageDealsParams
|
|
||||||
type PublishStorageDealsReturn = market0.PublishStorageDealsReturn
|
|
||||||
type VerifyDealsForActivationParams = market0.VerifyDealsForActivationParams
|
|
||||||
type WithdrawBalanceParams = market0.WithdrawBalanceParams
|
|
||||||
|
|
||||||
type ClientDealProposal = market0.ClientDealProposal
|
|
||||||
|
|
||||||
type DealState struct {
|
|
||||||
SectorStartEpoch abi.ChainEpoch // -1 if not yet included in proven sector
|
|
||||||
LastUpdatedEpoch abi.ChainEpoch // -1 if deal state never updated
|
|
||||||
SlashEpoch abi.ChainEpoch // -1 if deal never slashed
|
|
||||||
}
|
|
||||||
|
|
||||||
type DealProposal struct {
|
|
||||||
PieceCID cid.Cid
|
|
||||||
PieceSize abi.PaddedPieceSize
|
|
||||||
VerifiedDeal bool
|
|
||||||
Client address.Address
|
|
||||||
Provider address.Address
|
|
||||||
Label string
|
|
||||||
StartEpoch abi.ChainEpoch
|
|
||||||
EndEpoch abi.ChainEpoch
|
|
||||||
StoragePricePerEpoch abi.TokenAmount
|
|
||||||
ProviderCollateral abi.TokenAmount
|
|
||||||
ClientCollateral abi.TokenAmount
|
|
||||||
}
|
|
||||||
|
|
||||||
type DealStateChanges struct {
|
|
||||||
Added []DealIDState
|
|
||||||
Modified []DealStateChange
|
|
||||||
Removed []DealIDState
|
|
||||||
}
|
|
||||||
|
|
||||||
type DealIDState struct {
|
|
||||||
ID abi.DealID
|
|
||||||
Deal DealState
|
|
||||||
}
|
|
||||||
|
|
||||||
// DealStateChange is a change in deal state from -> to
|
|
||||||
type DealStateChange struct {
|
|
||||||
ID abi.DealID
|
|
||||||
From *DealState
|
|
||||||
To *DealState
|
|
||||||
}
|
|
||||||
|
|
||||||
type DealProposalChanges struct {
|
|
||||||
Added []ProposalIDState
|
|
||||||
Removed []ProposalIDState
|
|
||||||
}
|
|
||||||
|
|
||||||
type ProposalIDState struct {
|
|
||||||
ID abi.DealID
|
|
||||||
Proposal DealProposal
|
|
||||||
}
|
|
||||||
|
|
||||||
func EmptyDealState() *DealState {
|
|
||||||
return &DealState{
|
|
||||||
SectorStartEpoch: -1,
|
|
||||||
SlashEpoch: -1,
|
|
||||||
LastUpdatedEpoch: -1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,204 +0,0 @@
|
|||||||
package market
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
|
|
||||||
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
|
|
||||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ State = (*state0)(nil)
|
|
||||||
|
|
||||||
func load0(store adt.Store, root cid.Cid) (State, error) {
|
|
||||||
out := state0{store: store}
|
|
||||||
err := store.Get(store.Context(), root, &out)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type state0 struct {
|
|
||||||
market0.State
|
|
||||||
store adt.Store
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) TotalLocked() (abi.TokenAmount, error) {
|
|
||||||
fml := types.BigAdd(s.TotalClientLockedCollateral, s.TotalProviderLockedCollateral)
|
|
||||||
fml = types.BigAdd(fml, s.TotalClientStorageFee)
|
|
||||||
return fml, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) BalancesChanged(otherState State) (bool, error) {
|
|
||||||
otherState0, ok := otherState.(*state0)
|
|
||||||
if !ok {
|
|
||||||
// there's no way to compare different versions of the state, so let's
|
|
||||||
// just say that means the state of balances has changed
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
return !s.State.EscrowTable.Equals(otherState0.State.EscrowTable) || !s.State.LockedTable.Equals(otherState0.State.LockedTable), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) StatesChanged(otherState State) (bool, error) {
|
|
||||||
otherState0, ok := otherState.(*state0)
|
|
||||||
if !ok {
|
|
||||||
// there's no way to compare different versions of the state, so let's
|
|
||||||
// just say that means the state of balances has changed
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
return !s.State.States.Equals(otherState0.State.States), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) States() (DealStates, error) {
|
|
||||||
stateArray, err := adt0.AsArray(s.store, s.State.States)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &dealStates0{stateArray}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) ProposalsChanged(otherState State) (bool, error) {
|
|
||||||
otherState0, ok := otherState.(*state0)
|
|
||||||
if !ok {
|
|
||||||
// there's no way to compare different versions of the state, so let's
|
|
||||||
// just say that means the state of balances has changed
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
return !s.State.Proposals.Equals(otherState0.State.Proposals), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) Proposals() (DealProposals, error) {
|
|
||||||
proposalArray, err := adt0.AsArray(s.store, s.State.Proposals)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &dealProposals0{proposalArray}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) EscrowTable() (BalanceTable, error) {
|
|
||||||
bt, err := adt0.AsBalanceTable(s.store, s.State.EscrowTable)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &balanceTable0{bt}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) LockedTable() (BalanceTable, error) {
|
|
||||||
bt, err := adt0.AsBalanceTable(s.store, s.State.LockedTable)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &balanceTable0{bt}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) VerifyDealsForActivation(
|
|
||||||
minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch,
|
|
||||||
) (weight, verifiedWeight abi.DealWeight, err error) {
|
|
||||||
return market0.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch)
|
|
||||||
}
|
|
||||||
|
|
||||||
type balanceTable0 struct {
|
|
||||||
*adt0.BalanceTable
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bt *balanceTable0) ForEach(cb func(address.Address, abi.TokenAmount) error) error {
|
|
||||||
asMap := (*adt0.Map)(bt.BalanceTable)
|
|
||||||
var ta abi.TokenAmount
|
|
||||||
return asMap.ForEach(&ta, func(key string) error {
|
|
||||||
a, err := address.NewFromBytes([]byte(key))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return cb(a, ta)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
type dealStates0 struct {
|
|
||||||
adt.Array
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *dealStates0) Get(dealID abi.DealID) (*DealState, bool, error) {
|
|
||||||
var deal0 market0.DealState
|
|
||||||
found, err := s.Array.Get(uint64(dealID), &deal0)
|
|
||||||
if err != nil {
|
|
||||||
return nil, false, err
|
|
||||||
}
|
|
||||||
if !found {
|
|
||||||
return nil, false, nil
|
|
||||||
}
|
|
||||||
deal := fromV0DealState(deal0)
|
|
||||||
return &deal, true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *dealStates0) ForEach(cb func(dealID abi.DealID, ds DealState) error) error {
|
|
||||||
var ds0 market0.DealState
|
|
||||||
return s.Array.ForEach(&ds0, func(idx int64) error {
|
|
||||||
return cb(abi.DealID(idx), fromV0DealState(ds0))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *dealStates0) decode(val *cbg.Deferred) (*DealState, error) {
|
|
||||||
var ds0 market0.DealState
|
|
||||||
if err := ds0.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
ds := fromV0DealState(ds0)
|
|
||||||
return &ds, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *dealStates0) array() adt.Array {
|
|
||||||
return s.Array
|
|
||||||
}
|
|
||||||
|
|
||||||
func fromV0DealState(v0 market0.DealState) DealState {
|
|
||||||
return (DealState)(v0)
|
|
||||||
}
|
|
||||||
|
|
||||||
type dealProposals0 struct {
|
|
||||||
adt.Array
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *dealProposals0) Get(dealID abi.DealID) (*DealProposal, bool, error) {
|
|
||||||
var proposal0 market0.DealProposal
|
|
||||||
found, err := s.Array.Get(uint64(dealID), &proposal0)
|
|
||||||
if err != nil {
|
|
||||||
return nil, false, err
|
|
||||||
}
|
|
||||||
if !found {
|
|
||||||
return nil, false, nil
|
|
||||||
}
|
|
||||||
proposal := fromV0DealProposal(proposal0)
|
|
||||||
return &proposal, true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *dealProposals0) ForEach(cb func(dealID abi.DealID, dp DealProposal) error) error {
|
|
||||||
var dp0 market0.DealProposal
|
|
||||||
return s.Array.ForEach(&dp0, func(idx int64) error {
|
|
||||||
return cb(abi.DealID(idx), fromV0DealProposal(dp0))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *dealProposals0) decode(val *cbg.Deferred) (*DealProposal, error) {
|
|
||||||
var dp0 market0.DealProposal
|
|
||||||
if err := dp0.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
dp := fromV0DealProposal(dp0)
|
|
||||||
return &dp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *dealProposals0) array() adt.Array {
|
|
||||||
return s.Array
|
|
||||||
}
|
|
||||||
|
|
||||||
func fromV0DealProposal(v0 market0.DealProposal) DealProposal {
|
|
||||||
return (DealProposal)(v0)
|
|
||||||
}
|
|
||||||
@@ -1,205 +0,0 @@
|
|||||||
package market
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
|
|
||||||
market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market"
|
|
||||||
adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ State = (*state2)(nil)
|
|
||||||
|
|
||||||
func load2(store adt.Store, root cid.Cid) (State, error) {
|
|
||||||
out := state2{store: store}
|
|
||||||
err := store.Get(store.Context(), root, &out)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type state2 struct {
|
|
||||||
market2.State
|
|
||||||
store adt.Store
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) TotalLocked() (abi.TokenAmount, error) {
|
|
||||||
fml := types.BigAdd(s.TotalClientLockedCollateral, s.TotalProviderLockedCollateral)
|
|
||||||
fml = types.BigAdd(fml, s.TotalClientStorageFee)
|
|
||||||
return fml, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) BalancesChanged(otherState State) (bool, error) {
|
|
||||||
otherState2, ok := otherState.(*state2)
|
|
||||||
if !ok {
|
|
||||||
// there's no way to compare different versions of the state, so let's
|
|
||||||
// just say that means the state of balances has changed
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
return !s.State.EscrowTable.Equals(otherState2.State.EscrowTable) || !s.State.LockedTable.Equals(otherState2.State.LockedTable), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) StatesChanged(otherState State) (bool, error) {
|
|
||||||
otherState2, ok := otherState.(*state2)
|
|
||||||
if !ok {
|
|
||||||
// there's no way to compare different versions of the state, so let's
|
|
||||||
// just say that means the state of balances has changed
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
return !s.State.States.Equals(otherState2.State.States), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) States() (DealStates, error) {
|
|
||||||
stateArray, err := adt2.AsArray(s.store, s.State.States)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &dealStates2{stateArray}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) ProposalsChanged(otherState State) (bool, error) {
|
|
||||||
otherState2, ok := otherState.(*state2)
|
|
||||||
if !ok {
|
|
||||||
// there's no way to compare different versions of the state, so let's
|
|
||||||
// just say that means the state of balances has changed
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
return !s.State.Proposals.Equals(otherState2.State.Proposals), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) Proposals() (DealProposals, error) {
|
|
||||||
proposalArray, err := adt2.AsArray(s.store, s.State.Proposals)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &dealProposals2{proposalArray}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) EscrowTable() (BalanceTable, error) {
|
|
||||||
bt, err := adt2.AsBalanceTable(s.store, s.State.EscrowTable)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &balanceTable2{bt}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) LockedTable() (BalanceTable, error) {
|
|
||||||
bt, err := adt2.AsBalanceTable(s.store, s.State.LockedTable)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &balanceTable2{bt}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) VerifyDealsForActivation(
|
|
||||||
minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch,
|
|
||||||
) (weight, verifiedWeight abi.DealWeight, err error) {
|
|
||||||
w, vw, _, err := market2.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch)
|
|
||||||
return w, vw, err
|
|
||||||
}
|
|
||||||
|
|
||||||
type balanceTable2 struct {
|
|
||||||
*adt2.BalanceTable
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bt *balanceTable2) ForEach(cb func(address.Address, abi.TokenAmount) error) error {
|
|
||||||
asMap := (*adt2.Map)(bt.BalanceTable)
|
|
||||||
var ta abi.TokenAmount
|
|
||||||
return asMap.ForEach(&ta, func(key string) error {
|
|
||||||
a, err := address.NewFromBytes([]byte(key))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return cb(a, ta)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
type dealStates2 struct {
|
|
||||||
adt.Array
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *dealStates2) Get(dealID abi.DealID) (*DealState, bool, error) {
|
|
||||||
var deal2 market2.DealState
|
|
||||||
found, err := s.Array.Get(uint64(dealID), &deal2)
|
|
||||||
if err != nil {
|
|
||||||
return nil, false, err
|
|
||||||
}
|
|
||||||
if !found {
|
|
||||||
return nil, false, nil
|
|
||||||
}
|
|
||||||
deal := fromV2DealState(deal2)
|
|
||||||
return &deal, true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *dealStates2) ForEach(cb func(dealID abi.DealID, ds DealState) error) error {
|
|
||||||
var ds1 market2.DealState
|
|
||||||
return s.Array.ForEach(&ds1, func(idx int64) error {
|
|
||||||
return cb(abi.DealID(idx), fromV2DealState(ds1))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *dealStates2) decode(val *cbg.Deferred) (*DealState, error) {
|
|
||||||
var ds1 market2.DealState
|
|
||||||
if err := ds1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
ds := fromV2DealState(ds1)
|
|
||||||
return &ds, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *dealStates2) array() adt.Array {
|
|
||||||
return s.Array
|
|
||||||
}
|
|
||||||
|
|
||||||
func fromV2DealState(v1 market2.DealState) DealState {
|
|
||||||
return (DealState)(v1)
|
|
||||||
}
|
|
||||||
|
|
||||||
type dealProposals2 struct {
|
|
||||||
adt.Array
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *dealProposals2) Get(dealID abi.DealID) (*DealProposal, bool, error) {
|
|
||||||
var proposal2 market2.DealProposal
|
|
||||||
found, err := s.Array.Get(uint64(dealID), &proposal2)
|
|
||||||
if err != nil {
|
|
||||||
return nil, false, err
|
|
||||||
}
|
|
||||||
if !found {
|
|
||||||
return nil, false, nil
|
|
||||||
}
|
|
||||||
proposal := fromV2DealProposal(proposal2)
|
|
||||||
return &proposal, true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *dealProposals2) ForEach(cb func(dealID abi.DealID, dp DealProposal) error) error {
|
|
||||||
var dp1 market2.DealProposal
|
|
||||||
return s.Array.ForEach(&dp1, func(idx int64) error {
|
|
||||||
return cb(abi.DealID(idx), fromV2DealProposal(dp1))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *dealProposals2) decode(val *cbg.Deferred) (*DealProposal, error) {
|
|
||||||
var dp1 market2.DealProposal
|
|
||||||
if err := dp1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
dp := fromV2DealProposal(dp1)
|
|
||||||
return &dp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *dealProposals2) array() adt.Array {
|
|
||||||
return s.Array
|
|
||||||
}
|
|
||||||
|
|
||||||
func fromV2DealProposal(v1 market2.DealProposal) DealProposal {
|
|
||||||
return (DealProposal)(v1)
|
|
||||||
}
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
package miner
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
|
||||||
)
|
|
||||||
|
|
||||||
func DiffPreCommits(pre, cur State) (*PreCommitChanges, error) {
|
|
||||||
results := new(PreCommitChanges)
|
|
||||||
|
|
||||||
prep, err := pre.precommits()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
curp, err := cur.precommits()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = adt.DiffAdtMap(prep, curp, &preCommitDiffer{results, pre, cur})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return results, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type preCommitDiffer struct {
|
|
||||||
Results *PreCommitChanges
|
|
||||||
pre, after State
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *preCommitDiffer) AsKey(key string) (abi.Keyer, error) {
|
|
||||||
sector, err := abi.ParseUIntKey(key)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return abi.UIntKey(sector), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *preCommitDiffer) Add(key string, val *cbg.Deferred) error {
|
|
||||||
sp, err := m.after.decodeSectorPreCommitOnChainInfo(val)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
m.Results.Added = append(m.Results.Added, sp)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *preCommitDiffer) Modify(key string, from, to *cbg.Deferred) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *preCommitDiffer) Remove(key string, val *cbg.Deferred) error {
|
|
||||||
sp, err := m.pre.decodeSectorPreCommitOnChainInfo(val)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
m.Results.Removed = append(m.Results.Removed, sp)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func DiffSectors(pre, cur State) (*SectorChanges, error) {
|
|
||||||
results := new(SectorChanges)
|
|
||||||
|
|
||||||
pres, err := pre.sectors()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
curs, err := cur.sectors()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = adt.DiffAdtArray(pres, curs, §orDiffer{results, pre, cur})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return results, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type sectorDiffer struct {
|
|
||||||
Results *SectorChanges
|
|
||||||
pre, after State
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *sectorDiffer) Add(key uint64, val *cbg.Deferred) error {
|
|
||||||
si, err := m.after.decodeSectorOnChainInfo(val)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
m.Results.Added = append(m.Results.Added, si)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *sectorDiffer) Modify(key uint64, from, to *cbg.Deferred) error {
|
|
||||||
siFrom, err := m.pre.decodeSectorOnChainInfo(from)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
siTo, err := m.after.decodeSectorOnChainInfo(to)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if siFrom.Expiration != siTo.Expiration {
|
|
||||||
m.Results.Extended = append(m.Results.Extended, SectorExtensions{
|
|
||||||
From: siFrom,
|
|
||||||
To: siTo,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *sectorDiffer) Remove(key uint64, val *cbg.Deferred) error {
|
|
||||||
si, err := m.pre.decodeSectorOnChainInfo(val)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
m.Results.Removed = append(m.Results.Removed, si)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,176 +0,0 @@
|
|||||||
package miner
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-bitfield"
|
|
||||||
"github.com/filecoin-project/go-state-types/exitcode"
|
|
||||||
)
|
|
||||||
|
|
||||||
type DeadlinesDiff map[uint64]DeadlineDiff
|
|
||||||
|
|
||||||
func DiffDeadlines(pre, cur State) (DeadlinesDiff, error) {
|
|
||||||
changed, err := pre.DeadlinesChanged(cur)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if !changed {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
dlDiff := make(DeadlinesDiff)
|
|
||||||
if err := pre.ForEachDeadline(func(idx uint64, preDl Deadline) error {
|
|
||||||
curDl, err := cur.LoadDeadline(idx)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
diff, err := DiffDeadline(preDl, curDl)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
dlDiff[idx] = diff
|
|
||||||
return nil
|
|
||||||
}); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return dlDiff, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type DeadlineDiff map[uint64]*PartitionDiff
|
|
||||||
|
|
||||||
func DiffDeadline(pre, cur Deadline) (DeadlineDiff, error) {
|
|
||||||
changed, err := pre.PartitionsChanged(cur)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if !changed {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
partDiff := make(DeadlineDiff)
|
|
||||||
if err := pre.ForEachPartition(func(idx uint64, prePart Partition) error {
|
|
||||||
// try loading current partition at this index
|
|
||||||
curPart, err := cur.LoadPartition(idx)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, exitcode.ErrNotFound) {
|
|
||||||
// TODO correctness?
|
|
||||||
return nil // the partition was removed.
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// compare it with the previous partition
|
|
||||||
diff, err := DiffPartition(prePart, curPart)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
partDiff[idx] = diff
|
|
||||||
return nil
|
|
||||||
}); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// all previous partitions have been walked.
|
|
||||||
// all partitions in cur and not in prev are new... can they be faulty already?
|
|
||||||
// TODO is this correct?
|
|
||||||
if err := cur.ForEachPartition(func(idx uint64, curPart Partition) error {
|
|
||||||
if _, found := partDiff[idx]; found {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
faults, err := curPart.FaultySectors()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
recovering, err := curPart.RecoveringSectors()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
partDiff[idx] = &PartitionDiff{
|
|
||||||
Removed: bitfield.New(),
|
|
||||||
Recovered: bitfield.New(),
|
|
||||||
Faulted: faults,
|
|
||||||
Recovering: recovering,
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return partDiff, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type PartitionDiff struct {
|
|
||||||
Removed bitfield.BitField
|
|
||||||
Recovered bitfield.BitField
|
|
||||||
Faulted bitfield.BitField
|
|
||||||
Recovering bitfield.BitField
|
|
||||||
}
|
|
||||||
|
|
||||||
func DiffPartition(pre, cur Partition) (*PartitionDiff, error) {
|
|
||||||
prevLiveSectors, err := pre.LiveSectors()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
curLiveSectors, err := cur.LiveSectors()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
removed, err := bitfield.SubtractBitField(prevLiveSectors, curLiveSectors)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
prevRecoveries, err := pre.RecoveringSectors()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
curRecoveries, err := cur.RecoveringSectors()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
recovering, err := bitfield.SubtractBitField(curRecoveries, prevRecoveries)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
prevFaults, err := pre.FaultySectors()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
curFaults, err := cur.FaultySectors()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
faulted, err := bitfield.SubtractBitField(curFaults, prevFaults)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// all current good sectors
|
|
||||||
curActiveSectors, err := cur.ActiveSectors()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// sectors that were previously fault and are now currently active are considered recovered.
|
|
||||||
recovered, err := bitfield.IntersectBitField(prevFaults, curActiveSectors)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &PartitionDiff{
|
|
||||||
Removed: removed,
|
|
||||||
Recovered: recovered,
|
|
||||||
Faulted: faulted,
|
|
||||||
Recovering: recovering,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
@@ -1,206 +0,0 @@
|
|||||||
package miner
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/filecoin-project/go-state-types/big"
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
"github.com/libp2p/go-libp2p-core/peer"
|
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-bitfield"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/filecoin-project/go-state-types/cbor"
|
|
||||||
"github.com/filecoin-project/go-state-types/dline"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
|
|
||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
|
||||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
builtin.RegisterActorState(builtin0.StorageMinerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
|
||||||
return load0(store, root)
|
|
||||||
})
|
|
||||||
builtin.RegisterActorState(builtin2.StorageMinerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
|
||||||
return load2(store, root)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
var Methods = builtin2.MethodsMiner
|
|
||||||
|
|
||||||
// Unchanged between v0 and v2 actors
|
|
||||||
var WPoStProvingPeriod = miner0.WPoStProvingPeriod
|
|
||||||
var WPoStPeriodDeadlines = miner0.WPoStPeriodDeadlines
|
|
||||||
var WPoStChallengeWindow = miner0.WPoStChallengeWindow
|
|
||||||
var WPoStChallengeLookback = miner0.WPoStChallengeLookback
|
|
||||||
var FaultDeclarationCutoff = miner0.FaultDeclarationCutoff
|
|
||||||
|
|
||||||
const MinSectorExpiration = miner0.MinSectorExpiration
|
|
||||||
|
|
||||||
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
|
||||||
switch act.Code {
|
|
||||||
case builtin0.StorageMinerActorCodeID:
|
|
||||||
return load0(store, act.Head)
|
|
||||||
case builtin2.StorageMinerActorCodeID:
|
|
||||||
return load2(store, act.Head)
|
|
||||||
}
|
|
||||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
|
||||||
}
|
|
||||||
|
|
||||||
type State interface {
|
|
||||||
cbor.Marshaler
|
|
||||||
|
|
||||||
// Total available balance to spend.
|
|
||||||
AvailableBalance(abi.TokenAmount) (abi.TokenAmount, error)
|
|
||||||
// Funds that will vest by the given epoch.
|
|
||||||
VestedFunds(abi.ChainEpoch) (abi.TokenAmount, error)
|
|
||||||
// Funds locked for various reasons.
|
|
||||||
LockedFunds() (LockedFunds, error)
|
|
||||||
FeeDebt() (abi.TokenAmount, error)
|
|
||||||
|
|
||||||
GetSector(abi.SectorNumber) (*SectorOnChainInfo, error)
|
|
||||||
FindSector(abi.SectorNumber) (*SectorLocation, error)
|
|
||||||
GetSectorExpiration(abi.SectorNumber) (*SectorExpiration, error)
|
|
||||||
GetPrecommittedSector(abi.SectorNumber) (*SectorPreCommitOnChainInfo, error)
|
|
||||||
LoadSectors(sectorNos *bitfield.BitField) ([]*SectorOnChainInfo, error)
|
|
||||||
NumLiveSectors() (uint64, error)
|
|
||||||
IsAllocated(abi.SectorNumber) (bool, error)
|
|
||||||
|
|
||||||
LoadDeadline(idx uint64) (Deadline, error)
|
|
||||||
ForEachDeadline(cb func(idx uint64, dl Deadline) error) error
|
|
||||||
NumDeadlines() (uint64, error)
|
|
||||||
DeadlinesChanged(State) (bool, error)
|
|
||||||
|
|
||||||
Info() (MinerInfo, error)
|
|
||||||
MinerInfoChanged(State) (bool, error)
|
|
||||||
|
|
||||||
DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error)
|
|
||||||
|
|
||||||
// Diff helpers. Used by Diff* functions internally.
|
|
||||||
sectors() (adt.Array, error)
|
|
||||||
decodeSectorOnChainInfo(*cbg.Deferred) (SectorOnChainInfo, error)
|
|
||||||
precommits() (adt.Map, error)
|
|
||||||
decodeSectorPreCommitOnChainInfo(*cbg.Deferred) (SectorPreCommitOnChainInfo, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Deadline interface {
|
|
||||||
LoadPartition(idx uint64) (Partition, error)
|
|
||||||
ForEachPartition(cb func(idx uint64, part Partition) error) error
|
|
||||||
PostSubmissions() (bitfield.BitField, error)
|
|
||||||
|
|
||||||
PartitionsChanged(Deadline) (bool, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Partition interface {
|
|
||||||
AllSectors() (bitfield.BitField, error)
|
|
||||||
FaultySectors() (bitfield.BitField, error)
|
|
||||||
RecoveringSectors() (bitfield.BitField, error)
|
|
||||||
LiveSectors() (bitfield.BitField, error)
|
|
||||||
ActiveSectors() (bitfield.BitField, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type SectorOnChainInfo struct {
|
|
||||||
SectorNumber abi.SectorNumber
|
|
||||||
SealProof abi.RegisteredSealProof
|
|
||||||
SealedCID cid.Cid
|
|
||||||
DealIDs []abi.DealID
|
|
||||||
Activation abi.ChainEpoch
|
|
||||||
Expiration abi.ChainEpoch
|
|
||||||
DealWeight abi.DealWeight
|
|
||||||
VerifiedDealWeight abi.DealWeight
|
|
||||||
InitialPledge abi.TokenAmount
|
|
||||||
ExpectedDayReward abi.TokenAmount
|
|
||||||
ExpectedStoragePledge abi.TokenAmount
|
|
||||||
}
|
|
||||||
|
|
||||||
type SectorPreCommitInfo = miner0.SectorPreCommitInfo
|
|
||||||
|
|
||||||
type SectorPreCommitOnChainInfo struct {
|
|
||||||
Info SectorPreCommitInfo
|
|
||||||
PreCommitDeposit abi.TokenAmount
|
|
||||||
PreCommitEpoch abi.ChainEpoch
|
|
||||||
DealWeight abi.DealWeight
|
|
||||||
VerifiedDealWeight abi.DealWeight
|
|
||||||
}
|
|
||||||
|
|
||||||
type PoStPartition = miner0.PoStPartition
|
|
||||||
type RecoveryDeclaration = miner0.RecoveryDeclaration
|
|
||||||
type FaultDeclaration = miner0.FaultDeclaration
|
|
||||||
|
|
||||||
// Params
|
|
||||||
type DeclareFaultsParams = miner0.DeclareFaultsParams
|
|
||||||
type DeclareFaultsRecoveredParams = miner0.DeclareFaultsRecoveredParams
|
|
||||||
type SubmitWindowedPoStParams = miner0.SubmitWindowedPoStParams
|
|
||||||
type ProveCommitSectorParams = miner0.ProveCommitSectorParams
|
|
||||||
|
|
||||||
type MinerInfo struct {
|
|
||||||
Owner address.Address // Must be an ID-address.
|
|
||||||
Worker address.Address // Must be an ID-address.
|
|
||||||
NewWorker address.Address // Must be an ID-address.
|
|
||||||
ControlAddresses []address.Address // Must be an ID-addresses.
|
|
||||||
WorkerChangeEpoch abi.ChainEpoch
|
|
||||||
PeerId *peer.ID
|
|
||||||
Multiaddrs []abi.Multiaddrs
|
|
||||||
SealProofType abi.RegisteredSealProof
|
|
||||||
SectorSize abi.SectorSize
|
|
||||||
WindowPoStPartitionSectors uint64
|
|
||||||
ConsensusFaultElapsed abi.ChainEpoch
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mi MinerInfo) IsController(addr address.Address) bool {
|
|
||||||
if addr == mi.Owner || addr == mi.Worker {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, ca := range mi.ControlAddresses {
|
|
||||||
if addr == ca {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
type SectorExpiration struct {
|
|
||||||
OnTime abi.ChainEpoch
|
|
||||||
|
|
||||||
// non-zero if sector is faulty, epoch at which it will be permanently
|
|
||||||
// removed if it doesn't recover
|
|
||||||
Early abi.ChainEpoch
|
|
||||||
}
|
|
||||||
|
|
||||||
type SectorLocation struct {
|
|
||||||
Deadline uint64
|
|
||||||
Partition uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
type SectorChanges struct {
|
|
||||||
Added []SectorOnChainInfo
|
|
||||||
Extended []SectorExtensions
|
|
||||||
Removed []SectorOnChainInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
type SectorExtensions struct {
|
|
||||||
From SectorOnChainInfo
|
|
||||||
To SectorOnChainInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
type PreCommitChanges struct {
|
|
||||||
Added []SectorPreCommitOnChainInfo
|
|
||||||
Removed []SectorPreCommitOnChainInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
type LockedFunds struct {
|
|
||||||
VestingFunds abi.TokenAmount
|
|
||||||
InitialPledgeRequirement abi.TokenAmount
|
|
||||||
PreCommitDeposits abi.TokenAmount
|
|
||||||
}
|
|
||||||
|
|
||||||
func (lf LockedFunds) TotalLockedFunds() abi.TokenAmount {
|
|
||||||
return big.Add(lf.VestingFunds, big.Add(lf.InitialPledgeRequirement, lf.PreCommitDeposits))
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
package miner
|
|
||||||
|
|
||||||
import (
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-bitfield"
|
|
||||||
)
|
|
||||||
|
|
||||||
func AllPartSectors(mas State, sget func(Partition) (bitfield.BitField, error)) (bitfield.BitField, error) {
|
|
||||||
var parts []bitfield.BitField
|
|
||||||
|
|
||||||
err := mas.ForEachDeadline(func(dlidx uint64, dl Deadline) error {
|
|
||||||
return dl.ForEachPartition(func(partidx uint64, part Partition) error {
|
|
||||||
s, err := sget(part)
|
|
||||||
if err != nil {
|
|
||||||
return xerrors.Errorf("getting sector list (dl: %d, part %d): %w", dlidx, partidx, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
parts = append(parts, s)
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return bitfield.BitField{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return bitfield.MultiMerge(parts...)
|
|
||||||
}
|
|
||||||
@@ -1,407 +0,0 @@
|
|||||||
package miner
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/big"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-bitfield"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/filecoin-project/go-state-types/dline"
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
"github.com/libp2p/go-libp2p-core/peer"
|
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
||||||
|
|
||||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
|
||||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ State = (*state0)(nil)
|
|
||||||
|
|
||||||
func load0(store adt.Store, root cid.Cid) (State, error) {
|
|
||||||
out := state0{store: store}
|
|
||||||
err := store.Get(store.Context(), root, &out)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type state0 struct {
|
|
||||||
miner0.State
|
|
||||||
store adt.Store
|
|
||||||
}
|
|
||||||
|
|
||||||
type deadline0 struct {
|
|
||||||
miner0.Deadline
|
|
||||||
store adt.Store
|
|
||||||
}
|
|
||||||
|
|
||||||
type partition0 struct {
|
|
||||||
miner0.Partition
|
|
||||||
store adt.Store
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) AvailableBalance(bal abi.TokenAmount) (available abi.TokenAmount, err error) {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
err = xerrors.Errorf("failed to get available balance: %w", r)
|
|
||||||
available = abi.NewTokenAmount(0)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
// this panics if the miner doesnt have enough funds to cover their locked pledge
|
|
||||||
available = s.GetAvailableBalance(bal)
|
|
||||||
return available, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) VestedFunds(epoch abi.ChainEpoch) (abi.TokenAmount, error) {
|
|
||||||
return s.CheckVestedFunds(s.store, epoch)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) LockedFunds() (LockedFunds, error) {
|
|
||||||
return LockedFunds{
|
|
||||||
VestingFunds: s.State.LockedFunds,
|
|
||||||
InitialPledgeRequirement: s.State.InitialPledgeRequirement,
|
|
||||||
PreCommitDeposits: s.State.PreCommitDeposits,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) FeeDebt() (abi.TokenAmount, error) {
|
|
||||||
return big.Zero(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) InitialPledge() (abi.TokenAmount, error) {
|
|
||||||
return s.State.InitialPledgeRequirement, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) PreCommitDeposits() (abi.TokenAmount, error) {
|
|
||||||
return s.State.PreCommitDeposits, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) GetSector(num abi.SectorNumber) (*SectorOnChainInfo, error) {
|
|
||||||
info, ok, err := s.State.GetSector(s.store, num)
|
|
||||||
if !ok || err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ret := fromV0SectorOnChainInfo(*info)
|
|
||||||
return &ret, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) FindSector(num abi.SectorNumber) (*SectorLocation, error) {
|
|
||||||
dlIdx, partIdx, err := s.State.FindSector(s.store, num)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &SectorLocation{
|
|
||||||
Deadline: dlIdx,
|
|
||||||
Partition: partIdx,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) NumLiveSectors() (uint64, error) {
|
|
||||||
dls, err := s.State.LoadDeadlines(s.store)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
var total uint64
|
|
||||||
if err := dls.ForEach(s.store, func(dlIdx uint64, dl *miner0.Deadline) error {
|
|
||||||
total += dl.LiveSectors
|
|
||||||
return nil
|
|
||||||
}); err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return total, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetSectorExpiration returns the effective expiration of the given sector.
|
|
||||||
//
|
|
||||||
// If the sector does not expire early, the Early expiration field is 0.
|
|
||||||
func (s *state0) GetSectorExpiration(num abi.SectorNumber) (*SectorExpiration, error) {
|
|
||||||
dls, err := s.State.LoadDeadlines(s.store)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// NOTE: this can be optimized significantly.
|
|
||||||
// 1. If the sector is non-faulty, it will either expire on-time (can be
|
|
||||||
// learned from the sector info), or in the next quantized expiration
|
|
||||||
// epoch (i.e., the first element in the partition's expiration queue.
|
|
||||||
// 2. If it's faulty, it will expire early within the first 14 entries
|
|
||||||
// of the expiration queue.
|
|
||||||
stopErr := errors.New("stop")
|
|
||||||
out := SectorExpiration{}
|
|
||||||
err = dls.ForEach(s.store, func(dlIdx uint64, dl *miner0.Deadline) error {
|
|
||||||
partitions, err := dl.PartitionsArray(s.store)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
quant := s.State.QuantSpecForDeadline(dlIdx)
|
|
||||||
var part miner0.Partition
|
|
||||||
return partitions.ForEach(&part, func(partIdx int64) error {
|
|
||||||
if found, err := part.Sectors.IsSet(uint64(num)); err != nil {
|
|
||||||
return err
|
|
||||||
} else if !found {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if found, err := part.Terminated.IsSet(uint64(num)); err != nil {
|
|
||||||
return err
|
|
||||||
} else if found {
|
|
||||||
// already terminated
|
|
||||||
return stopErr
|
|
||||||
}
|
|
||||||
|
|
||||||
q, err := miner0.LoadExpirationQueue(s.store, part.ExpirationsEpochs, quant)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var exp miner0.ExpirationSet
|
|
||||||
return q.ForEach(&exp, func(epoch int64) error {
|
|
||||||
if early, err := exp.EarlySectors.IsSet(uint64(num)); err != nil {
|
|
||||||
return err
|
|
||||||
} else if early {
|
|
||||||
out.Early = abi.ChainEpoch(epoch)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if onTime, err := exp.OnTimeSectors.IsSet(uint64(num)); err != nil {
|
|
||||||
return err
|
|
||||||
} else if onTime {
|
|
||||||
out.OnTime = abi.ChainEpoch(epoch)
|
|
||||||
return stopErr
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
if err == stopErr {
|
|
||||||
err = nil
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if out.Early == 0 && out.OnTime == 0 {
|
|
||||||
return nil, xerrors.Errorf("failed to find sector %d", num)
|
|
||||||
}
|
|
||||||
return &out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) GetPrecommittedSector(num abi.SectorNumber) (*SectorPreCommitOnChainInfo, error) {
|
|
||||||
info, ok, err := s.State.GetPrecommittedSector(s.store, num)
|
|
||||||
if !ok || err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ret := fromV0SectorPreCommitOnChainInfo(*info)
|
|
||||||
return &ret, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) LoadSectors(snos *bitfield.BitField) ([]*SectorOnChainInfo, error) {
|
|
||||||
sectors, err := miner0.LoadSectors(s.store, s.State.Sectors)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// If no sector numbers are specified, load all.
|
|
||||||
if snos == nil {
|
|
||||||
infos := make([]*SectorOnChainInfo, 0, sectors.Length())
|
|
||||||
var info0 miner0.SectorOnChainInfo
|
|
||||||
if err := sectors.ForEach(&info0, func(_ int64) error {
|
|
||||||
info := fromV0SectorOnChainInfo(info0)
|
|
||||||
infos = append(infos, &info)
|
|
||||||
return nil
|
|
||||||
}); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return infos, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, load selected.
|
|
||||||
infos0, err := sectors.Load(*snos)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
infos := make([]*SectorOnChainInfo, len(infos0))
|
|
||||||
for i, info0 := range infos0 {
|
|
||||||
info := fromV0SectorOnChainInfo(*info0)
|
|
||||||
infos[i] = &info
|
|
||||||
}
|
|
||||||
return infos, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) IsAllocated(num abi.SectorNumber) (bool, error) {
|
|
||||||
var allocatedSectors bitfield.BitField
|
|
||||||
if err := s.store.Get(s.store.Context(), s.State.AllocatedSectors, &allocatedSectors); err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return allocatedSectors.IsSet(uint64(num))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) LoadDeadline(idx uint64) (Deadline, error) {
|
|
||||||
dls, err := s.State.LoadDeadlines(s.store)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
dl, err := dls.LoadDeadline(s.store, idx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &deadline0{*dl, s.store}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) ForEachDeadline(cb func(uint64, Deadline) error) error {
|
|
||||||
dls, err := s.State.LoadDeadlines(s.store)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return dls.ForEach(s.store, func(i uint64, dl *miner0.Deadline) error {
|
|
||||||
return cb(i, &deadline0{*dl, s.store})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) NumDeadlines() (uint64, error) {
|
|
||||||
return miner0.WPoStPeriodDeadlines, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) DeadlinesChanged(other State) (bool, error) {
|
|
||||||
other0, ok := other.(*state0)
|
|
||||||
if !ok {
|
|
||||||
// treat an upgrade as a change, always
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return !s.State.Deadlines.Equals(other0.Deadlines), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) MinerInfoChanged(other State) (bool, error) {
|
|
||||||
other0, ok := other.(*state0)
|
|
||||||
if !ok {
|
|
||||||
// treat an upgrade as a change, always
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
return !s.State.Info.Equals(other0.State.Info), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) Info() (MinerInfo, error) {
|
|
||||||
info, err := s.State.GetInfo(s.store)
|
|
||||||
if err != nil {
|
|
||||||
return MinerInfo{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var pid *peer.ID
|
|
||||||
if peerID, err := peer.IDFromBytes(info.PeerId); err == nil {
|
|
||||||
pid = &peerID
|
|
||||||
}
|
|
||||||
|
|
||||||
mi := MinerInfo{
|
|
||||||
Owner: info.Owner,
|
|
||||||
Worker: info.Worker,
|
|
||||||
ControlAddresses: info.ControlAddresses,
|
|
||||||
|
|
||||||
NewWorker: address.Undef,
|
|
||||||
WorkerChangeEpoch: -1,
|
|
||||||
|
|
||||||
PeerId: pid,
|
|
||||||
Multiaddrs: info.Multiaddrs,
|
|
||||||
SealProofType: info.SealProofType,
|
|
||||||
SectorSize: info.SectorSize,
|
|
||||||
WindowPoStPartitionSectors: info.WindowPoStPartitionSectors,
|
|
||||||
ConsensusFaultElapsed: -1,
|
|
||||||
}
|
|
||||||
|
|
||||||
if info.PendingWorkerKey != nil {
|
|
||||||
mi.NewWorker = info.PendingWorkerKey.NewWorker
|
|
||||||
mi.WorkerChangeEpoch = info.PendingWorkerKey.EffectiveAt
|
|
||||||
}
|
|
||||||
|
|
||||||
return mi, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error) {
|
|
||||||
return s.State.DeadlineInfo(epoch), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) sectors() (adt.Array, error) {
|
|
||||||
return adt0.AsArray(s.store, s.Sectors)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) decodeSectorOnChainInfo(val *cbg.Deferred) (SectorOnChainInfo, error) {
|
|
||||||
var si miner0.SectorOnChainInfo
|
|
||||||
err := si.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
|
||||||
if err != nil {
|
|
||||||
return SectorOnChainInfo{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return fromV0SectorOnChainInfo(si), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) precommits() (adt.Map, error) {
|
|
||||||
return adt0.AsMap(s.store, s.PreCommittedSectors)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreCommitOnChainInfo, error) {
|
|
||||||
var sp miner0.SectorPreCommitOnChainInfo
|
|
||||||
err := sp.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
|
||||||
if err != nil {
|
|
||||||
return SectorPreCommitOnChainInfo{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return fromV0SectorPreCommitOnChainInfo(sp), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *deadline0) LoadPartition(idx uint64) (Partition, error) {
|
|
||||||
p, err := d.Deadline.LoadPartition(d.store, idx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &partition0{*p, d.store}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *deadline0) ForEachPartition(cb func(uint64, Partition) error) error {
|
|
||||||
ps, err := d.Deadline.PartitionsArray(d.store)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var part miner0.Partition
|
|
||||||
return ps.ForEach(&part, func(i int64) error {
|
|
||||||
return cb(uint64(i), &partition0{part, d.store})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *deadline0) PartitionsChanged(other Deadline) (bool, error) {
|
|
||||||
other0, ok := other.(*deadline0)
|
|
||||||
if !ok {
|
|
||||||
// treat an upgrade as a change, always
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return !d.Deadline.Partitions.Equals(other0.Deadline.Partitions), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *deadline0) PostSubmissions() (bitfield.BitField, error) {
|
|
||||||
return d.Deadline.PostSubmissions, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *partition0) AllSectors() (bitfield.BitField, error) {
|
|
||||||
return p.Partition.Sectors, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *partition0) FaultySectors() (bitfield.BitField, error) {
|
|
||||||
return p.Partition.Faults, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *partition0) RecoveringSectors() (bitfield.BitField, error) {
|
|
||||||
return p.Partition.Recoveries, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func fromV0SectorOnChainInfo(v0 miner0.SectorOnChainInfo) SectorOnChainInfo {
|
|
||||||
return (SectorOnChainInfo)(v0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func fromV0SectorPreCommitOnChainInfo(v0 miner0.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo {
|
|
||||||
return (SectorPreCommitOnChainInfo)(v0)
|
|
||||||
}
|
|
||||||
@@ -1,424 +0,0 @@
|
|||||||
package miner
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-bitfield"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/filecoin-project/go-state-types/dline"
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
"github.com/libp2p/go-libp2p-core/peer"
|
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
||||||
|
|
||||||
miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner"
|
|
||||||
adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ State = (*state2)(nil)
|
|
||||||
|
|
||||||
func load2(store adt.Store, root cid.Cid) (State, error) {
|
|
||||||
out := state2{store: store}
|
|
||||||
err := store.Get(store.Context(), root, &out)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type state2 struct {
|
|
||||||
miner2.State
|
|
||||||
store adt.Store
|
|
||||||
}
|
|
||||||
|
|
||||||
type deadline2 struct {
|
|
||||||
miner2.Deadline
|
|
||||||
store adt.Store
|
|
||||||
}
|
|
||||||
|
|
||||||
type partition2 struct {
|
|
||||||
miner2.Partition
|
|
||||||
store adt.Store
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) AvailableBalance(bal abi.TokenAmount) (available abi.TokenAmount, err error) {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
err = xerrors.Errorf("failed to get available balance: %w", r)
|
|
||||||
available = abi.NewTokenAmount(0)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
// this panics if the miner doesnt have enough funds to cover their locked pledge
|
|
||||||
available, err = s.GetAvailableBalance(bal)
|
|
||||||
return available, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) VestedFunds(epoch abi.ChainEpoch) (abi.TokenAmount, error) {
|
|
||||||
return s.CheckVestedFunds(s.store, epoch)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) LockedFunds() (LockedFunds, error) {
|
|
||||||
return LockedFunds{
|
|
||||||
VestingFunds: s.State.LockedFunds,
|
|
||||||
InitialPledgeRequirement: s.State.InitialPledge,
|
|
||||||
PreCommitDeposits: s.State.PreCommitDeposits,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) FeeDebt() (abi.TokenAmount, error) {
|
|
||||||
return s.State.FeeDebt, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) InitialPledge() (abi.TokenAmount, error) {
|
|
||||||
return s.State.InitialPledge, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) PreCommitDeposits() (abi.TokenAmount, error) {
|
|
||||||
return s.State.PreCommitDeposits, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) GetSector(num abi.SectorNumber) (*SectorOnChainInfo, error) {
|
|
||||||
info, ok, err := s.State.GetSector(s.store, num)
|
|
||||||
if !ok || err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ret := fromV2SectorOnChainInfo(*info)
|
|
||||||
return &ret, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) FindSector(num abi.SectorNumber) (*SectorLocation, error) {
|
|
||||||
dlIdx, partIdx, err := s.State.FindSector(s.store, num)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &SectorLocation{
|
|
||||||
Deadline: dlIdx,
|
|
||||||
Partition: partIdx,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) NumLiveSectors() (uint64, error) {
|
|
||||||
dls, err := s.State.LoadDeadlines(s.store)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
var total uint64
|
|
||||||
if err := dls.ForEach(s.store, func(dlIdx uint64, dl *miner2.Deadline) error {
|
|
||||||
total += dl.LiveSectors
|
|
||||||
return nil
|
|
||||||
}); err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return total, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetSectorExpiration returns the effective expiration of the given sector.
|
|
||||||
//
|
|
||||||
// If the sector does not expire early, the Early expiration field is 0.
|
|
||||||
func (s *state2) GetSectorExpiration(num abi.SectorNumber) (*SectorExpiration, error) {
|
|
||||||
dls, err := s.State.LoadDeadlines(s.store)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// NOTE: this can be optimized significantly.
|
|
||||||
// 1. If the sector is non-faulty, it will either expire on-time (can be
|
|
||||||
// learned from the sector info), or in the next quantized expiration
|
|
||||||
// epoch (i.e., the first element in the partition's expiration queue.
|
|
||||||
// 2. If it's faulty, it will expire early within the first 14 entries
|
|
||||||
// of the expiration queue.
|
|
||||||
stopErr := errors.New("stop")
|
|
||||||
out := SectorExpiration{}
|
|
||||||
err = dls.ForEach(s.store, func(dlIdx uint64, dl *miner2.Deadline) error {
|
|
||||||
partitions, err := dl.PartitionsArray(s.store)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
quant := s.State.QuantSpecForDeadline(dlIdx)
|
|
||||||
var part miner2.Partition
|
|
||||||
return partitions.ForEach(&part, func(partIdx int64) error {
|
|
||||||
if found, err := part.Sectors.IsSet(uint64(num)); err != nil {
|
|
||||||
return err
|
|
||||||
} else if !found {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if found, err := part.Terminated.IsSet(uint64(num)); err != nil {
|
|
||||||
return err
|
|
||||||
} else if found {
|
|
||||||
// already terminated
|
|
||||||
return stopErr
|
|
||||||
}
|
|
||||||
|
|
||||||
q, err := miner2.LoadExpirationQueue(s.store, part.ExpirationsEpochs, quant)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var exp miner2.ExpirationSet
|
|
||||||
return q.ForEach(&exp, func(epoch int64) error {
|
|
||||||
if early, err := exp.EarlySectors.IsSet(uint64(num)); err != nil {
|
|
||||||
return err
|
|
||||||
} else if early {
|
|
||||||
out.Early = abi.ChainEpoch(epoch)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if onTime, err := exp.OnTimeSectors.IsSet(uint64(num)); err != nil {
|
|
||||||
return err
|
|
||||||
} else if onTime {
|
|
||||||
out.OnTime = abi.ChainEpoch(epoch)
|
|
||||||
return stopErr
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
if err == stopErr {
|
|
||||||
err = nil
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if out.Early == 0 && out.OnTime == 0 {
|
|
||||||
return nil, xerrors.Errorf("failed to find sector %d", num)
|
|
||||||
}
|
|
||||||
return &out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) GetPrecommittedSector(num abi.SectorNumber) (*SectorPreCommitOnChainInfo, error) {
|
|
||||||
info, ok, err := s.State.GetPrecommittedSector(s.store, num)
|
|
||||||
if !ok || err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ret := fromV2SectorPreCommitOnChainInfo(*info)
|
|
||||||
|
|
||||||
return &ret, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) LoadSectors(snos *bitfield.BitField) ([]*SectorOnChainInfo, error) {
|
|
||||||
sectors, err := miner2.LoadSectors(s.store, s.State.Sectors)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// If no sector numbers are specified, load all.
|
|
||||||
if snos == nil {
|
|
||||||
infos := make([]*SectorOnChainInfo, 0, sectors.Length())
|
|
||||||
var info2 miner2.SectorOnChainInfo
|
|
||||||
if err := sectors.ForEach(&info2, func(_ int64) error {
|
|
||||||
info := fromV2SectorOnChainInfo(info2)
|
|
||||||
infos = append(infos, &info)
|
|
||||||
return nil
|
|
||||||
}); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return infos, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, load selected.
|
|
||||||
infos2, err := sectors.Load(*snos)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
infos := make([]*SectorOnChainInfo, len(infos2))
|
|
||||||
for i, info2 := range infos2 {
|
|
||||||
info := fromV2SectorOnChainInfo(*info2)
|
|
||||||
infos[i] = &info
|
|
||||||
}
|
|
||||||
return infos, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) IsAllocated(num abi.SectorNumber) (bool, error) {
|
|
||||||
var allocatedSectors bitfield.BitField
|
|
||||||
if err := s.store.Get(s.store.Context(), s.State.AllocatedSectors, &allocatedSectors); err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return allocatedSectors.IsSet(uint64(num))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) LoadDeadline(idx uint64) (Deadline, error) {
|
|
||||||
dls, err := s.State.LoadDeadlines(s.store)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
dl, err := dls.LoadDeadline(s.store, idx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &deadline2{*dl, s.store}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) ForEachDeadline(cb func(uint64, Deadline) error) error {
|
|
||||||
dls, err := s.State.LoadDeadlines(s.store)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return dls.ForEach(s.store, func(i uint64, dl *miner2.Deadline) error {
|
|
||||||
return cb(i, &deadline2{*dl, s.store})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) NumDeadlines() (uint64, error) {
|
|
||||||
return miner2.WPoStPeriodDeadlines, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) DeadlinesChanged(other State) (bool, error) {
|
|
||||||
other2, ok := other.(*state2)
|
|
||||||
if !ok {
|
|
||||||
// treat an upgrade as a change, always
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return !s.State.Deadlines.Equals(other2.Deadlines), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) MinerInfoChanged(other State) (bool, error) {
|
|
||||||
other0, ok := other.(*state2)
|
|
||||||
if !ok {
|
|
||||||
// treat an upgrade as a change, always
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
return !s.State.Info.Equals(other0.State.Info), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) Info() (MinerInfo, error) {
|
|
||||||
info, err := s.State.GetInfo(s.store)
|
|
||||||
if err != nil {
|
|
||||||
return MinerInfo{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var pid *peer.ID
|
|
||||||
if peerID, err := peer.IDFromBytes(info.PeerId); err == nil {
|
|
||||||
pid = &peerID
|
|
||||||
}
|
|
||||||
|
|
||||||
mi := MinerInfo{
|
|
||||||
Owner: info.Owner,
|
|
||||||
Worker: info.Worker,
|
|
||||||
ControlAddresses: info.ControlAddresses,
|
|
||||||
|
|
||||||
NewWorker: address.Undef,
|
|
||||||
WorkerChangeEpoch: -1,
|
|
||||||
|
|
||||||
PeerId: pid,
|
|
||||||
Multiaddrs: info.Multiaddrs,
|
|
||||||
SealProofType: info.SealProofType,
|
|
||||||
SectorSize: info.SectorSize,
|
|
||||||
WindowPoStPartitionSectors: info.WindowPoStPartitionSectors,
|
|
||||||
ConsensusFaultElapsed: info.ConsensusFaultElapsed,
|
|
||||||
}
|
|
||||||
|
|
||||||
if info.PendingWorkerKey != nil {
|
|
||||||
mi.NewWorker = info.PendingWorkerKey.NewWorker
|
|
||||||
mi.WorkerChangeEpoch = info.PendingWorkerKey.EffectiveAt
|
|
||||||
}
|
|
||||||
|
|
||||||
return mi, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error) {
|
|
||||||
return s.State.DeadlineInfo(epoch), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) sectors() (adt.Array, error) {
|
|
||||||
return adt2.AsArray(s.store, s.Sectors)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) decodeSectorOnChainInfo(val *cbg.Deferred) (SectorOnChainInfo, error) {
|
|
||||||
var si miner2.SectorOnChainInfo
|
|
||||||
err := si.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
|
||||||
if err != nil {
|
|
||||||
return SectorOnChainInfo{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return fromV2SectorOnChainInfo(si), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) precommits() (adt.Map, error) {
|
|
||||||
return adt2.AsMap(s.store, s.PreCommittedSectors)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreCommitOnChainInfo, error) {
|
|
||||||
var sp miner2.SectorPreCommitOnChainInfo
|
|
||||||
err := sp.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
|
||||||
if err != nil {
|
|
||||||
return SectorPreCommitOnChainInfo{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return fromV2SectorPreCommitOnChainInfo(sp), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *deadline2) LoadPartition(idx uint64) (Partition, error) {
|
|
||||||
p, err := d.Deadline.LoadPartition(d.store, idx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &partition2{*p, d.store}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *deadline2) ForEachPartition(cb func(uint64, Partition) error) error {
|
|
||||||
ps, err := d.Deadline.PartitionsArray(d.store)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var part miner2.Partition
|
|
||||||
return ps.ForEach(&part, func(i int64) error {
|
|
||||||
return cb(uint64(i), &partition2{part, d.store})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *deadline2) PartitionsChanged(other Deadline) (bool, error) {
|
|
||||||
other2, ok := other.(*deadline2)
|
|
||||||
if !ok {
|
|
||||||
// treat an upgrade as a change, always
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return !d.Deadline.Partitions.Equals(other2.Deadline.Partitions), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *deadline2) PostSubmissions() (bitfield.BitField, error) {
|
|
||||||
return d.Deadline.PostSubmissions, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *partition2) AllSectors() (bitfield.BitField, error) {
|
|
||||||
return p.Partition.Sectors, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *partition2) FaultySectors() (bitfield.BitField, error) {
|
|
||||||
return p.Partition.Faults, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *partition2) RecoveringSectors() (bitfield.BitField, error) {
|
|
||||||
return p.Partition.Recoveries, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func fromV2SectorOnChainInfo(v2 miner2.SectorOnChainInfo) SectorOnChainInfo {
|
|
||||||
return SectorOnChainInfo{
|
|
||||||
SectorNumber: v2.SectorNumber,
|
|
||||||
SealProof: v2.SealProof,
|
|
||||||
SealedCID: v2.SealedCID,
|
|
||||||
DealIDs: v2.DealIDs,
|
|
||||||
Activation: v2.Activation,
|
|
||||||
Expiration: v2.Expiration,
|
|
||||||
DealWeight: v2.DealWeight,
|
|
||||||
VerifiedDealWeight: v2.VerifiedDealWeight,
|
|
||||||
InitialPledge: v2.InitialPledge,
|
|
||||||
ExpectedDayReward: v2.ExpectedDayReward,
|
|
||||||
ExpectedStoragePledge: v2.ExpectedStoragePledge,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func fromV2SectorPreCommitOnChainInfo(v2 miner2.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo {
|
|
||||||
return SectorPreCommitOnChainInfo{
|
|
||||||
Info: (SectorPreCommitInfo)(v2.Info),
|
|
||||||
PreCommitDeposit: v2.PreCommitDeposit,
|
|
||||||
PreCommitEpoch: v2.PreCommitEpoch,
|
|
||||||
DealWeight: v2.DealWeight,
|
|
||||||
VerifiedDealWeight: v2.VerifiedDealWeight,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
package multisig
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
||||||
)
|
|
||||||
|
|
||||||
type PendingTransactionChanges struct {
|
|
||||||
Added []TransactionChange
|
|
||||||
Modified []TransactionModification
|
|
||||||
Removed []TransactionChange
|
|
||||||
}
|
|
||||||
|
|
||||||
type TransactionChange struct {
|
|
||||||
TxID int64
|
|
||||||
Tx Transaction
|
|
||||||
}
|
|
||||||
|
|
||||||
type TransactionModification struct {
|
|
||||||
TxID int64
|
|
||||||
From Transaction
|
|
||||||
To Transaction
|
|
||||||
}
|
|
||||||
|
|
||||||
func DiffPendingTransactions(pre, cur State) (*PendingTransactionChanges, error) {
|
|
||||||
results := new(PendingTransactionChanges)
|
|
||||||
if changed, err := pre.PendingTxnChanged(cur); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else if !changed { // if nothing has changed then return an empty result and bail.
|
|
||||||
return results, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
pret, err := pre.transactions()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
curt, err := cur.transactions()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := adt.DiffAdtMap(pret, curt, &transactionDiffer{results, pre, cur}); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return results, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type transactionDiffer struct {
|
|
||||||
Results *PendingTransactionChanges
|
|
||||||
pre, after State
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *transactionDiffer) AsKey(key string) (abi.Keyer, error) {
|
|
||||||
txID, err := abi.ParseIntKey(key)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return abi.IntKey(txID), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *transactionDiffer) Add(key string, val *cbg.Deferred) error {
|
|
||||||
txID, err := abi.ParseIntKey(key)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
tx, err := t.after.decodeTransaction(val)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
t.Results.Added = append(t.Results.Added, TransactionChange{
|
|
||||||
TxID: txID,
|
|
||||||
Tx: tx,
|
|
||||||
})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *transactionDiffer) Modify(key string, from, to *cbg.Deferred) error {
|
|
||||||
txID, err := abi.ParseIntKey(key)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
txFrom, err := t.pre.decodeTransaction(from)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
txTo, err := t.after.decodeTransaction(to)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if approvalsChanged(txFrom.Approved, txTo.Approved) {
|
|
||||||
t.Results.Modified = append(t.Results.Modified, TransactionModification{
|
|
||||||
TxID: txID,
|
|
||||||
From: txFrom,
|
|
||||||
To: txTo,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func approvalsChanged(from, to []address.Address) bool {
|
|
||||||
if len(from) != len(to) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
for idx := range from {
|
|
||||||
if from[idx] != to[idx] {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *transactionDiffer) Remove(key string, val *cbg.Deferred) error {
|
|
||||||
txID, err := abi.ParseIntKey(key)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
tx, err := t.pre.decodeTransaction(val)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
t.Results.Removed = append(t.Results.Removed, TransactionChange{
|
|
||||||
TxID: txID,
|
|
||||||
Tx: tx,
|
|
||||||
})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
package multisig
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/minio/blake2b-simd"
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
|
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
|
||||||
multisig2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
var Methods = builtin2.MethodsMultisig
|
|
||||||
|
|
||||||
func Message(version actors.Version, from address.Address) MessageBuilder {
|
|
||||||
switch version {
|
|
||||||
case actors.Version0:
|
|
||||||
return message0{from}
|
|
||||||
case actors.Version2:
|
|
||||||
return message2{message0{from}}
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("unsupported actors version: %d", version))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type MessageBuilder interface {
|
|
||||||
// Create a new multisig with the specified parameters.
|
|
||||||
Create(signers []address.Address, threshold uint64,
|
|
||||||
vestingStart, vestingDuration abi.ChainEpoch,
|
|
||||||
initialAmount abi.TokenAmount) (*types.Message, error)
|
|
||||||
|
|
||||||
// Propose a transaction to the given multisig.
|
|
||||||
Propose(msig, target address.Address, amt abi.TokenAmount,
|
|
||||||
method abi.MethodNum, params []byte) (*types.Message, error)
|
|
||||||
|
|
||||||
// Approve a multisig transaction. The "hash" is optional.
|
|
||||||
Approve(msig address.Address, txID uint64, hash *ProposalHashData) (*types.Message, error)
|
|
||||||
|
|
||||||
// Cancel a multisig transaction. The "hash" is optional.
|
|
||||||
Cancel(msig address.Address, txID uint64, hash *ProposalHashData) (*types.Message, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// this type is the same between v0 and v2
|
|
||||||
type ProposalHashData = multisig2.ProposalHashData
|
|
||||||
type ProposeReturn = multisig2.ProposeReturn
|
|
||||||
|
|
||||||
func txnParams(id uint64, data *ProposalHashData) ([]byte, error) {
|
|
||||||
params := multisig2.TxnIDParams{ID: multisig2.TxnID(id)}
|
|
||||||
if data != nil {
|
|
||||||
if data.Requester.Protocol() != address.ID {
|
|
||||||
return nil, xerrors.Errorf("proposer address must be an ID address, was %s", data.Requester)
|
|
||||||
}
|
|
||||||
if data.Value.Sign() == -1 {
|
|
||||||
return nil, xerrors.Errorf("proposal value must be non-negative, was %s", data.Value)
|
|
||||||
}
|
|
||||||
if data.To == address.Undef {
|
|
||||||
return nil, xerrors.Errorf("proposed destination address must be set")
|
|
||||||
}
|
|
||||||
pser, err := data.Serialize()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
hash := blake2b.Sum256(pser)
|
|
||||||
params.ProposalHash = hash[:]
|
|
||||||
}
|
|
||||||
|
|
||||||
return actors.SerializeParams(¶ms)
|
|
||||||
}
|
|
||||||
@@ -1,142 +0,0 @@
|
|||||||
package multisig
|
|
||||||
|
|
||||||
import (
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
|
|
||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
|
||||||
init0 "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
|
||||||
multisig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors"
|
|
||||||
init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
type message0 struct{ from address.Address }
|
|
||||||
|
|
||||||
func (m message0) Create(
|
|
||||||
signers []address.Address, threshold uint64,
|
|
||||||
unlockStart, unlockDuration abi.ChainEpoch,
|
|
||||||
initialAmount abi.TokenAmount,
|
|
||||||
) (*types.Message, error) {
|
|
||||||
|
|
||||||
lenAddrs := uint64(len(signers))
|
|
||||||
|
|
||||||
if lenAddrs < threshold {
|
|
||||||
return nil, xerrors.Errorf("cannot require signing of more addresses than provided for multisig")
|
|
||||||
}
|
|
||||||
|
|
||||||
if threshold == 0 {
|
|
||||||
threshold = lenAddrs
|
|
||||||
}
|
|
||||||
|
|
||||||
if m.from == address.Undef {
|
|
||||||
return nil, xerrors.Errorf("must provide source address")
|
|
||||||
}
|
|
||||||
|
|
||||||
if unlockStart != 0 {
|
|
||||||
return nil, xerrors.Errorf("actors v0 does not support a non-zero vesting start time")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up constructor parameters for multisig
|
|
||||||
msigParams := &multisig0.ConstructorParams{
|
|
||||||
Signers: signers,
|
|
||||||
NumApprovalsThreshold: threshold,
|
|
||||||
UnlockDuration: unlockDuration,
|
|
||||||
}
|
|
||||||
|
|
||||||
enc, actErr := actors.SerializeParams(msigParams)
|
|
||||||
if actErr != nil {
|
|
||||||
return nil, actErr
|
|
||||||
}
|
|
||||||
|
|
||||||
// new actors are created by invoking 'exec' on the init actor with the constructor params
|
|
||||||
execParams := &init0.ExecParams{
|
|
||||||
CodeCID: builtin0.MultisigActorCodeID,
|
|
||||||
ConstructorParams: enc,
|
|
||||||
}
|
|
||||||
|
|
||||||
enc, actErr = actors.SerializeParams(execParams)
|
|
||||||
if actErr != nil {
|
|
||||||
return nil, actErr
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.Message{
|
|
||||||
To: init_.Address,
|
|
||||||
From: m.from,
|
|
||||||
Method: builtin0.MethodsInit.Exec,
|
|
||||||
Params: enc,
|
|
||||||
Value: initialAmount,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m message0) Propose(msig, to address.Address, amt abi.TokenAmount,
|
|
||||||
method abi.MethodNum, params []byte) (*types.Message, error) {
|
|
||||||
|
|
||||||
if msig == address.Undef {
|
|
||||||
return nil, xerrors.Errorf("must provide a multisig address for proposal")
|
|
||||||
}
|
|
||||||
|
|
||||||
if to == address.Undef {
|
|
||||||
return nil, xerrors.Errorf("must provide a target address for proposal")
|
|
||||||
}
|
|
||||||
|
|
||||||
if amt.Sign() == -1 {
|
|
||||||
return nil, xerrors.Errorf("must provide a non-negative amount for proposed send")
|
|
||||||
}
|
|
||||||
|
|
||||||
if m.from == address.Undef {
|
|
||||||
return nil, xerrors.Errorf("must provide source address")
|
|
||||||
}
|
|
||||||
|
|
||||||
enc, actErr := actors.SerializeParams(&multisig0.ProposeParams{
|
|
||||||
To: to,
|
|
||||||
Value: amt,
|
|
||||||
Method: method,
|
|
||||||
Params: params,
|
|
||||||
})
|
|
||||||
if actErr != nil {
|
|
||||||
return nil, xerrors.Errorf("failed to serialize parameters: %w", actErr)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.Message{
|
|
||||||
To: msig,
|
|
||||||
From: m.from,
|
|
||||||
Value: abi.NewTokenAmount(0),
|
|
||||||
Method: builtin0.MethodsMultisig.Propose,
|
|
||||||
Params: enc,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m message0) Approve(msig address.Address, txID uint64, hashData *ProposalHashData) (*types.Message, error) {
|
|
||||||
enc, err := txnParams(txID, hashData)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.Message{
|
|
||||||
To: msig,
|
|
||||||
From: m.from,
|
|
||||||
Value: types.NewInt(0),
|
|
||||||
Method: builtin0.MethodsMultisig.Approve,
|
|
||||||
Params: enc,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m message0) Cancel(msig address.Address, txID uint64, hashData *ProposalHashData) (*types.Message, error) {
|
|
||||||
enc, err := txnParams(txID, hashData)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.Message{
|
|
||||||
To: msig,
|
|
||||||
From: m.from,
|
|
||||||
Value: types.NewInt(0),
|
|
||||||
Method: builtin0.MethodsMultisig.Cancel,
|
|
||||||
Params: enc,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
package multisig
|
|
||||||
|
|
||||||
import (
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
|
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
|
||||||
init2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/init"
|
|
||||||
multisig2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors"
|
|
||||||
init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
type message2 struct{ message0 }
|
|
||||||
|
|
||||||
func (m message2) Create(
|
|
||||||
signers []address.Address, threshold uint64,
|
|
||||||
unlockStart, unlockDuration abi.ChainEpoch,
|
|
||||||
initialAmount abi.TokenAmount,
|
|
||||||
) (*types.Message, error) {
|
|
||||||
|
|
||||||
lenAddrs := uint64(len(signers))
|
|
||||||
|
|
||||||
if lenAddrs < threshold {
|
|
||||||
return nil, xerrors.Errorf("cannot require signing of more addresses than provided for multisig")
|
|
||||||
}
|
|
||||||
|
|
||||||
if threshold == 0 {
|
|
||||||
threshold = lenAddrs
|
|
||||||
}
|
|
||||||
|
|
||||||
if m.from == address.Undef {
|
|
||||||
return nil, xerrors.Errorf("must provide source address")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up constructor parameters for multisig
|
|
||||||
msigParams := &multisig2.ConstructorParams{
|
|
||||||
Signers: signers,
|
|
||||||
NumApprovalsThreshold: threshold,
|
|
||||||
UnlockDuration: unlockDuration,
|
|
||||||
StartEpoch: unlockStart,
|
|
||||||
}
|
|
||||||
|
|
||||||
enc, actErr := actors.SerializeParams(msigParams)
|
|
||||||
if actErr != nil {
|
|
||||||
return nil, actErr
|
|
||||||
}
|
|
||||||
|
|
||||||
// new actors are created by invoking 'exec' on the init actor with the constructor params
|
|
||||||
execParams := &init2.ExecParams{
|
|
||||||
CodeCID: builtin2.MultisigActorCodeID,
|
|
||||||
ConstructorParams: enc,
|
|
||||||
}
|
|
||||||
|
|
||||||
enc, actErr = actors.SerializeParams(execParams)
|
|
||||||
if actErr != nil {
|
|
||||||
return nil, actErr
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.Message{
|
|
||||||
To: init_.Address,
|
|
||||||
From: m.from,
|
|
||||||
Method: builtin2.MethodsInit.Exec,
|
|
||||||
Params: enc,
|
|
||||||
Value: initialAmount,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
package multisig
|
|
||||||
|
|
||||||
import (
|
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/filecoin-project/go-state-types/cbor"
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
|
|
||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
|
||||||
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
builtin.RegisterActorState(builtin0.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
|
||||||
return load0(store, root)
|
|
||||||
})
|
|
||||||
builtin.RegisterActorState(builtin2.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
|
||||||
return load2(store, root)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
|
||||||
switch act.Code {
|
|
||||||
case builtin0.MultisigActorCodeID:
|
|
||||||
return load0(store, act.Head)
|
|
||||||
case builtin2.MultisigActorCodeID:
|
|
||||||
return load2(store, act.Head)
|
|
||||||
}
|
|
||||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
|
||||||
}
|
|
||||||
|
|
||||||
type State interface {
|
|
||||||
cbor.Marshaler
|
|
||||||
|
|
||||||
LockedBalance(epoch abi.ChainEpoch) (abi.TokenAmount, error)
|
|
||||||
StartEpoch() (abi.ChainEpoch, error)
|
|
||||||
UnlockDuration() (abi.ChainEpoch, error)
|
|
||||||
InitialBalance() (abi.TokenAmount, error)
|
|
||||||
Threshold() (uint64, error)
|
|
||||||
Signers() ([]address.Address, error)
|
|
||||||
|
|
||||||
ForEachPendingTxn(func(id int64, txn Transaction) error) error
|
|
||||||
PendingTxnChanged(State) (bool, error)
|
|
||||||
|
|
||||||
transactions() (adt.Map, error)
|
|
||||||
decodeTransaction(val *cbg.Deferred) (Transaction, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Transaction = msig0.Transaction
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
package multisig
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/binary"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
||||||
|
|
||||||
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
|
||||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
|
||||||
multisig0 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ State = (*state0)(nil)
|
|
||||||
|
|
||||||
func load0(store adt.Store, root cid.Cid) (State, error) {
|
|
||||||
out := state0{store: store}
|
|
||||||
err := store.Get(store.Context(), root, &out)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type state0 struct {
|
|
||||||
msig0.State
|
|
||||||
store adt.Store
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) LockedBalance(currEpoch abi.ChainEpoch) (abi.TokenAmount, error) {
|
|
||||||
return s.State.AmountLocked(currEpoch - s.State.StartEpoch), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) StartEpoch() (abi.ChainEpoch, error) {
|
|
||||||
return s.State.StartEpoch, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) UnlockDuration() (abi.ChainEpoch, error) {
|
|
||||||
return s.State.UnlockDuration, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) InitialBalance() (abi.TokenAmount, error) {
|
|
||||||
return s.State.InitialBalance, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) Threshold() (uint64, error) {
|
|
||||||
return s.State.NumApprovalsThreshold, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) Signers() ([]address.Address, error) {
|
|
||||||
return s.State.Signers, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) ForEachPendingTxn(cb func(id int64, txn Transaction) error) error {
|
|
||||||
arr, err := adt0.AsMap(s.store, s.State.PendingTxns)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var out msig0.Transaction
|
|
||||||
return arr.ForEach(&out, func(key string) error {
|
|
||||||
txid, n := binary.Varint([]byte(key))
|
|
||||||
if n <= 0 {
|
|
||||||
return xerrors.Errorf("invalid pending transaction key: %v", key)
|
|
||||||
}
|
|
||||||
return cb(txid, (Transaction)(out))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) PendingTxnChanged(other State) (bool, error) {
|
|
||||||
other0, ok := other.(*state0)
|
|
||||||
if !ok {
|
|
||||||
// treat an upgrade as a change, always
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
return !s.State.PendingTxns.Equals(other0.PendingTxns), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) transactions() (adt.Map, error) {
|
|
||||||
return adt0.AsMap(s.store, s.PendingTxns)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) decodeTransaction(val *cbg.Deferred) (Transaction, error) {
|
|
||||||
var tx multisig0.Transaction
|
|
||||||
if err := tx.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
|
||||||
return Transaction{}, err
|
|
||||||
}
|
|
||||||
return tx, nil
|
|
||||||
}
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
package multisig
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/binary"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
||||||
|
|
||||||
msig2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig"
|
|
||||||
adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ State = (*state2)(nil)
|
|
||||||
|
|
||||||
func load2(store adt.Store, root cid.Cid) (State, error) {
|
|
||||||
out := state2{store: store}
|
|
||||||
err := store.Get(store.Context(), root, &out)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type state2 struct {
|
|
||||||
msig2.State
|
|
||||||
store adt.Store
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) LockedBalance(currEpoch abi.ChainEpoch) (abi.TokenAmount, error) {
|
|
||||||
return s.State.AmountLocked(currEpoch - s.State.StartEpoch), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) StartEpoch() (abi.ChainEpoch, error) {
|
|
||||||
return s.State.StartEpoch, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) UnlockDuration() (abi.ChainEpoch, error) {
|
|
||||||
return s.State.UnlockDuration, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) InitialBalance() (abi.TokenAmount, error) {
|
|
||||||
return s.State.InitialBalance, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) Threshold() (uint64, error) {
|
|
||||||
return s.State.NumApprovalsThreshold, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) Signers() ([]address.Address, error) {
|
|
||||||
return s.State.Signers, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) ForEachPendingTxn(cb func(id int64, txn Transaction) error) error {
|
|
||||||
arr, err := adt2.AsMap(s.store, s.State.PendingTxns)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var out msig2.Transaction
|
|
||||||
return arr.ForEach(&out, func(key string) error {
|
|
||||||
txid, n := binary.Varint([]byte(key))
|
|
||||||
if n <= 0 {
|
|
||||||
return xerrors.Errorf("invalid pending transaction key: %v", key)
|
|
||||||
}
|
|
||||||
return cb(txid, (Transaction)(out))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) PendingTxnChanged(other State) (bool, error) {
|
|
||||||
other2, ok := other.(*state2)
|
|
||||||
if !ok {
|
|
||||||
// treat an upgrade as a change, always
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
return !s.State.PendingTxns.Equals(other2.PendingTxns), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) transactions() (adt.Map, error) {
|
|
||||||
return adt2.AsMap(s.store, s.PendingTxns)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) decodeTransaction(val *cbg.Deferred) (Transaction, error) {
|
|
||||||
var tx msig2.Transaction
|
|
||||||
if err := tx.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
|
||||||
return Transaction{}, err
|
|
||||||
}
|
|
||||||
return tx, nil
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
package paych
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
|
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
|
||||||
)
|
|
||||||
|
|
||||||
var Methods = builtin2.MethodsPaych
|
|
||||||
|
|
||||||
func Message(version actors.Version, from address.Address) MessageBuilder {
|
|
||||||
switch version {
|
|
||||||
case actors.Version0:
|
|
||||||
return message0{from}
|
|
||||||
case actors.Version2:
|
|
||||||
return message2{from}
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("unsupported actors version: %d", version))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type MessageBuilder interface {
|
|
||||||
Create(to address.Address, initialAmount abi.TokenAmount) (*types.Message, error)
|
|
||||||
Update(paych address.Address, voucher *SignedVoucher, secret []byte) (*types.Message, error)
|
|
||||||
Settle(paych address.Address) (*types.Message, error)
|
|
||||||
Collect(paych address.Address) (*types.Message, error)
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
package paych
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
|
|
||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
|
||||||
init0 "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
|
||||||
paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors"
|
|
||||||
init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
type message0 struct{ from address.Address }
|
|
||||||
|
|
||||||
func (m message0) Create(to address.Address, initialAmount abi.TokenAmount) (*types.Message, error) {
|
|
||||||
params, aerr := actors.SerializeParams(&paych0.ConstructorParams{From: m.from, To: to})
|
|
||||||
if aerr != nil {
|
|
||||||
return nil, aerr
|
|
||||||
}
|
|
||||||
enc, aerr := actors.SerializeParams(&init0.ExecParams{
|
|
||||||
CodeCID: builtin0.PaymentChannelActorCodeID,
|
|
||||||
ConstructorParams: params,
|
|
||||||
})
|
|
||||||
if aerr != nil {
|
|
||||||
return nil, aerr
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.Message{
|
|
||||||
To: init_.Address,
|
|
||||||
From: m.from,
|
|
||||||
Value: initialAmount,
|
|
||||||
Method: builtin0.MethodsInit.Exec,
|
|
||||||
Params: enc,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m message0) Update(paych address.Address, sv *SignedVoucher, secret []byte) (*types.Message, error) {
|
|
||||||
params, aerr := actors.SerializeParams(&paych0.UpdateChannelStateParams{
|
|
||||||
Sv: *sv,
|
|
||||||
Secret: secret,
|
|
||||||
})
|
|
||||||
if aerr != nil {
|
|
||||||
return nil, aerr
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.Message{
|
|
||||||
To: paych,
|
|
||||||
From: m.from,
|
|
||||||
Value: abi.NewTokenAmount(0),
|
|
||||||
Method: builtin0.MethodsPaych.UpdateChannelState,
|
|
||||||
Params: params,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m message0) Settle(paych address.Address) (*types.Message, error) {
|
|
||||||
return &types.Message{
|
|
||||||
To: paych,
|
|
||||||
From: m.from,
|
|
||||||
Value: abi.NewTokenAmount(0),
|
|
||||||
Method: builtin0.MethodsPaych.Settle,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m message0) Collect(paych address.Address) (*types.Message, error) {
|
|
||||||
return &types.Message{
|
|
||||||
To: paych,
|
|
||||||
From: m.from,
|
|
||||||
Value: abi.NewTokenAmount(0),
|
|
||||||
Method: builtin0.MethodsPaych.Collect,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
package paych
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
|
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
|
||||||
init2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/init"
|
|
||||||
paych2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/paych"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors"
|
|
||||||
init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
type message2 struct{ from address.Address }
|
|
||||||
|
|
||||||
func (m message2) Create(to address.Address, initialAmount abi.TokenAmount) (*types.Message, error) {
|
|
||||||
params, aerr := actors.SerializeParams(&paych2.ConstructorParams{From: m.from, To: to})
|
|
||||||
if aerr != nil {
|
|
||||||
return nil, aerr
|
|
||||||
}
|
|
||||||
enc, aerr := actors.SerializeParams(&init2.ExecParams{
|
|
||||||
CodeCID: builtin2.PaymentChannelActorCodeID,
|
|
||||||
ConstructorParams: params,
|
|
||||||
})
|
|
||||||
if aerr != nil {
|
|
||||||
return nil, aerr
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.Message{
|
|
||||||
To: init_.Address,
|
|
||||||
From: m.from,
|
|
||||||
Value: initialAmount,
|
|
||||||
Method: builtin2.MethodsInit.Exec,
|
|
||||||
Params: enc,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m message2) Update(paych address.Address, sv *SignedVoucher, secret []byte) (*types.Message, error) {
|
|
||||||
params, aerr := actors.SerializeParams(&paych2.UpdateChannelStateParams{
|
|
||||||
Sv: *sv,
|
|
||||||
Secret: secret,
|
|
||||||
})
|
|
||||||
if aerr != nil {
|
|
||||||
return nil, aerr
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.Message{
|
|
||||||
To: paych,
|
|
||||||
From: m.from,
|
|
||||||
Value: abi.NewTokenAmount(0),
|
|
||||||
Method: builtin2.MethodsPaych.UpdateChannelState,
|
|
||||||
Params: params,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m message2) Settle(paych address.Address) (*types.Message, error) {
|
|
||||||
return &types.Message{
|
|
||||||
To: paych,
|
|
||||||
From: m.from,
|
|
||||||
Value: abi.NewTokenAmount(0),
|
|
||||||
Method: builtin2.MethodsPaych.Settle,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m message2) Collect(paych address.Address) (*types.Message, error) {
|
|
||||||
return &types.Message{
|
|
||||||
To: paych,
|
|
||||||
From: m.from,
|
|
||||||
Value: abi.NewTokenAmount(0),
|
|
||||||
Method: builtin2.MethodsPaych.Collect,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
package mock
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/filecoin-project/go-state-types/big"
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin/paych"
|
|
||||||
)
|
|
||||||
|
|
||||||
type mockState struct {
|
|
||||||
from address.Address
|
|
||||||
to address.Address
|
|
||||||
settlingAt abi.ChainEpoch
|
|
||||||
toSend abi.TokenAmount
|
|
||||||
lanes map[uint64]paych.LaneState
|
|
||||||
}
|
|
||||||
|
|
||||||
type mockLaneState struct {
|
|
||||||
redeemed big.Int
|
|
||||||
nonce uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewMockPayChState constructs a state for a payment channel with the set fixed values
|
|
||||||
// that satisfies the paych.State interface.
|
|
||||||
func NewMockPayChState(from address.Address,
|
|
||||||
to address.Address,
|
|
||||||
settlingAt abi.ChainEpoch,
|
|
||||||
lanes map[uint64]paych.LaneState,
|
|
||||||
) paych.State {
|
|
||||||
return &mockState{from: from, to: to, settlingAt: settlingAt, toSend: big.NewInt(0), lanes: lanes}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewMockLaneState constructs a state for a payment channel lane with the set fixed values
|
|
||||||
// that satisfies the paych.LaneState interface. Useful for populating lanes when
|
|
||||||
// calling NewMockPayChState
|
|
||||||
func NewMockLaneState(redeemed big.Int, nonce uint64) paych.LaneState {
|
|
||||||
return &mockLaneState{redeemed, nonce}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ms *mockState) MarshalCBOR(io.Writer) error {
|
|
||||||
panic("not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Channel owner, who has funded the actor
|
|
||||||
func (ms *mockState) From() (address.Address, error) {
|
|
||||||
return ms.from, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recipient of payouts from channel
|
|
||||||
func (ms *mockState) To() (address.Address, error) {
|
|
||||||
return ms.to, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Height at which the channel can be `Collected`
|
|
||||||
func (ms *mockState) SettlingAt() (abi.ChainEpoch, error) {
|
|
||||||
return ms.settlingAt, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Amount successfully redeemed through the payment channel, paid out on `Collect()`
|
|
||||||
func (ms *mockState) ToSend() (abi.TokenAmount, error) {
|
|
||||||
return ms.toSend, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get total number of lanes
|
|
||||||
func (ms *mockState) LaneCount() (uint64, error) {
|
|
||||||
return uint64(len(ms.lanes)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Iterate lane states
|
|
||||||
func (ms *mockState) ForEachLaneState(cb func(idx uint64, dl paych.LaneState) error) error {
|
|
||||||
var lastErr error
|
|
||||||
for lane, state := range ms.lanes {
|
|
||||||
if err := cb(lane, state); err != nil {
|
|
||||||
lastErr = err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return lastErr
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mls *mockLaneState) Redeemed() (big.Int, error) {
|
|
||||||
return mls.redeemed, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mls *mockLaneState) Nonce() (uint64, error) {
|
|
||||||
return mls.nonce, nil
|
|
||||||
}
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
package paych
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/base64"
|
|
||||||
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
big "github.com/filecoin-project/go-state-types/big"
|
|
||||||
"github.com/filecoin-project/go-state-types/cbor"
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
ipldcbor "github.com/ipfs/go-ipld-cbor"
|
|
||||||
|
|
||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
|
||||||
paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
builtin.RegisterActorState(builtin0.PaymentChannelActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
|
||||||
return load0(store, root)
|
|
||||||
})
|
|
||||||
builtin.RegisterActorState(builtin2.PaymentChannelActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
|
||||||
return load2(store, root)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load returns an abstract copy of payment channel state, irregardless of actor version
|
|
||||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
|
||||||
switch act.Code {
|
|
||||||
case builtin0.PaymentChannelActorCodeID:
|
|
||||||
return load0(store, act.Head)
|
|
||||||
case builtin2.PaymentChannelActorCodeID:
|
|
||||||
return load2(store, act.Head)
|
|
||||||
}
|
|
||||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
|
||||||
}
|
|
||||||
|
|
||||||
// State is an abstract version of payment channel state that works across
|
|
||||||
// versions
|
|
||||||
type State interface {
|
|
||||||
cbor.Marshaler
|
|
||||||
// Channel owner, who has funded the actor
|
|
||||||
From() (address.Address, error)
|
|
||||||
// Recipient of payouts from channel
|
|
||||||
To() (address.Address, error)
|
|
||||||
|
|
||||||
// Height at which the channel can be `Collected`
|
|
||||||
SettlingAt() (abi.ChainEpoch, error)
|
|
||||||
|
|
||||||
// Amount successfully redeemed through the payment channel, paid out on `Collect()`
|
|
||||||
ToSend() (abi.TokenAmount, error)
|
|
||||||
|
|
||||||
// Get total number of lanes
|
|
||||||
LaneCount() (uint64, error)
|
|
||||||
|
|
||||||
// Iterate lane states
|
|
||||||
ForEachLaneState(cb func(idx uint64, dl LaneState) error) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// LaneState is an abstract copy of the state of a single lane
|
|
||||||
type LaneState interface {
|
|
||||||
Redeemed() (big.Int, error)
|
|
||||||
Nonce() (uint64, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type SignedVoucher = paych0.SignedVoucher
|
|
||||||
type ModVerifyParams = paych0.ModVerifyParams
|
|
||||||
|
|
||||||
// DecodeSignedVoucher decodes base64 encoded signed voucher.
|
|
||||||
func DecodeSignedVoucher(s string) (*SignedVoucher, error) {
|
|
||||||
data, err := base64.RawURLEncoding.DecodeString(s)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var sv SignedVoucher
|
|
||||||
if err := ipldcbor.DecodeInto(data, &sv); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &sv, nil
|
|
||||||
}
|
|
||||||
@@ -1,104 +0,0 @@
|
|||||||
package paych
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/filecoin-project/go-state-types/big"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
||||||
|
|
||||||
paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
|
||||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ State = (*state0)(nil)
|
|
||||||
|
|
||||||
func load0(store adt.Store, root cid.Cid) (State, error) {
|
|
||||||
out := state0{store: store}
|
|
||||||
err := store.Get(store.Context(), root, &out)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type state0 struct {
|
|
||||||
paych0.State
|
|
||||||
store adt.Store
|
|
||||||
lsAmt *adt0.Array
|
|
||||||
}
|
|
||||||
|
|
||||||
// Channel owner, who has funded the actor
|
|
||||||
func (s *state0) From() (address.Address, error) {
|
|
||||||
return s.State.From, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recipient of payouts from channel
|
|
||||||
func (s *state0) To() (address.Address, error) {
|
|
||||||
return s.State.To, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Height at which the channel can be `Collected`
|
|
||||||
func (s *state0) SettlingAt() (abi.ChainEpoch, error) {
|
|
||||||
return s.State.SettlingAt, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Amount successfully redeemed through the payment channel, paid out on `Collect()`
|
|
||||||
func (s *state0) ToSend() (abi.TokenAmount, error) {
|
|
||||||
return s.State.ToSend, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) getOrLoadLsAmt() (*adt0.Array, error) {
|
|
||||||
if s.lsAmt != nil {
|
|
||||||
return s.lsAmt, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the lane state from the chain
|
|
||||||
lsamt, err := adt0.AsArray(s.store, s.State.LaneStates)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
s.lsAmt = lsamt
|
|
||||||
return lsamt, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get total number of lanes
|
|
||||||
func (s *state0) LaneCount() (uint64, error) {
|
|
||||||
lsamt, err := s.getOrLoadLsAmt()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return lsamt.Length(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Iterate lane states
|
|
||||||
func (s *state0) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error {
|
|
||||||
// Get the lane state from the chain
|
|
||||||
lsamt, err := s.getOrLoadLsAmt()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: we use a map instead of an array to store laneStates because the
|
|
||||||
// client sets the lane ID (the index) and potentially they could use a
|
|
||||||
// very large index.
|
|
||||||
var ls paych0.LaneState
|
|
||||||
return lsamt.ForEach(&ls, func(i int64) error {
|
|
||||||
return cb(uint64(i), &laneState0{ls})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
type laneState0 struct {
|
|
||||||
paych0.LaneState
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ls *laneState0) Redeemed() (big.Int, error) {
|
|
||||||
return ls.LaneState.Redeemed, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ls *laneState0) Nonce() (uint64, error) {
|
|
||||||
return ls.LaneState.Nonce, nil
|
|
||||||
}
|
|
||||||
@@ -1,104 +0,0 @@
|
|||||||
package paych
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/filecoin-project/go-state-types/big"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
||||||
|
|
||||||
paych2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/paych"
|
|
||||||
adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ State = (*state2)(nil)
|
|
||||||
|
|
||||||
func load2(store adt.Store, root cid.Cid) (State, error) {
|
|
||||||
out := state2{store: store}
|
|
||||||
err := store.Get(store.Context(), root, &out)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type state2 struct {
|
|
||||||
paych2.State
|
|
||||||
store adt.Store
|
|
||||||
lsAmt *adt2.Array
|
|
||||||
}
|
|
||||||
|
|
||||||
// Channel owner, who has funded the actor
|
|
||||||
func (s *state2) From() (address.Address, error) {
|
|
||||||
return s.State.From, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recipient of payouts from channel
|
|
||||||
func (s *state2) To() (address.Address, error) {
|
|
||||||
return s.State.To, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Height at which the channel can be `Collected`
|
|
||||||
func (s *state2) SettlingAt() (abi.ChainEpoch, error) {
|
|
||||||
return s.State.SettlingAt, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Amount successfully redeemed through the payment channel, paid out on `Collect()`
|
|
||||||
func (s *state2) ToSend() (abi.TokenAmount, error) {
|
|
||||||
return s.State.ToSend, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) getOrLoadLsAmt() (*adt2.Array, error) {
|
|
||||||
if s.lsAmt != nil {
|
|
||||||
return s.lsAmt, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the lane state from the chain
|
|
||||||
lsamt, err := adt2.AsArray(s.store, s.State.LaneStates)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
s.lsAmt = lsamt
|
|
||||||
return lsamt, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get total number of lanes
|
|
||||||
func (s *state2) LaneCount() (uint64, error) {
|
|
||||||
lsamt, err := s.getOrLoadLsAmt()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return lsamt.Length(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Iterate lane states
|
|
||||||
func (s *state2) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error {
|
|
||||||
// Get the lane state from the chain
|
|
||||||
lsamt, err := s.getOrLoadLsAmt()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: we use a map instead of an array to store laneStates because the
|
|
||||||
// client sets the lane ID (the index) and potentially they could use a
|
|
||||||
// very large index.
|
|
||||||
var ls paych2.LaneState
|
|
||||||
return lsamt.ForEach(&ls, func(i int64) error {
|
|
||||||
return cb(uint64(i), &laneState2{ls})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
type laneState2 struct {
|
|
||||||
paych2.LaneState
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ls *laneState2) Redeemed() (big.Int, error) {
|
|
||||||
return ls.LaneState.Redeemed, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ls *laneState2) Nonce() (uint64, error) {
|
|
||||||
return ls.LaneState.Nonce, nil
|
|
||||||
}
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
package power
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ClaimChanges struct {
|
|
||||||
Added []ClaimInfo
|
|
||||||
Modified []ClaimModification
|
|
||||||
Removed []ClaimInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
type ClaimModification struct {
|
|
||||||
Miner address.Address
|
|
||||||
From Claim
|
|
||||||
To Claim
|
|
||||||
}
|
|
||||||
|
|
||||||
type ClaimInfo struct {
|
|
||||||
Miner address.Address
|
|
||||||
Claim Claim
|
|
||||||
}
|
|
||||||
|
|
||||||
func DiffClaims(pre, cur State) (*ClaimChanges, error) {
|
|
||||||
results := new(ClaimChanges)
|
|
||||||
|
|
||||||
prec, err := pre.claims()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
curc, err := cur.claims()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := adt.DiffAdtMap(prec, curc, &claimDiffer{results, pre, cur}); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return results, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type claimDiffer struct {
|
|
||||||
Results *ClaimChanges
|
|
||||||
pre, after State
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *claimDiffer) AsKey(key string) (abi.Keyer, error) {
|
|
||||||
addr, err := address.NewFromBytes([]byte(key))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return abi.AddrKey(addr), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *claimDiffer) Add(key string, val *cbg.Deferred) error {
|
|
||||||
ci, err := c.after.decodeClaim(val)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
addr, err := address.NewFromBytes([]byte(key))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
c.Results.Added = append(c.Results.Added, ClaimInfo{
|
|
||||||
Miner: addr,
|
|
||||||
Claim: ci,
|
|
||||||
})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *claimDiffer) Modify(key string, from, to *cbg.Deferred) error {
|
|
||||||
ciFrom, err := c.pre.decodeClaim(from)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
ciTo, err := c.after.decodeClaim(to)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
addr, err := address.NewFromBytes([]byte(key))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if ciFrom != ciTo {
|
|
||||||
c.Results.Modified = append(c.Results.Modified, ClaimModification{
|
|
||||||
Miner: addr,
|
|
||||||
From: ciFrom,
|
|
||||||
To: ciTo,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *claimDiffer) Remove(key string, val *cbg.Deferred) error {
|
|
||||||
ci, err := c.after.decodeClaim(val)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
addr, err := address.NewFromBytes([]byte(key))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
c.Results.Removed = append(c.Results.Removed, ClaimInfo{
|
|
||||||
Miner: addr,
|
|
||||||
Claim: ci,
|
|
||||||
})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
package power
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/big"
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/filecoin-project/go-state-types/cbor"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
|
|
||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
builtin.RegisterActorState(builtin0.StoragePowerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
|
||||||
return load0(store, root)
|
|
||||||
})
|
|
||||||
builtin.RegisterActorState(builtin2.StoragePowerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
|
||||||
return load2(store, root)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
Address = builtin2.StoragePowerActorAddr
|
|
||||||
Methods = builtin2.MethodsPower
|
|
||||||
)
|
|
||||||
|
|
||||||
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
|
||||||
switch act.Code {
|
|
||||||
case builtin0.StoragePowerActorCodeID:
|
|
||||||
return load0(store, act.Head)
|
|
||||||
case builtin2.StoragePowerActorCodeID:
|
|
||||||
return load2(store, act.Head)
|
|
||||||
}
|
|
||||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
|
||||||
}
|
|
||||||
|
|
||||||
type State interface {
|
|
||||||
cbor.Marshaler
|
|
||||||
|
|
||||||
TotalLocked() (abi.TokenAmount, error)
|
|
||||||
TotalPower() (Claim, error)
|
|
||||||
TotalCommitted() (Claim, error)
|
|
||||||
TotalPowerSmoothed() (builtin.FilterEstimate, error)
|
|
||||||
|
|
||||||
// MinerCounts returns the number of miners. Participating is the number
|
|
||||||
// with power above the minimum miner threshold.
|
|
||||||
MinerCounts() (participating, total uint64, err error)
|
|
||||||
MinerPower(address.Address) (Claim, bool, error)
|
|
||||||
MinerNominalPowerMeetsConsensusMinimum(address.Address) (bool, error)
|
|
||||||
ListAllMiners() ([]address.Address, error)
|
|
||||||
ForEachClaim(func(miner address.Address, claim Claim) error) error
|
|
||||||
ClaimsChanged(State) (bool, error)
|
|
||||||
|
|
||||||
// Diff helpers. Used by Diff* functions internally.
|
|
||||||
claims() (adt.Map, error)
|
|
||||||
decodeClaim(*cbg.Deferred) (Claim, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Claim struct {
|
|
||||||
// Sum of raw byte power for a miner's sectors.
|
|
||||||
RawBytePower abi.StoragePower
|
|
||||||
|
|
||||||
// Sum of quality adjusted power for a miner's sectors.
|
|
||||||
QualityAdjPower abi.StoragePower
|
|
||||||
}
|
|
||||||
|
|
||||||
func AddClaims(a Claim, b Claim) Claim {
|
|
||||||
return Claim{
|
|
||||||
RawBytePower: big.Add(a.RawBytePower, b.RawBytePower),
|
|
||||||
QualityAdjPower: big.Add(a.QualityAdjPower, b.QualityAdjPower),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,145 +0,0 @@
|
|||||||
package power
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
|
||||||
|
|
||||||
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
|
|
||||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ State = (*state0)(nil)
|
|
||||||
|
|
||||||
func load0(store adt.Store, root cid.Cid) (State, error) {
|
|
||||||
out := state0{store: store}
|
|
||||||
err := store.Get(store.Context(), root, &out)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type state0 struct {
|
|
||||||
power0.State
|
|
||||||
store adt.Store
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) TotalLocked() (abi.TokenAmount, error) {
|
|
||||||
return s.TotalPledgeCollateral, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) TotalPower() (Claim, error) {
|
|
||||||
return Claim{
|
|
||||||
RawBytePower: s.TotalRawBytePower,
|
|
||||||
QualityAdjPower: s.TotalQualityAdjPower,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Committed power to the network. Includes miners below the minimum threshold.
|
|
||||||
func (s *state0) TotalCommitted() (Claim, error) {
|
|
||||||
return Claim{
|
|
||||||
RawBytePower: s.TotalBytesCommitted,
|
|
||||||
QualityAdjPower: s.TotalQABytesCommitted,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) MinerPower(addr address.Address) (Claim, bool, error) {
|
|
||||||
claims, err := adt0.AsMap(s.store, s.Claims)
|
|
||||||
if err != nil {
|
|
||||||
return Claim{}, false, err
|
|
||||||
}
|
|
||||||
var claim power0.Claim
|
|
||||||
ok, err := claims.Get(abi.AddrKey(addr), &claim)
|
|
||||||
if err != nil {
|
|
||||||
return Claim{}, false, err
|
|
||||||
}
|
|
||||||
return Claim{
|
|
||||||
RawBytePower: claim.RawBytePower,
|
|
||||||
QualityAdjPower: claim.QualityAdjPower,
|
|
||||||
}, ok, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) MinerNominalPowerMeetsConsensusMinimum(a address.Address) (bool, error) {
|
|
||||||
return s.State.MinerNominalPowerMeetsConsensusMinimum(s.store, a)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) TotalPowerSmoothed() (builtin.FilterEstimate, error) {
|
|
||||||
return builtin.FromV0FilterEstimate(*s.State.ThisEpochQAPowerSmoothed), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) MinerCounts() (uint64, uint64, error) {
|
|
||||||
return uint64(s.State.MinerAboveMinPowerCount), uint64(s.State.MinerCount), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) ListAllMiners() ([]address.Address, error) {
|
|
||||||
claims, err := adt0.AsMap(s.store, s.Claims)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var miners []address.Address
|
|
||||||
err = claims.ForEach(nil, func(k string) error {
|
|
||||||
a, err := address.NewFromBytes([]byte(k))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
miners = append(miners, a)
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return miners, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) ForEachClaim(cb func(miner address.Address, claim Claim) error) error {
|
|
||||||
claims, err := adt0.AsMap(s.store, s.Claims)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var claim power0.Claim
|
|
||||||
return claims.ForEach(&claim, func(k string) error {
|
|
||||||
a, err := address.NewFromBytes([]byte(k))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return cb(a, Claim{
|
|
||||||
RawBytePower: claim.RawBytePower,
|
|
||||||
QualityAdjPower: claim.QualityAdjPower,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) ClaimsChanged(other State) (bool, error) {
|
|
||||||
other0, ok := other.(*state0)
|
|
||||||
if !ok {
|
|
||||||
// treat an upgrade as a change, always
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
return !s.State.Claims.Equals(other0.State.Claims), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) claims() (adt.Map, error) {
|
|
||||||
return adt0.AsMap(s.store, s.Claims)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) decodeClaim(val *cbg.Deferred) (Claim, error) {
|
|
||||||
var ci power0.Claim
|
|
||||||
if err := ci.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
|
||||||
return Claim{}, err
|
|
||||||
}
|
|
||||||
return fromV0Claim(ci), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func fromV0Claim(v0 power0.Claim) Claim {
|
|
||||||
return (Claim)(v0)
|
|
||||||
}
|
|
||||||
@@ -1,148 +0,0 @@
|
|||||||
package power
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
|
||||||
|
|
||||||
power2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/power"
|
|
||||||
adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ State = (*state2)(nil)
|
|
||||||
|
|
||||||
func load2(store adt.Store, root cid.Cid) (State, error) {
|
|
||||||
out := state2{store: store}
|
|
||||||
err := store.Get(store.Context(), root, &out)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type state2 struct {
|
|
||||||
power2.State
|
|
||||||
store adt.Store
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) TotalLocked() (abi.TokenAmount, error) {
|
|
||||||
return s.TotalPledgeCollateral, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) TotalPower() (Claim, error) {
|
|
||||||
return Claim{
|
|
||||||
RawBytePower: s.TotalRawBytePower,
|
|
||||||
QualityAdjPower: s.TotalQualityAdjPower,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Committed power to the network. Includes miners below the minimum threshold.
|
|
||||||
func (s *state2) TotalCommitted() (Claim, error) {
|
|
||||||
return Claim{
|
|
||||||
RawBytePower: s.TotalBytesCommitted,
|
|
||||||
QualityAdjPower: s.TotalQABytesCommitted,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) MinerPower(addr address.Address) (Claim, bool, error) {
|
|
||||||
claims, err := adt2.AsMap(s.store, s.Claims)
|
|
||||||
if err != nil {
|
|
||||||
return Claim{}, false, err
|
|
||||||
}
|
|
||||||
var claim power2.Claim
|
|
||||||
ok, err := claims.Get(abi.AddrKey(addr), &claim)
|
|
||||||
if err != nil {
|
|
||||||
return Claim{}, false, err
|
|
||||||
}
|
|
||||||
return Claim{
|
|
||||||
RawBytePower: claim.RawBytePower,
|
|
||||||
QualityAdjPower: claim.QualityAdjPower,
|
|
||||||
}, ok, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) MinerNominalPowerMeetsConsensusMinimum(a address.Address) (bool, error) {
|
|
||||||
return s.State.MinerNominalPowerMeetsConsensusMinimum(s.store, a)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) TotalPowerSmoothed() (builtin.FilterEstimate, error) {
|
|
||||||
return builtin.FromV2FilterEstimate(s.State.ThisEpochQAPowerSmoothed), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) MinerCounts() (uint64, uint64, error) {
|
|
||||||
return uint64(s.State.MinerAboveMinPowerCount), uint64(s.State.MinerCount), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) ListAllMiners() ([]address.Address, error) {
|
|
||||||
claims, err := adt2.AsMap(s.store, s.Claims)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var miners []address.Address
|
|
||||||
err = claims.ForEach(nil, func(k string) error {
|
|
||||||
a, err := address.NewFromBytes([]byte(k))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
miners = append(miners, a)
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return miners, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) ForEachClaim(cb func(miner address.Address, claim Claim) error) error {
|
|
||||||
claims, err := adt2.AsMap(s.store, s.Claims)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var claim power2.Claim
|
|
||||||
return claims.ForEach(&claim, func(k string) error {
|
|
||||||
a, err := address.NewFromBytes([]byte(k))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return cb(a, Claim{
|
|
||||||
RawBytePower: claim.RawBytePower,
|
|
||||||
QualityAdjPower: claim.QualityAdjPower,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) ClaimsChanged(other State) (bool, error) {
|
|
||||||
other2, ok := other.(*state2)
|
|
||||||
if !ok {
|
|
||||||
// treat an upgrade as a change, always
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
return !s.State.Claims.Equals(other2.State.Claims), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) claims() (adt.Map, error) {
|
|
||||||
return adt2.AsMap(s.store, s.Claims)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) decodeClaim(val *cbg.Deferred) (Claim, error) {
|
|
||||||
var ci power2.Claim
|
|
||||||
if err := ci.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
|
||||||
return Claim{}, err
|
|
||||||
}
|
|
||||||
return fromV2Claim(ci), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func fromV2Claim(v2 power2.Claim) Claim {
|
|
||||||
return Claim{
|
|
||||||
RawBytePower: v2.RawBytePower,
|
|
||||||
QualityAdjPower: v2.QualityAdjPower,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
package reward
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/cbor"
|
|
||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
builtin.RegisterActorState(builtin0.RewardActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
|
||||||
return load0(store, root)
|
|
||||||
})
|
|
||||||
builtin.RegisterActorState(builtin2.RewardActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
|
||||||
return load2(store, root)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
Address = builtin2.RewardActorAddr
|
|
||||||
Methods = builtin2.MethodsReward
|
|
||||||
)
|
|
||||||
|
|
||||||
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
|
||||||
switch act.Code {
|
|
||||||
case builtin0.RewardActorCodeID:
|
|
||||||
return load0(store, act.Head)
|
|
||||||
case builtin2.RewardActorCodeID:
|
|
||||||
return load2(store, act.Head)
|
|
||||||
}
|
|
||||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
|
||||||
}
|
|
||||||
|
|
||||||
type State interface {
|
|
||||||
cbor.Marshaler
|
|
||||||
|
|
||||||
ThisEpochBaselinePower() (abi.StoragePower, error)
|
|
||||||
ThisEpochReward() (abi.StoragePower, error)
|
|
||||||
ThisEpochRewardSmoothed() (builtin.FilterEstimate, error)
|
|
||||||
|
|
||||||
EffectiveBaselinePower() (abi.StoragePower, error)
|
|
||||||
EffectiveNetworkTime() (abi.ChainEpoch, error)
|
|
||||||
|
|
||||||
TotalStoragePowerReward() (abi.TokenAmount, error)
|
|
||||||
|
|
||||||
CumsumBaseline() (abi.StoragePower, error)
|
|
||||||
CumsumRealized() (abi.StoragePower, error)
|
|
||||||
|
|
||||||
InitialPledgeForPower(abi.StoragePower, abi.TokenAmount, *builtin.FilterEstimate, abi.TokenAmount) (abi.TokenAmount, error)
|
|
||||||
PreCommitDepositForPower(builtin.FilterEstimate, abi.StoragePower) (abi.TokenAmount, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type AwardBlockRewardParams = reward0.AwardBlockRewardParams
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
package reward
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
|
||||||
|
|
||||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
|
||||||
reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
|
||||||
smoothing0 "github.com/filecoin-project/specs-actors/actors/util/smoothing"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ State = (*state0)(nil)
|
|
||||||
|
|
||||||
func load0(store adt.Store, root cid.Cid) (State, error) {
|
|
||||||
out := state0{store: store}
|
|
||||||
err := store.Get(store.Context(), root, &out)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type state0 struct {
|
|
||||||
reward0.State
|
|
||||||
store adt.Store
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) ThisEpochReward() (abi.StoragePower, error) {
|
|
||||||
return s.State.ThisEpochReward, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) {
|
|
||||||
return builtin.FromV0FilterEstimate(*s.State.ThisEpochRewardSmoothed), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) ThisEpochBaselinePower() (abi.StoragePower, error) {
|
|
||||||
return s.State.ThisEpochBaselinePower, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) TotalStoragePowerReward() (abi.TokenAmount, error) {
|
|
||||||
return s.State.TotalMined, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) EffectiveBaselinePower() (abi.StoragePower, error) {
|
|
||||||
return s.State.EffectiveBaselinePower, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) EffectiveNetworkTime() (abi.ChainEpoch, error) {
|
|
||||||
return s.State.EffectiveNetworkTime, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) CumsumBaseline() (abi.StoragePower, error) {
|
|
||||||
return s.State.CumsumBaseline, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) CumsumRealized() (abi.StoragePower, error) {
|
|
||||||
return s.State.CumsumRealized, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) InitialPledgeForPower(sectorWeight abi.StoragePower, networkTotalPledge abi.TokenAmount, networkQAPower *builtin.FilterEstimate, circSupply abi.TokenAmount) (abi.TokenAmount, error) {
|
|
||||||
return miner0.InitialPledgeForPower(
|
|
||||||
sectorWeight,
|
|
||||||
s.State.ThisEpochBaselinePower,
|
|
||||||
networkTotalPledge,
|
|
||||||
s.State.ThisEpochRewardSmoothed,
|
|
||||||
&smoothing0.FilterEstimate{
|
|
||||||
PositionEstimate: networkQAPower.PositionEstimate,
|
|
||||||
VelocityEstimate: networkQAPower.VelocityEstimate,
|
|
||||||
},
|
|
||||||
circSupply), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state0) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, sectorWeight abi.StoragePower) (abi.TokenAmount, error) {
|
|
||||||
return miner0.PreCommitDepositForPower(s.State.ThisEpochRewardSmoothed,
|
|
||||||
&smoothing0.FilterEstimate{
|
|
||||||
PositionEstimate: networkQAPower.PositionEstimate,
|
|
||||||
VelocityEstimate: networkQAPower.VelocityEstimate,
|
|
||||||
},
|
|
||||||
sectorWeight), nil
|
|
||||||
}
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
package reward
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
|
||||||
|
|
||||||
miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner"
|
|
||||||
reward2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/reward"
|
|
||||||
smoothing2 "github.com/filecoin-project/specs-actors/v2/actors/util/smoothing"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ State = (*state2)(nil)
|
|
||||||
|
|
||||||
func load2(store adt.Store, root cid.Cid) (State, error) {
|
|
||||||
out := state2{store: store}
|
|
||||||
err := store.Get(store.Context(), root, &out)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type state2 struct {
|
|
||||||
reward2.State
|
|
||||||
store adt.Store
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) ThisEpochReward() (abi.TokenAmount, error) {
|
|
||||||
return s.State.ThisEpochReward, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) {
|
|
||||||
return builtin.FilterEstimate{
|
|
||||||
PositionEstimate: s.State.ThisEpochRewardSmoothed.PositionEstimate,
|
|
||||||
VelocityEstimate: s.State.ThisEpochRewardSmoothed.VelocityEstimate,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) ThisEpochBaselinePower() (abi.StoragePower, error) {
|
|
||||||
return s.State.ThisEpochBaselinePower, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) TotalStoragePowerReward() (abi.TokenAmount, error) {
|
|
||||||
return s.State.TotalStoragePowerReward, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) EffectiveBaselinePower() (abi.StoragePower, error) {
|
|
||||||
return s.State.EffectiveBaselinePower, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) EffectiveNetworkTime() (abi.ChainEpoch, error) {
|
|
||||||
return s.State.EffectiveNetworkTime, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) CumsumBaseline() (reward2.Spacetime, error) {
|
|
||||||
return s.State.CumsumBaseline, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) CumsumRealized() (reward2.Spacetime, error) {
|
|
||||||
return s.State.CumsumRealized, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) InitialPledgeForPower(qaPower abi.StoragePower, networkTotalPledge abi.TokenAmount, networkQAPower *builtin.FilterEstimate, circSupply abi.TokenAmount) (abi.TokenAmount, error) {
|
|
||||||
return miner2.InitialPledgeForPower(
|
|
||||||
qaPower,
|
|
||||||
s.State.ThisEpochBaselinePower,
|
|
||||||
s.State.ThisEpochRewardSmoothed,
|
|
||||||
smoothing2.FilterEstimate{
|
|
||||||
PositionEstimate: networkQAPower.PositionEstimate,
|
|
||||||
VelocityEstimate: networkQAPower.VelocityEstimate,
|
|
||||||
},
|
|
||||||
circSupply,
|
|
||||||
), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *state2) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, sectorWeight abi.StoragePower) (abi.TokenAmount, error) {
|
|
||||||
return miner2.PreCommitDepositForPower(s.State.ThisEpochRewardSmoothed,
|
|
||||||
smoothing2.FilterEstimate{
|
|
||||||
PositionEstimate: networkQAPower.PositionEstimate,
|
|
||||||
VelocityEstimate: networkQAPower.VelocityEstimate,
|
|
||||||
},
|
|
||||||
sectorWeight), nil
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user