Merge pull request #1842 from filecoin-project/next

Next network staging
This commit is contained in:
Łukasz Magiera 2020-06-17 20:58:21 +02:00 committed by GitHub
commit fe4efa0e0e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
190 changed files with 3675 additions and 2233 deletions

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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
}

View File

@ -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)
}

View File

@ -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

View File

@ -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{}

View File

@ -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{}{

View File

@ -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)

View File

@ -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 {

View File

@ -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

View File

@ -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
View 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
}

View File

@ -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
}

View File

@ -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)
}

View File

@ -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")
}

View File

@ -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

View File

@ -4,6 +4,7 @@ package build
func init() {
InsecurePoStValidation = true
BuildType |= BuildDebug
}
// NOTE: Also includes settings from params_2k

View File

@ -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"}`

View File

@ -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: {},
}
}

View File

@ -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
}
}

View File

@ -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

View File

@ -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{

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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

View File

@ -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) {

View File

@ -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{},
},
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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{

View File

@ -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

View File

@ -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")
}

View File

@ -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)

View File

@ -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,

View File

@ -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 {

View File

@ -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

View File

@ -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())

View File

@ -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

View File

@ -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)

View File

@ -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()

View File

@ -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
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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")

View File

@ -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")
}

View File

@ -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)

View File

@ -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
}

View File

@ -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) {

View File

@ -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)
}

View File

@ -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) {

View File

@ -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)
}

View File

@ -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,

View File

@ -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))

View File

@ -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
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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 {

View File

@ -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)

View File

@ -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 {

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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)
}

View File

@ -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"

View File

@ -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"

View File

@ -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 {

View File

@ -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)

View File

@ -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"

View File

@ -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{

View File

@ -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"

View File

@ -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
}

View File

@ -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

View File

@ -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)
}

View File

@ -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
},

View File

@ -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{

View File

@ -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> -&gt; <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> -&gt; <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> -&gt; <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
}

View File

@ -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"

View File

@ -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
},

View File

@ -4,7 +4,7 @@ import (
"fmt"
"time"
"gopkg.in/urfave/cli.v2"
"github.com/urfave/cli/v2"
)
var waitApiCmd = &cli.Command{

View File

@ -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{

View File

@ -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)
},
}

View File

@ -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
})

View File

@ -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))

View File

@ -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)
}
}
}

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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()))

View File

@ -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 {

View File

@ -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)
}
}()
}

View File

@ -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"

View File

@ -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

View File

@ -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,

View File

@ -8,7 +8,7 @@ import (
"os"
"strings"
"gopkg.in/urfave/cli.v2"
"github.com/urfave/cli/v2"
)
var base16Cmd = &cli.Command{

View File

@ -7,7 +7,7 @@ import (
"os"
"strings"
"gopkg.in/urfave/cli.v2"
"github.com/urfave/cli/v2"
"github.com/multiformats/go-base32"
)

View File

@ -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{

View File

@ -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