Merge pull request #1842 from filecoin-project/next
Next network staging
This commit is contained in:
commit
fe4efa0e0e
@ -1,6 +1,6 @@
|
||||
version: 2.1
|
||||
orbs:
|
||||
go: gotest/tools@0.0.9
|
||||
go: gotest/tools@0.0.13
|
||||
|
||||
executors:
|
||||
golang:
|
||||
@ -79,7 +79,6 @@ jobs:
|
||||
steps:
|
||||
- install-deps
|
||||
- prepare
|
||||
- go/mod-download
|
||||
- go/mod-tidy-check
|
||||
|
||||
build-all:
|
||||
@ -87,12 +86,8 @@ jobs:
|
||||
steps:
|
||||
- install-deps
|
||||
- prepare
|
||||
- go/mod-download
|
||||
- run: sudo apt-get update
|
||||
- run: sudo apt-get install npm
|
||||
- restore_cache:
|
||||
name: restore go mod cache
|
||||
key: v1-go-deps-{{ arch }}-{{ checksum "/home/circleci/project/go.mod" }}
|
||||
- run:
|
||||
command: make buildall
|
||||
- store_artifacts:
|
||||
@ -112,10 +107,6 @@ jobs:
|
||||
steps:
|
||||
- install-deps
|
||||
- prepare
|
||||
- go/mod-download
|
||||
- restore_cache:
|
||||
name: restore go mod cache
|
||||
key: v1-go-deps-{{ arch }}-{{ checksum "/home/circleci/project/go.mod" }}
|
||||
- run:
|
||||
command: make debug
|
||||
|
||||
@ -134,6 +125,9 @@ jobs:
|
||||
type: string
|
||||
default: "./..."
|
||||
description: Import paths of packages to be tested.
|
||||
winpost-test:
|
||||
type: string
|
||||
default: "0"
|
||||
test-suite-name:
|
||||
type: string
|
||||
default: unit
|
||||
@ -156,10 +150,6 @@ jobs:
|
||||
steps:
|
||||
- install-deps
|
||||
- prepare
|
||||
- go/mod-download
|
||||
- restore_cache:
|
||||
name: restore go mod cache
|
||||
key: v1-go-deps-{{ arch }}-{{ checksum "/home/circleci/project/go.mod" }}
|
||||
- run:
|
||||
command: make deps lotus
|
||||
no_output_timeout: 30m
|
||||
@ -171,6 +161,7 @@ jobs:
|
||||
environment:
|
||||
GOTESTSUM_JUNITFILE: /tmp/test-reports/<< parameters.test-suite-name >>/junit.xml
|
||||
GOTESTSUM_FORMAT: << parameters.gotestsum-format >>
|
||||
LOTUS_TEST_WINDOW_POST: << parameters.winpost-test >>
|
||||
command: |
|
||||
mkdir -p /tmp/test-reports/<< parameters.test-suite-name >>
|
||||
gotestsum -- \
|
||||
@ -189,16 +180,11 @@ jobs:
|
||||
shell: /bin/bash -eo pipefail
|
||||
command: |
|
||||
bash <(curl -s https://codecov.io/bash)
|
||||
- save_cache:
|
||||
name: save go mod cache
|
||||
key: v1-go-deps-{{ arch }}-{{ checksum "/home/circleci/project/go.mod" }}
|
||||
paths:
|
||||
- "~/go/pkg"
|
||||
- "~/go/src/github.com"
|
||||
- "~/go/src/golang.org"
|
||||
|
||||
test-short:
|
||||
<<: *test
|
||||
test-window-post:
|
||||
<<: *test
|
||||
|
||||
build-macos:
|
||||
description: build darwin lotus binary
|
||||
@ -228,10 +214,9 @@ jobs:
|
||||
curl --location https://github.com/stedolan/jq/releases/download/jq-1.6/jq-osx-amd64 --output /usr/local/bin/jq
|
||||
chmod +x /usr/local/bin/jq
|
||||
- restore_cache:
|
||||
name: restore go mod and cargo cache
|
||||
name: restore cargo cache
|
||||
key: v3-go-deps-{{ arch }}-{{ checksum "~/go/src/github.com/filecoin-project/lotus/go.sum" }}
|
||||
- install-deps
|
||||
- go/mod-download
|
||||
- run:
|
||||
command: make build
|
||||
no_output_timeout: 30m
|
||||
@ -258,7 +243,6 @@ jobs:
|
||||
steps:
|
||||
- install-deps
|
||||
- prepare
|
||||
- go/mod-download
|
||||
- run:
|
||||
command: "! go fmt ./... 2>&1 | read"
|
||||
|
||||
@ -271,7 +255,7 @@ jobs:
|
||||
default: golang
|
||||
golangci-lint-version:
|
||||
type: string
|
||||
default: 1.23.8
|
||||
default: 1.27.0
|
||||
concurrency:
|
||||
type: string
|
||||
default: '2'
|
||||
@ -287,7 +271,6 @@ jobs:
|
||||
steps:
|
||||
- install-deps
|
||||
- prepare
|
||||
- go/mod-download
|
||||
- run:
|
||||
command: make deps
|
||||
no_output_timeout: 30m
|
||||
@ -297,7 +280,7 @@ jobs:
|
||||
- run:
|
||||
name: Lint
|
||||
command: |
|
||||
$HOME/.local/bin/golangci-lint run -v \
|
||||
$HOME/.local/bin/golangci-lint run -v --timeout 2m \
|
||||
--concurrency << parameters.concurrency >> << parameters.args >>
|
||||
lint-changes:
|
||||
<<: *lint
|
||||
@ -331,11 +314,14 @@ workflows:
|
||||
ci:
|
||||
jobs:
|
||||
- lint-changes:
|
||||
args: "--new-from-rev origin/master"
|
||||
- test:
|
||||
codecov-upload: true
|
||||
args: "--new-from-rev origin/next"
|
||||
- mod-tidy-check
|
||||
- gofmt
|
||||
- test:
|
||||
codecov-upload: true
|
||||
- test-window-post:
|
||||
go-test-flags: "-run=TestWindowedPost"
|
||||
winpost-test: "1"
|
||||
- test-short:
|
||||
go-test-flags: "--timeout 10m --short"
|
||||
filters:
|
||||
|
@ -22,13 +22,27 @@ issues:
|
||||
- "func name will be used as test\\.Test.* by other packages, and that stutters; consider calling this"
|
||||
- "Potential file inclusion via variable"
|
||||
- "should have( a package)? comment"
|
||||
- "Error return value of `logging.SetLogLevel` is not checked"
|
||||
|
||||
exclude-use-default: false
|
||||
exclude-rules:
|
||||
- path: lotuspond
|
||||
linters:
|
||||
- errcheck
|
||||
|
||||
- path: node/modules/lp2p
|
||||
linters:
|
||||
- golint
|
||||
- path: ".*_test.go"
|
||||
|
||||
- path: build/params_.*\.go
|
||||
linters:
|
||||
- golint
|
||||
|
||||
- path: api/apistruct/struct.go
|
||||
linters:
|
||||
- golint
|
||||
|
||||
- path: .*_test.go
|
||||
linters:
|
||||
- gosec
|
||||
|
||||
|
4
Makefile
4
Makefile
@ -17,7 +17,7 @@ MODULES:=
|
||||
CLEAN:=
|
||||
BINS:=
|
||||
|
||||
ldflags=-X=github.com/filecoin-project/lotus/build.CurrentCommit='+git$(subst -,.,$(shell git describe --always --match=NeVeRmAtCh --dirty 2>/dev/null || git rev-parse --short HEAD 2>/dev/null))'
|
||||
ldflags=-X=github.com/filecoin-project/lotus/build.CurrentCommit=+git.$(subst -,.,$(shell git describe --always --match=NeVeRmAtCh --dirty 2>/dev/null || git rev-parse --short HEAD 2>/dev/null))
|
||||
ifneq ($(strip $(LDFLAGS)),)
|
||||
ldflags+=-extldflags=$(LDFLAGS)
|
||||
endif
|
||||
@ -132,7 +132,7 @@ benchmarks:
|
||||
@curl -X POST 'http://benchmark.kittyhawk.wtf/benchmark' -d '@bench.json' -u "${benchmark_http_cred}"
|
||||
.PHONY: benchmarks
|
||||
|
||||
pond: build
|
||||
pond: 2k
|
||||
go build -o pond ./lotuspond
|
||||
(cd lotuspond/front && npm i && CI=false npm run build)
|
||||
.PHONY: pond
|
||||
|
@ -25,6 +25,7 @@ type Common interface {
|
||||
NetAddrsListen(context.Context) (peer.AddrInfo, error)
|
||||
NetDisconnect(context.Context, peer.ID) error
|
||||
NetFindPeer(context.Context, peer.ID) (peer.AddrInfo, error)
|
||||
NetPubsubScores(context.Context) ([]PubsubScore, error)
|
||||
|
||||
// ID returns peerID of libp2p node backing this API
|
||||
ID(context.Context) (peer.ID, error)
|
||||
@ -37,6 +38,8 @@ type Common interface {
|
||||
|
||||
// trigger graceful shutdown
|
||||
Shutdown(context.Context) error
|
||||
|
||||
Closing(context.Context) (<-chan struct{}, error)
|
||||
}
|
||||
|
||||
// Version provides various build-time information
|
||||
|
@ -147,7 +147,7 @@ type FullNode interface {
|
||||
StateMinerProvingSet(context.Context, address.Address, types.TipSetKey) ([]*ChainSectorInfo, error)
|
||||
StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*miner.DeadlineInfo, error)
|
||||
StateMinerPower(context.Context, address.Address, types.TipSetKey) (*MinerPower, error)
|
||||
StateMinerInfo(context.Context, address.Address, types.TipSetKey) (miner.MinerInfo, error)
|
||||
StateMinerInfo(context.Context, address.Address, types.TipSetKey) (MinerInfo, error)
|
||||
StateMinerDeadlines(context.Context, address.Address, types.TipSetKey) (*miner.Deadlines, error)
|
||||
StateMinerFaults(context.Context, address.Address, types.TipSetKey) (*abi.BitField, error)
|
||||
// Returns all non-expired Faults that occur within lookback epochs of the given tipset
|
||||
@ -156,8 +156,9 @@ type FullNode interface {
|
||||
StateMinerInitialPledgeCollateral(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (types.BigInt, error)
|
||||
StateMinerAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error)
|
||||
StateSectorPreCommitInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error)
|
||||
StateSectorGetInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorOnChainInfo, error)
|
||||
StatePledgeCollateral(context.Context, types.TipSetKey) (types.BigInt, error)
|
||||
StateWaitMsg(context.Context, cid.Cid) (*MsgLookup, error)
|
||||
StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64) (*MsgLookup, error)
|
||||
StateSearchMsg(context.Context, cid.Cid) (*MsgLookup, error)
|
||||
StateListMiners(context.Context, types.TipSetKey) ([]address.Address, error)
|
||||
StateListActors(context.Context, types.TipSetKey) ([]address.Address, error)
|
||||
@ -352,7 +353,7 @@ type RetrievalOrder struct {
|
||||
type InvocResult struct {
|
||||
Msg *types.Message
|
||||
MsgRct *types.MessageReceipt
|
||||
InternalExecutions []*types.ExecutionResult
|
||||
ExecutionTrace types.ExecutionTrace
|
||||
Error string
|
||||
Duration time.Duration
|
||||
}
|
||||
|
@ -8,11 +8,10 @@ import (
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/sector-storage/stores"
|
||||
"github.com/filecoin-project/sector-storage/storiface"
|
||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
// StorageMiner is a low-level interface to the Filecoin network storage miner node
|
||||
@ -51,10 +50,12 @@ type StorageMiner interface {
|
||||
MarketImportDealData(ctx context.Context, propcid cid.Cid, path string) error
|
||||
MarketListDeals(ctx context.Context) ([]storagemarket.StorageDeal, error)
|
||||
MarketListIncompleteDeals(ctx context.Context) ([]storagemarket.MinerDeal, error)
|
||||
MarketSetPrice(context.Context, types.BigInt) error
|
||||
MarketSetAsk(ctx context.Context, price types.BigInt, duration abi.ChainEpoch, minPieceSize abi.PaddedPieceSize, maxPieceSize abi.PaddedPieceSize) error
|
||||
MarketGetAsk(ctx context.Context) (*storagemarket.SignedStorageAsk, error)
|
||||
|
||||
DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error
|
||||
DealsList(ctx context.Context) ([]storagemarket.StorageDeal, error)
|
||||
DealsSetAcceptingStorageDeals(context.Context, bool) error
|
||||
|
||||
StorageAddLocal(ctx context.Context, path string) error
|
||||
}
|
||||
|
@ -2,6 +2,9 @@ package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/filecoin-project/sector-storage/sealtasks"
|
||||
"github.com/filecoin-project/sector-storage/stores"
|
||||
@ -12,7 +15,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
)
|
||||
|
||||
type WorkerApi interface {
|
||||
type WorkerAPI interface {
|
||||
Version(context.Context) (build.Version, error)
|
||||
// TODO: Info() (name, ...) ?
|
||||
|
||||
@ -21,7 +24,13 @@ type WorkerApi interface {
|
||||
Info(context.Context) (storiface.WorkerInfo, error)
|
||||
|
||||
storage.Sealer
|
||||
Fetch(context.Context, abi.SectorID, stores.SectorFileType, bool) error
|
||||
|
||||
MoveStorage(ctx context.Context, sector abi.SectorID) 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
|
||||
|
||||
Fetch(context.Context, abi.SectorID, stores.SectorFileType, stores.PathType, stores.AcquireMode) error
|
||||
|
||||
Closing(context.Context) (<-chan struct{}, error)
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ func PermissionedFullAPI(a api.FullNode) api.FullNode {
|
||||
return &out
|
||||
}
|
||||
|
||||
func PermissionedWorkerAPI(a api.WorkerApi) api.WorkerApi {
|
||||
func PermissionedWorkerAPI(a api.WorkerAPI) api.WorkerAPI {
|
||||
var out WorkerStruct
|
||||
auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.Internal)
|
||||
return &out
|
||||
|
@ -2,6 +2,7 @@ package apistruct
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/libp2p/go-libp2p-core/network"
|
||||
@ -41,6 +42,7 @@ type CommonStruct struct {
|
||||
NetAddrsListen func(context.Context) (peer.AddrInfo, error) `perm:"read"`
|
||||
NetDisconnect func(context.Context, peer.ID) error `perm:"write"`
|
||||
NetFindPeer func(context.Context, peer.ID) (peer.AddrInfo, error) `perm:"read"`
|
||||
NetPubsubScores func(context.Context) ([]api.PubsubScore, error) `perm:"read"`
|
||||
|
||||
ID func(context.Context) (peer.ID, error) `perm:"read"`
|
||||
Version func(context.Context) (api.Version, error) `perm:"read"`
|
||||
@ -49,6 +51,7 @@ type CommonStruct struct {
|
||||
LogSetLevel func(context.Context, string, string) error `perm:"write"`
|
||||
|
||||
Shutdown func(context.Context) error `perm:"admin"`
|
||||
Closing func(context.Context) (<-chan struct{}, error) `perm:"read"`
|
||||
}
|
||||
}
|
||||
|
||||
@ -124,7 +127,7 @@ type FullNodeStruct struct {
|
||||
StateMinerProvingSet func(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) `perm:"read"`
|
||||
StateMinerProvingDeadline func(context.Context, address.Address, types.TipSetKey) (*miner.DeadlineInfo, error) `perm:"read"`
|
||||
StateMinerPower func(context.Context, address.Address, types.TipSetKey) (*api.MinerPower, error) `perm:"read"`
|
||||
StateMinerInfo func(context.Context, address.Address, types.TipSetKey) (miner.MinerInfo, error) `perm:"read"`
|
||||
StateMinerInfo func(context.Context, address.Address, types.TipSetKey) (api.MinerInfo, error) `perm:"read"`
|
||||
StateMinerDeadlines func(context.Context, address.Address, types.TipSetKey) (*miner.Deadlines, error) `perm:"read"`
|
||||
StateMinerFaults func(context.Context, address.Address, types.TipSetKey) (*abi.BitField, error) `perm:"read"`
|
||||
StateAllMinerFaults func(context.Context, abi.ChainEpoch, types.TipSetKey) ([]*api.Fault, error) `perm:"read"`
|
||||
@ -132,12 +135,13 @@ type FullNodeStruct struct {
|
||||
StateMinerInitialPledgeCollateral func(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
StateMinerAvailableBalance func(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
StateSectorPreCommitInfo func(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) `perm:"read"`
|
||||
StateSectorGetInfo func(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorOnChainInfo, error) `perm:"read"`
|
||||
StateCall func(context.Context, *types.Message, types.TipSetKey) (*api.InvocResult, error) `perm:"read"`
|
||||
StateReplay func(context.Context, types.TipSetKey, cid.Cid) (*api.InvocResult, error) `perm:"read"`
|
||||
StateGetActor func(context.Context, address.Address, types.TipSetKey) (*types.Actor, error) `perm:"read"`
|
||||
StateReadState func(context.Context, *types.Actor, types.TipSetKey) (*api.ActorState, error) `perm:"read"`
|
||||
StatePledgeCollateral func(context.Context, types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
StateWaitMsg func(context.Context, cid.Cid) (*api.MsgLookup, error) `perm:"read"`
|
||||
StateWaitMsg func(ctx context.Context, cid cid.Cid, confidence uint64) (*api.MsgLookup, error) `perm:"read"`
|
||||
StateSearchMsg func(context.Context, cid.Cid) (*api.MsgLookup, error) `perm:"read"`
|
||||
StateListMiners func(context.Context, types.TipSetKey) ([]address.Address, error) `perm:"read"`
|
||||
StateListActors func(context.Context, types.TipSetKey) ([]address.Address, error) `perm:"read"`
|
||||
@ -193,7 +197,8 @@ type StorageMinerStruct struct {
|
||||
MarketImportDealData func(context.Context, cid.Cid, string) error `perm:"write"`
|
||||
MarketListDeals func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"`
|
||||
MarketListIncompleteDeals func(ctx context.Context) ([]storagemarket.MinerDeal, error) `perm:"read"`
|
||||
MarketSetPrice func(context.Context, types.BigInt) error `perm:"admin"`
|
||||
MarketSetAsk func(ctx context.Context, price types.BigInt, duration abi.ChainEpoch, minPieceSize abi.PaddedPieceSize, maxPieceSize abi.PaddedPieceSize) error `perm:"admin"`
|
||||
MarketGetAsk func(ctx context.Context) (*storagemarket.SignedStorageAsk, error) `perm:"read"`
|
||||
|
||||
PledgeSector func(context.Context) error `perm:"write"`
|
||||
|
||||
@ -209,15 +214,18 @@ type StorageMinerStruct struct {
|
||||
StorageLocal func(context.Context) (map[stores.ID]string, error) `perm:"admin"`
|
||||
StorageStat func(context.Context, stores.ID) (stores.FsStat, error) `perm:"admin"`
|
||||
StorageAttach func(context.Context, stores.StorageInfo, stores.FsStat) error `perm:"admin"`
|
||||
StorageDeclareSector func(context.Context, stores.ID, abi.SectorID, stores.SectorFileType) error `perm:"admin"`
|
||||
StorageDeclareSector func(context.Context, stores.ID, abi.SectorID, stores.SectorFileType, bool) error `perm:"admin"`
|
||||
StorageDropSector func(context.Context, stores.ID, abi.SectorID, stores.SectorFileType) error `perm:"admin"`
|
||||
StorageFindSector func(context.Context, abi.SectorID, stores.SectorFileType, bool) ([]stores.StorageInfo, error) `perm:"admin"`
|
||||
StorageFindSector func(context.Context, abi.SectorID, stores.SectorFileType, bool) ([]stores.SectorStorageInfo, error) `perm:"admin"`
|
||||
StorageInfo func(context.Context, stores.ID) (stores.StorageInfo, error) `perm:"admin"`
|
||||
StorageBestAlloc func(ctx context.Context, allocate stores.SectorFileType, spt abi.RegisteredProof, sealing bool) ([]stores.StorageInfo, error) `perm:"admin"`
|
||||
StorageBestAlloc func(ctx context.Context, allocate stores.SectorFileType, spt abi.RegisteredSealProof, sealing stores.PathType) ([]stores.StorageInfo, error) `perm:"admin"`
|
||||
StorageReportHealth func(ctx context.Context, id stores.ID, report stores.HealthReport) error `perm:"admin"`
|
||||
StorageLock func(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) error `perm:"admin"`
|
||||
StorageTryLock func(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) (bool, error) `perm:"admin"`
|
||||
|
||||
DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"`
|
||||
DealsList func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"`
|
||||
DealsSetAcceptingStorageDeals func(context.Context, bool) error `perm:"admin"`
|
||||
|
||||
StorageAddLocal func(ctx context.Context, path string) error `perm:"admin"`
|
||||
}
|
||||
@ -238,8 +246,12 @@ type WorkerStruct struct {
|
||||
SealCommit1 func(ctx context.Context, sector abi.SectorID, ticket abi.SealRandomness, seed abi.InteractiveSealRandomness, pieces []abi.PieceInfo, cids storage.SectorCids) (storage.Commit1Out, error) `perm:"admin"`
|
||||
SealCommit2 func(context.Context, abi.SectorID, storage.Commit1Out) (storage.Proof, error) `perm:"admin"`
|
||||
FinalizeSector func(context.Context, abi.SectorID) error `perm:"admin"`
|
||||
MoveStorage func(ctx context.Context, sector abi.SectorID) error `perm:"admin"`
|
||||
|
||||
Fetch func(context.Context, abi.SectorID, stores.SectorFileType, bool) error `perm:"admin"`
|
||||
UnsealPiece func(context.Context, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) error `perm:"admin"`
|
||||
ReadPiece func(context.Context, io.Writer, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize) error `perm:"admin"`
|
||||
|
||||
Fetch func(context.Context, abi.SectorID, stores.SectorFileType, stores.PathType, stores.AcquireMode) error `perm:"admin"`
|
||||
|
||||
Closing func(context.Context) (<-chan struct{}, error) `perm:"admin"`
|
||||
}
|
||||
@ -255,6 +267,9 @@ func (c *CommonStruct) AuthNew(ctx context.Context, perms []auth.Permission) ([]
|
||||
return c.Internal.AuthNew(ctx, perms)
|
||||
}
|
||||
|
||||
func (c *CommonStruct) NetPubsubScores(ctx context.Context) ([]api.PubsubScore, error) {
|
||||
return c.Internal.NetPubsubScores(ctx)
|
||||
}
|
||||
func (c *CommonStruct) NetConnectedness(ctx context.Context, pid peer.ID) (network.Connectedness, error) {
|
||||
return c.Internal.NetConnectedness(ctx, pid)
|
||||
}
|
||||
@ -301,6 +316,10 @@ func (c *CommonStruct) Shutdown(ctx context.Context) error {
|
||||
return c.Internal.Shutdown(ctx)
|
||||
}
|
||||
|
||||
func (c *CommonStruct) Closing(ctx context.Context) (<-chan struct{}, error) {
|
||||
return c.Internal.Closing(ctx)
|
||||
}
|
||||
|
||||
// FullNodeStruct
|
||||
|
||||
func (c *FullNodeStruct) ClientListImports(ctx context.Context) ([]api.Import, error) {
|
||||
@ -545,7 +564,7 @@ func (c *FullNodeStruct) StateMinerPower(ctx context.Context, a address.Address,
|
||||
return c.Internal.StateMinerPower(ctx, a, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (miner.MinerInfo, error) {
|
||||
func (c *FullNodeStruct) StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (api.MinerInfo, error) {
|
||||
return c.Internal.StateMinerInfo(ctx, actor, tsk)
|
||||
}
|
||||
|
||||
@ -577,6 +596,10 @@ func (c *FullNodeStruct) StateSectorPreCommitInfo(ctx context.Context, maddr add
|
||||
return c.Internal.StateSectorPreCommitInfo(ctx, maddr, n, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error) {
|
||||
return c.Internal.StateSectorGetInfo(ctx, maddr, n, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateCall(ctx context.Context, msg *types.Message, tsk types.TipSetKey) (*api.InvocResult, error) {
|
||||
return c.Internal.StateCall(ctx, msg, tsk)
|
||||
}
|
||||
@ -597,8 +620,8 @@ func (c *FullNodeStruct) StatePledgeCollateral(ctx context.Context, tsk types.Ti
|
||||
return c.Internal.StatePledgeCollateral(ctx, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateWaitMsg(ctx context.Context, msgc cid.Cid) (*api.MsgLookup, error) {
|
||||
return c.Internal.StateWaitMsg(ctx, msgc)
|
||||
func (c *FullNodeStruct) StateWaitMsg(ctx context.Context, msgc cid.Cid, confidence uint64) (*api.MsgLookup, error) {
|
||||
return c.Internal.StateWaitMsg(ctx, msgc, confidence)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateSearchMsg(ctx context.Context, msgc cid.Cid) (*api.MsgLookup, error) {
|
||||
@ -773,15 +796,15 @@ func (c *StorageMinerStruct) StorageAttach(ctx context.Context, si stores.Storag
|
||||
return c.Internal.StorageAttach(ctx, si, st)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) StorageDeclareSector(ctx context.Context, storageId stores.ID, s abi.SectorID, ft stores.SectorFileType) error {
|
||||
return c.Internal.StorageDeclareSector(ctx, storageId, s, ft)
|
||||
func (c *StorageMinerStruct) StorageDeclareSector(ctx context.Context, storageId stores.ID, s abi.SectorID, ft stores.SectorFileType, primary bool) error {
|
||||
return c.Internal.StorageDeclareSector(ctx, storageId, s, ft, primary)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) StorageDropSector(ctx context.Context, storageId stores.ID, s abi.SectorID, ft stores.SectorFileType) error {
|
||||
return c.Internal.StorageDropSector(ctx, storageId, s, ft)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) StorageFindSector(ctx context.Context, si abi.SectorID, types stores.SectorFileType, allowFetch bool) ([]stores.StorageInfo, error) {
|
||||
func (c *StorageMinerStruct) StorageFindSector(ctx context.Context, si abi.SectorID, types stores.SectorFileType, allowFetch bool) ([]stores.SectorStorageInfo, error) {
|
||||
return c.Internal.StorageFindSector(ctx, si, types, allowFetch)
|
||||
}
|
||||
|
||||
@ -801,14 +824,22 @@ func (c *StorageMinerStruct) StorageInfo(ctx context.Context, id stores.ID) (sto
|
||||
return c.Internal.StorageInfo(ctx, id)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) StorageBestAlloc(ctx context.Context, allocate stores.SectorFileType, spt abi.RegisteredProof, sealing bool) ([]stores.StorageInfo, error) {
|
||||
return c.Internal.StorageBestAlloc(ctx, allocate, spt, sealing)
|
||||
func (c *StorageMinerStruct) StorageBestAlloc(ctx context.Context, allocate stores.SectorFileType, spt abi.RegisteredSealProof, pt stores.PathType) ([]stores.StorageInfo, error) {
|
||||
return c.Internal.StorageBestAlloc(ctx, allocate, spt, pt)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) StorageReportHealth(ctx context.Context, id stores.ID, report stores.HealthReport) error {
|
||||
return c.Internal.StorageReportHealth(ctx, id, report)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) StorageLock(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) error {
|
||||
return c.Internal.StorageLock(ctx, sector, read, write)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) StorageTryLock(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) (bool, error) {
|
||||
return c.Internal.StorageTryLock(ctx, sector, read, write)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) MarketImportDealData(ctx context.Context, propcid cid.Cid, path string) error {
|
||||
return c.Internal.MarketImportDealData(ctx, propcid, path)
|
||||
}
|
||||
@ -821,8 +852,12 @@ func (c *StorageMinerStruct) MarketListIncompleteDeals(ctx context.Context) ([]s
|
||||
return c.Internal.MarketListIncompleteDeals(ctx)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) MarketSetPrice(ctx context.Context, p types.BigInt) error {
|
||||
return c.Internal.MarketSetPrice(ctx, p)
|
||||
func (c *StorageMinerStruct) MarketSetAsk(ctx context.Context, price types.BigInt, duration abi.ChainEpoch, minPieceSize abi.PaddedPieceSize, maxPieceSize abi.PaddedPieceSize) error {
|
||||
return c.Internal.MarketSetAsk(ctx, price, duration, minPieceSize, maxPieceSize)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) MarketGetAsk(ctx context.Context) (*storagemarket.SignedStorageAsk, error) {
|
||||
return c.Internal.MarketGetAsk(ctx)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error {
|
||||
@ -833,6 +868,10 @@ func (c *StorageMinerStruct) DealsList(ctx context.Context) ([]storagemarket.Sto
|
||||
return c.Internal.DealsList(ctx)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) DealsSetAcceptingStorageDeals(ctx context.Context, b bool) error {
|
||||
return c.Internal.DealsSetAcceptingStorageDeals(ctx, b)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) StorageAddLocal(ctx context.Context, path string) error {
|
||||
return c.Internal.StorageAddLocal(ctx, path)
|
||||
}
|
||||
@ -875,8 +914,20 @@ func (w *WorkerStruct) FinalizeSector(ctx context.Context, sector abi.SectorID)
|
||||
return w.Internal.FinalizeSector(ctx, sector)
|
||||
}
|
||||
|
||||
func (w *WorkerStruct) Fetch(ctx context.Context, id abi.SectorID, fileType stores.SectorFileType, b bool) error {
|
||||
return w.Internal.Fetch(ctx, id, fileType, b)
|
||||
func (w *WorkerStruct) MoveStorage(ctx context.Context, sector abi.SectorID) error {
|
||||
return w.Internal.MoveStorage(ctx, sector)
|
||||
}
|
||||
|
||||
func (w *WorkerStruct) UnsealPiece(ctx context.Context, id abi.SectorID, index storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, randomness abi.SealRandomness, c cid.Cid) error {
|
||||
return w.Internal.UnsealPiece(ctx, id, index, size, randomness, c)
|
||||
}
|
||||
|
||||
func (w *WorkerStruct) ReadPiece(ctx context.Context, writer io.Writer, id abi.SectorID, index storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) error {
|
||||
return w.Internal.ReadPiece(ctx, writer, id, index, size)
|
||||
}
|
||||
|
||||
func (w *WorkerStruct) Fetch(ctx context.Context, id abi.SectorID, fileType stores.SectorFileType, ptype stores.PathType, am stores.AcquireMode) error {
|
||||
return w.Internal.Fetch(ctx, id, fileType, ptype, am)
|
||||
}
|
||||
|
||||
func (w *WorkerStruct) Closing(ctx context.Context) (<-chan struct{}, error) {
|
||||
@ -886,4 +937,4 @@ func (w *WorkerStruct) Closing(ctx context.Context) (<-chan struct{}, error) {
|
||||
var _ api.Common = &CommonStruct{}
|
||||
var _ api.FullNode = &FullNodeStruct{}
|
||||
var _ api.StorageMiner = &StorageMinerStruct{}
|
||||
var _ api.WorkerApi = &WorkerStruct{}
|
||||
var _ api.WorkerAPI = &WorkerStruct{}
|
||||
|
@ -48,7 +48,7 @@ func NewStorageMinerRPC(addr string, requestHeader http.Header) (api.StorageMine
|
||||
return &res, closer, err
|
||||
}
|
||||
|
||||
func NewWorkerRPC(addr string, requestHeader http.Header) (api.WorkerApi, jsonrpc.ClientCloser, error) {
|
||||
func NewWorkerRPC(addr string, requestHeader http.Header) (api.WorkerAPI, jsonrpc.ClientCloser, error) {
|
||||
var res apistruct.WorkerStruct
|
||||
closer, err := jsonrpc.NewMergeClient(addr, "Filecoin",
|
||||
[]interface{}{
|
||||
|
@ -72,7 +72,7 @@ func init() {
|
||||
addExample(pid)
|
||||
|
||||
addExample(bitfield.NewFromSet([]uint64{5}))
|
||||
addExample(abi.RegisteredProof_StackedDRG32GiBPoSt)
|
||||
addExample(abi.RegisteredSealProof_StackedDrg32GiBV1)
|
||||
addExample(abi.ChainEpoch(10101))
|
||||
addExample(crypto.SigTypeBLS)
|
||||
addExample(int64(9))
|
||||
@ -93,7 +93,7 @@ func init() {
|
||||
addExample(build.APIVersion)
|
||||
addExample(api.PCHInbound)
|
||||
addExample(time.Minute)
|
||||
addExample(&types.ExecutionResult{
|
||||
addExample(&types.ExecutionTrace{
|
||||
Msg: exampleValue(reflect.TypeOf(&types.Message{})).(*types.Message),
|
||||
MsgRct: exampleValue(reflect.TypeOf(&types.MessageReceipt{})).(*types.MessageReceipt),
|
||||
})
|
||||
@ -193,8 +193,7 @@ func (v *Visitor) Visit(node ast.Node) ast.Visitor {
|
||||
|
||||
const noComment = "There are not yet any comments for this method."
|
||||
|
||||
func parseApiASTInfo() (map[string]string, map[string]string) {
|
||||
|
||||
func parseApiASTInfo() (map[string]string, map[string]string) { //nolint:golint
|
||||
fset := token.NewFileSet()
|
||||
pkgs, err := parser.ParseDir(fset, "./api", nil, parser.AllErrors|parser.ParseComments)
|
||||
if err != nil {
|
||||
@ -320,6 +319,7 @@ func main() {
|
||||
})
|
||||
|
||||
for _, g := range groupslice {
|
||||
g := g
|
||||
fmt.Printf("## %s\n", g.GroupName)
|
||||
fmt.Printf("%s\n\n", g.Header)
|
||||
|
||||
|
@ -35,7 +35,7 @@ func init() {
|
||||
}
|
||||
|
||||
func TestDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, carExport bool) {
|
||||
os.Setenv("BELLMAN_NO_GPU", "1")
|
||||
_ = os.Setenv("BELLMAN_NO_GPU", "1")
|
||||
|
||||
ctx := context.Background()
|
||||
n, sn := b(t, 1, oneMiner)
|
||||
@ -72,7 +72,7 @@ func TestDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, carExport
|
||||
}
|
||||
|
||||
func TestDoubleDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
os.Setenv("BELLMAN_NO_GPU", "1")
|
||||
_ = os.Setenv("BELLMAN_NO_GPU", "1")
|
||||
|
||||
ctx := context.Background()
|
||||
n, sn := b(t, 1, oneMiner)
|
||||
@ -193,7 +193,7 @@ func testRetrieval(t *testing.T, ctx context.Context, err error, client *impl.Fu
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(rpath)
|
||||
defer os.RemoveAll(rpath) //nolint:errcheck
|
||||
|
||||
caddr, err := client.WalletDefaultAddress(ctx)
|
||||
if err != nil {
|
||||
|
@ -82,7 +82,7 @@ func (ts *testSuite) testMiningReal(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDealMining(t *testing.T, b APIBuilder, blocktime time.Duration, carExport bool) {
|
||||
os.Setenv("BELLMAN_NO_GPU", "1")
|
||||
_ = os.Setenv("BELLMAN_NO_GPU", "1")
|
||||
|
||||
// test making a deal with a fresh miner, and see if it starts to mine
|
||||
|
||||
|
@ -4,9 +4,11 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type TestNode struct {
|
||||
@ -21,6 +23,8 @@ type TestStorageNode struct {
|
||||
|
||||
var PresealGenesis = -1
|
||||
|
||||
const GenesisPreseals = 2
|
||||
|
||||
type StorageMiner struct {
|
||||
Full int
|
||||
Preseal int
|
||||
@ -60,9 +64,7 @@ func (ts *testSuite) testVersion(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if v.Version != build.BuildVersion {
|
||||
t.Error("Version didn't work properly")
|
||||
}
|
||||
require.Equal(t, v.Version, build.BuildVersion)
|
||||
}
|
||||
|
||||
func (ts *testSuite) testID(t *testing.T) {
|
||||
|
169
api/test/window_post.go
Normal file
169
api/test/window_post.go
Normal file
@ -0,0 +1,169 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||
miner2 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
sealing "github.com/filecoin-project/storage-fsm"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/node/impl"
|
||||
)
|
||||
|
||||
func TestPledgeSector(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int) {
|
||||
os.Setenv("BELLMAN_NO_GPU", "1")
|
||||
|
||||
ctx := context.Background()
|
||||
n, sn := b(t, 1, oneMiner)
|
||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||
miner := sn[0]
|
||||
|
||||
addrinfo, err := client.NetAddrsListen(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := miner.NetConnect(ctx, addrinfo); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
time.Sleep(time.Second)
|
||||
|
||||
mine := true
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
defer close(done)
|
||||
for mine {
|
||||
time.Sleep(blocktime)
|
||||
if err := sn[0].MineOne(ctx, func(bool) {}); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
pledgeSectors(t, ctx, miner, nSectors)
|
||||
|
||||
mine = false
|
||||
<-done
|
||||
}
|
||||
|
||||
func pledgeSectors(t *testing.T, ctx context.Context, miner TestStorageNode, n int) {
|
||||
for i := 0; i < n; i++ {
|
||||
err := miner.PledgeSector(ctx)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
for {
|
||||
s, err := miner.SectorsList(ctx) // Note - the test builder doesn't import genesis sectors into FSM
|
||||
require.NoError(t, err)
|
||||
fmt.Printf("Sectors: %d\n", len(s))
|
||||
if len(s) >= n {
|
||||
break
|
||||
}
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
|
||||
fmt.Printf("All sectors is fsm\n")
|
||||
|
||||
s, err := miner.SectorsList(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
toCheck := map[abi.SectorNumber]struct{}{}
|
||||
for _, number := range s {
|
||||
toCheck[number] = struct{}{}
|
||||
}
|
||||
|
||||
for len(toCheck) > 0 {
|
||||
for n := range toCheck {
|
||||
st, err := miner.SectorsStatus(ctx, n)
|
||||
require.NoError(t, err)
|
||||
if st.State == api.SectorState(sealing.Proving) {
|
||||
delete(toCheck, n)
|
||||
}
|
||||
if strings.Contains(string(st.State), "Fail") {
|
||||
t.Fatal("sector in a failed state", st.State)
|
||||
}
|
||||
}
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
fmt.Printf("WaitSeal: %d\n", len(s))
|
||||
}
|
||||
}
|
||||
|
||||
func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int) {
|
||||
os.Setenv("BELLMAN_NO_GPU", "1")
|
||||
|
||||
ctx := context.Background()
|
||||
n, sn := b(t, 1, oneMiner)
|
||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||
miner := sn[0]
|
||||
|
||||
addrinfo, err := client.NetAddrsListen(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := miner.NetConnect(ctx, addrinfo); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
time.Sleep(time.Second)
|
||||
|
||||
mine := true
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
defer close(done)
|
||||
for mine {
|
||||
time.Sleep(blocktime)
|
||||
if err := sn[0].MineOne(ctx, func(bool) {}); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
pledgeSectors(t, ctx, miner, nSectors)
|
||||
|
||||
maddr, err := miner.ActorAddress(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
di, err := client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK)
|
||||
require.NoError(t, err)
|
||||
|
||||
fmt.Printf("Running one proving periods\n")
|
||||
|
||||
for {
|
||||
head, err := client.ChainHead(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
if head.Height() > di.PeriodStart+(miner2.WPoStProvingPeriod)+2 {
|
||||
break
|
||||
}
|
||||
|
||||
if head.Height()%100 == 0 {
|
||||
fmt.Printf("@%d\n", head.Height())
|
||||
}
|
||||
time.Sleep(blocktime)
|
||||
}
|
||||
|
||||
p, err := client.StateMinerPower(ctx, maddr, types.EmptyTSK)
|
||||
require.NoError(t, err)
|
||||
|
||||
ssz, err := miner.ActorSectorSize(ctx, maddr)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, p.MinerPower, p.TotalPower)
|
||||
require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz)*uint64(nSectors+GenesisPreseals)))
|
||||
|
||||
// TODO: Inject faults here
|
||||
|
||||
mine = false
|
||||
<-done
|
||||
}
|
43
api/types.go
43
api/types.go
@ -2,11 +2,16 @@ package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
// TODO: check if this exists anywhere else
|
||||
|
||||
type MultiaddrSlice []ma.Multiaddr
|
||||
|
||||
func (m *MultiaddrSlice) UnmarshalJSON(raw []byte) (err error) {
|
||||
@ -32,3 +37,41 @@ type ObjStat struct {
|
||||
Size uint64
|
||||
Links uint64
|
||||
}
|
||||
|
||||
type PubsubScore struct {
|
||||
ID peer.ID
|
||||
Score float64
|
||||
}
|
||||
|
||||
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.
|
||||
WorkerChangeEpoch abi.ChainEpoch
|
||||
PeerId peer.ID
|
||||
Multiaddrs []abi.Multiaddrs
|
||||
SealProofType abi.RegisteredSealProof
|
||||
SectorSize abi.SectorSize
|
||||
WindowPoStPartitionSectors uint64
|
||||
}
|
||||
|
||||
func NewApiMinerInfo(info miner.MinerInfo) MinerInfo {
|
||||
mi := MinerInfo{
|
||||
Owner: info.Owner,
|
||||
Worker: info.Worker,
|
||||
NewWorker: address.Undef,
|
||||
WorkerChangeEpoch: -1,
|
||||
PeerId: peer.ID(info.PeerId),
|
||||
Multiaddrs: info.Multiaddrs,
|
||||
SealProofType: info.SealProofType,
|
||||
SectorSize: info.SectorSize,
|
||||
WindowPoStPartitionSectors: info.WindowPoStPartitionSectors,
|
||||
}
|
||||
|
||||
if info.PendingWorkerKey != nil {
|
||||
mi.NewWorker = info.PendingWorkerKey.NewWorker
|
||||
mi.WorkerChangeEpoch = info.PendingWorkerKey.EffectiveAt
|
||||
}
|
||||
|
||||
return mi
|
||||
}
|
||||
|
@ -34,3 +34,12 @@ func BuiltinBootstrap() ([]peer.AddrInfo, error) {
|
||||
})
|
||||
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)
|
||||
}
|
||||
|
@ -2,6 +2,6 @@ package build
|
||||
|
||||
import rice "github.com/GeertJohan/go.rice"
|
||||
|
||||
func ParametersJson() []byte {
|
||||
func ParametersJSON() []byte {
|
||||
return rice.MustFindBox("proof-params").MustBytes("parameters.json")
|
||||
}
|
||||
|
@ -12,10 +12,12 @@ import (
|
||||
|
||||
func init() {
|
||||
power.ConsensusMinerMinPower = big.NewInt(2048)
|
||||
miner.SupportedProofTypes = map[abi.RegisteredProof]struct{}{
|
||||
abi.RegisteredProof_StackedDRG2KiBSeal: {},
|
||||
miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
|
||||
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
|
||||
}
|
||||
verifreg.MinVerifiedDealSize = big.NewInt(256)
|
||||
|
||||
BuildType |= Build2k
|
||||
}
|
||||
|
||||
// Seconds
|
||||
|
@ -4,6 +4,7 @@ package build
|
||||
|
||||
func init() {
|
||||
InsecurePoStValidation = true
|
||||
BuildType |= BuildDebug
|
||||
}
|
||||
|
||||
// NOTE: Also includes settings from params_2k
|
||||
|
@ -59,6 +59,7 @@ 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
|
||||
@ -118,11 +119,6 @@ const VerifSigCacheSize = 32000
|
||||
|
||||
// TODO: If this is gonna stay, it should move to specs-actors
|
||||
const BlockMessageLimit = 512
|
||||
const BlockGasLimit = 100_000_000
|
||||
const BlockGasLimit = 100_000_000_000
|
||||
|
||||
var DrandCoeffs = []string{
|
||||
"82c279cce744450e68de98ee08f9698a01dd38f8e3be3c53f2b840fb9d09ad62a0b6b87981e179e1b14bc9a2d284c985",
|
||||
"82d51308ad346c686f81b8094551597d7b963295cbf313401a93df9baf52d5ae98a87745bee70839a4d6e65c342bd15b",
|
||||
"94eebfd53f4ba6a3b8304236400a12e73885e5a781509a5c8d41d2e8b476923d8ea6052649b3c17282f596217f96c5de",
|
||||
"8dc4231e42b4edf39e86ef1579401692480647918275da767d3e558c520d6375ad953530610fd27daf110187877a65d0",
|
||||
}
|
||||
var DrandChain = `{"public_key":"922a2e93828ff83345bae533f5172669a26c02dc76d6bf59c80892e12ab1455c229211886f35bb56af6d5bea981024df","period":25,"genesis_time":1590445175,"hash":"138a324aa6540f93d0dad002aa89454b1bec2b6e948682cde6bd4db40f4b7c9b"}`
|
||||
|
@ -13,9 +13,9 @@ import (
|
||||
|
||||
func init() {
|
||||
power.ConsensusMinerMinPower = big.NewInt(1024 << 30)
|
||||
miner.SupportedProofTypes = map[abi.RegisteredProof]struct{}{
|
||||
abi.RegisteredProof_StackedDRG32GiBSeal: {},
|
||||
abi.RegisteredProof_StackedDRG64GiBSeal: {},
|
||||
miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
|
||||
abi.RegisteredSealProof_StackedDrg32GiBV1: {},
|
||||
abi.RegisteredSealProof_StackedDrg64GiBV1: {},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,152 +1,152 @@
|
||||
{
|
||||
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0170db1f394b35d995252228ee359194b13199d259380541dc529fb0099096b0.params": {
|
||||
"cid": "QmYkygifkXnrnsN4MJsjBFHTQJHx294CyikDgDK8nYxdGh",
|
||||
"digest": "df3f30442a6d6b4192f5071fb17e820c",
|
||||
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0170db1f394b35d995252228ee359194b13199d259380541dc529fb0099096b0.params": {
|
||||
"cid": "QmeDRyxek34F1H6xJY6AkFdWvPsy5F6dKTrebV3ZtWT4ky",
|
||||
"digest": "f5827f2d8801c62c831e0f972f6dc8bb",
|
||||
"sector_size": 2048
|
||||
},
|
||||
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0170db1f394b35d995252228ee359194b13199d259380541dc529fb0099096b0.vk": {
|
||||
"cid": "QmdXyqbmy2bkJA9Kyhh6z25GrTCq48LwX6c1mxPsm54wi7",
|
||||
"digest": "0bea3951abf9557a3569f68e52a30c6c",
|
||||
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0170db1f394b35d995252228ee359194b13199d259380541dc529fb0099096b0.vk": {
|
||||
"cid": "QmUw1ZmG4BBbX19MsbH3zAEGKUc42iFJc5ZAyomDHeJTsA",
|
||||
"digest": "398fecdb4b2de445125852bc3c080b35",
|
||||
"sector_size": 2048
|
||||
},
|
||||
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0cfb4f178bbb71cf2ecfcd42accce558b27199ab4fb59cb78f2483fe21ef36d9.params": {
|
||||
"cid": "Qmf5XZZtP5VcYTf65MbKjLVabcS6cYMbr2rFShmfJzh5e5",
|
||||
"digest": "655e6277638edc8c658094f6f0b33d54",
|
||||
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0cfb4f178bbb71cf2ecfcd42accce558b27199ab4fb59cb78f2483fe21ef36d9.params": {
|
||||
"cid": "QmUeNKp9YZpiAFm81RV5KuxH1FDGJx2DuwcbU2XNSZLLSv",
|
||||
"digest": "2b6d2972ac9e862e8134d98fb695b0c5",
|
||||
"sector_size": 536870912
|
||||
},
|
||||
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0cfb4f178bbb71cf2ecfcd42accce558b27199ab4fb59cb78f2483fe21ef36d9.vk": {
|
||||
"cid": "QmPuhdWnAXBks43emnkqi9FQzyU1gASKyz23zrD27BPGs8",
|
||||
"digest": "57690e3a6a94c3f704802a674b34f36b",
|
||||
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0cfb4f178bbb71cf2ecfcd42accce558b27199ab4fb59cb78f2483fe21ef36d9.vk": {
|
||||
"cid": "QmQaQmTXX995Akd66ggtJY5bNx6Gkxk8P34JTdMMq8393G",
|
||||
"digest": "3688c9eb256b7b17f411dad78d5ef74a",
|
||||
"sector_size": 536870912
|
||||
},
|
||||
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-3ea05428c9d11689f23529cde32fd30aabd50f7d2c93657c1d3650bca3e8ea9e.params": {
|
||||
"cid": "QmPNVgTN7N5vDtD5u7ERMTLcvUtrKRBfYVUDr6uW3pKhX7",
|
||||
"digest": "3d390654f58e603b896ac70c653f5676",
|
||||
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-3ea05428c9d11689f23529cde32fd30aabd50f7d2c93657c1d3650bca3e8ea9e.params": {
|
||||
"cid": "QmfEYTMSkwGJTumQx26iKXGNKiYh3mmAC4SkdybZpJCj5p",
|
||||
"digest": "09bff16aed893349d94485cfae366a9c",
|
||||
"sector_size": 2048
|
||||
},
|
||||
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-3ea05428c9d11689f23529cde32fd30aabd50f7d2c93657c1d3650bca3e8ea9e.vk": {
|
||||
"cid": "Qmbj61Zez7v5xA7nSCnmWbyLYznWJDWeusz7Yg8EcgVdoN",
|
||||
"digest": "8c170a164743c39576a7f47a1b51e6f3",
|
||||
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-3ea05428c9d11689f23529cde32fd30aabd50f7d2c93657c1d3650bca3e8ea9e.vk": {
|
||||
"cid": "QmP4ThPieSUJyRanjibWpT5R5cCMzMAU4j8Y7kBn7CSW1Q",
|
||||
"digest": "142f2f7e8f1b1779290315cabfd2c803",
|
||||
"sector_size": 2048
|
||||
},
|
||||
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-50c7368dea9593ed0989e70974d28024efa9d156d585b7eea1be22b2e753f331.params": {
|
||||
"cid": "QmRApb8RZoBK3cqicT7V3ydXg8yVvqPFMPrQNXP33aBihp",
|
||||
"digest": "b1b58ff9a297b82885e8a7dfb035f83c",
|
||||
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-50c7368dea9593ed0989e70974d28024efa9d156d585b7eea1be22b2e753f331.params": {
|
||||
"cid": "QmcAixrHsz29DgvtZiMc2kQjvPRvWxYUp36QYmRDZbmREm",
|
||||
"digest": "8f987f64d434365562180b96ec12e299",
|
||||
"sector_size": 8388608
|
||||
},
|
||||
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-50c7368dea9593ed0989e70974d28024efa9d156d585b7eea1be22b2e753f331.vk": {
|
||||
"cid": "QmcytF1dTdqMFoyXi931j1RgmGtLfR9LLLaBznRt1tPQyD",
|
||||
"digest": "1a09e00c641f192f55af3433a028f050",
|
||||
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-50c7368dea9593ed0989e70974d28024efa9d156d585b7eea1be22b2e753f331.vk": {
|
||||
"cid": "QmT4iFnbL6r4txS5PXsiV7NTzbhCxHy54PvdkJJGV2VFXb",
|
||||
"digest": "94b6c24ac01924f4feeecedd16b5d77d",
|
||||
"sector_size": 8388608
|
||||
},
|
||||
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-5294475db5237a2e83c3e52fd6c2b03859a1831d45ed08c4f35dbf9a803165a9.params": {
|
||||
"cid": "QmPvr54tWaVeP4WnekivzUAJitTqsQfvikBvAHNEaDNQSw",
|
||||
"digest": "9380e41368ed4083dbc922b290d3b786",
|
||||
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-5294475db5237a2e83c3e52fd6c2b03859a1831d45ed08c4f35dbf9a803165a9.params": {
|
||||
"cid": "QmbjFst6SFCK1KsTQrfwPdxf3VTNa1raed574tEZZ9PoyQ",
|
||||
"digest": "2c245fe8179839dd6c6cdea207c67ae8",
|
||||
"sector_size": 8388608
|
||||
},
|
||||
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-5294475db5237a2e83c3e52fd6c2b03859a1831d45ed08c4f35dbf9a803165a9.vk": {
|
||||
"cid": "QmXyVLVDRCcxA9SjT7PeK8HFtyxZ2ZH3SHa8KoGLw8VGJt",
|
||||
"digest": "f0731a7e20f90704bd38fc5d27882f6d",
|
||||
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-5294475db5237a2e83c3e52fd6c2b03859a1831d45ed08c4f35dbf9a803165a9.vk": {
|
||||
"cid": "QmQJKmvZN1a5cQ1Nw6CDyXs3nuRPzvyU5NvCFMUL2BfcZC",
|
||||
"digest": "56ae47bfda53bb8d22981ed8d8d27d72",
|
||||
"sector_size": 8388608
|
||||
},
|
||||
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-7d739b8cf60f1b0709eeebee7730e297683552e4b69cab6984ec0285663c5781.params": {
|
||||
"cid": "Qmf5f6ko3dqj7qauzXpZqxM9B2x2sL977K6gE2ppNwuJPv",
|
||||
"digest": "273ebb8c896326b7c292bee8b775fd38",
|
||||
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-7d739b8cf60f1b0709eeebee7730e297683552e4b69cab6984ec0285663c5781.params": {
|
||||
"cid": "QmQCABxeTpdvXTyjDyk7nPBxkQzCh7MXfGztWnSXEPKMLW",
|
||||
"digest": "7e6b2eb5ecbb11ac651ad66ebbb2075a",
|
||||
"sector_size": 536870912
|
||||
},
|
||||
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-7d739b8cf60f1b0709eeebee7730e297683552e4b69cab6984ec0285663c5781.vk": {
|
||||
"cid": "QmfP3MQe8koW63n5MkDENENVHxib78MJYYyZvbneCsuze8",
|
||||
"digest": "3dd94da9da64e51b3445bc528d84e76d",
|
||||
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-7d739b8cf60f1b0709eeebee7730e297683552e4b69cab6984ec0285663c5781.vk": {
|
||||
"cid": "QmPBweyugh5Sx4umk8ULhgEGbjY8xmWLfU6M7EMpc8Mad6",
|
||||
"digest": "94a8d9e25a9ab9674d339833664eba25",
|
||||
"sector_size": 536870912
|
||||
},
|
||||
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-0377ded656c6f524f1618760bffe4e0a1c51d5a70c4509eedae8a27555733edc.params": {
|
||||
"cid": "QmYEeeCE8uT2bsVkxcqqUYeMmMEbe6rfmo8wQCv7jFHqqm",
|
||||
"digest": "c947f2021304ed43b7216f7a8436e294",
|
||||
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-0377ded656c6f524f1618760bffe4e0a1c51d5a70c4509eedae8a27555733edc.params": {
|
||||
"cid": "QmY5yax1E9KymBnCeHksE9Zi8NieZbmwcpoDGoabkeeb9h",
|
||||
"digest": "c909ea9e3fe25ab9b391a64593afdbba",
|
||||
"sector_size": 34359738368
|
||||
},
|
||||
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-0377ded656c6f524f1618760bffe4e0a1c51d5a70c4509eedae8a27555733edc.vk": {
|
||||
"cid": "QmXB63ExriFjB4ywWnXTnFwCcLFfCeEP3h15qtL5i7F4aX",
|
||||
"digest": "ab20d7b253e7e9a0d2ccdf7599ec8ec3",
|
||||
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-0377ded656c6f524f1618760bffe4e0a1c51d5a70c4509eedae8a27555733edc.vk": {
|
||||
"cid": "QmXnPo4yH5mwMguwrvqgRfduSttbmPrXtbBfbwU21wQWHt",
|
||||
"digest": "caf900461e988bbf86dbcaca087b7864",
|
||||
"sector_size": 34359738368
|
||||
},
|
||||
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-559e581f022bb4e4ec6e719e563bf0e026ad6de42e56c18714a2c692b1b88d7e.params": {
|
||||
"cid": "QmW5Yxg3L1NSzuQVcRMHMbG3uvVoi4dTLzVaDpnEUPQpnA",
|
||||
"digest": "079ba19645828ae42b22b0e3f4866e8d",
|
||||
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-559e581f022bb4e4ec6e719e563bf0e026ad6de42e56c18714a2c692b1b88d7e.params": {
|
||||
"cid": "QmZtzzPWwmZEgR7MSMvXRbt9KVK8k4XZ5RLWHybHJW9SdE",
|
||||
"digest": "a2844f0703f186d143a06146a04577d8",
|
||||
"sector_size": 34359738368
|
||||
},
|
||||
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-559e581f022bb4e4ec6e719e563bf0e026ad6de42e56c18714a2c692b1b88d7e.vk": {
|
||||
"cid": "QmQzZ5dJ11tcSBees38WX41tZLXS9BqpEti253m5QcnTNs",
|
||||
"digest": "c76125a50a7de315165de359b5174ae4",
|
||||
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-559e581f022bb4e4ec6e719e563bf0e026ad6de42e56c18714a2c692b1b88d7e.vk": {
|
||||
"cid": "QmWxEA7EdQCUJTzjNpxg5XTF45D2uVyYnN1QRUb5TRYU8M",
|
||||
"digest": "2306247a1e616dbe07f01b88196c2044",
|
||||
"sector_size": 34359738368
|
||||
},
|
||||
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-2627e4006b67f99cef990c0a47d5426cb7ab0a0ad58fc1061547bf2d28b09def.params": {
|
||||
"cid": "QmNk3wga1tS53FUu1QnkK8ehWA2cqpCnSEAPv3KLxdJxNa",
|
||||
"digest": "421e4790c0b80e0107a7ff67acf14084",
|
||||
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-2627e4006b67f99cef990c0a47d5426cb7ab0a0ad58fc1061547bf2d28b09def.params": {
|
||||
"cid": "QmP676KwuvyF9Y64uJnXvLtvD1xcuWQ6wD23RzYtQ6dd4f",
|
||||
"digest": "215b1c667a4f46a1d0178338df568615",
|
||||
"sector_size": 68719476736
|
||||
},
|
||||
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-2627e4006b67f99cef990c0a47d5426cb7ab0a0ad58fc1061547bf2d28b09def.vk": {
|
||||
"cid": "QmVQCHGsrUtbn9RjHs1e6GXfeXDW5m9w4ge48PSX3Z2as2",
|
||||
"digest": "8b60e9cc1470a6729c687d6cf0a1f79c",
|
||||
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-2627e4006b67f99cef990c0a47d5426cb7ab0a0ad58fc1061547bf2d28b09def.vk": {
|
||||
"cid": "QmPvPwbJtcSGyqB1rQJhSF5yvFbX9ZBSsHVej5F8JUyHUJ",
|
||||
"digest": "0c9c423b28b1455fcbc329a1045fd4dd",
|
||||
"sector_size": 68719476736
|
||||
},
|
||||
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-b62098629d07946e9028127e70295ed996fe3ed25b0f9f88eb610a0ab4385a3c.params": {
|
||||
"cid": "QmTL3VvydaMFWKvE5VzxjgKsJYgL9JMM4JVYNtQxdj9JK1",
|
||||
"digest": "2685f31124b22ea6b2857e5a5e87ffa3",
|
||||
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-b62098629d07946e9028127e70295ed996fe3ed25b0f9f88eb610a0ab4385a3c.params": {
|
||||
"cid": "QmUxPQfvckzm1t6MFRdDZ1fDK5UJzAjK7pTZ97cwyachdr",
|
||||
"digest": "965132f51ae445b0e6d32692b7561995",
|
||||
"sector_size": 68719476736
|
||||
},
|
||||
"v26-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-b62098629d07946e9028127e70295ed996fe3ed25b0f9f88eb610a0ab4385a3c.vk": {
|
||||
"cid": "QmSVWbLqQYbUbbJyfsRMzEib2rfSqMtnPks1Nw22omcBQm",
|
||||
"digest": "efe703cd2839597c7ca5c2a906b74296",
|
||||
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-b62098629d07946e9028127e70295ed996fe3ed25b0f9f88eb610a0ab4385a3c.vk": {
|
||||
"cid": "QmTxq2EBnQWb5R8tS4MHdchj4vNfLYGoSXxwJFvs5xgW4K",
|
||||
"digest": "fc8c3d26e0e56373ad96cb41520d55a6",
|
||||
"sector_size": 68719476736
|
||||
},
|
||||
"v26-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-032d3138d22506ec0082ed72b2dcba18df18477904e35bafee82b3793b06832f.params": {
|
||||
"cid": "QmU9dH31nZZUJnsogR4Ld4ySUcH6wm2RgmGiujwnqtbU6k",
|
||||
"digest": "fcef8e87ae2afd7a28aae44347b804cf",
|
||||
"v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-032d3138d22506ec0082ed72b2dcba18df18477904e35bafee82b3793b06832f.params": {
|
||||
"cid": "QmRjgZHERgqGoRagR788Kh6ybi26csVYa8mqbqhmZm57Jx",
|
||||
"digest": "cfc7b0897d1eee48c586f7beb89e67f7",
|
||||
"sector_size": 2048
|
||||
},
|
||||
"v26-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-032d3138d22506ec0082ed72b2dcba18df18477904e35bafee82b3793b06832f.vk": {
|
||||
"cid": "QmdJ15DMGPooye5NaPcRfXUdHUDibcN7hKjbmTGuu1K4AQ",
|
||||
"digest": "2ee2b3518229680db15161d4f582af37",
|
||||
"v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-032d3138d22506ec0082ed72b2dcba18df18477904e35bafee82b3793b06832f.vk": {
|
||||
"cid": "QmNjvnvFP7KgovHUddULoB19fBHT81iz7NcUbzEHZUUPsm",
|
||||
"digest": "fb59bd061c987eac7068008c44de346b",
|
||||
"sector_size": 2048
|
||||
},
|
||||
"v26-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-6babf46ce344ae495d558e7770a585b2382d54f225af8ed0397b8be7c3fcd472.params": {
|
||||
"cid": "QmZgtxcY3tMXXQxZTA7ZTUDXLVUnfxNcerXgeW4gG2NnfP",
|
||||
"digest": "3273c7135cb75684248b475781b738ee",
|
||||
"v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-6babf46ce344ae495d558e7770a585b2382d54f225af8ed0397b8be7c3fcd472.params": {
|
||||
"cid": "QmTpRPBA4dt8fgGpcVzi4L1KA1U2eBHCE8WVmS2GUygMvT",
|
||||
"digest": "36d465915b0afbf96bd08e7915e00952",
|
||||
"sector_size": 536870912
|
||||
},
|
||||
"v26-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-6babf46ce344ae495d558e7770a585b2382d54f225af8ed0397b8be7c3fcd472.vk": {
|
||||
"cid": "QmSS6ZkAV2aGZcgKgdPpEEgihXF1ryZX8PSAZDWSoeL1d4",
|
||||
"digest": "1519b5f61d9044a59f2bdc57537c094b",
|
||||
"v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-6babf46ce344ae495d558e7770a585b2382d54f225af8ed0397b8be7c3fcd472.vk": {
|
||||
"cid": "QmRzDyVfQCLsxspoVsed5bcQRsG6KiktngJfcNBL3TJPZe",
|
||||
"digest": "99d16df0eb6a7e227a4f4570c4f6b6f1",
|
||||
"sector_size": 536870912
|
||||
},
|
||||
"v26-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-ecd683648512ab1765faa2a5f14bab48f676e633467f0aa8aad4b55dcb0652bb.params": {
|
||||
"cid": "QmQBGXeiNn6hVwbR6qFarQqiNGDdKk4h9ucfyvcXyfYz2N",
|
||||
"digest": "7d5f896f435c38e93bcda6dd168d860b",
|
||||
"v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-ecd683648512ab1765faa2a5f14bab48f676e633467f0aa8aad4b55dcb0652bb.params": {
|
||||
"cid": "QmV8ZjTSGzDUWmFvsq9NSyPBR7eDDUcvCPNgj2yE7HMAFu",
|
||||
"digest": "34f3ddf1d1c9f41c0cd73b91e8b4bc27",
|
||||
"sector_size": 8388608
|
||||
},
|
||||
"v26-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-ecd683648512ab1765faa2a5f14bab48f676e633467f0aa8aad4b55dcb0652bb.vk": {
|
||||
"cid": "QmPrZgBVGMckEAeu5eSJnLmiAwcPQjKjZe5ir6VaQ5AxKs",
|
||||
"digest": "fe6d2de44580a0db5a4934688899b92f",
|
||||
"v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-ecd683648512ab1765faa2a5f14bab48f676e633467f0aa8aad4b55dcb0652bb.vk": {
|
||||
"cid": "QmTa3VbjTiqJWU6r4WKayaQrUaaBsrpp5UDqYvPDd2C5hs",
|
||||
"digest": "ec62d59651daa5631d3d1e9c782dd940",
|
||||
"sector_size": 8388608
|
||||
},
|
||||
"v26-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-0-sha256_hasher-82a357d2f2ca81dc61bb45f4a762807aedee1b0a53fd6c4e77b46a01bfef7820.params": {
|
||||
"cid": "QmZL2cq45XJn5BFzagAZwgFmLrcM1W6CXoiEF9C5j5tjEF",
|
||||
"digest": "acdfed9f0512bc85a01a9fb871d475d5",
|
||||
"v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-0-sha256_hasher-82a357d2f2ca81dc61bb45f4a762807aedee1b0a53fd6c4e77b46a01bfef7820.params": {
|
||||
"cid": "Qmf8ngfArxrv9tFWDqBcNegdBMymvuakwyHKd1pbW3pbsb",
|
||||
"digest": "a16d6f4c6424fb280236739f84b24f97",
|
||||
"sector_size": 34359738368
|
||||
},
|
||||
"v26-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-0-sha256_hasher-82a357d2f2ca81dc61bb45f4a762807aedee1b0a53fd6c4e77b46a01bfef7820.vk": {
|
||||
"cid": "QmQ4zB7nNa1tDYNifBkExRnZtwtxZw775iaqvVsZyRi6Q2",
|
||||
"digest": "524a2f3e9d6826593caebc41bb545c40",
|
||||
"v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-0-sha256_hasher-82a357d2f2ca81dc61bb45f4a762807aedee1b0a53fd6c4e77b46a01bfef7820.vk": {
|
||||
"cid": "QmfQgVFerArJ6Jupwyc9tKjLD9n1J9ajLHBdpY465tRM7M",
|
||||
"digest": "7a139d82b8a02e35279d657e197f5c1f",
|
||||
"sector_size": 34359738368
|
||||
},
|
||||
"v26-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-2-sha256_hasher-96f1b4a04c5c51e4759bbf224bbc2ef5a42c7100f16ec0637123f16a845ddfb2.params": {
|
||||
"cid": "QmY7DitNKXFeLQt9QoVQkfjM1EvRnprqUVxjmkTXkHDNka",
|
||||
"digest": "f27271c0537ba65ade2ec045f8fbd069",
|
||||
"v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-2-sha256_hasher-96f1b4a04c5c51e4759bbf224bbc2ef5a42c7100f16ec0637123f16a845ddfb2.params": {
|
||||
"cid": "QmfDha8271nXJn14Aq3qQeghjMBWbs6HNSGa6VuzCVk4TW",
|
||||
"digest": "5d3cd3f107a3bea8a96d1189efd2965c",
|
||||
"sector_size": 68719476736
|
||||
},
|
||||
"v26-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-2-sha256_hasher-96f1b4a04c5c51e4759bbf224bbc2ef5a42c7100f16ec0637123f16a845ddfb2.vk": {
|
||||
"cid": "QmUJsvoCuQ4LszPmeRVAkMYb5qY95ctz3UXKhu8xLzyFKo",
|
||||
"digest": "576b292938c6c9d0a0e721bd867a543b",
|
||||
"v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-2-sha256_hasher-96f1b4a04c5c51e4759bbf224bbc2ef5a42c7100f16ec0637123f16a845ddfb2.vk": {
|
||||
"cid": "QmRVtTtiFzHJTHurYzaCvetGAchux9cktixT4aGHthN6Zt",
|
||||
"digest": "62c366405404e60f171e661492740b1c",
|
||||
"sector_size": 68719476736
|
||||
}
|
||||
}
|
@ -3,11 +3,33 @@ package build
|
||||
import "fmt"
|
||||
|
||||
var CurrentCommit string
|
||||
var BuildType int
|
||||
|
||||
const (
|
||||
BuildDefault = 0
|
||||
Build2k = 0x1
|
||||
BuildDebug = 0x3
|
||||
)
|
||||
|
||||
func buildType() string {
|
||||
switch BuildType {
|
||||
case BuildDefault:
|
||||
return ""
|
||||
case BuildDebug:
|
||||
return "+debug"
|
||||
case Build2k:
|
||||
return "+2k"
|
||||
default:
|
||||
return "+huh?"
|
||||
}
|
||||
}
|
||||
|
||||
// BuildVersion is the local build version, set by build system
|
||||
const BuildVersion = "0.3.0"
|
||||
const BuildVersion = "0.4.0"
|
||||
|
||||
var UserVersion = BuildVersion + CurrentCommit
|
||||
func UserVersion() string {
|
||||
return BuildVersion + buildType() + CurrentCommit
|
||||
}
|
||||
|
||||
type Version uint32
|
||||
|
||||
@ -33,6 +55,7 @@ func (ve Version) EqMajorMinor(v2 Version) bool {
|
||||
// APIVersion is a semver version of the rpc api exposed
|
||||
var APIVersion Version = newVer(0, 3, 0)
|
||||
|
||||
//nolint:varcheck,deadcode
|
||||
const (
|
||||
majorMask = 0xff0000
|
||||
minorMask = 0xffff00
|
||||
|
@ -50,6 +50,7 @@ func Newf(retCode exitcode.ExitCode, format string, args ...interface{}) ActorEr
|
||||
}
|
||||
|
||||
// todo: bit hacky
|
||||
|
||||
func NewfSkip(skip int, retCode exitcode.ExitCode, format string, args ...interface{}) ActorError {
|
||||
if retCode == 0 {
|
||||
return &actorError{
|
||||
|
@ -1,45 +1,46 @@
|
||||
package drand
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"math/rand"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
dchain "github.com/drand/drand/chain"
|
||||
dclient "github.com/drand/drand/client"
|
||||
hclient "github.com/drand/drand/client/http"
|
||||
dlog "github.com/drand/drand/log"
|
||||
gclient "github.com/drand/drand/lp2p/client"
|
||||
"github.com/drand/kyber"
|
||||
kzap "github.com/go-kit/kit/log/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
logging "github.com/ipfs/go-log"
|
||||
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/beacon"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
logging "github.com/ipfs/go-log"
|
||||
|
||||
dbeacon "github.com/drand/drand/beacon"
|
||||
"github.com/drand/drand/core"
|
||||
dkey "github.com/drand/drand/key"
|
||||
dnet "github.com/drand/drand/net"
|
||||
dproto "github.com/drand/drand/protobuf/drand"
|
||||
)
|
||||
|
||||
var log = logging.Logger("drand")
|
||||
|
||||
var drandServers = []string{
|
||||
"nicolas.drand.fil-test.net:443",
|
||||
"philipp.drand.fil-test.net:443",
|
||||
"mathilde.drand.fil-test.net:443",
|
||||
"ludovic.drand.fil-test.net:443",
|
||||
"gabbi.drand.fil-test.net:443",
|
||||
"linus.drand.fil-test.net:443",
|
||||
"jeff.drand.fil-test.net:443",
|
||||
"https://pl-eu.testnet.drand.sh",
|
||||
"https://pl-us.testnet.drand.sh",
|
||||
"https://pl-sin.testnet.drand.sh",
|
||||
}
|
||||
|
||||
var drandPubKey *dkey.DistPublic
|
||||
var drandChain *dchain.Info
|
||||
|
||||
func init() {
|
||||
drandPubKey = new(dkey.DistPublic)
|
||||
err := drandPubKey.FromTOML(&dkey.DistPublicTOML{Coefficients: build.DrandCoeffs})
|
||||
|
||||
var err error
|
||||
drandChain, err = dchain.InfoFromJSON(bytes.NewReader([]byte(build.DrandChain)))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
panic("could not unmarshal chain info: " + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,13 +58,9 @@ func (dp *drandPeer) IsTLS() bool {
|
||||
}
|
||||
|
||||
type DrandBeacon struct {
|
||||
client dnet.Client
|
||||
client dclient.Client
|
||||
|
||||
peers []dnet.Peer
|
||||
peersIndex int
|
||||
peersIndexMtx sync.Mutex
|
||||
|
||||
pubkey *dkey.DistPublic
|
||||
pubkey kyber.Point
|
||||
|
||||
// seconds
|
||||
interval time.Duration
|
||||
@ -76,120 +73,86 @@ type DrandBeacon struct {
|
||||
localCache map[uint64]types.BeaconEntry
|
||||
}
|
||||
|
||||
func NewDrandBeacon(genesisTs, interval uint64) (*DrandBeacon, error) {
|
||||
func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub) (*DrandBeacon, error) {
|
||||
if genesisTs == 0 {
|
||||
panic("what are you doing this cant be zero")
|
||||
}
|
||||
|
||||
dlogger := dlog.NewKitLoggerFrom(kzap.NewZapSugarLogger(
|
||||
log.SugaredLogger.Desugar(), zapcore.InfoLevel))
|
||||
|
||||
var clients []dclient.Client
|
||||
for _, url := range drandServers {
|
||||
hc, err := hclient.NewWithInfo(url, drandChain, nil)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("could not create http drand client: %w", err)
|
||||
}
|
||||
clients = append(clients, hc)
|
||||
|
||||
}
|
||||
|
||||
opts := []dclient.Option{
|
||||
dclient.WithChainInfo(drandChain),
|
||||
dclient.WithCacheSize(1024),
|
||||
dclient.WithLogger(dlogger),
|
||||
dclient.WithAutoWatch(),
|
||||
}
|
||||
|
||||
if ps != nil {
|
||||
opts = append(opts, gclient.WithPubsub(ps))
|
||||
} else {
|
||||
log.Info("drand beacon without pubsub")
|
||||
}
|
||||
|
||||
client, err := dclient.Wrap(clients, opts...)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("creating drand client")
|
||||
}
|
||||
|
||||
db := &DrandBeacon{
|
||||
client: dnet.NewGrpcClient(),
|
||||
client: client,
|
||||
localCache: make(map[uint64]types.BeaconEntry),
|
||||
}
|
||||
for _, ds := range drandServers {
|
||||
db.peers = append(db.peers, &drandPeer{addr: ds, tls: true})
|
||||
}
|
||||
|
||||
db.peersIndex = rand.Intn(len(db.peers))
|
||||
|
||||
groupResp, err := db.client.Group(context.TODO(), db.peers[db.peersIndex], &dproto.GroupRequest{})
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to get group response from beacon peer: %w", err)
|
||||
}
|
||||
|
||||
kgroup, err := core.ProtoToGroup(groupResp)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to parse group response: %w", err)
|
||||
}
|
||||
|
||||
// TODO: verify these values are what we expect them to be
|
||||
if !kgroup.PublicKey.Equal(drandPubKey) {
|
||||
return nil, xerrors.Errorf("public key does not match")
|
||||
}
|
||||
// fmt.Printf("Drand Pubkey:\n%#v\n", kgroup.PublicKey.TOML()) // use to print public key
|
||||
db.pubkey = drandPubKey
|
||||
db.interval = kgroup.Period
|
||||
db.drandGenTime = uint64(kgroup.GenesisTime)
|
||||
db.pubkey = drandChain.PublicKey
|
||||
db.interval = drandChain.Period
|
||||
db.drandGenTime = uint64(drandChain.GenesisTime)
|
||||
db.filRoundTime = interval
|
||||
db.filGenTime = genesisTs
|
||||
|
||||
// TODO: the stream currently gives you back *all* values since drand genesis.
|
||||
// Having the stream in the background is merely an optimization, so not a big deal to disable it for now
|
||||
// go db.handleStreamingUpdates()
|
||||
|
||||
return db, nil
|
||||
}
|
||||
|
||||
func (db *DrandBeacon) rotatePeersIndex() {
|
||||
db.peersIndexMtx.Lock()
|
||||
nval := rand.Intn(len(db.peers))
|
||||
db.peersIndex = nval
|
||||
db.peersIndexMtx.Unlock()
|
||||
|
||||
log.Warnf("rotated to drand peer %d, %q", nval, db.peers[nval].Address())
|
||||
}
|
||||
|
||||
func (db *DrandBeacon) getPeerIndex() int {
|
||||
db.peersIndexMtx.Lock()
|
||||
defer db.peersIndexMtx.Unlock()
|
||||
return db.peersIndex
|
||||
}
|
||||
|
||||
func (db *DrandBeacon) handleStreamingUpdates() {
|
||||
for {
|
||||
p := db.peers[db.getPeerIndex()]
|
||||
ch, err := db.client.PublicRandStream(context.Background(), p, &dproto.PublicRandRequest{})
|
||||
if err != nil {
|
||||
log.Warnf("failed to get public rand stream to peer %q: %s", p.Address(), err)
|
||||
log.Warnf("trying again in 10 seconds")
|
||||
db.rotatePeersIndex()
|
||||
time.Sleep(time.Second * 10)
|
||||
continue
|
||||
}
|
||||
|
||||
for e := range ch {
|
||||
db.cacheValue(types.BeaconEntry{
|
||||
Round: e.Round,
|
||||
Data: e.Signature,
|
||||
})
|
||||
}
|
||||
|
||||
log.Warnf("drand beacon stream to peer %q broke, reconnecting in 10 seconds", p.Address())
|
||||
db.rotatePeersIndex()
|
||||
time.Sleep(time.Second * 10)
|
||||
}
|
||||
}
|
||||
|
||||
func (db *DrandBeacon) Entry(ctx context.Context, round uint64) <-chan beacon.Response {
|
||||
// check cache, it it if there, otherwise query the endpoint
|
||||
cres := db.getCachedValue(round)
|
||||
if cres != nil {
|
||||
out := make(chan beacon.Response, 1)
|
||||
out <- beacon.Response{Entry: *cres}
|
||||
if round != 0 {
|
||||
be := db.getCachedValue(round)
|
||||
if be != nil {
|
||||
out <- beacon.Response{Entry: *be}
|
||||
close(out)
|
||||
return out
|
||||
}
|
||||
|
||||
out := make(chan beacon.Response, 1)
|
||||
}
|
||||
|
||||
go func() {
|
||||
p := db.peers[db.getPeerIndex()]
|
||||
resp, err := db.client.PublicRand(ctx, p, &dproto.PublicRandRequest{Round: round})
|
||||
start := time.Now()
|
||||
log.Infow("start fetching randomness", "round", round)
|
||||
resp, err := db.client.Get(ctx, round)
|
||||
|
||||
var br beacon.Response
|
||||
if err != nil {
|
||||
db.rotatePeersIndex()
|
||||
br.Err = xerrors.Errorf("drand peer %q failed publicRand request: %w", p.Address(), err)
|
||||
br.Err = xerrors.Errorf("drand failed Get request: %w", err)
|
||||
} else {
|
||||
br.Entry.Round = resp.GetRound()
|
||||
br.Entry.Data = resp.GetSignature()
|
||||
br.Entry.Round = resp.Round()
|
||||
br.Entry.Data = resp.Signature()
|
||||
}
|
||||
|
||||
log.Infow("done fetching randomness", "round", round, "took", time.Since(start))
|
||||
out <- br
|
||||
close(out)
|
||||
}()
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (db *DrandBeacon) cacheValue(e types.BeaconEntry) {
|
||||
db.cacheLk.Lock()
|
||||
defer db.cacheLk.Unlock()
|
||||
@ -211,13 +174,12 @@ func (db *DrandBeacon) VerifyEntry(curr types.BeaconEntry, prev types.BeaconEntr
|
||||
// TODO handle genesis better
|
||||
return nil
|
||||
}
|
||||
b := &dbeacon.Beacon{
|
||||
b := &dchain.Beacon{
|
||||
PreviousSig: prev.Data,
|
||||
Round: curr.Round,
|
||||
Signature: curr.Data,
|
||||
}
|
||||
//log.Warnw("VerifyEntry", "beacon", b)
|
||||
err := dbeacon.VerifyBeacon(db.pubkey.Key(), b)
|
||||
err := dchain.VerifyBeacon(db.pubkey, b)
|
||||
if err == nil {
|
||||
db.cacheValue(curr)
|
||||
}
|
||||
|
@ -1,14 +1,22 @@
|
||||
package drand
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
dchain "github.com/drand/drand/chain"
|
||||
hclient "github.com/drand/drand/client/http"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestPrintDrandPubkey(t *testing.T) {
|
||||
bc, err := NewDrandBeacon(1, 1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
fmt.Printf("Drand Pubkey:\n%#v\n", bc.pubkey.TOML())
|
||||
func TestPrintGroupInfo(t *testing.T) {
|
||||
c, err := hclient.New(drandServers[0], nil, nil)
|
||||
assert.NoError(t, err)
|
||||
cg := c.(interface {
|
||||
FetchChainInfo(groupHash []byte) (*dchain.Info, error)
|
||||
})
|
||||
chain, err := cg.FetchChainInfo(nil)
|
||||
assert.NoError(t, err)
|
||||
err = chain.ToJSON(os.Stdout)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ func (bss *BlockSyncService) HandleStream(s inet.Stream) {
|
||||
ctx, span := trace.StartSpan(context.Background(), "blocksync.HandleStream")
|
||||
defer span.End()
|
||||
|
||||
defer s.Close()
|
||||
defer s.Close() //nolint:errcheck
|
||||
|
||||
var req BlockSyncRequest
|
||||
if err := cborutil.ReadCborRPC(bufio.NewReader(s), &req); err != nil {
|
||||
@ -107,7 +107,7 @@ func (bss *BlockSyncService) HandleStream(s inet.Stream) {
|
||||
}
|
||||
|
||||
writeDeadline := 60 * time.Second
|
||||
s.SetDeadline(time.Now().Add(writeDeadline))
|
||||
_ = s.SetDeadline(time.Now().Add(writeDeadline))
|
||||
if err := cborutil.WriteCborRPC(s, resp); err != nil {
|
||||
log.Warnw("failed to write back response for handle stream", "err", err, "peer", s.Conn().RemotePeer())
|
||||
return
|
||||
|
@ -283,14 +283,14 @@ func (bs *BlockSync) fetchBlocksBlockSync(ctx context.Context, p peer.ID, req *B
|
||||
bs.RemovePeer(p)
|
||||
return nil, xerrors.Errorf("failed to open stream to peer: %w", err)
|
||||
}
|
||||
s.SetWriteDeadline(time.Now().Add(5 * time.Second))
|
||||
_ = s.SetWriteDeadline(time.Now().Add(5 * time.Second))
|
||||
|
||||
if err := cborutil.WriteCborRPC(s, req); err != nil {
|
||||
s.SetWriteDeadline(time.Time{})
|
||||
_ = s.SetWriteDeadline(time.Time{})
|
||||
bs.syncPeers.logFailure(p, time.Since(start))
|
||||
return nil, err
|
||||
}
|
||||
s.SetWriteDeadline(time.Time{})
|
||||
_ = s.SetWriteDeadline(time.Time{})
|
||||
|
||||
var res BlockSyncResponse
|
||||
r := incrt.New(s, 50<<10, 5*time.Second)
|
||||
@ -561,26 +561,30 @@ func (bpt *bsPeerTracker) logSuccess(p peer.ID, dur time.Duration) {
|
||||
bpt.lk.Lock()
|
||||
defer bpt.lk.Unlock()
|
||||
|
||||
if pi, ok := bpt.peers[p]; !ok {
|
||||
var pi *peerStats
|
||||
var ok bool
|
||||
if pi, ok = bpt.peers[p]; !ok {
|
||||
log.Warnw("log success called on peer not in tracker", "peerid", p.String())
|
||||
return
|
||||
} else {
|
||||
pi.successes++
|
||||
|
||||
logTime(pi, dur)
|
||||
}
|
||||
|
||||
pi.successes++
|
||||
logTime(pi, dur)
|
||||
}
|
||||
|
||||
func (bpt *bsPeerTracker) logFailure(p peer.ID, dur time.Duration) {
|
||||
bpt.lk.Lock()
|
||||
defer bpt.lk.Unlock()
|
||||
if pi, ok := bpt.peers[p]; !ok {
|
||||
|
||||
var pi *peerStats
|
||||
var ok bool
|
||||
if pi, ok = bpt.peers[p]; !ok {
|
||||
log.Warn("log failure called on peer not in tracker", "peerid", p.String())
|
||||
return
|
||||
} else {
|
||||
}
|
||||
|
||||
pi.failures++
|
||||
logTime(pi, dur)
|
||||
}
|
||||
}
|
||||
|
||||
func (bpt *bsPeerTracker) removePeer(p peer.ID) {
|
||||
|
@ -19,7 +19,7 @@ import (
|
||||
|
||||
var log = logging.Logger("events")
|
||||
|
||||
// `curH`-`ts.Height` = `confidence`
|
||||
// HeightHandler `curH`-`ts.Height` = `confidence`
|
||||
type HeightHandler func(ctx context.Context, ts *types.TipSet, curH abi.ChainEpoch) error
|
||||
type RevertHandler func(ctx context.Context, ts *types.TipSet) error
|
||||
|
||||
@ -31,7 +31,7 @@ type heightHandler struct {
|
||||
revert RevertHandler
|
||||
}
|
||||
|
||||
type eventApi interface {
|
||||
type eventAPI interface {
|
||||
ChainNotify(context.Context) (<-chan []*api.HeadChange, error)
|
||||
ChainGetBlockMessages(context.Context, cid.Cid) (*api.BlockMessages, error)
|
||||
ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error)
|
||||
@ -42,7 +42,7 @@ type eventApi interface {
|
||||
}
|
||||
|
||||
type Events struct {
|
||||
api eventApi
|
||||
api eventAPI
|
||||
|
||||
tsc *tipSetCache
|
||||
lk sync.Mutex
|
||||
@ -54,7 +54,7 @@ type Events struct {
|
||||
calledEvents
|
||||
}
|
||||
|
||||
func NewEvents(ctx context.Context, api eventApi) *Events {
|
||||
func NewEvents(ctx context.Context, api eventAPI) *Events {
|
||||
gcConfidence := 2 * build.ForkLengthThreshold
|
||||
|
||||
tsc := newTSCache(gcConfidence, api.ChainGetTipSetByHeight)
|
||||
@ -67,7 +67,7 @@ func NewEvents(ctx context.Context, api eventApi) *Events {
|
||||
heightEvents: heightEvents{
|
||||
tsc: tsc,
|
||||
ctx: ctx,
|
||||
gcConfidence: abi.ChainEpoch(gcConfidence),
|
||||
gcConfidence: gcConfidence,
|
||||
|
||||
heightTriggers: map[uint64]*heightHandler{},
|
||||
htTriggerHeights: map[abi.ChainEpoch][]uint64{},
|
||||
@ -82,9 +82,9 @@ func NewEvents(ctx context.Context, api eventApi) *Events {
|
||||
|
||||
confQueue: map[triggerH]map[msgH][]*queuedEvent{},
|
||||
revertQueue: map[msgH][]triggerH{},
|
||||
triggers: map[triggerId]*callHandler{},
|
||||
matchers: map[triggerId][]MatchFunc{},
|
||||
timeouts: map[abi.ChainEpoch]map[triggerId]int{},
|
||||
triggers: map[triggerID]*callHandler{},
|
||||
matchers: map[triggerID][]MatchFunc{},
|
||||
timeouts: map[abi.ChainEpoch]map[triggerID]int{},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@ import (
|
||||
|
||||
const NoTimeout = math.MaxInt64
|
||||
|
||||
type triggerId = uint64
|
||||
type triggerID = uint64
|
||||
|
||||
// msgH is the block height at which a message was present / event has happened
|
||||
type msgH = abi.ChainEpoch
|
||||
@ -23,6 +23,7 @@ type msgH = abi.ChainEpoch
|
||||
// message (msgH+confidence)
|
||||
type triggerH = abi.ChainEpoch
|
||||
|
||||
// CalledHandler arguments:
|
||||
// `ts` is the tipset, in which the `msg` is included.
|
||||
// `curH`-`ts.Height` = `confidence`
|
||||
type CalledHandler func(msg *types.Message, rec *types.MessageReceipt, ts *types.TipSet, curH abi.ChainEpoch) (more bool, err error)
|
||||
@ -48,7 +49,7 @@ type callHandler struct {
|
||||
}
|
||||
|
||||
type queuedEvent struct {
|
||||
trigger triggerId
|
||||
trigger triggerID
|
||||
|
||||
h abi.ChainEpoch
|
||||
msg *types.Message
|
||||
@ -57,7 +58,7 @@ type queuedEvent struct {
|
||||
}
|
||||
|
||||
type calledEvents struct {
|
||||
cs eventApi
|
||||
cs eventAPI
|
||||
tsc *tipSetCache
|
||||
ctx context.Context
|
||||
gcConfidence uint64
|
||||
@ -66,10 +67,10 @@ type calledEvents struct {
|
||||
|
||||
lk sync.Mutex
|
||||
|
||||
ctr triggerId
|
||||
ctr triggerID
|
||||
|
||||
triggers map[triggerId]*callHandler
|
||||
matchers map[triggerId][]MatchFunc
|
||||
triggers map[triggerID]*callHandler
|
||||
matchers map[triggerID][]MatchFunc
|
||||
|
||||
// maps block heights to events
|
||||
// [triggerH][msgH][event]
|
||||
@ -78,8 +79,8 @@ type calledEvents struct {
|
||||
// [msgH][triggerH]
|
||||
revertQueue map[msgH][]triggerH
|
||||
|
||||
// [timeoutH+confidence][triggerId]{calls}
|
||||
timeouts map[abi.ChainEpoch]map[triggerId]int
|
||||
// [timeoutH+confidence][triggerID]{calls}
|
||||
timeouts map[abi.ChainEpoch]map[triggerID]int
|
||||
}
|
||||
|
||||
func (e *calledEvents) headChangeCalled(rev, app []*types.TipSet) error {
|
||||
@ -157,8 +158,8 @@ func (e *calledEvents) checkNewCalls(ts *types.TipSet) {
|
||||
})
|
||||
}
|
||||
|
||||
func (e *calledEvents) queueForConfidence(triggerId uint64, msg *types.Message, ts *types.TipSet) {
|
||||
trigger := e.triggers[triggerId]
|
||||
func (e *calledEvents) queueForConfidence(trigID uint64, msg *types.Message, ts *types.TipSet) {
|
||||
trigger := e.triggers[trigID]
|
||||
|
||||
appliedH := ts.Height()
|
||||
|
||||
@ -171,7 +172,7 @@ func (e *calledEvents) queueForConfidence(triggerId uint64, msg *types.Message,
|
||||
}
|
||||
|
||||
byOrigH[appliedH] = append(byOrigH[appliedH], &queuedEvent{
|
||||
trigger: triggerId,
|
||||
trigger: trigID,
|
||||
h: appliedH,
|
||||
msg: msg,
|
||||
})
|
||||
@ -231,11 +232,11 @@ func (e *calledEvents) applyTimeouts(ts *types.TipSet) {
|
||||
return // nothing to do
|
||||
}
|
||||
|
||||
for triggerId, calls := range triggers {
|
||||
for triggerID, calls := range triggers {
|
||||
if calls > 0 {
|
||||
continue // don't timeout if the method was called
|
||||
}
|
||||
trigger := e.triggers[triggerId]
|
||||
trigger := e.triggers[triggerID]
|
||||
if trigger.disabled {
|
||||
continue
|
||||
}
|
||||
|
@ -15,12 +15,12 @@ type heightEvents struct {
|
||||
tsc *tipSetCache
|
||||
gcConfidence abi.ChainEpoch
|
||||
|
||||
ctr triggerId
|
||||
ctr triggerID
|
||||
|
||||
heightTriggers map[triggerId]*heightHandler
|
||||
heightTriggers map[triggerID]*heightHandler
|
||||
|
||||
htTriggerHeights map[triggerH][]triggerId
|
||||
htHeights map[msgH][]triggerId
|
||||
htTriggerHeights map[triggerH][]triggerID
|
||||
htHeights map[msgH][]triggerID
|
||||
|
||||
ctx context.Context
|
||||
}
|
||||
|
@ -211,15 +211,14 @@ func (fcs *fakeCS) advance(rev, app int, msgs map[int]cid.Cid, nulls ...int) { /
|
||||
fcs.sub(revs, apps)
|
||||
|
||||
fcs.sync.Lock()
|
||||
fcs.sync.Unlock()
|
||||
|
||||
fcs.sync.Unlock() //nolint:staticcheck
|
||||
}
|
||||
|
||||
func (fcs *fakeCS) notifDone() {
|
||||
fcs.sync.Unlock()
|
||||
}
|
||||
|
||||
var _ eventApi = &fakeCS{}
|
||||
var _ eventAPI = &fakeCS{}
|
||||
|
||||
func TestAt(t *testing.T) {
|
||||
fcs := &fakeCS{
|
||||
|
@ -36,7 +36,7 @@ func (e *calledEvents) CheckMsg(ctx context.Context, smsg types.ChainMsg, hnd Ca
|
||||
func (e *calledEvents) MatchMsg(inmsg *types.Message) MatchFunc {
|
||||
return func(msg *types.Message) (bool, error) {
|
||||
if msg.From == inmsg.From && msg.Nonce == inmsg.Nonce && !inmsg.Equals(msg) {
|
||||
return false, xerrors.Errorf("matching msg %s from %s, nonce %d: got duplicate origin/nonce msg %s", inmsg.Cid(), inmsg.From, inmsg.Nonce, msg.Nonce)
|
||||
return false, xerrors.Errorf("matching msg %s from %s, nonce %d: got duplicate origin/nonce msg %d", inmsg.Cid(), inmsg.From, inmsg.Nonce, msg.Nonce)
|
||||
}
|
||||
|
||||
return inmsg.Equals(msg), nil
|
||||
|
@ -93,8 +93,8 @@ func (m mybs) Get(c cid.Cid) (block.Block, error) {
|
||||
}
|
||||
|
||||
func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
|
||||
saminer.SupportedProofTypes = map[abi.RegisteredProof]struct{}{
|
||||
abi.RegisteredProof_StackedDRG2KiBSeal: {},
|
||||
saminer.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
|
||||
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
|
||||
}
|
||||
|
||||
mr := repo.NewMemory(nil)
|
||||
@ -108,7 +108,7 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
|
||||
return nil, xerrors.Errorf("failed to get metadata datastore: %w", err)
|
||||
}
|
||||
|
||||
bds, err := lr.Datastore("/blocks")
|
||||
bds, err := lr.Datastore("/chain")
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to get blocks datastore: %w", err)
|
||||
}
|
||||
@ -145,7 +145,7 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
genm1, k1, err := seed.PreSeal(maddr1, abi.RegisteredProof_StackedDRG2KiBPoSt, 0, numSectors, m1temp, []byte("some randomness"), nil)
|
||||
genm1, k1, err := seed.PreSeal(maddr1, abi.RegisteredSealProof_StackedDrg2KiBV1, 0, numSectors, m1temp, []byte("some randomness"), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -157,7 +157,7 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
genm2, k2, err := seed.PreSeal(maddr2, abi.RegisteredProof_StackedDRG2KiBPoSt, 0, numSectors, m2temp, []byte("some randomness"), nil)
|
||||
genm2, k2, err := seed.PreSeal(maddr2, abi.RegisteredSealProof_StackedDrg2KiBV1, 0, numSectors, m2temp, []byte("some randomness"), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -223,6 +223,10 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
|
||||
miners := []address.Address{maddr1, maddr2}
|
||||
|
||||
beac := beacon.NewMockBeacon(time.Second)
|
||||
//beac, err := drand.NewDrandBeacon(tpl.Timestamp, build.BlockDelay)
|
||||
//if err != nil {
|
||||
//return nil, xerrors.Errorf("creating drand beacon: %w", err)
|
||||
//}
|
||||
|
||||
gen := &ChainGen{
|
||||
bs: bs,
|
||||
@ -431,7 +435,7 @@ func (cg *ChainGen) makeBlock(parents *types.TipSet, m address.Address, vrfticke
|
||||
return fblk, err
|
||||
}
|
||||
|
||||
// This function is awkward. It's used to deal with messages made when
|
||||
// ResyncBankerNonce is used for dealing with messages made when
|
||||
// simulating forks
|
||||
func (cg *ChainGen) ResyncBankerNonce(ts *types.TipSet) error {
|
||||
act, err := cg.sm.GetActor(cg.banker, ts)
|
||||
@ -536,13 +540,6 @@ func (wpp *wppProvider) ComputeProof(context.Context, []abi.SectorInfo, abi.PoSt
|
||||
return ValidWpostForTesting, nil
|
||||
}
|
||||
|
||||
type ProofInput struct {
|
||||
sectors []abi.SectorInfo
|
||||
hvrf []byte
|
||||
challengedSectors []uint64
|
||||
vrfout []byte
|
||||
}
|
||||
|
||||
func IsRoundWinner(ctx context.Context, ts *types.TipSet, round abi.ChainEpoch,
|
||||
miner address.Address, brand types.BeaconEntry, mbi *api.MiningBaseInfo, a MiningCheckAPI) (*types.ElectionProof, error) {
|
||||
|
||||
@ -616,6 +613,6 @@ func (m genFakeVerifier) VerifyWindowPoSt(ctx context.Context, info abi.WindowPo
|
||||
panic("not supported")
|
||||
}
|
||||
|
||||
func (m genFakeVerifier) GenerateWinningPoStSectorChallenge(ctx context.Context, proof abi.RegisteredProof, id abi.ActorID, randomness abi.PoStRandomness, u uint64) ([]uint64, error) {
|
||||
func (m genFakeVerifier) GenerateWinningPoStSectorChallenge(ctx context.Context, proof abi.RegisteredPoStProof, id abi.ActorID, randomness abi.PoStRandomness, u uint64) ([]uint64, error) {
|
||||
panic("not supported")
|
||||
}
|
||||
|
@ -14,8 +14,8 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
miner.SupportedProofTypes = map[abi.RegisteredProof]struct{}{
|
||||
abi.RegisteredProof_StackedDRG2KiBSeal: {},
|
||||
miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
|
||||
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
|
||||
}
|
||||
power.ConsensusMinerMinPower = big.NewInt(2048)
|
||||
verifreg.MinVerifiedDealSize = big.NewInt(256)
|
||||
|
@ -58,6 +58,8 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
|
||||
for i, m := range miners {
|
||||
// Create miner through power actor
|
||||
i := i
|
||||
m := m
|
||||
|
||||
spt, err := ffiwrapper.SealProofTypeFromSectorSize(m.SectorSize)
|
||||
if err != nil {
|
||||
@ -69,7 +71,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
constructorParams := &power.CreateMinerParams{
|
||||
Owner: m.Worker,
|
||||
Worker: m.Worker,
|
||||
Peer: m.PeerId,
|
||||
Peer: []byte(m.PeerId),
|
||||
SealProofType: spt,
|
||||
}
|
||||
|
||||
@ -154,6 +156,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
|
||||
// Commit sectors
|
||||
for pi, preseal := range m.Sectors {
|
||||
preseal := preseal
|
||||
// TODO: Maybe check seal (Can just be snark inputs, doesn't go into the genesis file)
|
||||
|
||||
// check deals, get dealWeight
|
||||
@ -201,7 +204,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
{
|
||||
newSectorInfo := &miner.SectorOnChainInfo{
|
||||
Info: miner.SectorPreCommitInfo{
|
||||
RegisteredProof: preseal.ProofType,
|
||||
SealProof: preseal.ProofType,
|
||||
SectorNumber: preseal.SectorID,
|
||||
SealedCID: preseal.CommR,
|
||||
SealRandEpoch: 0,
|
||||
|
@ -16,7 +16,7 @@ import (
|
||||
"github.com/ipfs/go-datastore"
|
||||
)
|
||||
|
||||
type testMpoolApi struct {
|
||||
type testMpoolAPI struct {
|
||||
cb func(rev, app []*types.TipSet) error
|
||||
|
||||
bmsgs map[cid.Cid][]*types.SignedMessage
|
||||
@ -25,68 +25,68 @@ type testMpoolApi struct {
|
||||
tipsets []*types.TipSet
|
||||
}
|
||||
|
||||
func newTestMpoolApi() *testMpoolApi {
|
||||
return &testMpoolApi{
|
||||
func newTestMpoolAPI() *testMpoolAPI {
|
||||
return &testMpoolAPI{
|
||||
bmsgs: make(map[cid.Cid][]*types.SignedMessage),
|
||||
statenonce: make(map[address.Address]uint64),
|
||||
}
|
||||
}
|
||||
|
||||
func (tma *testMpoolApi) applyBlock(t *testing.T, b *types.BlockHeader) {
|
||||
func (tma *testMpoolAPI) applyBlock(t *testing.T, b *types.BlockHeader) {
|
||||
t.Helper()
|
||||
if err := tma.cb(nil, []*types.TipSet{mock.TipSet(b)}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (tma *testMpoolApi) revertBlock(t *testing.T, b *types.BlockHeader) {
|
||||
func (tma *testMpoolAPI) revertBlock(t *testing.T, b *types.BlockHeader) {
|
||||
t.Helper()
|
||||
if err := tma.cb([]*types.TipSet{mock.TipSet(b)}, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (tma *testMpoolApi) setStateNonce(addr address.Address, v uint64) {
|
||||
func (tma *testMpoolAPI) setStateNonce(addr address.Address, v uint64) {
|
||||
tma.statenonce[addr] = v
|
||||
}
|
||||
|
||||
func (tma *testMpoolApi) setBlockMessages(h *types.BlockHeader, msgs ...*types.SignedMessage) {
|
||||
func (tma *testMpoolAPI) setBlockMessages(h *types.BlockHeader, msgs ...*types.SignedMessage) {
|
||||
tma.bmsgs[h.Cid()] = msgs
|
||||
tma.tipsets = append(tma.tipsets, mock.TipSet(h))
|
||||
}
|
||||
|
||||
func (tma *testMpoolApi) SubscribeHeadChanges(cb func(rev, app []*types.TipSet) error) *types.TipSet {
|
||||
func (tma *testMpoolAPI) SubscribeHeadChanges(cb func(rev, app []*types.TipSet) error) *types.TipSet {
|
||||
tma.cb = cb
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tma *testMpoolApi) PutMessage(m types.ChainMsg) (cid.Cid, error) {
|
||||
func (tma *testMpoolAPI) PutMessage(m types.ChainMsg) (cid.Cid, error) {
|
||||
return cid.Undef, nil
|
||||
}
|
||||
|
||||
func (tma *testMpoolApi) PubSubPublish(string, []byte) error {
|
||||
func (tma *testMpoolAPI) PubSubPublish(string, []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tma *testMpoolApi) StateGetActor(addr address.Address, ts *types.TipSet) (*types.Actor, error) {
|
||||
func (tma *testMpoolAPI) StateGetActor(addr address.Address, ts *types.TipSet) (*types.Actor, error) {
|
||||
return &types.Actor{
|
||||
Nonce: tma.statenonce[addr],
|
||||
Balance: types.NewInt(90000000),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (tma *testMpoolApi) StateAccountKey(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) {
|
||||
func (tma *testMpoolAPI) StateAccountKey(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) {
|
||||
if addr.Protocol() != address.BLS && addr.Protocol() != address.SECP256K1 {
|
||||
return address.Undef, fmt.Errorf("given address was not a key addr")
|
||||
}
|
||||
return addr, nil
|
||||
}
|
||||
|
||||
func (tma *testMpoolApi) MessagesForBlock(h *types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error) {
|
||||
func (tma *testMpoolAPI) MessagesForBlock(h *types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error) {
|
||||
return nil, tma.bmsgs[h.Cid()], nil
|
||||
}
|
||||
|
||||
func (tma *testMpoolApi) MessagesForTipset(ts *types.TipSet) ([]types.ChainMsg, error) {
|
||||
func (tma *testMpoolAPI) MessagesForTipset(ts *types.TipSet) ([]types.ChainMsg, error) {
|
||||
if len(ts.Blocks()) != 1 {
|
||||
panic("cant deal with multiblock tipsets in this test")
|
||||
}
|
||||
@ -108,7 +108,7 @@ func (tma *testMpoolApi) MessagesForTipset(ts *types.TipSet) ([]types.ChainMsg,
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (tma *testMpoolApi) LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error) {
|
||||
func (tma *testMpoolAPI) LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error) {
|
||||
for _, ts := range tma.tipsets {
|
||||
if types.CidArrsEqual(tsk.Cids(), ts.Cids()) {
|
||||
return ts, nil
|
||||
@ -138,7 +138,7 @@ func mustAdd(t *testing.T, mp *MessagePool, msg *types.SignedMessage) {
|
||||
}
|
||||
|
||||
func TestMessagePool(t *testing.T) {
|
||||
tma := newTestMpoolApi()
|
||||
tma := newTestMpoolAPI()
|
||||
|
||||
w, err := wallet.NewWallet(wallet.NewMemKeyStore())
|
||||
if err != nil {
|
||||
@ -179,7 +179,7 @@ func TestMessagePool(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRevertMessages(t *testing.T) {
|
||||
tma := newTestMpoolApi()
|
||||
tma := newTestMpoolAPI()
|
||||
|
||||
w, err := wallet.NewWallet(wallet.NewMemKeyStore())
|
||||
if err != nil {
|
||||
|
@ -21,7 +21,7 @@ import (
|
||||
|
||||
var log = logging.Logger("statetree")
|
||||
|
||||
// Stores actors state by their ID.
|
||||
// StateTree stores actors state by their ID.
|
||||
type StateTree struct {
|
||||
root *hamt.Node
|
||||
Store cbor.IpldStore
|
||||
@ -149,7 +149,7 @@ func (st *StateTree) SetActor(addr address.Address, act *types.Actor) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// `LookupID` gets the ID address of this actor's `addr` stored in the `InitActor`.
|
||||
// LookupID gets the ID address of this actor's `addr` stored in the `InitActor`.
|
||||
func (st *StateTree) LookupID(addr address.Address) (address.Address, error) {
|
||||
if addr.Protocol() == address.ID {
|
||||
return addr, nil
|
||||
|
@ -255,12 +255,15 @@ func TestStateTreeConsistency(t *testing.T) {
|
||||
}
|
||||
|
||||
for i, a := range addrs {
|
||||
st.SetActor(a, &types.Actor{
|
||||
err := st.SetActor(a, &types.Actor{
|
||||
Code: randomCid,
|
||||
Head: randomCid,
|
||||
Balance: types.NewInt(uint64(10000 + i)),
|
||||
Nonce: uint64(1000 - i),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("while setting actor: %+v", err)
|
||||
}
|
||||
}
|
||||
|
||||
root, err := st.Flush(context.TODO())
|
||||
|
@ -64,7 +64,7 @@ func (sm *StateManager) CallRaw(ctx context.Context, msg *types.Message, bstate
|
||||
return &api.InvocResult{
|
||||
Msg: msg,
|
||||
MsgRct: &ret.MessageReceipt,
|
||||
InternalExecutions: ret.InternalExecutions,
|
||||
ExecutionTrace: ret.ExecutionTrace,
|
||||
Error: errs,
|
||||
Duration: ret.Duration,
|
||||
}, nil
|
||||
|
@ -37,8 +37,8 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
miner.SupportedProofTypes = map[abi.RegisteredProof]struct{}{
|
||||
abi.RegisteredProof_StackedDRG2KiBSeal: {},
|
||||
miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
|
||||
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
|
||||
}
|
||||
power.ConsensusMinerMinPower = big.NewInt(2048)
|
||||
verifreg.MinVerifiedDealSize = big.NewInt(256)
|
||||
|
@ -123,7 +123,7 @@ func (sm *StateManager) ExecutionTrace(ctx context.Context, ts *types.TipSet) (c
|
||||
ir := &api.InvocResult{
|
||||
Msg: msg,
|
||||
MsgRct: &ret.MessageReceipt,
|
||||
InternalExecutions: ret.InternalExecutions,
|
||||
ExecutionTrace: ret.ExecutionTrace,
|
||||
Duration: ret.Duration,
|
||||
}
|
||||
if ret.ActorErr != nil {
|
||||
@ -187,7 +187,6 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, pstate cid.Cid, bms []B
|
||||
Miner: b.Miner,
|
||||
Penalty: penalty,
|
||||
GasReward: gasReward,
|
||||
TicketCount: 1, // TODO: no longer need ticket count here.
|
||||
})
|
||||
if err != nil {
|
||||
return cid.Undef, cid.Undef, xerrors.Errorf("failed to serialize award params: %w", err)
|
||||
@ -326,7 +325,7 @@ func (sm *StateManager) computeTipSetState(ctx context.Context, blks []*types.Bl
|
||||
blkmsgs = append(blkmsgs, bm)
|
||||
}
|
||||
|
||||
return sm.ApplyBlocks(ctx, pstate, blkmsgs, abi.ChainEpoch(blks[0].Height), r, cb)
|
||||
return sm.ApplyBlocks(ctx, pstate, blkmsgs, blks[0].Height, r, cb)
|
||||
}
|
||||
|
||||
func (sm *StateManager) parentState(ts *types.TipSet) cid.Cid {
|
||||
@ -382,8 +381,8 @@ func (sm *StateManager) LoadActorState(ctx context.Context, a address.Address, o
|
||||
cst := cbor.NewCborStore(sm.cs.Blockstore())
|
||||
if err := cst.Get(ctx, act.Head, out); err != nil {
|
||||
var r cbg.Deferred
|
||||
cst.Get(ctx, act.Head, &r)
|
||||
fmt.Printf("badhead %x\n", r.Raw)
|
||||
_ = cst.Get(ctx, act.Head, &r)
|
||||
log.Errorw("bad actor head", "error", err, "raw", r.Raw, "address", a)
|
||||
|
||||
return nil, err
|
||||
}
|
||||
@ -405,8 +404,8 @@ func (sm *StateManager) LoadActorStateRaw(ctx context.Context, a address.Address
|
||||
return act, nil
|
||||
}
|
||||
|
||||
// Similar to `vm.ResolveToKeyAddr` but does not allow `Actor` type of addresses. Uses the `TipSet` `ts`
|
||||
// to generate the VM state.
|
||||
// ResolveToKeyAddress is similar to `vm.ResolveToKeyAddr` but does not allow `Actor` type of addresses.
|
||||
// Uses the `TipSet` `ts` to generate the VM state.
|
||||
func (sm *StateManager) ResolveToKeyAddress(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) {
|
||||
switch addr.Protocol() {
|
||||
case address.BLS, address.SECP256K1:
|
||||
@ -480,7 +479,10 @@ func (sm *StateManager) GetReceipt(ctx context.Context, msg cid.Cid, ts *types.T
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid) (*types.TipSet, *types.MessageReceipt, error) {
|
||||
// WaitForMessage blocks until a message appears on chain. It looks backwards in the chain to see if this has already
|
||||
// happened. It guarantees that the message has been on chain for at least confidence epochs without being reverted
|
||||
// before returning.
|
||||
func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confidence uint64) (*types.TipSet, *types.MessageReceipt, error) {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
@ -528,6 +530,11 @@ func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid) (*type
|
||||
close(backSearchWait)
|
||||
}()
|
||||
|
||||
var candidateTs *types.TipSet
|
||||
var candidateRcp *types.MessageReceipt
|
||||
heightOfHead := head[0].Val.Height()
|
||||
reverts := map[types.TipSetKey]bool{}
|
||||
|
||||
for {
|
||||
select {
|
||||
case notif, ok := <-tsub:
|
||||
@ -537,21 +544,44 @@ func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid) (*type
|
||||
for _, val := range notif {
|
||||
switch val.Type {
|
||||
case store.HCRevert:
|
||||
continue
|
||||
if val.Val.Equals(candidateTs) {
|
||||
candidateTs = nil
|
||||
candidateRcp = nil
|
||||
}
|
||||
if backSearchWait != nil {
|
||||
reverts[val.Val.Key()] = true
|
||||
}
|
||||
case store.HCApply:
|
||||
if candidateTs != nil && val.Val.Height() >= candidateTs.Height()+abi.ChainEpoch(confidence) {
|
||||
return candidateTs, candidateRcp, nil
|
||||
}
|
||||
r, err := sm.tipsetExecutedMessage(val.Val, mcid, msg.VMMessage())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if r != nil {
|
||||
return val.Val, r, nil
|
||||
if confidence == 0 {
|
||||
return val.Val, r, err
|
||||
}
|
||||
candidateTs = val.Val
|
||||
candidateRcp = r
|
||||
}
|
||||
heightOfHead = val.Val.Height()
|
||||
}
|
||||
}
|
||||
case <-backSearchWait:
|
||||
if backTs != nil {
|
||||
// check if we found the message in the chain and that is hasn't been reverted since we started searching
|
||||
if backTs != nil && !reverts[backTs.Key()] {
|
||||
// if head is at or past confidence interval, return immediately
|
||||
if heightOfHead >= backTs.Height()+abi.ChainEpoch(confidence) {
|
||||
return backTs, backRcp, nil
|
||||
}
|
||||
|
||||
// wait for confidence interval
|
||||
candidateTs = backTs
|
||||
candidateRcp = backRcp
|
||||
}
|
||||
reverts = nil
|
||||
backSearchWait = nil
|
||||
case <-ctx.Done():
|
||||
return nil, nil, ctx.Err()
|
||||
|
@ -138,6 +138,24 @@ func PreCommitInfo(ctx context.Context, sm *StateManager, maddr address.Address,
|
||||
return *i, nil
|
||||
}
|
||||
|
||||
func MinerSectorInfo(ctx context.Context, sm *StateManager, maddr address.Address, sid abi.SectorNumber, ts *types.TipSet) (*miner.SectorOnChainInfo, error) {
|
||||
var mas miner.State
|
||||
_, err := sm.LoadActorState(ctx, maddr, &mas, ts)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("(get sset) failed to load miner actor state: %w", err)
|
||||
}
|
||||
|
||||
sectorInfo, ok, err := mas.GetSector(sm.cs.Store(ctx), sid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !ok {
|
||||
return nil, xerrors.New("sector not found")
|
||||
}
|
||||
|
||||
return sectorInfo, nil
|
||||
}
|
||||
|
||||
func GetMinerSectorSet(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address, filter *abi.BitField, filterOut bool) ([]*api.ChainSectorInfo, error) {
|
||||
var mas miner.State
|
||||
_, err := sm.LoadActorState(ctx, maddr, &mas, ts)
|
||||
@ -188,7 +206,7 @@ func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *S
|
||||
out := make([]abi.SectorInfo, len(ids))
|
||||
for i, n := range ids {
|
||||
out[i] = abi.SectorInfo{
|
||||
RegisteredProof: wpt,
|
||||
SealProof: spt,
|
||||
SectorNumber: sectorSet[n].ID,
|
||||
SealedCID: sectorSet[n].Info.Info.SealedCID,
|
||||
}
|
||||
@ -268,7 +286,7 @@ func GetMinerRecoveries(ctx context.Context, sm *StateManager, ts *types.TipSet,
|
||||
return mas.Recoveries, nil
|
||||
}
|
||||
|
||||
func GetStorageDeal(ctx context.Context, sm *StateManager, dealId abi.DealID, ts *types.TipSet) (*api.MarketDeal, error) {
|
||||
func GetStorageDeal(ctx context.Context, sm *StateManager, dealID abi.DealID, ts *types.TipSet) (*api.MarketDeal, error) {
|
||||
var state market.State
|
||||
if _, err := sm.LoadActorState(ctx, builtin.StorageMarketActorAddr, &state, ts); err != nil {
|
||||
return nil, err
|
||||
@ -280,7 +298,7 @@ func GetStorageDeal(ctx context.Context, sm *StateManager, dealId abi.DealID, ts
|
||||
}
|
||||
|
||||
var dp market.DealProposal
|
||||
if err := da.Get(ctx, uint64(dealId), &dp); err != nil {
|
||||
if err := da.Get(ctx, uint64(dealID), &dp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -289,7 +307,7 @@ func GetStorageDeal(ctx context.Context, sm *StateManager, dealId abi.DealID, ts
|
||||
return nil, err
|
||||
}
|
||||
|
||||
st, found, err := sa.Get(dealId)
|
||||
st, found, err := sa.Get(dealID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -49,6 +49,9 @@ var log = logging.Logger("chainstore")
|
||||
var chainHeadKey = dstore.NewKey("head")
|
||||
var blockValidationCacheKeyPrefix = dstore.NewKey("blockValidation")
|
||||
|
||||
// ReorgNotifee represents a callback that gets called upon reorgs.
|
||||
type ReorgNotifee func(rev, app []*types.TipSet) error
|
||||
|
||||
type ChainStore struct {
|
||||
bs bstore.Blockstore
|
||||
ds dstore.Datastore
|
||||
@ -65,7 +68,7 @@ type ChainStore struct {
|
||||
cindex *ChainIndex
|
||||
|
||||
reorgCh chan<- reorg
|
||||
headChangeNotifs []func(rev, app []*types.TipSet) error
|
||||
reorgNotifeeCh chan ReorgNotifee
|
||||
|
||||
mmCache *lru.ARCCache
|
||||
tsCache *lru.ARCCache
|
||||
@ -90,8 +93,6 @@ func NewChainStore(bs bstore.Blockstore, ds dstore.Batching, vmcalls runtime.Sys
|
||||
|
||||
cs.cindex = ci
|
||||
|
||||
cs.reorgCh = cs.reorgWorker(context.TODO())
|
||||
|
||||
hcnf := func(rev, app []*types.TipSet) error {
|
||||
cs.pubLk.Lock()
|
||||
defer cs.pubLk.Unlock()
|
||||
@ -123,7 +124,8 @@ func NewChainStore(bs bstore.Blockstore, ds dstore.Batching, vmcalls runtime.Sys
|
||||
return nil
|
||||
}
|
||||
|
||||
cs.headChangeNotifs = append(cs.headChangeNotifs, hcnf, hcmetric)
|
||||
cs.reorgNotifeeCh = make(chan ReorgNotifee)
|
||||
cs.reorgCh = cs.reorgWorker(context.TODO(), []ReorgNotifee{hcnf, hcmetric})
|
||||
|
||||
return cs
|
||||
}
|
||||
@ -212,8 +214,8 @@ func (cs *ChainStore) SubHeadChanges(ctx context.Context) chan []*api.HeadChange
|
||||
return out
|
||||
}
|
||||
|
||||
func (cs *ChainStore) SubscribeHeadChanges(f func(rev, app []*types.TipSet) error) {
|
||||
cs.headChangeNotifs = append(cs.headChangeNotifs, f)
|
||||
func (cs *ChainStore) SubscribeHeadChanges(f ReorgNotifee) {
|
||||
cs.reorgNotifeeCh <- f
|
||||
}
|
||||
|
||||
func (cs *ChainStore) IsBlockValidated(ctx context.Context, blkid cid.Cid) (bool, error) {
|
||||
@ -290,13 +292,19 @@ type reorg struct {
|
||||
new *types.TipSet
|
||||
}
|
||||
|
||||
func (cs *ChainStore) reorgWorker(ctx context.Context) chan<- reorg {
|
||||
func (cs *ChainStore) reorgWorker(ctx context.Context, initialNotifees []ReorgNotifee) chan<- reorg {
|
||||
out := make(chan reorg, 32)
|
||||
notifees := make([]ReorgNotifee, len(initialNotifees))
|
||||
copy(notifees, initialNotifees)
|
||||
|
||||
go func() {
|
||||
defer log.Warn("reorgWorker quit")
|
||||
|
||||
for {
|
||||
select {
|
||||
case n := <-cs.reorgNotifeeCh:
|
||||
notifees = append(notifees, n)
|
||||
|
||||
case r := <-out:
|
||||
revert, apply, err := cs.ReorgOps(r.old, r.new)
|
||||
if err != nil {
|
||||
@ -310,7 +318,7 @@ func (cs *ChainStore) reorgWorker(ctx context.Context) chan<- reorg {
|
||||
apply[i], apply[opp] = apply[opp], apply[i]
|
||||
}
|
||||
|
||||
for _, hcf := range cs.headChangeNotifs {
|
||||
for _, hcf := range notifees {
|
||||
if err := hcf(revert, apply); err != nil {
|
||||
log.Error("head change func errored (BAD): ", err)
|
||||
}
|
||||
@ -409,7 +417,7 @@ func (cs *ChainStore) LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error) {
|
||||
return ts, nil
|
||||
}
|
||||
|
||||
// returns true if 'a' is an ancestor of 'b'
|
||||
// IsAncestorOf returns true if 'a' is an ancestor of 'b'
|
||||
func (cs *ChainStore) IsAncestorOf(a, b *types.TipSet) (bool, error) {
|
||||
if b.Height() <= a.Height() {
|
||||
return false, nil
|
||||
@ -917,39 +925,50 @@ func DrawRandomness(rbase []byte, pers crypto.DomainSeparationTag, round abi.Cha
|
||||
return nil, xerrors.Errorf("deriving randomness: %w", err)
|
||||
}
|
||||
VRFDigest := blake2b.Sum256(rbase)
|
||||
h.Write(VRFDigest[:])
|
||||
_, err := h.Write(VRFDigest[:])
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("hashing VRFDigest: %w", err)
|
||||
}
|
||||
if err := binary.Write(h, binary.BigEndian, round); err != nil {
|
||||
return nil, xerrors.Errorf("deriving randomness: %w", err)
|
||||
}
|
||||
h.Write(entropy)
|
||||
_, err = h.Write(entropy)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("hashing entropy: %w", err)
|
||||
}
|
||||
|
||||
return h.Sum(nil), nil
|
||||
}
|
||||
|
||||
func (cs *ChainStore) GetRandomness(ctx context.Context, blks []cid.Cid, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) (out []byte, err error) {
|
||||
func (cs *ChainStore) GetRandomness(ctx context.Context, blks []cid.Cid, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
|
||||
_, span := trace.StartSpan(ctx, "store.GetRandomness")
|
||||
defer span.End()
|
||||
span.AddAttributes(trace.Int64Attribute("round", int64(round)))
|
||||
|
||||
//defer func() {
|
||||
//log.Infof("getRand %v %d %d %x -> %x", blks, pers, round, entropy, out)
|
||||
//}()
|
||||
for {
|
||||
nts, err := cs.LoadTipSet(types.NewTipSetKey(blks...))
|
||||
ts, err := cs.LoadTipSet(types.NewTipSetKey(blks...))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mtb := nts.MinTicketBlock()
|
||||
if round > ts.Height() {
|
||||
return nil, xerrors.Errorf("cannot draw randomness from the future")
|
||||
}
|
||||
|
||||
searchHeight := round
|
||||
if searchHeight < 0 {
|
||||
searchHeight = 0
|
||||
}
|
||||
|
||||
randTs, err := cs.GetTipsetByHeight(ctx, searchHeight, ts, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mtb := randTs.MinTicketBlock()
|
||||
|
||||
// if at (or just past -- for null epochs) appropriate epoch
|
||||
// or at genesis (works for negative epochs)
|
||||
if nts.Height() <= round || mtb.Height == 0 {
|
||||
return DrawRandomness(nts.MinTicketBlock().Ticket.VRFProof, pers, round, entropy)
|
||||
}
|
||||
|
||||
blks = mtb.Parents
|
||||
}
|
||||
return DrawRandomness(mtb.Ticket.VRFProof, pers, round, entropy)
|
||||
}
|
||||
|
||||
// GetTipsetByHeight returns the tipset on the chain behind 'ts' at the given
|
||||
@ -1166,7 +1185,6 @@ func (cr *chainRand) GetRandomness(ctx context.Context, pers crypto.DomainSepara
|
||||
func (cs *ChainStore) GetTipSetFromKey(tsk types.TipSetKey) (*types.TipSet, error) {
|
||||
if tsk.IsEmpty() {
|
||||
return cs.GetHeaviestTipSet(), nil
|
||||
} else {
|
||||
return cs.LoadTipSet(tsk)
|
||||
}
|
||||
return cs.LoadTipSet(tsk)
|
||||
}
|
||||
|
@ -22,8 +22,8 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
miner.SupportedProofTypes = map[abi.RegisteredProof]struct{}{
|
||||
abi.RegisteredProof_StackedDRG2KiBSeal: {},
|
||||
miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
|
||||
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
|
||||
}
|
||||
power.ConsensusMinerMinPower = big.NewInt(2048)
|
||||
verifreg.MinVerifiedDealSize = big.NewInt(256)
|
||||
@ -55,7 +55,7 @@ func BenchmarkGetRandomness(b *testing.B) {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
bds, err := lr.Datastore("/blocks")
|
||||
bds, err := lr.Datastore("/chain")
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
@ -57,8 +57,7 @@ func HandleIncomingBlocks(ctx context.Context, bsub *pubsub.Subscription, s *cha
|
||||
return
|
||||
}
|
||||
|
||||
//nolint:golint
|
||||
src := peer.ID(msg.GetFrom())
|
||||
src := msg.GetFrom()
|
||||
|
||||
go func() {
|
||||
start := time.Now()
|
||||
@ -204,7 +203,7 @@ func (bv *BlockValidator) Validate(ctx context.Context, pid peer.ID, msg *pubsub
|
||||
}
|
||||
}
|
||||
|
||||
err = sigs.CheckBlockSignature(blk.Header, ctx, key)
|
||||
err = sigs.CheckBlockSignature(ctx, blk.Header, key)
|
||||
if err != nil {
|
||||
log.Errorf("block signature verification failed: %s", err)
|
||||
recordFailure("signature_verification_failed")
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/Gurpartap/async"
|
||||
@ -528,7 +527,7 @@ func blockSanityChecks(h *types.BlockHeader) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Should match up with 'Semantical Validation' in validation.md in the spec
|
||||
// ValidateBlock should match up with 'Semantical Validation' in validation.md in the spec
|
||||
func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) (err error) {
|
||||
defer func() {
|
||||
// b.Cid() could panic for empty blocks that are used in tests.
|
||||
@ -693,7 +692,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) (er
|
||||
})
|
||||
|
||||
blockSigCheck := async.Err(func() error {
|
||||
if err := sigs.CheckBlockSignature(h, ctx, waddr); err != nil {
|
||||
if err := sigs.CheckBlockSignature(ctx, h, waddr); err != nil {
|
||||
return xerrors.Errorf("check block signature failed: %w", err)
|
||||
}
|
||||
return nil
|
||||
@ -878,7 +877,7 @@ func (syncer *Syncer) checkBlockMessages(ctx context.Context, b *types.FullBlock
|
||||
|
||||
// Phase 1: syntactic validation, as defined in the spec
|
||||
minGas := vm.PricelistByEpoch(baseTs.Height()).OnChainMessage(msg.ChainLength())
|
||||
if err := m.ValidForBlockInclusion(minGas); err != nil {
|
||||
if err := m.ValidForBlockInclusion(minGas.Total()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -970,23 +969,14 @@ func (syncer *Syncer) verifyBlsAggregate(ctx context.Context, sig *crypto.Signat
|
||||
trace.Int64Attribute("msgCount", int64(len(msgs))),
|
||||
)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
|
||||
digests := make([]bls.Digest, len(msgs))
|
||||
for i := 0; i < 10; i++ {
|
||||
wg.Add(1)
|
||||
go func(w int) {
|
||||
defer wg.Done()
|
||||
for j := 0; (j*10)+w < len(msgs); j++ {
|
||||
digests[j*10+w] = bls.Hash(bls.Message(msgs[j*10+w].Bytes()))
|
||||
bmsgs := make([]bls.Message, len(msgs))
|
||||
for i, m := range msgs {
|
||||
bmsgs[i] = m.Bytes()
|
||||
}
|
||||
}(i)
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
var bsig bls.Signature
|
||||
copy(bsig[:], sig.Data)
|
||||
if !bls.Verify(&bsig, digests, pubks) {
|
||||
if !bls.HashVerify(&bsig, bmsgs, pubks) {
|
||||
return xerrors.New("bls aggregate signature failed to verify")
|
||||
}
|
||||
|
||||
|
@ -34,8 +34,8 @@ import (
|
||||
func init() {
|
||||
build.InsecurePoStValidation = true
|
||||
os.Setenv("TRUST_PARAMS", "1")
|
||||
miner.SupportedProofTypes = map[abi.RegisteredProof]struct{}{
|
||||
abi.RegisteredProof_StackedDRG2KiBSeal: {},
|
||||
miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
|
||||
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
|
||||
}
|
||||
power.ConsensusMinerMinPower = big.NewInt(2048)
|
||||
verifreg.MinVerifiedDealSize = big.NewInt(256)
|
||||
@ -417,7 +417,7 @@ func TestSyncBadTimestamp(t *testing.T) {
|
||||
a1 := tu.mineOnBlock(base, 0, nil, false, true)
|
||||
|
||||
tu.g.Timestamper = nil
|
||||
tu.g.ResyncBankerNonce(a1.TipSet())
|
||||
require.NoError(t, tu.g.ResyncBankerNonce(a1.TipSet()))
|
||||
|
||||
fmt.Println("After mine bad block!")
|
||||
tu.printHeads()
|
||||
@ -479,7 +479,7 @@ func TestSyncFork(t *testing.T) {
|
||||
a := tu.mineOnBlock(a1, p1, []int{0}, true, false)
|
||||
a = tu.mineOnBlock(a, p1, []int{0}, true, false)
|
||||
|
||||
tu.g.ResyncBankerNonce(a1.TipSet())
|
||||
require.NoError(t, tu.g.ResyncBankerNonce(a1.TipSet()))
|
||||
// chain B will now be heaviest
|
||||
b := tu.mineOnBlock(base, p2, []int{1}, true, false)
|
||||
b = tu.mineOnBlock(b, p2, []int{1}, true, false)
|
||||
|
@ -74,8 +74,8 @@ type BlockHeader struct {
|
||||
validated bool // true if the signature has been validated
|
||||
}
|
||||
|
||||
func (b *BlockHeader) ToStorageBlock() (block.Block, error) {
|
||||
data, err := b.Serialize()
|
||||
func (blk *BlockHeader) ToStorageBlock() (block.Block, error) {
|
||||
data, err := blk.Serialize()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -89,8 +89,8 @@ func (b *BlockHeader) ToStorageBlock() (block.Block, error) {
|
||||
return block.NewBlockWithCid(data, c)
|
||||
}
|
||||
|
||||
func (b *BlockHeader) Cid() cid.Cid {
|
||||
sb, err := b.ToStorageBlock()
|
||||
func (blk *BlockHeader) Cid() cid.Cid {
|
||||
sb, err := blk.ToStorageBlock()
|
||||
if err != nil {
|
||||
panic(err) // Not sure i'm entirely comfortable with this one, needs to be checked
|
||||
}
|
||||
|
@ -4,13 +4,15 @@ import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||
"github.com/stretchr/testify/require"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||
)
|
||||
|
||||
func testBlockHeader(t testing.TB) *BlockHeader {
|
||||
@ -78,7 +80,7 @@ func TestInteropBH(t *testing.T) {
|
||||
}
|
||||
|
||||
posts := []abi.PoStProof{
|
||||
{abi.RegisteredProof_StackedDRG2KiBWinningPoSt, []byte{0x07}},
|
||||
{abi.RegisteredPoStProof_StackedDrgWinning2KiBV1, []byte{0x07}},
|
||||
}
|
||||
|
||||
bh := &BlockHeader{
|
||||
@ -115,10 +117,8 @@ func TestInteropBH(t *testing.T) {
|
||||
}
|
||||
|
||||
// acquired from go-filecoin
|
||||
gfc := "8f5501d04cb15021bf6bd003073d79e2238d4e61f1ad22814301020381420a0b818205410c818209410781d82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619cc430003e802d82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619ccd82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619ccd82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619cc410001f603"
|
||||
if gfc != hex.EncodeToString(bhsb) {
|
||||
t.Fatal("not equal!")
|
||||
}
|
||||
gfc := "8f5501d04cb15021bf6bd003073d79e2238d4e61f1ad22814301020381420a0b818205410c818200410781d82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619cc430003e802d82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619ccd82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619ccd82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619cc410001f603"
|
||||
require.Equal(t, gfc, hex.EncodeToString(bhsb))
|
||||
}
|
||||
|
||||
func BenchmarkBlockHeaderMarshal(b *testing.B) {
|
||||
|
@ -1,12 +1,103 @@
|
||||
package types
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ExecutionResult struct {
|
||||
type ExecutionTrace struct {
|
||||
Msg *Message
|
||||
MsgRct *MessageReceipt
|
||||
Error string
|
||||
Duration time.Duration
|
||||
GasCharges []*GasTrace
|
||||
|
||||
Subcalls []*ExecutionResult
|
||||
Subcalls []ExecutionTrace
|
||||
}
|
||||
|
||||
type GasTrace struct {
|
||||
Name string
|
||||
|
||||
Location []Loc
|
||||
TotalGas int64
|
||||
ComputeGas int64
|
||||
StorageGas int64
|
||||
TotalVirtualGas int64
|
||||
VirtualComputeGas int64
|
||||
VirtualStorageGas int64
|
||||
|
||||
TimeTaken time.Duration
|
||||
Extra interface{} `json:",omitempty"`
|
||||
|
||||
Callers []uintptr `json:"-"`
|
||||
}
|
||||
|
||||
type Loc struct {
|
||||
File string
|
||||
Line int
|
||||
Function string
|
||||
}
|
||||
|
||||
func (l Loc) Show() bool {
|
||||
ignorePrefix := []string{
|
||||
"reflect.",
|
||||
"github.com/filecoin-project/lotus/chain/vm.(*Invoker).transform",
|
||||
"github.com/filecoin-project/go-amt-ipld/",
|
||||
}
|
||||
for _, pre := range ignorePrefix {
|
||||
if strings.HasPrefix(l.Function, pre) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
func (l Loc) String() string {
|
||||
file := strings.Split(l.File, "/")
|
||||
|
||||
fn := strings.Split(l.Function, "/")
|
||||
var fnpkg string
|
||||
if len(fn) > 2 {
|
||||
fnpkg = strings.Join(fn[len(fn)-2:], "/")
|
||||
} else {
|
||||
fnpkg = l.Function
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s@%s:%d", fnpkg, file[len(file)-1], l.Line)
|
||||
}
|
||||
|
||||
func (l Loc) Important() bool {
|
||||
if strings.HasPrefix(l.Function, "github.com/filecoin-project/specs-actors/actors/builtin") {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (gt *GasTrace) MarshalJSON() ([]byte, error) {
|
||||
type GasTraceCopy GasTrace
|
||||
if len(gt.Location) == 0 {
|
||||
if len(gt.Callers) != 0 {
|
||||
frames := runtime.CallersFrames(gt.Callers)
|
||||
for {
|
||||
frame, more := frames.Next()
|
||||
if frame.Function == "github.com/filecoin-project/lotus/chain/vm.(*VM).ApplyMessage" {
|
||||
break
|
||||
}
|
||||
l := Loc{
|
||||
File: frame.File,
|
||||
Line: frame.Line,
|
||||
Function: frame.Function,
|
||||
}
|
||||
gt.Location = append(gt.Location, l)
|
||||
if !more {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cpy := (*GasTraceCopy)(gt)
|
||||
return json.Marshal(cpy)
|
||||
}
|
||||
|
@ -41,20 +41,16 @@ type Message struct {
|
||||
Params []byte
|
||||
}
|
||||
|
||||
func (t *Message) BlockMiner() address.Address {
|
||||
panic("implement me")
|
||||
func (m *Message) Caller() address.Address {
|
||||
return m.From
|
||||
}
|
||||
|
||||
func (t *Message) Caller() address.Address {
|
||||
return t.From
|
||||
func (m *Message) Receiver() address.Address {
|
||||
return m.To
|
||||
}
|
||||
|
||||
func (t *Message) Receiver() address.Address {
|
||||
return t.To
|
||||
}
|
||||
|
||||
func (t *Message) ValueReceived() abi.TokenAmount {
|
||||
return t.Value
|
||||
func (m *Message) ValueReceived() abi.TokenAmount {
|
||||
return m.Value
|
||||
}
|
||||
|
||||
func DecodeMessage(b []byte) (*Message, error) {
|
||||
|
@ -9,12 +9,12 @@ import (
|
||||
"github.com/multiformats/go-multihash"
|
||||
)
|
||||
|
||||
func (m *SignedMessage) ToStorageBlock() (block.Block, error) {
|
||||
if m.Signature.Type == crypto.SigTypeBLS {
|
||||
return m.Message.ToStorageBlock()
|
||||
func (sm *SignedMessage) ToStorageBlock() (block.Block, error) {
|
||||
if sm.Signature.Type == crypto.SigTypeBLS {
|
||||
return sm.Message.ToStorageBlock()
|
||||
}
|
||||
|
||||
data, err := m.Serialize()
|
||||
data, err := sm.Serialize()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -28,12 +28,12 @@ func (m *SignedMessage) ToStorageBlock() (block.Block, error) {
|
||||
return block.NewBlockWithCid(data, c)
|
||||
}
|
||||
|
||||
func (m *SignedMessage) Cid() cid.Cid {
|
||||
if m.Signature.Type == crypto.SigTypeBLS {
|
||||
return m.Message.Cid()
|
||||
func (sm *SignedMessage) Cid() cid.Cid {
|
||||
if sm.Signature.Type == crypto.SigTypeBLS {
|
||||
return sm.Message.Cid()
|
||||
}
|
||||
|
||||
sb, err := m.ToStorageBlock()
|
||||
sb, err := sm.ToStorageBlock()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -23,8 +23,6 @@ type TipSet struct {
|
||||
height abi.ChainEpoch
|
||||
}
|
||||
|
||||
// why didnt i just export the fields? Because the struct has methods with the
|
||||
// same names already
|
||||
type ExpTipSet struct {
|
||||
Cids []cid.Cid
|
||||
Blocks []*BlockHeader
|
||||
@ -32,6 +30,8 @@ type ExpTipSet struct {
|
||||
}
|
||||
|
||||
func (ts *TipSet) MarshalJSON() ([]byte, error) {
|
||||
// why didnt i just export the fields? Because the struct has methods with the
|
||||
// same names already
|
||||
return json.Marshal(ExpTipSet{
|
||||
Cids: ts.cids,
|
||||
Blocks: ts.blks,
|
||||
|
@ -61,9 +61,9 @@ func TestTipSetKey(t *testing.T) {
|
||||
|
||||
t.Run("JSON", func(t *testing.T) {
|
||||
k0 := NewTipSetKey()
|
||||
verifyJson(t, "[]", k0)
|
||||
verifyJSON(t, "[]", k0)
|
||||
k3 := NewTipSetKey(c1, c2, c3)
|
||||
verifyJson(t, `[`+
|
||||
verifyJSON(t, `[`+
|
||||
`{"/":"bafy2bzacecesrkxghscnq7vatble2hqdvwat6ed23vdu4vvo3uuggsoaya7ki"},`+
|
||||
`{"/":"bafy2bzacebxfyh2fzoxrt6kcgc5dkaodpcstgwxxdizrww225vrhsizsfcg4g"},`+
|
||||
`{"/":"bafy2bzacedwviarjtjraqakob5pslltmuo5n3xev3nt5zylezofkbbv5jclyu"}`+
|
||||
@ -71,7 +71,7 @@ func TestTipSetKey(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func verifyJson(t *testing.T, expected string, k TipSetKey) {
|
||||
func verifyJSON(t *testing.T, expected string, k TipSetKey) {
|
||||
bytes, err := json.Marshal(k)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, expected, string(bytes))
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/gen"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@ -173,14 +174,18 @@ func WriteJsonToFile(fname string, obj interface{}) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fi.Close()
|
||||
defer fi.Close() //nolint:errcheck
|
||||
|
||||
out, err := json.MarshalIndent(obj, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fi.Write(out)
|
||||
_, err = fi.Write(out)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("writing json: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ package vm
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
addr "github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||
@ -11,34 +12,74 @@ import (
|
||||
"github.com/ipfs/go-cid"
|
||||
)
|
||||
|
||||
const (
|
||||
GasStorageMulti = 1
|
||||
GasComputeMulti = 1
|
||||
)
|
||||
|
||||
type GasCharge struct {
|
||||
Name string
|
||||
Extra interface{}
|
||||
|
||||
ComputeGas int64
|
||||
StorageGas int64
|
||||
|
||||
VirtualCompute int64
|
||||
VirtualStorage int64
|
||||
}
|
||||
|
||||
func (g GasCharge) Total() int64 {
|
||||
return g.ComputeGas*GasComputeMulti + g.StorageGas*GasStorageMulti
|
||||
}
|
||||
func (g GasCharge) WithVirtual(compute, storage int64) GasCharge {
|
||||
out := g
|
||||
out.VirtualCompute = compute
|
||||
out.VirtualStorage = storage
|
||||
return out
|
||||
}
|
||||
|
||||
func (g GasCharge) WithExtra(extra interface{}) GasCharge {
|
||||
out := g
|
||||
out.Extra = extra
|
||||
return out
|
||||
}
|
||||
|
||||
func newGasCharge(name string, computeGas int64, storageGas int64) GasCharge {
|
||||
return GasCharge{
|
||||
Name: name,
|
||||
ComputeGas: computeGas,
|
||||
StorageGas: storageGas,
|
||||
}
|
||||
}
|
||||
|
||||
// Pricelist provides prices for operations in the VM.
|
||||
//
|
||||
// Note: this interface should be APPEND ONLY since last chain checkpoint
|
||||
type Pricelist interface {
|
||||
// OnChainMessage returns the gas used for storing a message of a given size in the chain.
|
||||
OnChainMessage(msgSize int) int64
|
||||
OnChainMessage(msgSize int) GasCharge
|
||||
// OnChainReturnValue returns the gas used for storing the response of a message in the chain.
|
||||
OnChainReturnValue(dataSize int) int64
|
||||
OnChainReturnValue(dataSize int) GasCharge
|
||||
|
||||
// OnMethodInvocation returns the gas used when invoking a method.
|
||||
OnMethodInvocation(value abi.TokenAmount, methodNum abi.MethodNum) int64
|
||||
OnMethodInvocation(value abi.TokenAmount, methodNum abi.MethodNum) GasCharge
|
||||
|
||||
// OnIpldGet returns the gas used for storing an object
|
||||
OnIpldGet(dataSize int) int64
|
||||
OnIpldGet(dataSize int) GasCharge
|
||||
// OnIpldPut returns the gas used for storing an object
|
||||
OnIpldPut(dataSize int) int64
|
||||
OnIpldPut(dataSize int) GasCharge
|
||||
|
||||
// OnCreateActor returns the gas used for creating an actor
|
||||
OnCreateActor() int64
|
||||
OnCreateActor() GasCharge
|
||||
// OnDeleteActor returns the gas used for deleting an actor
|
||||
OnDeleteActor() int64
|
||||
OnDeleteActor() GasCharge
|
||||
|
||||
OnVerifySignature(sigType crypto.SigType, planTextSize int) (int64, error)
|
||||
OnHashing(dataSize int) int64
|
||||
OnComputeUnsealedSectorCid(proofType abi.RegisteredProof, pieces []abi.PieceInfo) int64
|
||||
OnVerifySeal(info abi.SealVerifyInfo) int64
|
||||
OnVerifyPost(info abi.WindowPoStVerifyInfo) int64
|
||||
OnVerifyConsensusFault() int64
|
||||
OnVerifySignature(sigType crypto.SigType, planTextSize int) (GasCharge, error)
|
||||
OnHashing(dataSize int) GasCharge
|
||||
OnComputeUnsealedSectorCid(proofType abi.RegisteredSealProof, pieces []abi.PieceInfo) GasCharge
|
||||
OnVerifySeal(info abi.SealVerifyInfo) GasCharge
|
||||
OnVerifyPost(info abi.WindowPoStVerifyInfo) GasCharge
|
||||
OnVerifyConsensusFault() GasCharge
|
||||
}
|
||||
|
||||
var prices = map[abi.ChainEpoch]Pricelist{
|
||||
@ -92,7 +133,7 @@ func PricelistByEpoch(epoch abi.ChainEpoch) Pricelist {
|
||||
type pricedSyscalls struct {
|
||||
under vmr.Syscalls
|
||||
pl Pricelist
|
||||
chargeGas func(int64)
|
||||
chargeGas func(GasCharge)
|
||||
}
|
||||
|
||||
// Verifies that a signature is valid for an address and plaintext.
|
||||
@ -112,7 +153,7 @@ func (ps pricedSyscalls) HashBlake2b(data []byte) [32]byte {
|
||||
}
|
||||
|
||||
// Computes an unsealed sector CID (CommD) from its constituent piece CIDs (CommPs) and sizes.
|
||||
func (ps pricedSyscalls) ComputeUnsealedSectorCID(reg abi.RegisteredProof, pieces []abi.PieceInfo) (cid.Cid, error) {
|
||||
func (ps pricedSyscalls) ComputeUnsealedSectorCID(reg abi.RegisteredSealProof, pieces []abi.PieceInfo) (cid.Cid, error) {
|
||||
ps.chargeGas(ps.pl.OnComputeUnsealedSectorCid(reg, pieces))
|
||||
return ps.under.ComputeUnsealedSectorCID(reg, pieces)
|
||||
}
|
||||
@ -143,3 +184,17 @@ func (ps pricedSyscalls) VerifyConsensusFault(h1 []byte, h2 []byte, extra []byte
|
||||
ps.chargeGas(ps.pl.OnVerifyConsensusFault())
|
||||
return ps.under.VerifyConsensusFault(h1, h2, extra)
|
||||
}
|
||||
|
||||
func (ps pricedSyscalls) BatchVerifySeals(inp map[address.Address][]abi.SealVerifyInfo) (map[address.Address][]bool, error) {
|
||||
var gasChargeSum GasCharge
|
||||
gasChargeSum.Name = "BatchVerifySeals"
|
||||
ps.chargeGas(gasChargeSum) // TODO: this is only called by the cron actor. Should we even charge gas?
|
||||
|
||||
for _, svis := range inp {
|
||||
for _, svi := range svis {
|
||||
ch := ps.pl.OnVerifySeal(svi)
|
||||
ps.chargeGas(newGasCharge("BatchVerifySingle", 0, 0).WithVirtual(ch.VirtualCompute+ch.ComputeGas, 0))
|
||||
}
|
||||
}
|
||||
return ps.under.BatchVerifySeals(inp)
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package vm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||
@ -84,17 +85,17 @@ type pricelistV0 struct {
|
||||
var _ Pricelist = (*pricelistV0)(nil)
|
||||
|
||||
// OnChainMessage returns the gas used for storing a message of a given size in the chain.
|
||||
func (pl *pricelistV0) OnChainMessage(msgSize int) int64 {
|
||||
return pl.onChainMessageBase + pl.onChainMessagePerByte*int64(msgSize)
|
||||
func (pl *pricelistV0) OnChainMessage(msgSize int) GasCharge {
|
||||
return newGasCharge("OnChainMessage", 0, pl.onChainMessageBase+pl.onChainMessagePerByte*int64(msgSize))
|
||||
}
|
||||
|
||||
// OnChainReturnValue returns the gas used for storing the response of a message in the chain.
|
||||
func (pl *pricelistV0) OnChainReturnValue(dataSize int) int64 {
|
||||
return int64(dataSize) * pl.onChainReturnValuePerByte
|
||||
func (pl *pricelistV0) OnChainReturnValue(dataSize int) GasCharge {
|
||||
return newGasCharge("OnChainReturnValue", 0, int64(dataSize)*pl.onChainReturnValuePerByte)
|
||||
}
|
||||
|
||||
// OnMethodInvocation returns the gas used when invoking a method.
|
||||
func (pl *pricelistV0) OnMethodInvocation(value abi.TokenAmount, methodNum abi.MethodNum) int64 {
|
||||
func (pl *pricelistV0) OnMethodInvocation(value abi.TokenAmount, methodNum abi.MethodNum) GasCharge {
|
||||
ret := pl.sendBase
|
||||
if value != abi.NewTokenAmount(0) {
|
||||
ret += pl.sendTransferFunds
|
||||
@ -102,62 +103,63 @@ func (pl *pricelistV0) OnMethodInvocation(value abi.TokenAmount, methodNum abi.M
|
||||
if methodNum != builtin.MethodSend {
|
||||
ret += pl.sendInvokeMethod
|
||||
}
|
||||
return ret
|
||||
return newGasCharge("OnMethodInvocation", ret, 0).WithVirtual(ret*15000, 0)
|
||||
}
|
||||
|
||||
// OnIpldGet returns the gas used for storing an object
|
||||
func (pl *pricelistV0) OnIpldGet(dataSize int) int64 {
|
||||
return pl.ipldGetBase + int64(dataSize)*pl.ipldGetPerByte
|
||||
func (pl *pricelistV0) OnIpldGet(dataSize int) GasCharge {
|
||||
return newGasCharge("OnIpldGet", pl.ipldGetBase+int64(dataSize)*pl.ipldGetPerByte, 0).WithExtra(dataSize).WithVirtual(pl.ipldGetBase*13750+(pl.ipldGetPerByte*100), 0)
|
||||
}
|
||||
|
||||
// OnIpldPut returns the gas used for storing an object
|
||||
func (pl *pricelistV0) OnIpldPut(dataSize int) int64 {
|
||||
return pl.ipldPutBase + int64(dataSize)*pl.ipldPutPerByte
|
||||
func (pl *pricelistV0) OnIpldPut(dataSize int) GasCharge {
|
||||
return newGasCharge("OnIpldPut", pl.ipldPutBase, int64(dataSize)*pl.ipldPutPerByte).WithExtra(dataSize).WithVirtual(pl.ipldPutBase*8700+(pl.ipldPutPerByte*100), 0)
|
||||
}
|
||||
|
||||
// OnCreateActor returns the gas used for creating an actor
|
||||
func (pl *pricelistV0) OnCreateActor() int64 {
|
||||
return pl.createActorBase + pl.createActorExtra
|
||||
func (pl *pricelistV0) OnCreateActor() GasCharge {
|
||||
return newGasCharge("OnCreateActor", pl.createActorBase, pl.createActorExtra)
|
||||
}
|
||||
|
||||
// OnDeleteActor returns the gas used for deleting an actor
|
||||
func (pl *pricelistV0) OnDeleteActor() int64 {
|
||||
return pl.deleteActor
|
||||
func (pl *pricelistV0) OnDeleteActor() GasCharge {
|
||||
return newGasCharge("OnDeleteActor", 0, pl.deleteActor)
|
||||
}
|
||||
|
||||
// OnVerifySignature
|
||||
func (pl *pricelistV0) OnVerifySignature(sigType crypto.SigType, planTextSize int) (int64, error) {
|
||||
func (pl *pricelistV0) OnVerifySignature(sigType crypto.SigType, planTextSize int) (GasCharge, error) {
|
||||
costFn, ok := pl.verifySignature[sigType]
|
||||
if !ok {
|
||||
return 0, fmt.Errorf("cost function for signature type %d not supported", sigType)
|
||||
return GasCharge{}, fmt.Errorf("cost function for signature type %d not supported", sigType)
|
||||
}
|
||||
return costFn(int64(planTextSize)), nil
|
||||
sigName, _ := sigType.Name()
|
||||
return newGasCharge("OnVerifySignature", costFn(int64(planTextSize)), 0).WithExtra(sigName), nil
|
||||
}
|
||||
|
||||
// OnHashing
|
||||
func (pl *pricelistV0) OnHashing(dataSize int) int64 {
|
||||
return pl.hashingBase + int64(dataSize)*pl.hashingPerByte
|
||||
func (pl *pricelistV0) OnHashing(dataSize int) GasCharge {
|
||||
return newGasCharge("OnHashing", pl.hashingBase+int64(dataSize)*pl.hashingPerByte, 0)
|
||||
}
|
||||
|
||||
// OnComputeUnsealedSectorCid
|
||||
func (pl *pricelistV0) OnComputeUnsealedSectorCid(proofType abi.RegisteredProof, pieces []abi.PieceInfo) int64 {
|
||||
func (pl *pricelistV0) OnComputeUnsealedSectorCid(proofType abi.RegisteredSealProof, pieces []abi.PieceInfo) GasCharge {
|
||||
// TODO: this needs more cost tunning, check with @lotus
|
||||
return pl.computeUnsealedSectorCidBase
|
||||
return newGasCharge("OnComputeUnsealedSectorCid", pl.computeUnsealedSectorCidBase, 0).WithVirtual(pl.computeUnsealedSectorCidBase*24500, 0)
|
||||
}
|
||||
|
||||
// OnVerifySeal
|
||||
func (pl *pricelistV0) OnVerifySeal(info abi.SealVerifyInfo) int64 {
|
||||
func (pl *pricelistV0) OnVerifySeal(info abi.SealVerifyInfo) GasCharge {
|
||||
// TODO: this needs more cost tunning, check with @lotus
|
||||
return pl.verifySealBase
|
||||
return newGasCharge("OnVerifySeal", pl.verifySealBase, 0).WithVirtual(pl.verifySealBase*177500, 0)
|
||||
}
|
||||
|
||||
// OnVerifyPost
|
||||
func (pl *pricelistV0) OnVerifyPost(info abi.WindowPoStVerifyInfo) int64 {
|
||||
func (pl *pricelistV0) OnVerifyPost(info abi.WindowPoStVerifyInfo) GasCharge {
|
||||
// TODO: this needs more cost tunning, check with @lotus
|
||||
return pl.verifyPostBase
|
||||
return newGasCharge("OnVerifyPost", pl.verifyPostBase, 0)
|
||||
}
|
||||
|
||||
// OnVerifyConsensusFault
|
||||
func (pl *pricelistV0) OnVerifyConsensusFault() int64 {
|
||||
return pl.verifyConsensusFault
|
||||
func (pl *pricelistV0) OnVerifyConsensusFault() GasCharge {
|
||||
return newGasCharge("OnVerifyConsensusFault", pl.verifyConsensusFault, 0)
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||
)
|
||||
|
||||
type invoker struct {
|
||||
type Invoker struct {
|
||||
builtInCode map[cid.Cid]nativeCode
|
||||
builtInState map[cid.Cid]reflect.Type
|
||||
}
|
||||
@ -40,8 +40,8 @@ type invoker struct {
|
||||
type invokeFunc func(rt runtime.Runtime, params []byte) ([]byte, aerrors.ActorError)
|
||||
type nativeCode []invokeFunc
|
||||
|
||||
func NewInvoker() *invoker {
|
||||
inv := &invoker{
|
||||
func NewInvoker() *Invoker {
|
||||
inv := &Invoker{
|
||||
builtInCode: make(map[cid.Cid]nativeCode),
|
||||
builtInState: make(map[cid.Cid]reflect.Type),
|
||||
}
|
||||
@ -62,7 +62,7 @@ func NewInvoker() *invoker {
|
||||
return inv
|
||||
}
|
||||
|
||||
func (inv *invoker) Invoke(codeCid cid.Cid, rt runtime.Runtime, method abi.MethodNum, params []byte) ([]byte, aerrors.ActorError) {
|
||||
func (inv *Invoker) Invoke(codeCid cid.Cid, rt runtime.Runtime, method abi.MethodNum, params []byte) ([]byte, aerrors.ActorError) {
|
||||
|
||||
code, ok := inv.builtInCode[codeCid]
|
||||
if !ok {
|
||||
@ -76,7 +76,7 @@ func (inv *invoker) Invoke(codeCid cid.Cid, rt runtime.Runtime, method abi.Metho
|
||||
|
||||
}
|
||||
|
||||
func (inv *invoker) Register(c cid.Cid, instance Invokee, state interface{}) {
|
||||
func (inv *Invoker) Register(c cid.Cid, instance Invokee, state interface{}) {
|
||||
code, err := inv.transform(instance)
|
||||
if err != nil {
|
||||
panic(xerrors.Errorf("%s: %w", string(c.Hash()), err))
|
||||
@ -89,9 +89,7 @@ type Invokee interface {
|
||||
Exports() []interface{}
|
||||
}
|
||||
|
||||
var tAError = reflect.TypeOf((*aerrors.ActorError)(nil)).Elem()
|
||||
|
||||
func (*invoker) transform(instance Invokee) (nativeCode, error) {
|
||||
func (*Invoker) transform(instance Invokee) (nativeCode, error) {
|
||||
itype := reflect.TypeOf(instance)
|
||||
exports := instance.Exports()
|
||||
for i, m := range exports {
|
||||
|
@ -76,7 +76,7 @@ func (basicContract) InvokeSomething10(rt runtime.Runtime, params *basicParams)
|
||||
}
|
||||
|
||||
func TestInvokerBasic(t *testing.T) {
|
||||
inv := invoker{}
|
||||
inv := Invoker{}
|
||||
code, err := inv.transform(basicContract{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
|
@ -2,6 +2,7 @@ package vm
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
@ -27,7 +28,7 @@ func init() {
|
||||
|
||||
var EmptyObjectCid cid.Cid
|
||||
|
||||
// Creates account actors from only BLS/SECP256K1 addresses.
|
||||
// TryCreateAccountActor creates account actors from only BLS/SECP256K1 addresses.
|
||||
func TryCreateAccountActor(rt *Runtime, addr address.Address) (*types.Actor, aerrors.ActorError) {
|
||||
addrID, err := rt.state.RegisterNewAddress(addr)
|
||||
if err != nil {
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
gruntime "runtime"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
@ -51,10 +52,12 @@ type Runtime struct {
|
||||
origin address.Address
|
||||
originNonce uint64
|
||||
|
||||
internalExecutions []*types.ExecutionResult
|
||||
executionTrace types.ExecutionTrace
|
||||
numActorsCreated uint64
|
||||
allowInternal bool
|
||||
callerValidated bool
|
||||
lastGasChargeTime time.Time
|
||||
lastGasCharge *types.GasTrace
|
||||
}
|
||||
|
||||
func (rt *Runtime) TotalFilCircSupply() abi.TokenAmount {
|
||||
@ -107,8 +110,8 @@ type notFoundErr interface {
|
||||
IsNotFound() bool
|
||||
}
|
||||
|
||||
func (rs *Runtime) Get(c cid.Cid, o vmr.CBORUnmarshaler) bool {
|
||||
if err := rs.cst.Get(context.TODO(), c, o); err != nil {
|
||||
func (rt *Runtime) Get(c cid.Cid, o vmr.CBORUnmarshaler) bool {
|
||||
if err := rt.cst.Get(context.TODO(), c, o); err != nil {
|
||||
var nfe notFoundErr
|
||||
if xerrors.As(err, &nfe) && nfe.IsNotFound() {
|
||||
if xerrors.As(err, new(cbor.SerializationError)) {
|
||||
@ -122,8 +125,8 @@ func (rs *Runtime) Get(c cid.Cid, o vmr.CBORUnmarshaler) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (rs *Runtime) Put(x vmr.CBORMarshaler) cid.Cid {
|
||||
c, err := rs.cst.Put(context.TODO(), x)
|
||||
func (rt *Runtime) Put(x vmr.CBORMarshaler) cid.Cid {
|
||||
c, err := rt.cst.Put(context.TODO(), x)
|
||||
if err != nil {
|
||||
if xerrors.As(err, new(cbor.SerializationError)) {
|
||||
panic(aerrors.Newf(exitcode.ErrSerialization, "failed to marshal cbor object %s", err))
|
||||
@ -135,7 +138,7 @@ func (rs *Runtime) Put(x vmr.CBORMarshaler) cid.Cid {
|
||||
|
||||
var _ vmr.Runtime = (*Runtime)(nil)
|
||||
|
||||
func (rs *Runtime) shimCall(f func() interface{}) (rval []byte, aerr aerrors.ActorError) {
|
||||
func (rt *Runtime) shimCall(f func() interface{}) (rval []byte, aerr aerrors.ActorError) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
if ar, ok := r.(aerrors.ActorError); ok {
|
||||
@ -150,8 +153,8 @@ func (rs *Runtime) shimCall(f func() interface{}) (rval []byte, aerr aerrors.Act
|
||||
|
||||
ret := f()
|
||||
|
||||
if !rs.callerValidated {
|
||||
rs.Abortf(exitcode.SysErrorIllegalActor, "Caller MUST be validated during method execution")
|
||||
if !rt.callerValidated {
|
||||
rt.Abortf(exitcode.SysErrorIllegalActor, "Caller MUST be validated during method execution")
|
||||
}
|
||||
|
||||
switch ret := ret.(type) {
|
||||
@ -172,25 +175,25 @@ func (rs *Runtime) shimCall(f func() interface{}) (rval []byte, aerr aerrors.Act
|
||||
}
|
||||
}
|
||||
|
||||
func (rs *Runtime) Message() vmr.Message {
|
||||
return rs.vmsg
|
||||
func (rt *Runtime) Message() vmr.Message {
|
||||
return rt.vmsg
|
||||
}
|
||||
|
||||
func (rs *Runtime) ValidateImmediateCallerAcceptAny() {
|
||||
rs.abortIfAlreadyValidated()
|
||||
func (rt *Runtime) ValidateImmediateCallerAcceptAny() {
|
||||
rt.abortIfAlreadyValidated()
|
||||
return
|
||||
}
|
||||
|
||||
func (rs *Runtime) CurrentBalance() abi.TokenAmount {
|
||||
b, err := rs.GetBalance(rs.Message().Receiver())
|
||||
func (rt *Runtime) CurrentBalance() abi.TokenAmount {
|
||||
b, err := rt.GetBalance(rt.Message().Receiver())
|
||||
if err != nil {
|
||||
rs.Abortf(exitcode.ExitCode(err.RetCode()), "get current balance: %v", err)
|
||||
rt.Abortf(err.RetCode(), "get current balance: %v", err)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func (rs *Runtime) GetActorCodeCID(addr address.Address) (ret cid.Cid, ok bool) {
|
||||
act, err := rs.state.GetActor(addr)
|
||||
func (rt *Runtime) GetActorCodeCID(addr address.Address) (ret cid.Cid, ok bool) {
|
||||
act, err := rt.state.GetActor(addr)
|
||||
if err != nil {
|
||||
if xerrors.Is(err, types.ErrActorNotFound) {
|
||||
return cid.Undef, false
|
||||
@ -210,8 +213,8 @@ func (rt *Runtime) GetRandomness(personalization crypto.DomainSeparationTag, ran
|
||||
return res
|
||||
}
|
||||
|
||||
func (rs *Runtime) Store() vmr.Store {
|
||||
return rs
|
||||
func (rt *Runtime) Store() vmr.Store {
|
||||
return rt
|
||||
}
|
||||
|
||||
func (rt *Runtime) NewActorAddress() address.Address {
|
||||
@ -236,12 +239,12 @@ func (rt *Runtime) NewActorAddress() address.Address {
|
||||
return addr
|
||||
}
|
||||
|
||||
func (rt *Runtime) CreateActor(codeId cid.Cid, address address.Address) {
|
||||
if !builtin.IsBuiltinActor(codeId) {
|
||||
func (rt *Runtime) CreateActor(codeID cid.Cid, address address.Address) {
|
||||
if !builtin.IsBuiltinActor(codeID) {
|
||||
rt.Abortf(exitcode.SysErrorIllegalArgument, "Can only create built-in actors.")
|
||||
}
|
||||
|
||||
if builtin.IsSingletonActor(codeId) {
|
||||
if builtin.IsSingletonActor(codeID) {
|
||||
rt.Abortf(exitcode.SysErrorIllegalArgument, "Can only have one instance of singleton actors.")
|
||||
}
|
||||
|
||||
@ -250,10 +253,10 @@ func (rt *Runtime) CreateActor(codeId cid.Cid, address address.Address) {
|
||||
rt.Abortf(exitcode.SysErrorIllegalArgument, "Actor address already exists")
|
||||
}
|
||||
|
||||
rt.ChargeGas(rt.Pricelist().OnCreateActor())
|
||||
rt.chargeGas(rt.Pricelist().OnCreateActor())
|
||||
|
||||
err = rt.state.SetActor(address, &types.Actor{
|
||||
Code: codeId,
|
||||
Code: codeID,
|
||||
Head: EmptyObjectCid,
|
||||
Nonce: 0,
|
||||
Balance: big.Zero(),
|
||||
@ -264,7 +267,7 @@ func (rt *Runtime) CreateActor(codeId cid.Cid, address address.Address) {
|
||||
}
|
||||
|
||||
func (rt *Runtime) DeleteActor(addr address.Address) {
|
||||
rt.ChargeGas(rt.Pricelist().OnDeleteActor())
|
||||
rt.chargeGas(rt.Pricelist().OnDeleteActor())
|
||||
act, err := rt.state.GetActor(rt.Message().Receiver())
|
||||
if err != nil {
|
||||
if xerrors.Is(err, types.ErrActorNotFound) {
|
||||
@ -283,12 +286,12 @@ func (rt *Runtime) DeleteActor(addr address.Address) {
|
||||
}
|
||||
}
|
||||
|
||||
func (rs *Runtime) Syscalls() vmr.Syscalls {
|
||||
func (rt *Runtime) Syscalls() vmr.Syscalls {
|
||||
// TODO: Make sure this is wrapped in something that charges gas for each of the calls
|
||||
return rs.sys
|
||||
return rt.sys
|
||||
}
|
||||
|
||||
func (rs *Runtime) StartSpan(name string) vmr.TraceSpan {
|
||||
func (rt *Runtime) StartSpan(name string) vmr.TraceSpan {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
@ -308,12 +311,12 @@ func (rt *Runtime) Context() context.Context {
|
||||
return rt.ctx
|
||||
}
|
||||
|
||||
func (rs *Runtime) Abortf(code exitcode.ExitCode, msg string, args ...interface{}) {
|
||||
func (rt *Runtime) Abortf(code exitcode.ExitCode, msg string, args ...interface{}) {
|
||||
log.Warnf("Abortf: ", fmt.Sprintf(msg, args...))
|
||||
panic(aerrors.NewfSkip(2, code, msg, args...))
|
||||
}
|
||||
|
||||
func (rs *Runtime) AbortStateMsg(msg string) {
|
||||
func (rt *Runtime) AbortStateMsg(msg string) {
|
||||
panic(aerrors.NewfSkip(3, 101, msg))
|
||||
}
|
||||
|
||||
@ -331,8 +334,8 @@ func (rt *Runtime) ValidateImmediateCallerType(ts ...cid.Cid) {
|
||||
rt.Abortf(exitcode.SysErrForbidden, "caller cid type %q was not one of %v", callerCid, ts)
|
||||
}
|
||||
|
||||
func (rs *Runtime) CurrEpoch() abi.ChainEpoch {
|
||||
return rs.height
|
||||
func (rt *Runtime) CurrEpoch() abi.ChainEpoch {
|
||||
return rt.height
|
||||
}
|
||||
|
||||
type dumbWrapperType struct {
|
||||
@ -343,31 +346,32 @@ func (dwt *dumbWrapperType) Into(um vmr.CBORUnmarshaler) error {
|
||||
return um.UnmarshalCBOR(bytes.NewReader(dwt.val))
|
||||
}
|
||||
|
||||
func (rs *Runtime) Send(to address.Address, method abi.MethodNum, m vmr.CBORMarshaler, value abi.TokenAmount) (vmr.SendReturn, exitcode.ExitCode) {
|
||||
if !rs.allowInternal {
|
||||
rs.Abortf(exitcode.SysErrorIllegalActor, "runtime.Send() is currently disallowed")
|
||||
func (rt *Runtime) Send(to address.Address, method abi.MethodNum, m vmr.CBORMarshaler, value abi.TokenAmount) (vmr.SendReturn, exitcode.ExitCode) {
|
||||
if !rt.allowInternal {
|
||||
rt.Abortf(exitcode.SysErrorIllegalActor, "runtime.Send() is currently disallowed")
|
||||
}
|
||||
var params []byte
|
||||
if m != nil {
|
||||
buf := new(bytes.Buffer)
|
||||
if err := m.MarshalCBOR(buf); err != nil {
|
||||
rs.Abortf(exitcode.SysErrInvalidParameters, "failed to marshal input parameters: %s", err)
|
||||
rt.Abortf(exitcode.SysErrInvalidParameters, "failed to marshal input parameters: %s", err)
|
||||
}
|
||||
params = buf.Bytes()
|
||||
}
|
||||
|
||||
ret, err := rs.internalSend(rs.Message().Receiver(), to, method, types.BigInt(value), params)
|
||||
ret, err := rt.internalSend(rt.Message().Receiver(), to, method, value, params)
|
||||
if err != nil {
|
||||
if err.IsFatal() {
|
||||
panic(err)
|
||||
}
|
||||
log.Warnf("vmctx send failed: to: %s, method: %d: ret: %d, err: %s", to, method, ret, err)
|
||||
return nil, exitcode.ExitCode(err.RetCode())
|
||||
return nil, err.RetCode()
|
||||
}
|
||||
return &dumbWrapperType{ret}, 0
|
||||
}
|
||||
|
||||
func (rt *Runtime) internalSend(from, to address.Address, method abi.MethodNum, value types.BigInt, params []byte) ([]byte, aerrors.ActorError) {
|
||||
|
||||
start := time.Now()
|
||||
ctx, span := trace.StartSpan(rt.ctx, "vmc.Send")
|
||||
defer span.End()
|
||||
@ -394,77 +398,62 @@ func (rt *Runtime) internalSend(from, to address.Address, method abi.MethodNum,
|
||||
}
|
||||
defer st.ClearSnapshot()
|
||||
|
||||
ret, errSend, subrt := rt.vm.send(ctx, msg, rt, 0)
|
||||
ret, errSend, subrt := rt.vm.send(ctx, msg, rt, nil, start)
|
||||
if errSend != nil {
|
||||
if errRevert := st.Revert(); errRevert != nil {
|
||||
return nil, aerrors.Escalate(errRevert, "failed to revert state tree after failed subcall")
|
||||
}
|
||||
}
|
||||
|
||||
mr := types.MessageReceipt{
|
||||
ExitCode: exitcode.ExitCode(aerrors.RetCode(errSend)),
|
||||
Return: ret,
|
||||
GasUsed: 0,
|
||||
}
|
||||
|
||||
er := types.ExecutionResult{
|
||||
Msg: msg,
|
||||
MsgRct: &mr,
|
||||
Duration: time.Since(start),
|
||||
}
|
||||
|
||||
if errSend != nil {
|
||||
er.Error = errSend.Error()
|
||||
}
|
||||
|
||||
if subrt != nil {
|
||||
er.Subcalls = subrt.internalExecutions
|
||||
rt.numActorsCreated = subrt.numActorsCreated
|
||||
}
|
||||
rt.internalExecutions = append(rt.internalExecutions, &er)
|
||||
rt.executionTrace.Subcalls = append(rt.executionTrace.Subcalls, subrt.executionTrace) //&er)
|
||||
return ret, errSend
|
||||
}
|
||||
|
||||
func (rs *Runtime) State() vmr.StateHandle {
|
||||
return &shimStateHandle{rs: rs}
|
||||
func (rt *Runtime) State() vmr.StateHandle {
|
||||
return &shimStateHandle{rt: rt}
|
||||
}
|
||||
|
||||
type shimStateHandle struct {
|
||||
rs *Runtime
|
||||
rt *Runtime
|
||||
}
|
||||
|
||||
func (ssh *shimStateHandle) Create(obj vmr.CBORMarshaler) {
|
||||
c := ssh.rs.Put(obj)
|
||||
ssh.rs.stateCommit(EmptyObjectCid, c)
|
||||
c := ssh.rt.Put(obj)
|
||||
// TODO: handle error below
|
||||
ssh.rt.stateCommit(EmptyObjectCid, c)
|
||||
}
|
||||
|
||||
func (ssh *shimStateHandle) Readonly(obj vmr.CBORUnmarshaler) {
|
||||
act, err := ssh.rs.state.GetActor(ssh.rs.Message().Receiver())
|
||||
act, err := ssh.rt.state.GetActor(ssh.rt.Message().Receiver())
|
||||
if err != nil {
|
||||
ssh.rs.Abortf(exitcode.SysErrorIllegalArgument, "failed to get actor for Readonly state: %s", err)
|
||||
ssh.rt.Abortf(exitcode.SysErrorIllegalArgument, "failed to get actor for Readonly state: %s", err)
|
||||
}
|
||||
ssh.rs.Get(act.Head, obj)
|
||||
ssh.rt.Get(act.Head, obj)
|
||||
}
|
||||
|
||||
func (ssh *shimStateHandle) Transaction(obj vmr.CBORer, f func() interface{}) interface{} {
|
||||
if obj == nil {
|
||||
ssh.rs.Abortf(exitcode.SysErrorIllegalActor, "Must not pass nil to Transaction()")
|
||||
ssh.rt.Abortf(exitcode.SysErrorIllegalActor, "Must not pass nil to Transaction()")
|
||||
}
|
||||
|
||||
act, err := ssh.rs.state.GetActor(ssh.rs.Message().Receiver())
|
||||
act, err := ssh.rt.state.GetActor(ssh.rt.Message().Receiver())
|
||||
if err != nil {
|
||||
ssh.rs.Abortf(exitcode.SysErrorIllegalActor, "failed to get actor for Transaction: %s", err)
|
||||
ssh.rt.Abortf(exitcode.SysErrorIllegalActor, "failed to get actor for Transaction: %s", err)
|
||||
}
|
||||
baseState := act.Head
|
||||
ssh.rs.Get(baseState, obj)
|
||||
ssh.rt.Get(baseState, obj)
|
||||
|
||||
ssh.rs.allowInternal = false
|
||||
ssh.rt.allowInternal = false
|
||||
out := f()
|
||||
ssh.rs.allowInternal = true
|
||||
ssh.rt.allowInternal = true
|
||||
|
||||
c := ssh.rs.Put(obj)
|
||||
c := ssh.rt.Put(obj)
|
||||
|
||||
ssh.rs.stateCommit(baseState, c)
|
||||
// TODO: handle error below
|
||||
ssh.rt.stateCommit(baseState, c)
|
||||
|
||||
return out
|
||||
}
|
||||
@ -501,22 +490,78 @@ func (rt *Runtime) stateCommit(oldh, newh cid.Cid) aerrors.ActorError {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rt *Runtime) ChargeGas(toUse int64) {
|
||||
err := rt.chargeGasSafe(toUse)
|
||||
func (rt *Runtime) finilizeGasTracing() {
|
||||
if rt.lastGasCharge != nil {
|
||||
rt.lastGasCharge.TimeTaken = time.Since(rt.lastGasChargeTime)
|
||||
}
|
||||
}
|
||||
|
||||
// ChargeGas is spec actors function
|
||||
func (rt *Runtime) ChargeGas(name string, compute int64, virtual int64) {
|
||||
err := rt.chargeGasInternal(newGasCharge(name, compute, 0).WithVirtual(virtual, 0), 1)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (rt *Runtime) chargeGasSafe(toUse int64) aerrors.ActorError {
|
||||
func (rt *Runtime) chargeGas(gas GasCharge) {
|
||||
err := rt.chargeGasInternal(gas, 1)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (rt *Runtime) chargeGasFunc(skip int) func(GasCharge) {
|
||||
return func(gas GasCharge) {
|
||||
err := rt.chargeGasInternal(gas, 1+skip)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (rt *Runtime) chargeGasInternal(gas GasCharge, skip int) aerrors.ActorError {
|
||||
toUse := gas.Total()
|
||||
var callers [10]uintptr
|
||||
cout := gruntime.Callers(2+skip, callers[:])
|
||||
|
||||
now := time.Now()
|
||||
if rt.lastGasCharge != nil {
|
||||
rt.lastGasCharge.TimeTaken = now.Sub(rt.lastGasChargeTime)
|
||||
}
|
||||
|
||||
gasTrace := types.GasTrace{
|
||||
Name: gas.Name,
|
||||
Extra: gas.Extra,
|
||||
|
||||
TotalGas: toUse,
|
||||
ComputeGas: gas.ComputeGas,
|
||||
StorageGas: gas.StorageGas,
|
||||
|
||||
TotalVirtualGas: gas.VirtualCompute*GasComputeMulti + gas.VirtualStorage*GasStorageMulti,
|
||||
VirtualComputeGas: gas.VirtualCompute,
|
||||
VirtualStorageGas: gas.VirtualStorage,
|
||||
|
||||
Callers: callers[:cout],
|
||||
}
|
||||
rt.executionTrace.GasCharges = append(rt.executionTrace.GasCharges, &gasTrace)
|
||||
rt.lastGasChargeTime = now
|
||||
rt.lastGasCharge = &gasTrace
|
||||
|
||||
if rt.gasUsed+toUse > rt.gasAvailable {
|
||||
rt.gasUsed = rt.gasAvailable
|
||||
return aerrors.Newf(exitcode.SysErrOutOfGas, "not enough gas: used=%d, available=%d", rt.gasUsed, rt.gasAvailable)
|
||||
return aerrors.Newf(exitcode.SysErrOutOfGas, "not enough gas: used=%d, available=%d",
|
||||
rt.gasUsed, rt.gasAvailable)
|
||||
}
|
||||
rt.gasUsed += toUse
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rt *Runtime) chargeGasSafe(gas GasCharge) aerrors.ActorError {
|
||||
return rt.chargeGasInternal(gas, 1)
|
||||
}
|
||||
|
||||
func (rt *Runtime) Pricelist() Pricelist {
|
||||
return rt.pricelist
|
||||
}
|
||||
|
@ -4,6 +4,8 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
goruntime "runtime"
|
||||
"sync"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/ipfs/go-cid"
|
||||
@ -41,7 +43,7 @@ type syscallShim struct {
|
||||
verifier ffiwrapper.Verifier
|
||||
}
|
||||
|
||||
func (ss *syscallShim) ComputeUnsealedSectorCID(st abi.RegisteredProof, pieces []abi.PieceInfo) (cid.Cid, error) {
|
||||
func (ss *syscallShim) ComputeUnsealedSectorCID(st abi.RegisteredSealProof, pieces []abi.PieceInfo) (cid.Cid, error) {
|
||||
var sum abi.PaddedPieceSize
|
||||
for _, p := range pieces {
|
||||
sum += p.Size
|
||||
@ -113,7 +115,7 @@ func (ss *syscallShim) VerifyConsensusFault(a, b, extra []byte) (*runtime.Consen
|
||||
// (b) time-offset mining fault
|
||||
// strictly speaking no need to compare heights based on double fork mining check above,
|
||||
// but at same height this would be a different fault.
|
||||
if !types.CidArrsEqual(blockA.Parents, blockB.Parents) && blockA.Height != blockB.Height {
|
||||
if types.CidArrsEqual(blockA.Parents, blockB.Parents) && blockA.Height != blockB.Height {
|
||||
consensusFault = &runtime.ConsensusFault{
|
||||
Target: blockA.Miner,
|
||||
Epoch: blockB.Height,
|
||||
@ -157,7 +159,7 @@ func (ss *syscallShim) VerifyConsensusFault(a, b, extra []byte) (*runtime.Consen
|
||||
}
|
||||
|
||||
if sigErr := ss.VerifyBlockSig(&blockB); sigErr != nil {
|
||||
return nil, xerrors.Errorf("cannot verify first block sig: %w", sigErr)
|
||||
return nil, xerrors.Errorf("cannot verify second block sig: %w", sigErr)
|
||||
}
|
||||
|
||||
return consensusFault, nil
|
||||
@ -183,7 +185,7 @@ func (ss *syscallShim) VerifyBlockSig(blk *types.BlockHeader) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := sigs.CheckBlockSignature(blk, ss.ctx, waddr); err != nil {
|
||||
if err := sigs.CheckBlockSignature(ss.ctx, blk, waddr); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -201,20 +203,6 @@ func (ss *syscallShim) VerifyPoSt(proof abi.WindowPoStVerifyInfo) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func cidToCommD(c cid.Cid) [32]byte {
|
||||
b := c.Bytes()
|
||||
var out [32]byte
|
||||
copy(out[:], b[len(b)-32:])
|
||||
return out
|
||||
}
|
||||
|
||||
func cidToCommR(c cid.Cid) [32]byte {
|
||||
b := c.Bytes()
|
||||
var out [32]byte
|
||||
copy(out[:], b[len(b)-32:])
|
||||
return out
|
||||
}
|
||||
|
||||
func (ss *syscallShim) VerifySeal(info abi.SealVerifyInfo) error {
|
||||
//_, span := trace.StartSpan(ctx, "ValidatePoRep")
|
||||
//defer span.End()
|
||||
@ -225,7 +213,7 @@ func (ss *syscallShim) VerifySeal(info abi.SealVerifyInfo) error {
|
||||
}
|
||||
|
||||
ticket := []byte(info.Randomness)
|
||||
proof := []byte(info.Proof)
|
||||
proof := info.Proof
|
||||
seed := []byte(info.InteractiveRandomness)
|
||||
|
||||
log.Debugf("Verif r:%x; d:%x; m:%s; t:%x; s:%x; N:%d; p:%x", info.SealedCID, info.UnsealedCID, miner, ticket, seed, info.SectorID.Number, proof)
|
||||
@ -252,3 +240,37 @@ func (ss *syscallShim) VerifySignature(sig crypto.Signature, addr address.Addres
|
||||
|
||||
return sigs.Verify(&sig, kaddr, input)
|
||||
}
|
||||
|
||||
var BatchSealVerifyParallelism = goruntime.NumCPU()
|
||||
|
||||
func (ss *syscallShim) BatchVerifySeals(inp map[address.Address][]abi.SealVerifyInfo) (map[address.Address][]bool, error) {
|
||||
out := make(map[address.Address][]bool)
|
||||
|
||||
sema := make(chan struct{}, BatchSealVerifyParallelism)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
for addr, seals := range inp {
|
||||
results := make([]bool, len(seals))
|
||||
out[addr] = results
|
||||
|
||||
for i, s := range seals {
|
||||
wg.Add(1)
|
||||
go func(ma address.Address, ix int, svi abi.SealVerifyInfo, res []bool) {
|
||||
defer wg.Done()
|
||||
sema <- struct{}{}
|
||||
|
||||
if err := ss.VerifySeal(svi); err != nil {
|
||||
log.Warnw("seal verify in batch failed", "miner", ma, "index", ix, "err", err)
|
||||
res[ix] = false
|
||||
} else {
|
||||
res[ix] = true
|
||||
}
|
||||
|
||||
<-sema
|
||||
}(addr, i, s, results)
|
||||
}
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ func init() {
|
||||
func TestChainValidationMessageSuite(t *testing.T) {
|
||||
f := factory.NewFactories()
|
||||
for _, testCase := range suites.MessageTestCases() {
|
||||
testCase := testCase
|
||||
if TestSuiteSkipper.Skip(testCase) {
|
||||
continue
|
||||
}
|
||||
@ -53,6 +54,7 @@ func TestChainValidationMessageSuite(t *testing.T) {
|
||||
func TestChainValidationTipSetSuite(t *testing.T) {
|
||||
f := factory.NewFactories()
|
||||
for _, testCase := range suites.TipSetTestCases() {
|
||||
testCase := testCase
|
||||
if TestSuiteSkipper.Skip(testCase) {
|
||||
continue
|
||||
}
|
||||
|
101
chain/vm/vm.go
101
chain/vm/vm.go
@ -62,7 +62,7 @@ func ResolveToKeyAddr(state types.StateTree, cst cbor.IpldStore, addr address.Ad
|
||||
var _ cbor.IpldBlockstore = (*gasChargingBlocks)(nil)
|
||||
|
||||
type gasChargingBlocks struct {
|
||||
chargeGas func(int64)
|
||||
chargeGas func(GasCharge)
|
||||
pricelist Pricelist
|
||||
under cbor.IpldBlockstore
|
||||
}
|
||||
@ -102,15 +102,16 @@ func (vm *VM) makeRuntime(ctx context.Context, msg *types.Message, origin addres
|
||||
pricelist: PricelistByEpoch(vm.blockHeight),
|
||||
allowInternal: true,
|
||||
callerValidated: false,
|
||||
executionTrace: types.ExecutionTrace{Msg: msg},
|
||||
}
|
||||
|
||||
rt.cst = &cbor.BasicIpldStore{
|
||||
Blocks: &gasChargingBlocks{rt.ChargeGas, rt.pricelist, vm.cst.Blocks},
|
||||
Blocks: &gasChargingBlocks{rt.chargeGasFunc(2), rt.pricelist, vm.cst.Blocks},
|
||||
Atlas: vm.cst.Atlas,
|
||||
}
|
||||
rt.sys = pricedSyscalls{
|
||||
under: vm.Syscalls,
|
||||
chargeGas: rt.ChargeGas,
|
||||
chargeGas: rt.chargeGasFunc(1),
|
||||
pl: rt.pricelist,
|
||||
}
|
||||
|
||||
@ -131,7 +132,7 @@ type VM struct {
|
||||
cst *cbor.BasicIpldStore
|
||||
buf *bufbstore.BufferedBS
|
||||
blockHeight abi.ChainEpoch
|
||||
inv *invoker
|
||||
inv *Invoker
|
||||
rand Rand
|
||||
|
||||
Syscalls runtime.Syscalls
|
||||
@ -165,34 +166,48 @@ type ApplyRet struct {
|
||||
types.MessageReceipt
|
||||
ActorErr aerrors.ActorError
|
||||
Penalty types.BigInt
|
||||
InternalExecutions []*types.ExecutionResult
|
||||
ExecutionTrace types.ExecutionTrace
|
||||
Duration time.Duration
|
||||
}
|
||||
|
||||
func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime,
|
||||
gasCharge int64) ([]byte, aerrors.ActorError, *Runtime) {
|
||||
gasCharge *GasCharge, start time.Time) ([]byte, aerrors.ActorError, *Runtime) {
|
||||
|
||||
st := vm.cstate
|
||||
gasUsed := gasCharge
|
||||
|
||||
origin := msg.From
|
||||
on := msg.Nonce
|
||||
var nac uint64 = 0
|
||||
var gasUsed int64
|
||||
if parent != nil {
|
||||
gasUsed = parent.gasUsed + gasUsed
|
||||
gasUsed = parent.gasUsed
|
||||
origin = parent.origin
|
||||
on = parent.originNonce
|
||||
nac = parent.numActorsCreated
|
||||
}
|
||||
|
||||
rt := vm.makeRuntime(ctx, msg, origin, on, gasUsed, nac)
|
||||
rt.lastGasChargeTime = start
|
||||
if parent != nil {
|
||||
rt.lastGasChargeTime = parent.lastGasChargeTime
|
||||
rt.lastGasCharge = parent.lastGasCharge
|
||||
defer func() {
|
||||
parent.gasUsed = rt.gasUsed
|
||||
parent.lastGasChargeTime = rt.lastGasChargeTime
|
||||
parent.lastGasCharge = rt.lastGasCharge
|
||||
}()
|
||||
}
|
||||
|
||||
if gasCharge != nil {
|
||||
if err := rt.chargeGasSafe(*gasCharge); err != nil {
|
||||
// this should never happen
|
||||
return nil, aerrors.Wrap(err, "not enough gas for initial message charge, this should not happen"), rt
|
||||
}
|
||||
}
|
||||
|
||||
ret, err := func() ([]byte, aerrors.ActorError) {
|
||||
if aerr := rt.chargeGasSafe(rt.Pricelist().OnMethodInvocation(msg.Value, msg.Method)); aerr != nil {
|
||||
return nil, aerrors.Wrap(aerr, "not enough gas for method invocation"), rt
|
||||
return nil, aerrors.Wrap(aerr, "not enough gas for method invocation")
|
||||
}
|
||||
|
||||
toActor, err := st.GetActor(msg.To)
|
||||
@ -200,26 +215,40 @@ func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime,
|
||||
if xerrors.Is(err, init_.ErrAddressNotFound) {
|
||||
a, err := TryCreateAccountActor(rt, msg.To)
|
||||
if err != nil {
|
||||
return nil, aerrors.Wrapf(err, "could not create account"), rt
|
||||
return nil, aerrors.Wrapf(err, "could not create account")
|
||||
}
|
||||
toActor = a
|
||||
} else {
|
||||
return nil, aerrors.Escalate(err, "getting actor"), rt
|
||||
return nil, aerrors.Escalate(err, "getting actor")
|
||||
}
|
||||
}
|
||||
|
||||
if types.BigCmp(msg.Value, types.NewInt(0)) != 0 {
|
||||
if err := vm.transfer(msg.From, msg.To, msg.Value); err != nil {
|
||||
return nil, aerrors.Wrap(err, "failed to transfer funds"), nil
|
||||
return nil, aerrors.Wrap(err, "failed to transfer funds")
|
||||
}
|
||||
}
|
||||
|
||||
if msg.Method != 0 {
|
||||
var ret []byte
|
||||
ret, err := vm.Invoke(toActor, rt, msg.Method, msg.Params)
|
||||
return ret, err, rt
|
||||
return ret, err
|
||||
}
|
||||
return nil, nil
|
||||
}()
|
||||
|
||||
mr := types.MessageReceipt{
|
||||
ExitCode: aerrors.RetCode(err),
|
||||
Return: ret,
|
||||
GasUsed: rt.gasUsed,
|
||||
}
|
||||
rt.executionTrace.MsgRct = &mr
|
||||
rt.executionTrace.Duration = time.Since(start)
|
||||
if err != nil {
|
||||
rt.executionTrace.Error = err.Error()
|
||||
}
|
||||
|
||||
return nil, nil, rt
|
||||
return ret, err, rt
|
||||
}
|
||||
|
||||
func checkMessage(msg *types.Message) error {
|
||||
@ -243,15 +272,16 @@ func checkMessage(msg *types.Message) error {
|
||||
|
||||
func (vm *VM) ApplyImplicitMessage(ctx context.Context, msg *types.Message) (*ApplyRet, error) {
|
||||
start := time.Now()
|
||||
ret, actorErr, rt := vm.send(ctx, msg, nil, 0)
|
||||
ret, actorErr, rt := vm.send(ctx, msg, nil, nil, start)
|
||||
rt.finilizeGasTracing()
|
||||
return &ApplyRet{
|
||||
MessageReceipt: types.MessageReceipt{
|
||||
ExitCode: exitcode.ExitCode(aerrors.RetCode(actorErr)),
|
||||
ExitCode: aerrors.RetCode(actorErr),
|
||||
Return: ret,
|
||||
GasUsed: 0,
|
||||
},
|
||||
ActorErr: actorErr,
|
||||
InternalExecutions: rt.internalExecutions,
|
||||
ExecutionTrace: rt.executionTrace,
|
||||
Penalty: types.NewInt(0),
|
||||
Duration: time.Since(start),
|
||||
}, actorErr
|
||||
@ -276,7 +306,8 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
||||
|
||||
pl := PricelistByEpoch(vm.blockHeight)
|
||||
|
||||
msgGasCost := pl.OnChainMessage(cmsg.ChainLength())
|
||||
msgGas := pl.OnChainMessage(cmsg.ChainLength())
|
||||
msgGasCost := msgGas.Total()
|
||||
// this should never happen, but is currently still exercised by some tests
|
||||
if msgGasCost > msg.GasLimit {
|
||||
return &ApplyRet{
|
||||
@ -359,7 +390,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
||||
}
|
||||
defer st.ClearSnapshot()
|
||||
|
||||
ret, actorErr, rt := vm.send(ctx, msg, nil, msgGasCost)
|
||||
ret, actorErr, rt := vm.send(ctx, msg, nil, &msgGas, start)
|
||||
if aerrors.IsFatal(actorErr) {
|
||||
return nil, xerrors.Errorf("[from=%s,to=%s,n=%d,m=%d,h=%d] fatal error: %w", msg.From, msg.To, msg.Nonce, msg.Method, vm.blockHeight, actorErr)
|
||||
}
|
||||
@ -413,14 +444,16 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
||||
return nil, xerrors.Errorf("gas handling math is wrong")
|
||||
}
|
||||
|
||||
rt.finilizeGasTracing()
|
||||
|
||||
return &ApplyRet{
|
||||
MessageReceipt: types.MessageReceipt{
|
||||
ExitCode: exitcode.ExitCode(errcode),
|
||||
ExitCode: errcode,
|
||||
Return: ret,
|
||||
GasUsed: gasUsed,
|
||||
},
|
||||
ActorErr: actorErr,
|
||||
InternalExecutions: rt.internalExecutions,
|
||||
ExecutionTrace: rt.executionTrace,
|
||||
Penalty: types.NewInt(0),
|
||||
Duration: time.Since(start),
|
||||
}, nil
|
||||
@ -454,7 +487,7 @@ func (vm *VM) Flush(ctx context.Context) (cid.Cid, error) {
|
||||
return root, nil
|
||||
}
|
||||
|
||||
// vm.MutateState(idAddr, func(cst cbor.IpldStore, st *ActorStateType) error {...})
|
||||
// MutateState usage: MutateState(ctx, idAddr, func(cst cbor.IpldStore, st *ActorStateType) error {...})
|
||||
func (vm *VM) MutateState(ctx context.Context, addr address.Address, fn interface{}) error {
|
||||
act, err := vm.cstate.GetActor(addr)
|
||||
if err != nil {
|
||||
@ -591,7 +624,7 @@ func (vm *VM) Invoke(act *types.Actor, rt *Runtime, method abi.MethodNum, params
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (vm *VM) SetInvoker(i *invoker) {
|
||||
func (vm *VM) SetInvoker(i *Invoker) {
|
||||
vm.inv = i
|
||||
}
|
||||
|
||||
@ -607,16 +640,30 @@ func (vm *VM) transfer(from, to address.Address, amt types.BigInt) aerrors.Actor
|
||||
return nil
|
||||
}
|
||||
|
||||
fromID, err := vm.cstate.LookupID(from)
|
||||
if err != nil {
|
||||
return aerrors.Fatalf("transfer failed when resolving sender address: %s", err)
|
||||
}
|
||||
|
||||
toID, err := vm.cstate.LookupID(to)
|
||||
if err != nil {
|
||||
return aerrors.Fatalf("transfer failed when resolving receiver address: %s", err)
|
||||
}
|
||||
|
||||
if fromID == toID {
|
||||
return nil
|
||||
}
|
||||
|
||||
if amt.LessThan(types.NewInt(0)) {
|
||||
return aerrors.Newf(exitcode.SysErrForbidden, "attempted to transfer negative value: %s", amt)
|
||||
}
|
||||
|
||||
f, err := vm.cstate.GetActor(from)
|
||||
f, err := vm.cstate.GetActor(fromID)
|
||||
if err != nil {
|
||||
return aerrors.Fatalf("transfer failed when retrieving sender actor: %s", err)
|
||||
}
|
||||
|
||||
t, err := vm.cstate.GetActor(to)
|
||||
t, err := vm.cstate.GetActor(toID)
|
||||
if err != nil {
|
||||
return aerrors.Fatalf("transfer failed when retrieving receiver actor: %s", err)
|
||||
}
|
||||
@ -626,11 +673,11 @@ func (vm *VM) transfer(from, to address.Address, amt types.BigInt) aerrors.Actor
|
||||
}
|
||||
depositFunds(t, amt)
|
||||
|
||||
if err := vm.cstate.SetActor(from, f); err != nil {
|
||||
if err := vm.cstate.SetActor(fromID, f); err != nil {
|
||||
return aerrors.Fatalf("transfer failed when setting receiver actor: %s", err)
|
||||
}
|
||||
|
||||
if err := vm.cstate.SetActor(to, t); err != nil {
|
||||
if err := vm.cstate.SetActor(toID, t); err != nil {
|
||||
return aerrors.Fatalf("transfer failed when setting sender actor: %s", err)
|
||||
}
|
||||
|
||||
|
@ -12,8 +12,8 @@ import (
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
|
||||
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
|
||||
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
|
||||
_ "github.com/filecoin-project/lotus/lib/sigs/bls" // enable bls signatures
|
||||
_ "github.com/filecoin-project/lotus/lib/sigs/secp" // enable secp signatures
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/lib/sigs"
|
||||
|
@ -3,8 +3,8 @@ package cli
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
|
||||
"github.com/filecoin-project/go-jsonrpc/auth"
|
||||
|
||||
|
10
cli/chain.go
10
cli/chain.go
@ -22,9 +22,9 @@ import (
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
"github.com/urfave/cli/v2"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
@ -445,6 +445,7 @@ var chainGetCmd = &cli.Command{
|
||||
- /ipfs/[cid]/@Hu:123 - get uvarint elem 123 from hamt
|
||||
- /ipfs/[cid]/@Ha:t01 - get element under Addr(t01).Bytes
|
||||
- /ipfs/[cid]/@A:10 - get 10th amt element
|
||||
- .../@Ha:t01/@state - get pretty map-based actor state
|
||||
|
||||
List of --as-type types:
|
||||
- raw
|
||||
@ -806,7 +807,12 @@ var chainExportCmd = &cli.Command{
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fi.Close()
|
||||
defer func() {
|
||||
err := fi.Close()
|
||||
if err != nil {
|
||||
fmt.Printf("error closing output file: %+v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
ts, err := LoadTipSet(ctx, cctx, api)
|
||||
if err != nil {
|
||||
|
@ -11,8 +11,8 @@ import (
|
||||
"github.com/ipfs/go-cidutil/cidenc"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
"github.com/multiformats/go-multibase"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
||||
@ -527,11 +527,11 @@ var clientQueryAskCmd = &cli.Command{
|
||||
return xerrors.Errorf("failed to get peerID for miner: %w", err)
|
||||
}
|
||||
|
||||
if mi.PeerId == peer.ID("SETME") {
|
||||
if peer.ID(mi.PeerId) == peer.ID("SETME") {
|
||||
return fmt.Errorf("the miner hasn't initialized yet")
|
||||
}
|
||||
|
||||
pid = mi.PeerId
|
||||
pid = peer.ID(mi.PeerId)
|
||||
}
|
||||
|
||||
ask, err := api.ClientQueryAsk(ctx, pid, maddr)
|
||||
|
@ -13,8 +13,8 @@ import (
|
||||
"github.com/mitchellh/go-homedir"
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
manet "github.com/multiformats/go-multiaddr-net"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
|
||||
"github.com/filecoin-project/go-jsonrpc"
|
||||
|
||||
|
@ -3,8 +3,8 @@ package cli
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
)
|
||||
|
||||
var logCmd = &cli.Command{
|
||||
|
@ -5,8 +5,8 @@ import (
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
|
||||
|
@ -17,12 +17,13 @@ import (
|
||||
cid "github.com/ipfs/go-cid"
|
||||
"github.com/ipfs/go-hamt-ipld"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
"github.com/urfave/cli/v2"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/api/apibstore"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
types "github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
@ -117,7 +118,7 @@ var msigCreateCmd = &cli.Command{
|
||||
}
|
||||
|
||||
// wait for it to get mined into a block
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid)
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, build.MessageConfidence)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -206,7 +207,10 @@ var msigInspectCmd = &cli.Command{
|
||||
tx := pending[txid]
|
||||
fmt.Fprintf(w, "%d\t%s\t%s\t%s\t%d\t%x\n", txid, state(tx), tx.To, types.FIL(tx.Value), tx.Method, tx.Params)
|
||||
}
|
||||
w.Flush()
|
||||
if err := w.Flush(); err != nil {
|
||||
return xerrors.Errorf("flushing output: %+v", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -333,7 +337,7 @@ var msigProposeCmd = &cli.Command{
|
||||
|
||||
fmt.Println("send proposal in message: ", msgCid)
|
||||
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid)
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, build.MessageConfidence)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -449,7 +453,7 @@ var msigApproveCmd = &cli.Command{
|
||||
|
||||
fmt.Println("sent approval in message: ", msgCid)
|
||||
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid)
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, build.MessageConfidence)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
28
cli/net.go
28
cli/net.go
@ -7,7 +7,7 @@ import (
|
||||
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
"github.com/filecoin-project/lotus/lib/addrutil"
|
||||
)
|
||||
@ -21,6 +21,7 @@ var netCmd = &cli.Command{
|
||||
netListen,
|
||||
netId,
|
||||
netFindPeer,
|
||||
netScores,
|
||||
},
|
||||
}
|
||||
|
||||
@ -44,7 +45,30 @@ var netPeers = &cli.Command{
|
||||
})
|
||||
|
||||
for _, peer := range peers {
|
||||
fmt.Println(peer)
|
||||
fmt.Printf("%s, %s\n", peer.ID, peer.Addrs)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var netScores = &cli.Command{
|
||||
Name: "scores",
|
||||
Usage: "Print peers' pubsub scores",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := GetAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
ctx := ReqContext(cctx)
|
||||
scores, err := api.NetPubsubScores(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, peer := range scores {
|
||||
fmt.Printf("%s, %f\n", peer.ID, peer.Score)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -3,8 +3,8 @@ package cli
|
||||
import (
|
||||
"github.com/docker/go-units"
|
||||
paramfetch "github.com/filecoin-project/go-paramfetch"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
)
|
||||
@ -23,7 +23,7 @@ var fetchParamCmd = &cli.Command{
|
||||
}
|
||||
sectorSize := uint64(sectorSizeInt)
|
||||
|
||||
err = paramfetch.GetParams(ReqContext(cctx), build.ParametersJson(), sectorSize)
|
||||
err = paramfetch.GetParams(ReqContext(cctx), build.ParametersJSON(), sectorSize)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("fetching proof parameters: %w", err)
|
||||
}
|
||||
|
@ -4,10 +4,11 @@ import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
types "github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
@ -361,7 +362,7 @@ var paychVoucherSubmitCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
mwait, err := api.StateWaitMsg(ctx, mcid)
|
||||
mwait, err := api.StateWaitMsg(ctx, mcid, build.MessageConfidence)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -370,7 +371,7 @@ var paychVoucherSubmitCmd = &cli.Command{
|
||||
return fmt.Errorf("message execution failed (exit code %d)", mwait.Receipt.ExitCode)
|
||||
}
|
||||
|
||||
fmt.Println("channel updated succesfully")
|
||||
fmt.Println("channel updated successfully")
|
||||
|
||||
return nil
|
||||
},
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var sendCmd = &cli.Command{
|
||||
|
378
cli/state.go
378
cli/state.go
@ -5,6 +5,8 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"os"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
@ -14,9 +16,9 @@ import (
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
"github.com/multiformats/go-multihash"
|
||||
"github.com/urfave/cli/v2"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||
@ -31,15 +33,17 @@ import (
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/miner"
|
||||
)
|
||||
|
||||
type methodMeta struct {
|
||||
name string
|
||||
Name string
|
||||
|
||||
params reflect.Type
|
||||
ret reflect.Type
|
||||
@ -67,7 +71,7 @@ func init() {
|
||||
nf := rt.NumField()
|
||||
|
||||
methods[c] = append(methods[c], methodMeta{
|
||||
name: "Send",
|
||||
Name: "Send",
|
||||
params: reflect.TypeOf(new(adt.EmptyValue)),
|
||||
ret: reflect.TypeOf(new(adt.EmptyValue)),
|
||||
})
|
||||
@ -77,7 +81,7 @@ func init() {
|
||||
export := reflect.TypeOf(exports[i+1])
|
||||
|
||||
methods[c] = append(methods[c], methodMeta{
|
||||
name: rt.Field(i).Name,
|
||||
Name: rt.Field(i).Name,
|
||||
params: export.In(1),
|
||||
ret: export.Out(0),
|
||||
})
|
||||
@ -143,23 +147,11 @@ var stateMinerInfo = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
act, err := api.StateGetActor(ctx, addr, ts.Key())
|
||||
mi, err := api.StateMinerInfo(ctx, addr, ts.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
aso, err := api.ChainReadObj(ctx, act.Head)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var mst miner2.State
|
||||
if err := mst.UnmarshalCBOR(bytes.NewReader(aso)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mi := mst.Info
|
||||
|
||||
fmt.Printf("Owner:\t%s\n", mi.Owner)
|
||||
fmt.Printf("Worker:\t%s\n", mi.Worker)
|
||||
fmt.Printf("PeerID:\t%s\n", mi.PeerId)
|
||||
@ -392,7 +384,7 @@ var stateReplaySetCmd = &cli.Command{
|
||||
ts, err = types.NewTipSet(headers)
|
||||
} else {
|
||||
var r *api.MsgLookup
|
||||
r, err = fapi.StateWaitMsg(ctx, mcid)
|
||||
r, err = fapi.StateWaitMsg(ctx, mcid, build.MessageConfidence)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("finding message in chain: %w", err)
|
||||
}
|
||||
@ -935,37 +927,29 @@ var stateComputeStateCmd = &cli.Command{
|
||||
return c.Code, nil
|
||||
}
|
||||
|
||||
return computeStateHtml(ts, stout, getCode)
|
||||
return computeStateHTMLTempl(ts, stout, getCode)
|
||||
}
|
||||
|
||||
fmt.Println("computed state cid: ", stout.Root)
|
||||
if cctx.Bool("show-trace") {
|
||||
for _, ir := range stout.Trace {
|
||||
fmt.Printf("%s\t%s\t%s\t%d\t%x\t%d\t%x\n", ir.Msg.From, ir.Msg.To, ir.Msg.Value, ir.Msg.Method, ir.Msg.Params, ir.MsgRct.ExitCode, ir.MsgRct.Return)
|
||||
printInternalExecutions("\t", ir.InternalExecutions)
|
||||
printInternalExecutions("\t", ir.ExecutionTrace.Subcalls)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
func printInternalExecutions(prefix string, trace []*types.ExecutionResult) {
|
||||
func printInternalExecutions(prefix string, trace []types.ExecutionTrace) {
|
||||
for _, im := range trace {
|
||||
fmt.Printf("%s%s\t%s\t%s\t%d\t%x\t%d\t%x\n", prefix, im.Msg.From, im.Msg.To, im.Msg.Value, im.Msg.Method, im.Msg.Params, im.MsgRct.ExitCode, im.MsgRct.Return)
|
||||
printInternalExecutions(prefix+"\t", im.Subcalls)
|
||||
}
|
||||
}
|
||||
|
||||
func codeStr(c cid.Cid) string {
|
||||
cmh, err := multihash.Decode(c.Hash())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return string(cmh.Digest)
|
||||
}
|
||||
|
||||
func computeStateHtml(ts *types.TipSet, o *api.ComputeStateOutput, getCode func(addr address.Address) (cid.Cid, error)) error {
|
||||
fmt.Printf(`<html>
|
||||
var compStateTemplate = `
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
html, body { font-family: monospace; }
|
||||
@ -987,123 +971,259 @@ func computeStateHtml(ts *types.TipSet, o *api.ComputeStateOutput, getCode func(
|
||||
}
|
||||
.slow-true-false { color: #660; }
|
||||
.slow-true-true { color: #f80; }
|
||||
.deemp { color: #444; }
|
||||
table {
|
||||
font-size: 12px;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
tr {
|
||||
border-top: 1px solid black;
|
||||
border-bottom: 1px solid black;
|
||||
}
|
||||
tr.sum { border-top: 2px solid black; }
|
||||
tr:first-child { border-top: none; }
|
||||
tr:last-child { border-bottom: none; }
|
||||
|
||||
|
||||
.ellipsis-content,
|
||||
.ellipsis-toggle input {
|
||||
display: none;
|
||||
}
|
||||
.ellipsis-toggle {
|
||||
cursor: pointer;
|
||||
}
|
||||
/**
|
||||
Checked State
|
||||
**/
|
||||
|
||||
.ellipsis-toggle input:checked + .ellipsis {
|
||||
display: none;
|
||||
}
|
||||
.ellipsis-toggle input:checked ~ .ellipsis-content {
|
||||
display: inline;
|
||||
background-color: #ddd;
|
||||
}
|
||||
hr {
|
||||
border: none;
|
||||
height: 1px;
|
||||
background-color: black;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div>Tipset: <b>%s</b></div>
|
||||
<div>Height: %d</div>
|
||||
<div>State CID: <b>%s</b></div>
|
||||
<div>Calls</div>`, ts.Key(), ts.Height(), o.Root)
|
||||
<div>Tipset: <b>{{.TipSet.Key}}</b></div>
|
||||
<div>Epoch: {{.TipSet.Height}}</div>
|
||||
<div>State CID: <b>{{.Comp.Root}}</b></div>
|
||||
<div>Calls</div>
|
||||
{{range .Comp.Trace}}
|
||||
{{template "message" (Call .ExecutionTrace false .Msg.Cid.String)}}
|
||||
{{end}}
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
|
||||
for _, ir := range o.Trace {
|
||||
toCode, err := getCode(ir.Msg.To)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting code for %s: %w", toCode, err)
|
||||
}
|
||||
var compStateMsg = `
|
||||
<div class="exec" id="{{.Hash}}">
|
||||
{{$code := GetCode .Msg.To}}
|
||||
<div>
|
||||
<a href="#{{.Hash}}">
|
||||
{{if not .Subcall}}
|
||||
<h2 class="call">
|
||||
{{else}}
|
||||
<h4 class="call">
|
||||
{{end}}
|
||||
{{- CodeStr $code}}:{{GetMethod ($code) (.Msg.Method)}}
|
||||
{{if not .Subcall}}
|
||||
</h2>
|
||||
{{else}}
|
||||
</h4>
|
||||
{{end}}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
params, err := jsonParams(toCode, ir.Msg.Method, ir.Msg.Params)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("decoding params: %w", err)
|
||||
}
|
||||
<div><b>{{.Msg.From}}</b> -> <b>{{.Msg.To}}</b> ({{ToFil .Msg.Value}} FIL), M{{.Msg.Method}}</div>
|
||||
{{if not .Subcall}}<div><small>Msg CID: {{.Msg.Cid}}</small></div>{{end}}
|
||||
{{if gt (len .Msg.Params) 0}}
|
||||
<div><pre class="params">{{JsonParams ($code) (.Msg.Method) (.Msg.Params) | html}}</pre></div>
|
||||
{{end}}
|
||||
<div><span class="slow-{{IsSlow .Duration}}-{{IsVerySlow .Duration}}">Took {{.Duration}}</span>, <span class="exit{{IntExit .MsgRct.ExitCode}}">Exit: <b>{{.MsgRct.ExitCode}}</b></span>{{if gt (len .MsgRct.Return) 0}}, Return{{end}}</div>
|
||||
|
||||
if len(ir.Msg.Params) != 0 {
|
||||
params = `<div><pre class="params">` + params + `</pre></div>`
|
||||
} else {
|
||||
params = ""
|
||||
}
|
||||
{{if gt (len .MsgRct.Return) 0}}
|
||||
<div><pre class="ret">{{JsonReturn ($code) (.Msg.Method) (.MsgRct.Return) | html}}</pre></div>
|
||||
{{end}}
|
||||
|
||||
ret, err := jsonReturn(toCode, ir.Msg.Method, ir.MsgRct.Return)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("decoding return value: %w", err)
|
||||
}
|
||||
{{if ne .MsgRct.ExitCode 0}}
|
||||
<div class="error">Error: <pre>{{.Error}}</pre></div>
|
||||
{{end}}
|
||||
|
||||
if len(ir.MsgRct.Return) == 0 {
|
||||
ret = "</div>"
|
||||
} else {
|
||||
ret = `, Return</div><div><pre class="ret">` + ret + `</pre></div>`
|
||||
}
|
||||
<details>
|
||||
<summary>Gas Trace</summary>
|
||||
<table>
|
||||
<tr><th>Name</th><th>Total/Compute/Storage</th><th>Time Taken</th><th>Location</th></tr>
|
||||
{{define "virt" -}}
|
||||
{{- if . -}}
|
||||
<span class="deemp">+({{.}})</span>
|
||||
{{- end -}}
|
||||
{{- end}}
|
||||
|
||||
slow := ir.Duration > 10*time.Millisecond
|
||||
veryslow := ir.Duration > 50*time.Millisecond
|
||||
{{define "gasC" -}}
|
||||
<td>{{.TotalGas}}{{template "virt" .TotalVirtualGas }}/{{.ComputeGas}}{{template "virt" .VirtualComputeGas}}/{{.StorageGas}}{{template "virt" .VirtualStorageGas}}</td>
|
||||
{{- end}}
|
||||
|
||||
cid := ir.Msg.Cid()
|
||||
{{range .GasCharges}}
|
||||
<tr><td>{{.Name}}{{if .Extra}}:{{.Extra}}{{end}}</td>
|
||||
{{template "gasC" .}}
|
||||
<td>{{.TimeTaken}}</td>
|
||||
<td>
|
||||
{{ $fImp := FirstImportant .Location }}
|
||||
{{ if $fImp }}
|
||||
<details>
|
||||
<summary>{{ $fImp }}</summary><hr />
|
||||
{{ $elipOn := false }}
|
||||
{{ range $index, $ele := .Location -}}
|
||||
{{- if $index }}<br />{{end -}}
|
||||
{{- if .Show -}}
|
||||
{{ if $elipOn }}
|
||||
{{ $elipOn = false }}
|
||||
</span></label>
|
||||
{{end}}
|
||||
|
||||
fmt.Printf(`<div class="exec" id="%s">
|
||||
<div><a href="#%s"><h2 class="call">%s:%s</h2></a></div>
|
||||
<div><b>%s</b> -> <b>%s</b> (%s FIL), M%d</div>
|
||||
<div><small>Msg CID: %s</small></div>
|
||||
%s
|
||||
<div><span class="slow-%t-%t">Took %s</span>, <span class="exit%d">Exit: <b>%d</b></span>%s
|
||||
`, cid, cid, codeStr(toCode), methods[toCode][ir.Msg.Method].name, ir.Msg.From, ir.Msg.To, types.FIL(ir.Msg.Value), ir.Msg.Method, cid, params, slow, veryslow, ir.Duration, ir.MsgRct.ExitCode, ir.MsgRct.ExitCode, ret)
|
||||
if ir.MsgRct.ExitCode != 0 {
|
||||
fmt.Printf(`<div class="error">Error: <pre>%s</pre></div>`, ir.Error)
|
||||
}
|
||||
{{- if .Important }}<b>{{end -}}
|
||||
{{- . -}}
|
||||
{{if .Important }}</b>{{end}}
|
||||
{{else}}
|
||||
{{ if not $elipOn }}
|
||||
{{ $elipOn = true }}
|
||||
<label class="ellipsis-toggle"><input type="checkbox" /><span class="ellipsis">[…]<br /></span>
|
||||
<span class="ellipsis-content">
|
||||
{{end}}
|
||||
{{- "" -}}
|
||||
{{- . -}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{ if $elipOn }}
|
||||
{{ $elipOn = false }}
|
||||
</span></label>
|
||||
{{end}}
|
||||
</details>
|
||||
{{end}}
|
||||
</td></tr>
|
||||
{{end}}
|
||||
{{with SumGas .GasCharges}}
|
||||
<tr class="sum"><td><b>Sum</b></td>
|
||||
{{template "gasC" .}}
|
||||
<td>{{.TimeTaken}}</td>
|
||||
<td></td></tr>
|
||||
{{end}}
|
||||
</table>
|
||||
</details>
|
||||
|
||||
if len(ir.InternalExecutions) > 0 {
|
||||
fmt.Println("<div>Internal executions:</div>")
|
||||
if err := printInternalExecutionsHtml(ir.InternalExecutions, getCode); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
fmt.Println("</div>")
|
||||
}
|
||||
|
||||
fmt.Printf(`</body>
|
||||
</html>`)
|
||||
return nil
|
||||
{{if gt (len .Subcalls) 0}}
|
||||
<div>Subcalls:</div>
|
||||
{{$hash := .Hash}}
|
||||
{{range .Subcalls}}
|
||||
{{template "message" (Call . true (printf "%s-%s" $hash .Msg.Cid.String))}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
</div>`
|
||||
|
||||
type compStateHTMLIn struct {
|
||||
TipSet *types.TipSet
|
||||
Comp *api.ComputeStateOutput
|
||||
}
|
||||
|
||||
func printInternalExecutionsHtml(trace []*types.ExecutionResult, getCode func(addr address.Address) (cid.Cid, error)) error {
|
||||
for _, im := range trace {
|
||||
toCode, err := getCode(im.Msg.To)
|
||||
func computeStateHTMLTempl(ts *types.TipSet, o *api.ComputeStateOutput, getCode func(addr address.Address) (cid.Cid, error)) error {
|
||||
t, err := template.New("compute_state").Funcs(map[string]interface{}{
|
||||
"GetCode": getCode,
|
||||
"GetMethod": getMethod,
|
||||
"ToFil": toFil,
|
||||
"JsonParams": jsonParams,
|
||||
"JsonReturn": jsonReturn,
|
||||
"IsSlow": isSlow,
|
||||
"IsVerySlow": isVerySlow,
|
||||
"IntExit": func(i exitcode.ExitCode) int64 { return int64(i) },
|
||||
"SumGas": sumGas,
|
||||
"CodeStr": codeStr,
|
||||
"Call": call,
|
||||
"FirstImportant": func(locs []types.Loc) *types.Loc {
|
||||
if len(locs) != 0 {
|
||||
for _, l := range locs {
|
||||
if l.Important() {
|
||||
return &l
|
||||
}
|
||||
}
|
||||
return &locs[0]
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}).Parse(compStateTemplate)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting code for %s: %w", toCode, err)
|
||||
}
|
||||
|
||||
params, err := jsonParams(toCode, im.Msg.Method, im.Msg.Params)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("decoding params: %w", err)
|
||||
}
|
||||
|
||||
if len(im.Msg.Params) != 0 {
|
||||
params = `<div><pre class="params">` + params + `</pre></div>`
|
||||
} else {
|
||||
params = ""
|
||||
}
|
||||
|
||||
ret, err := jsonReturn(toCode, im.Msg.Method, im.MsgRct.Return)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("decoding return value: %w", err)
|
||||
}
|
||||
|
||||
if len(im.MsgRct.Return) == 0 {
|
||||
ret = "</div>"
|
||||
} else {
|
||||
ret = `, Return</div><div><pre class="ret">` + ret + `</pre></div>`
|
||||
}
|
||||
|
||||
slow := im.Duration > 10*time.Millisecond
|
||||
veryslow := im.Duration > 50*time.Millisecond
|
||||
|
||||
fmt.Printf(`<div class="exec">
|
||||
<div><h4 class="call">%s:%s</h4></div>
|
||||
<div><b>%s</b> -> <b>%s</b> (%s FIL), M%d</div>
|
||||
%s
|
||||
<div><span class="slow-%t-%t">Took %s</span>, <span class="exit%d">Exit: <b>%d</b></span>%s
|
||||
`, codeStr(toCode), methods[toCode][im.Msg.Method].name, im.Msg.From, im.Msg.To, types.FIL(im.Msg.Value), im.Msg.Method, params, slow, veryslow, im.Duration, im.MsgRct.ExitCode, im.MsgRct.ExitCode, ret)
|
||||
if im.MsgRct.ExitCode != 0 {
|
||||
fmt.Printf(`<div class="error">Error: <pre>%s</pre></div>`, im.Error)
|
||||
}
|
||||
if len(im.Subcalls) > 0 {
|
||||
fmt.Println("<div>Subcalls:</div>")
|
||||
if err := printInternalExecutionsHtml(im.Subcalls, getCode); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
fmt.Println("</div>")
|
||||
t, err = t.New("message").Parse(compStateMsg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return t.ExecuteTemplate(os.Stdout, "compute_state", &compStateHTMLIn{
|
||||
TipSet: ts,
|
||||
Comp: o,
|
||||
})
|
||||
}
|
||||
|
||||
type callMeta struct {
|
||||
types.ExecutionTrace
|
||||
Subcall bool
|
||||
Hash string
|
||||
}
|
||||
|
||||
func call(e types.ExecutionTrace, subcall bool, hash string) callMeta {
|
||||
return callMeta{
|
||||
ExecutionTrace: e,
|
||||
Subcall: subcall,
|
||||
Hash: hash,
|
||||
}
|
||||
}
|
||||
|
||||
func codeStr(c cid.Cid) string {
|
||||
cmh, err := multihash.Decode(c.Hash())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return string(cmh.Digest)
|
||||
}
|
||||
|
||||
func getMethod(code cid.Cid, method abi.MethodNum) string {
|
||||
return methods[code][method].Name
|
||||
}
|
||||
|
||||
func toFil(f types.BigInt) types.FIL {
|
||||
return types.FIL(f)
|
||||
}
|
||||
|
||||
func isSlow(t time.Duration) bool {
|
||||
return t > 10*time.Millisecond
|
||||
}
|
||||
|
||||
func isVerySlow(t time.Duration) bool {
|
||||
return t > 50*time.Millisecond
|
||||
}
|
||||
|
||||
func sumGas(changes []*types.GasTrace) types.GasTrace {
|
||||
var out types.GasTrace
|
||||
for _, gc := range changes {
|
||||
out.TotalGas += gc.TotalGas
|
||||
out.ComputeGas += gc.ComputeGas
|
||||
out.StorageGas += gc.StorageGas
|
||||
|
||||
out.TotalVirtualGas += gc.TotalVirtualGas
|
||||
out.VirtualComputeGas += gc.VirtualComputeGas
|
||||
out.VirtualStorageGas += gc.VirtualStorageGas
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func jsonParams(code cid.Cid, method abi.MethodNum, params []byte) (string, error) {
|
||||
@ -1156,7 +1276,7 @@ var stateWaitMsgCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
mw, err := api.StateWaitMsg(ctx, msg)
|
||||
mw, err := api.StateWaitMsg(ctx, msg, build.MessageConfidence)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
|
@ -3,7 +3,7 @@ package cli
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var versionCmd = &cli.Command{
|
||||
@ -23,7 +23,9 @@ var versionCmd = &cli.Command{
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println(v)
|
||||
fmt.Println("Daemon: ", v)
|
||||
|
||||
fmt.Print("Local: ")
|
||||
cli.VersionPrinter(cctx)
|
||||
return nil
|
||||
},
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var waitApiCmd = &cli.Command{
|
||||
|
@ -15,7 +15,7 @@ import (
|
||||
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var walletCmd = &cli.Command{
|
||||
|
@ -14,7 +14,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
lcli "github.com/filecoin-project/lotus/cli"
|
||||
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@ -53,8 +53,7 @@ var runCmd = &cli.Command{
|
||||
defer closer()
|
||||
ctx := lcli.ReqContext(cctx)
|
||||
|
||||
sendSmallFundsTxs(ctx, api, addr, 5)
|
||||
return nil
|
||||
return sendSmallFundsTxs(ctx, api, addr, 5)
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,9 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"os"
|
||||
"runtime"
|
||||
"runtime/pprof"
|
||||
"sort"
|
||||
"time"
|
||||
@ -24,7 +26,7 @@ import (
|
||||
"github.com/ipfs/go-datastore"
|
||||
badger "github.com/ipfs/go-ds-badger2"
|
||||
blockstore "github.com/ipfs/go-ipfs-blockstore"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
type TipSetExec struct {
|
||||
@ -44,8 +46,14 @@ var importBenchCmd = &cli.Command{
|
||||
Name: "height",
|
||||
Usage: "halt validation after given height",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Name: "batch-seal-verify-threads",
|
||||
Usage: "set the parallelism factor for batch seal verification",
|
||||
Value: runtime.NumCPU(),
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
vm.BatchSealVerifyParallelism = cctx.Int("batch-seal-verify-threads")
|
||||
if !cctx.Args().Present() {
|
||||
fmt.Println("must pass car file of chain to benchmark importing")
|
||||
return nil
|
||||
@ -55,7 +63,7 @@ var importBenchCmd = &cli.Command{
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer cfi.Close()
|
||||
defer cfi.Close() //nolint:errcheck // read only file
|
||||
|
||||
tdir, err := ioutil.TempDir("", "lotus-import-bench")
|
||||
if err != nil {
|
||||
@ -80,7 +88,7 @@ var importBenchCmd = &cli.Command{
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer prof.Close()
|
||||
defer prof.Close() //nolint:errcheck
|
||||
|
||||
if err := pprof.StartCPUProfile(prof); err != nil {
|
||||
return err
|
||||
@ -146,7 +154,7 @@ var importBenchCmd = &cli.Command{
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer ibj.Close()
|
||||
defer ibj.Close() //nolint:errcheck
|
||||
|
||||
if err := json.NewEncoder(ibj).Encode(out); err != nil {
|
||||
return err
|
||||
@ -162,6 +170,58 @@ type Invocation struct {
|
||||
Invoc *api.InvocResult
|
||||
}
|
||||
|
||||
const GasPerNs = 10
|
||||
|
||||
func countGasCosts(et *types.ExecutionTrace) (int64, int64) {
|
||||
var cgas, vgas int64
|
||||
|
||||
for _, gc := range et.GasCharges {
|
||||
cgas += gc.ComputeGas
|
||||
vgas += gc.VirtualComputeGas
|
||||
}
|
||||
|
||||
for _, sub := range et.Subcalls {
|
||||
c, v := countGasCosts(&sub)
|
||||
cgas += c
|
||||
vgas += v
|
||||
}
|
||||
|
||||
return cgas, vgas
|
||||
}
|
||||
|
||||
func compStats(vals []float64) (float64, float64) {
|
||||
var sum float64
|
||||
|
||||
for _, v := range vals {
|
||||
sum += v
|
||||
}
|
||||
|
||||
av := sum / float64(len(vals))
|
||||
|
||||
var varsum float64
|
||||
for _, v := range vals {
|
||||
delta := av - v
|
||||
varsum += delta * delta
|
||||
}
|
||||
|
||||
return av, math.Sqrt(varsum / float64(len(vals)))
|
||||
}
|
||||
|
||||
func tallyGasCharges(charges map[string][]float64, et *types.ExecutionTrace) {
|
||||
for _, gc := range et.GasCharges {
|
||||
|
||||
compGas := gc.ComputeGas + gc.VirtualComputeGas
|
||||
ratio := float64(compGas) / float64(gc.TimeTaken.Nanoseconds())
|
||||
|
||||
charges[gc.Name] = append(charges[gc.Name], 1/(ratio/GasPerNs))
|
||||
//fmt.Printf("%s: %d, %s: %0.2f\n", gc.Name, compGas, gc.TimeTaken, 1/(ratio/GasPerNs))
|
||||
for _, sub := range et.Subcalls {
|
||||
tallyGasCharges(charges, &sub)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var importAnalyzeCmd = &cli.Command{
|
||||
Name: "analyze",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
@ -180,6 +240,8 @@ var importAnalyzeCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
chargeDeltas := make(map[string][]float64)
|
||||
|
||||
var invocs []Invocation
|
||||
var totalTime time.Duration
|
||||
for i, r := range results {
|
||||
@ -191,9 +253,29 @@ var importAnalyzeCmd = &cli.Command{
|
||||
TipSet: r.TipSet,
|
||||
Invoc: inv,
|
||||
})
|
||||
|
||||
cgas, vgas := countGasCosts(&inv.ExecutionTrace)
|
||||
fmt.Printf("Invocation: %d %s: %s %d -> %0.2f\n", inv.Msg.Method, inv.Msg.To, inv.Duration, cgas+vgas, float64(GasPerNs*inv.Duration.Nanoseconds())/float64(cgas+vgas))
|
||||
|
||||
tallyGasCharges(chargeDeltas, &inv.ExecutionTrace)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
var keys []string
|
||||
for k := range chargeDeltas {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
|
||||
fmt.Println("Gas Price Deltas")
|
||||
sort.Strings(keys)
|
||||
for _, k := range keys {
|
||||
vals := chargeDeltas[k]
|
||||
av, stdev := compStats(vals)
|
||||
|
||||
fmt.Printf("%s: incr by %f (%f)\n", k, av, stdev)
|
||||
}
|
||||
|
||||
sort.Slice(invocs, func(i, j int) bool {
|
||||
return invocs[i].Invoc.Duration > invocs[j].Invoc.Duration
|
||||
})
|
||||
|
@ -15,8 +15,8 @@ import (
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
"github.com/minio/blake2b-simd"
|
||||
"github.com/mitchellh/go-homedir"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
paramfetch "github.com/filecoin-project/go-paramfetch"
|
||||
@ -74,12 +74,12 @@ func main() {
|
||||
|
||||
log.Info("Starting lotus-bench")
|
||||
|
||||
miner.SupportedProofTypes[abi.RegisteredProof_StackedDRG2KiBSeal] = struct{}{}
|
||||
miner.SupportedProofTypes[abi.RegisteredSealProof_StackedDrg2KiBV1] = struct{}{}
|
||||
|
||||
app := &cli.App{
|
||||
Name: "lotus-bench",
|
||||
Usage: "Benchmark performance of lotus on your hardware",
|
||||
Version: build.UserVersion,
|
||||
Version: build.UserVersion(),
|
||||
Commands: []*cli.Command{
|
||||
proveCmd,
|
||||
sealBenchCmd,
|
||||
@ -142,7 +142,10 @@ var sealBenchCmd = &cli.Command{
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
if c.Bool("no-gpu") {
|
||||
os.Setenv("BELLMAN_NO_GPU", "1")
|
||||
err := os.Setenv("BELLMAN_NO_GPU", "1")
|
||||
if err != nil {
|
||||
return xerrors.Errorf("setting no-gpu flag: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
robench := c.String("benchmark-existing-sectorbuilder")
|
||||
@ -155,7 +158,10 @@ var sealBenchCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
os.MkdirAll(sdir, 0775)
|
||||
err = os.MkdirAll(sdir, 0775) //nolint:gosec
|
||||
if err != nil {
|
||||
return xerrors.Errorf("creating sectorbuilder dir: %w", err)
|
||||
}
|
||||
|
||||
tsdir, err := ioutil.TempDir(sdir, "bench")
|
||||
if err != nil {
|
||||
@ -210,7 +216,7 @@ var sealBenchCmd = &cli.Command{
|
||||
|
||||
// Only fetch parameters if actually needed
|
||||
if !c.Bool("skip-commit2") {
|
||||
if err := paramfetch.GetParams(lcli.ReqContext(c), build.ParametersJson(), uint64(sectorSize)); err != nil {
|
||||
if err := paramfetch.GetParams(lcli.ReqContext(c), build.ParametersJSON(), uint64(sectorSize)); err != nil {
|
||||
return xerrors.Errorf("getting params: %w", err)
|
||||
}
|
||||
}
|
||||
@ -266,7 +272,7 @@ var sealBenchCmd = &cli.Command{
|
||||
sealedSectors = append(sealedSectors, abi.SectorInfo{
|
||||
SealedCID: s.CommR,
|
||||
SectorNumber: s.SectorID,
|
||||
RegisteredProof: s.ProofType,
|
||||
SealProof: s.ProofType,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -278,7 +284,12 @@ var sealBenchCmd = &cli.Command{
|
||||
|
||||
if !c.Bool("skip-commit2") {
|
||||
log.Info("generating winning post candidates")
|
||||
fcandidates, err := ffiwrapper.ProofVerifier.GenerateWinningPoStSectorChallenge(context.TODO(), spt, mid, challenge[:], uint64(len(sealedSectors)))
|
||||
wipt, err := spt.RegisteredWinningPoStProof()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fcandidates, err := ffiwrapper.ProofVerifier.GenerateWinningPoStSectorChallenge(context.TODO(), wipt, mid, challenge[:], uint64(len(sealedSectors)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -339,7 +350,7 @@ var sealBenchCmd = &cli.Command{
|
||||
verifyWinningPost2 := time.Now()
|
||||
|
||||
log.Info("computing window post snark (cold)")
|
||||
wproof1, err := sb.GenerateWindowPoSt(context.TODO(), mid, sealedSectors, challenge[:])
|
||||
wproof1, _, err := sb.GenerateWindowPoSt(context.TODO(), mid, sealedSectors, challenge[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -347,7 +358,7 @@ var sealBenchCmd = &cli.Command{
|
||||
windowpost1 := time.Now()
|
||||
|
||||
log.Info("computing window post snark (hot)")
|
||||
wproof2, err := sb.GenerateWindowPoSt(context.TODO(), mid, sealedSectors, challenge[:])
|
||||
wproof2, _, err := sb.GenerateWindowPoSt(context.TODO(), mid, sealedSectors, challenge[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -406,7 +417,7 @@ var sealBenchCmd = &cli.Command{
|
||||
|
||||
fmt.Println(string(data))
|
||||
} else {
|
||||
fmt.Printf("----\nresults (v26) (%d)\n", sectorSize)
|
||||
fmt.Printf("----\nresults (v27) (%d)\n", sectorSize)
|
||||
if robench == "" {
|
||||
fmt.Printf("seal: addPiece: %s (%s)\n", bo.SealingResults[0].AddPiece, bps(bo.SectorSize, bo.SealingResults[0].AddPiece)) // TODO: average across multiple sealings
|
||||
fmt.Printf("seal: preCommit phase 1: %s (%s)\n", bo.SealingResults[0].PreCommit1, bps(bo.SectorSize, bo.SealingResults[0].PreCommit1))
|
||||
@ -479,7 +490,7 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, mid
|
||||
precommit2 := time.Now()
|
||||
|
||||
sealedSectors = append(sealedSectors, abi.SectorInfo{
|
||||
RegisteredProof: sb.SealProofType(),
|
||||
SealProof: sb.SealProofType(),
|
||||
SectorNumber: i,
|
||||
SealedCID: cids.Sealed,
|
||||
})
|
||||
@ -530,7 +541,7 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, mid
|
||||
svi := abi.SealVerifyInfo{
|
||||
SectorID: abi.SectorID{Miner: mid, Number: i},
|
||||
SealedCID: cids.Sealed,
|
||||
RegisteredProof: sb.SealProofType(),
|
||||
SealProof: sb.SealProofType(),
|
||||
Proof: proof,
|
||||
DealIDs: nil,
|
||||
Randomness: ticket,
|
||||
@ -563,15 +574,10 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, mid
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: RM unsealed sector first
|
||||
rc, err := sb.ReadPieceFromSealedSector(context.TODO(), abi.SectorID{Miner: mid, Number: 1}, 0, abi.UnpaddedPieceSize(sectorSize), ticket, cids.Unsealed)
|
||||
err := sb.UnsealPiece(context.TODO(), abi.SectorID{Miner: mid, Number: 1}, 0, abi.PaddedPieceSize(sectorSize).Unpadded(), ticket, cids.Unsealed)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if err := rc.Close(); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
unseal := time.Now()
|
||||
|
||||
@ -597,10 +603,18 @@ var proveCmd = &cli.Command{
|
||||
Name: "no-gpu",
|
||||
Usage: "disable gpu usage for the benchmark run",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "miner-addr",
|
||||
Usage: "pass miner address (only necessary if using existing sectorbuilder)",
|
||||
Value: "t01000",
|
||||
},
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
if c.Bool("no-gpu") {
|
||||
os.Setenv("BELLMAN_NO_GPU", "1")
|
||||
err := os.Setenv("BELLMAN_NO_GPU", "1")
|
||||
if err != nil {
|
||||
return xerrors.Errorf("setting no-gpu flag: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if !c.Args().Present() {
|
||||
@ -617,7 +631,7 @@ var proveCmd = &cli.Command{
|
||||
return xerrors.Errorf("unmarshalling input file: %w", err)
|
||||
}
|
||||
|
||||
if err := paramfetch.GetParams(lcli.ReqContext(c), build.ParametersJson(), c2in.SectorSize); err != nil {
|
||||
if err := paramfetch.GetParams(lcli.ReqContext(c), build.ParametersJSON(), c2in.SectorSize); err != nil {
|
||||
return xerrors.Errorf("getting params: %w", err)
|
||||
}
|
||||
|
||||
@ -655,7 +669,7 @@ var proveCmd = &cli.Command{
|
||||
|
||||
fmt.Printf("proof: %x\n", proof)
|
||||
|
||||
fmt.Printf("----\nresults (v23) (%d)\n", c2in.SectorSize)
|
||||
fmt.Printf("----\nresults (v27) (%d)\n", c2in.SectorSize)
|
||||
dur := sealCommit2.Sub(start)
|
||||
|
||||
fmt.Printf("seal: commit phase 2: %s (%s)\n", dur, bps(abi.SectorSize(c2in.SectorSize), dur))
|
||||
|
@ -21,7 +21,7 @@ func subBlocks(ctx context.Context, api aapi.FullNode, st *storage) {
|
||||
bh.Cid(): bh,
|
||||
}, false)
|
||||
if err != nil {
|
||||
//log.Errorf("%+v", err)
|
||||
log.Errorf("%+v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var dotCmd = &cli.Command{
|
||||
@ -20,7 +20,13 @@ var dotCmd = &cli.Command{
|
||||
}
|
||||
|
||||
minH, err := strconv.ParseInt(cctx.Args().Get(0), 10, 32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tosee, err := strconv.ParseInt(cctx.Args().Get(1), 10, 32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
maxH := minH + tosee
|
||||
|
||||
res, err := st.db.Query(`select block, parent, b.miner, b.height, p.height from block_parents
|
||||
|
@ -7,8 +7,8 @@ import (
|
||||
"os"
|
||||
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
lcli "github.com/filecoin-project/lotus/cli"
|
||||
@ -17,7 +17,7 @@ import (
|
||||
var log = logging.Logger("chainwatch")
|
||||
|
||||
func main() {
|
||||
logging.SetLogLevel("*", "INFO")
|
||||
_ = logging.SetLogLevel("*", "INFO")
|
||||
|
||||
log.Info("Starting chainwatch")
|
||||
|
||||
@ -29,7 +29,7 @@ func main() {
|
||||
app := &cli.App{
|
||||
Name: "lotus-chainwatch",
|
||||
Usage: "Devnet token distribution utility",
|
||||
Version: build.UserVersion,
|
||||
Version: build.UserVersion(),
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "repo",
|
||||
@ -86,7 +86,7 @@ var runCmd = &cli.Command{
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer st.close()
|
||||
defer st.close() //nolint:errcheck
|
||||
|
||||
runSyncer(ctx, api, st, maxBatch)
|
||||
|
||||
|
@ -20,6 +20,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
parmap "github.com/filecoin-project/lotus/lib/parmap"
|
||||
)
|
||||
|
||||
func runSyncer(ctx context.Context, api api.FullNode, st *storage, maxBatch int) {
|
||||
@ -138,21 +139,21 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS
|
||||
log.Infof("Syncing %d blocks", len(toSync))
|
||||
|
||||
paDone := 0
|
||||
par(50, maparr(toSync), func(bh *types.BlockHeader) {
|
||||
parmap.Par(50, parmap.MapArr(toSync), func(bh *types.BlockHeader) {
|
||||
paDone++
|
||||
if paDone%100 == 0 {
|
||||
log.Infof("pa: %d %d%%", paDone, (paDone*100)/len(toSync))
|
||||
}
|
||||
|
||||
if len(bh.Parents) == 0 { // genesis case
|
||||
ts, err := types.NewTipSet([]*types.BlockHeader{bh})
|
||||
ts, _ := types.NewTipSet([]*types.BlockHeader{bh})
|
||||
aadrs, err := api.StateListActors(ctx, ts.Key())
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
par(50, aadrs, func(addr address.Address) {
|
||||
parmap.Par(50, aadrs, func(addr address.Address) {
|
||||
act, err := api.StateGetActor(ctx, addr, ts.Key())
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
@ -198,6 +199,8 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS
|
||||
}
|
||||
|
||||
for a, act := range changes {
|
||||
act := act
|
||||
|
||||
addr, err := address.NewFromString(a)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
@ -239,7 +242,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS
|
||||
addresses[message.From] = address.Undef
|
||||
}
|
||||
|
||||
par(50, kmaparr(addresses), func(addr address.Address) {
|
||||
parmap.Par(50, parmap.KMapArr(addresses), func(addr address.Address) {
|
||||
raddr, err := api.StateLookupID(ctx, addr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
log.Warn(err)
|
||||
@ -268,7 +271,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS
|
||||
}
|
||||
}
|
||||
|
||||
par(50, kvmaparr(miners), func(it func() (minerKey, *minerInfo)) {
|
||||
parmap.Par(50, parmap.KVMapArr(miners), func(it func() (minerKey, *minerInfo)) {
|
||||
k, info := it()
|
||||
|
||||
pow, err := api.StateMinerPower(ctx, k.addr, types.EmptyTSK)
|
||||
@ -386,7 +389,7 @@ func fetchMessages(ctx context.Context, api api.FullNode, toSync map[cid.Cid]*ty
|
||||
messages := map[cid.Cid]*types.Message{}
|
||||
inclusions := map[cid.Cid][]cid.Cid{} // block -> msgs
|
||||
|
||||
par(50, maparr(toSync), func(header *types.BlockHeader) {
|
||||
parmap.Par(50, parmap.MapArr(toSync), func(header *types.BlockHeader) {
|
||||
msgs, err := api.ChainGetBlockMessages(ctx, header.Cid())
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
@ -423,7 +426,7 @@ func fetchParentReceipts(ctx context.Context, api api.FullNode, toSync map[cid.C
|
||||
var lk sync.Mutex
|
||||
out := map[mrec]*types.MessageReceipt{}
|
||||
|
||||
par(50, maparr(toSync), func(header *types.BlockHeader) {
|
||||
parmap.Par(50, parmap.MapArr(toSync), func(header *types.BlockHeader) {
|
||||
recs, err := api.ChainGetParentReceipts(ctx, header.Cid())
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
|
@ -14,8 +14,8 @@ import (
|
||||
"github.com/ipfs/go-cid"
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
|
||||
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||
@ -46,7 +46,7 @@ func main() {
|
||||
app := &cli.App{
|
||||
Name: "lotus-fountain",
|
||||
Usage: "Devnet token distribution utility",
|
||||
Version: build.UserVersion,
|
||||
Version: build.UserVersion(),
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "repo",
|
||||
@ -157,7 +157,7 @@ func (h *handler) send(w http.ResponseWriter, r *http.Request) {
|
||||
to, err := address.NewFromString(r.FormValue("address"))
|
||||
if err != nil {
|
||||
w.WriteHeader(400)
|
||||
w.Write([]byte(err.Error()))
|
||||
_, _ = w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
@ -204,25 +204,25 @@ func (h *handler) send(w http.ResponseWriter, r *http.Request) {
|
||||
})
|
||||
if err != nil {
|
||||
w.WriteHeader(400)
|
||||
w.Write([]byte(err.Error()))
|
||||
_, _ = w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
w.Write([]byte(smsg.Cid().String()))
|
||||
_, _ = w.Write([]byte(smsg.Cid().String()))
|
||||
}
|
||||
|
||||
func (h *handler) mkminer(w http.ResponseWriter, r *http.Request) {
|
||||
owner, err := address.NewFromString(r.FormValue("address"))
|
||||
if err != nil {
|
||||
w.WriteHeader(400)
|
||||
w.Write([]byte(err.Error()))
|
||||
_, _ = w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if owner.Protocol() != address.BLS {
|
||||
w.WriteHeader(400)
|
||||
w.Write([]byte("Miner address must use BLS. A BLS address starts with the prefix 't3'."))
|
||||
w.Write([]byte("Please create a BLS address by running \"lotus wallet new bls\" while connected to a Lotus node."))
|
||||
_, _ = w.Write([]byte("Miner address must use BLS. A BLS address starts with the prefix 't3'."))
|
||||
_, _ = w.Write([]byte("Please create a BLS address by running \"lotus wallet new bls\" while connected to a Lotus node."))
|
||||
return
|
||||
}
|
||||
|
||||
@ -294,7 +294,7 @@ func (h *handler) mkminer(w http.ResponseWriter, r *http.Request) {
|
||||
Owner: owner,
|
||||
Worker: owner,
|
||||
SealProofType: spt,
|
||||
Peer: h.defaultMinerPeer,
|
||||
Peer: abi.PeerID(h.defaultMinerPeer),
|
||||
})
|
||||
if err != nil {
|
||||
w.WriteHeader(400)
|
||||
@ -334,7 +334,7 @@ func (h *handler) msgwait(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
mw, err := h.api.StateWaitMsg(r.Context(), c)
|
||||
mw, err := h.api.StateWaitMsg(r.Context(), c, build.MessageConfidence)
|
||||
if err != nil {
|
||||
w.WriteHeader(400)
|
||||
w.Write([]byte(err.Error()))
|
||||
@ -357,7 +357,7 @@ func (h *handler) msgwaitaddr(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
mw, err := h.api.StateWaitMsg(r.Context(), c)
|
||||
mw, err := h.api.StateWaitMsg(r.Context(), c, build.MessageConfidence)
|
||||
if err != nil {
|
||||
w.WriteHeader(400)
|
||||
w.Write([]byte(err.Error()))
|
||||
|
@ -10,7 +10,7 @@ import (
|
||||
|
||||
cid "github.com/ipfs/go-cid"
|
||||
logging "github.com/ipfs/go-log"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
"github.com/filecoin-project/go-jsonrpc"
|
||||
|
||||
@ -36,7 +36,7 @@ func main() {
|
||||
app := &cli.App{
|
||||
Name: "lotus-health",
|
||||
Usage: "Tools for monitoring lotus daemon health",
|
||||
Version: build.UserVersion,
|
||||
Version: build.UserVersion(),
|
||||
Commands: local,
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
@ -79,7 +79,7 @@ var watchHeadCmd = &cli.Command{
|
||||
&cli.IntFlag{
|
||||
Name: "api-retries",
|
||||
Value: 8,
|
||||
Usage: "number of API retry attemps",
|
||||
Usage: "number of API retry attempts",
|
||||
},
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
|
@ -3,17 +3,20 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/gorilla/mux"
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
|
||||
"github.com/filecoin-project/go-jsonrpc"
|
||||
"github.com/filecoin-project/go-jsonrpc/auth"
|
||||
@ -47,7 +50,7 @@ func main() {
|
||||
app := &cli.App{
|
||||
Name: "lotus-seal-worker",
|
||||
Usage: "Remote storage miner worker",
|
||||
Version: build.UserVersion,
|
||||
Version: build.UserVersion(),
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: FlagStorageRepo,
|
||||
@ -107,7 +110,9 @@ var runCmd = &cli.Command{
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
if !cctx.Bool("enable-gpu-proving") {
|
||||
os.Setenv("BELLMAN_NO_GPU", "true")
|
||||
if err := os.Setenv("BELLMAN_NO_GPU", "true"); err != nil {
|
||||
return xerrors.Errorf("could not set no-gpu env: %+v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if cctx.String("address") == "" {
|
||||
@ -115,11 +120,19 @@ var runCmd = &cli.Command{
|
||||
}
|
||||
|
||||
// Connect to storage-miner
|
||||
|
||||
nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting miner api: %w", err)
|
||||
var nodeApi api.StorageMiner
|
||||
var closer func()
|
||||
var err error
|
||||
for {
|
||||
nodeApi, closer, err = lcli.GetStorageMinerAPI(cctx)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
fmt.Printf("\r\x1b[0KConnecting to miner API... (%s)", err)
|
||||
time.Sleep(time.Second)
|
||||
continue
|
||||
}
|
||||
|
||||
defer closer()
|
||||
ctx := lcli.ReqContext(cctx)
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
@ -134,6 +147,8 @@ var runCmd = &cli.Command{
|
||||
}
|
||||
log.Infof("Remote version %s", v)
|
||||
|
||||
watchMinerConn(ctx, cctx, nodeApi)
|
||||
|
||||
// Check params
|
||||
|
||||
act, err := nodeApi.ActorAddress(ctx)
|
||||
@ -146,14 +161,14 @@ var runCmd = &cli.Command{
|
||||
}
|
||||
|
||||
if cctx.Bool("commit") {
|
||||
if err := paramfetch.GetParams(ctx, build.ParametersJson(), uint64(ssize)); err != nil {
|
||||
if err := paramfetch.GetParams(ctx, build.ParametersJSON(), uint64(ssize)); err != nil {
|
||||
return xerrors.Errorf("get params: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
var taskTypes []sealtasks.TaskType
|
||||
|
||||
taskTypes = append(taskTypes, sealtasks.TTFetch)
|
||||
taskTypes = append(taskTypes, sealtasks.TTFetch, sealtasks.TTCommit1, sealtasks.TTFinalize)
|
||||
|
||||
if cctx.Bool("precommit1") {
|
||||
taskTypes = append(taskTypes, sealtasks.TTPreCommit1)
|
||||
@ -315,3 +330,42 @@ var runCmd = &cli.Command{
|
||||
return srv.Serve(nl)
|
||||
},
|
||||
}
|
||||
|
||||
func watchMinerConn(ctx context.Context, cctx *cli.Context, nodeApi api.StorageMiner) {
|
||||
go func() {
|
||||
closing, err := nodeApi.Closing(ctx)
|
||||
if err != nil {
|
||||
log.Errorf("failed to get remote closing channel: %+v", err)
|
||||
}
|
||||
|
||||
select {
|
||||
case <-closing:
|
||||
case <-ctx.Done():
|
||||
}
|
||||
|
||||
if ctx.Err() != nil {
|
||||
return // graceful shutdown
|
||||
}
|
||||
|
||||
log.Warnf("Connection with miner node lost, restarting")
|
||||
|
||||
exe, err := os.Executable()
|
||||
if err != nil {
|
||||
log.Errorf("getting executable for auto-restart: %+v", err)
|
||||
}
|
||||
|
||||
log.Sync()
|
||||
|
||||
// TODO: there are probably cleaner/more graceful ways to restart,
|
||||
// but this is good enough for now (FSM can recover from the mess this creates)
|
||||
if err := syscall.Exec(exe, []string{exe, "run",
|
||||
fmt.Sprintf("--address=%s", cctx.String("address")),
|
||||
fmt.Sprintf("--no-local-storage=%t", cctx.Bool("no-local-storage")),
|
||||
fmt.Sprintf("--precommit1=%t", cctx.Bool("precommit1")),
|
||||
fmt.Sprintf("--precommit2=%t", cctx.Bool("precommit2")),
|
||||
fmt.Sprintf("--commit=%t", cctx.Bool("commit")),
|
||||
}, os.Environ()); err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
@ -6,8 +6,8 @@ import (
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/mitchellh/go-homedir"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
||||
|
@ -12,7 +12,7 @@ import (
|
||||
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
"github.com/mitchellh/go-homedir"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||
@ -39,7 +39,7 @@ func main() {
|
||||
app := &cli.App{
|
||||
Name: "lotus-seed",
|
||||
Usage: "Seal sectors for genesis miner",
|
||||
Version: build.UserVersion,
|
||||
Version: build.UserVersion(),
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "sector-dir",
|
||||
@ -145,7 +145,6 @@ var aggregateManifestsCmd = &cli.Command{
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fi.Close()
|
||||
var val map[string]genesis.Miner
|
||||
if err := json.NewDecoder(fi).Decode(&val); err != nil {
|
||||
return err
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/minio/blake2b-simd"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@ -15,6 +14,7 @@ import (
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
ic "github.com/libp2p/go-libp2p-core/crypto"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
"github.com/minio/blake2b-simd"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
@ -33,12 +33,7 @@ import (
|
||||
|
||||
var log = logging.Logger("preseal")
|
||||
|
||||
func PreSeal(maddr address.Address, pt abi.RegisteredProof, offset abi.SectorNumber, sectors int, sbroot string, preimage []byte, key *types.KeyInfo) (*genesis.Miner, *types.KeyInfo, error) {
|
||||
spt, err := pt.RegisteredSealProof()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
func PreSeal(maddr address.Address, spt abi.RegisteredSealProof, offset abi.SectorNumber, sectors int, sbroot string, preimage []byte, key *types.KeyInfo) (*genesis.Miner, *types.KeyInfo, error) {
|
||||
mid, err := address.IDFromAddress(maddr)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@ -48,7 +43,7 @@ func PreSeal(maddr address.Address, pt abi.RegisteredProof, offset abi.SectorNum
|
||||
SealProofType: spt,
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(sbroot, 0775); err != nil {
|
||||
if err := os.MkdirAll(sbroot, 0775); err != nil { //nolint:gosec
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
@ -63,7 +58,7 @@ func PreSeal(maddr address.Address, pt abi.RegisteredProof, offset abi.SectorNum
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ssize, err := pt.SectorSize()
|
||||
ssize, err := spt.SectorSize()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@ -97,12 +92,16 @@ func PreSeal(maddr address.Address, pt abi.RegisteredProof, offset abi.SectorNum
|
||||
return nil, nil, xerrors.Errorf("trim cache: %w", err)
|
||||
}
|
||||
|
||||
if err := cleanupUnsealed(sbfs, sid); err != nil {
|
||||
return nil, nil, xerrors.Errorf("remove unsealed file: %w", err)
|
||||
}
|
||||
|
||||
log.Warn("PreCommitOutput: ", sid, cids.Sealed, cids.Unsealed)
|
||||
sealedSectors = append(sealedSectors, &genesis.PreSeal{
|
||||
CommR: cids.Sealed,
|
||||
CommD: cids.Unsealed,
|
||||
SectorID: sid.Number,
|
||||
ProofType: pt,
|
||||
ProofType: spt,
|
||||
})
|
||||
}
|
||||
|
||||
@ -166,6 +165,16 @@ func PreSeal(maddr address.Address, pt abi.RegisteredProof, offset abi.SectorNum
|
||||
return miner, &minerAddr.KeyInfo, nil
|
||||
}
|
||||
|
||||
func cleanupUnsealed(sbfs *basicfs.Provider, sid abi.SectorID) error {
|
||||
paths, done, err := sbfs.AcquireSector(context.TODO(), sid, stores.FTUnsealed, stores.FTNone, stores.PathSealing)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer done()
|
||||
|
||||
return os.Remove(paths.Unsealed)
|
||||
}
|
||||
|
||||
func WriteGenesisMiner(maddr address.Address, sbroot string, gm *genesis.Miner, key *types.KeyInfo) error {
|
||||
output := map[string]genesis.Miner{
|
||||
maddr.String(): *gm,
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var base16Cmd = &cli.Command{
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
"github.com/multiformats/go-base32"
|
||||
)
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var bigIntParseCmd = &cli.Command{
|
||||
|
@ -7,8 +7,8 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
|
||||
"github.com/filecoin-project/go-bitfield"
|
||||
rlepluslazy "github.com/filecoin-project/go-bitfield/rle"
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user