Compare commits

..
21 Commits
Author SHA1 Message Date
Łukasz Magiera 7d166fd730 Merge pull request #1908 from filecoin-project/docs/cpu-choice
add a doc on amd vs intel cpus
2020-06-05 01:21:50 +02:00
Łukasz Magiera bada564c10 Merge pull request #1912 from filecoin-project/asr/statesearch
search for a message should stop if we reach sender nonce of 0
2020-06-04 23:42:16 +02:00
vyzo 6beabb5e8a Merge pull request #1914 from filecoin-project/feat/update-pubsub
update libp2p dependencies
2020-06-04 22:50:48 +03:00
vyzo 3719938849 gomod: update go-maddr-filter 2020-06-04 22:35:33 +03:00
vyzo 6420990007 gomod: update go-libp2p-quic-transport 2020-06-04 22:34:07 +03:00
vyzo 1fab24b9bc gomod: update go-libp2p-kad-dht 2020-06-04 22:32:11 +03:00
vyzo b339750757 gomod: update go-libp2p-yamux 2020-06-04 21:34:01 +03:00
vyzo 954a20ff4c gomod: update go-libp2p to v0.9.4 2020-06-04 14:25:17 +03:00
vyzo 8057b994cf go.mod: remove unecessary (and harmful) replace directive for go-systemd 2020-06-04 14:23:59 +03:00
vyzo f210a6e91a pubsub: set Dout parameter to 3 (from the default of 2)
we are using a higher D value than the default, so this can be safely increased.
2020-06-04 00:03:31 +03:00
vyzo aded0706be gomod: update go-libp2p@v0.9.3 and go-libp2p-pubsub@v0.3.2 2020-06-04 00:02:54 +03:00
Aayush Rajasekaran 4b01b666f6 Bugfix: searchback for a message should stop if we reach sender nonce of 0 2020-06-03 14:08:05 -04:00
Łukasz Magiera 35740895ed Merge pull request #1899 from filecoin-project/feat/1827-lotus-daemon-stop-cmd
add (sub)commands which shut down lotus daemon and storage miner
2020-06-03 19:15:20 +02:00
Jeromy a8915f0331 add a doc on amd vs intel cpus 2020-06-03 08:45:53 -07:00
laser 46a016cdce name change, for consistency 2020-06-02 12:38:21 -07:00
laser bea9cd2fe2 rename to better convey intent + document 2020-06-02 12:35:11 -07:00
laser ee9d9a52a9 first take at a "lotus-storage-miner stop" command
Fixes #1827
2020-06-02 12:31:21 -07:00
laser 1e8a875edb shutdownChan instead of shutdownCh, for consistency 2020-06-02 12:31:01 -07:00
laser 36a93c90eb use a real ellipsis, kinda 2020-06-02 12:30:45 -07:00
laser 38d714a28a first take at "daemon stop" command
Fixes #1827

TODO: plumb the daemon-stopping into lotus-storage-miner, too
2020-06-02 12:29:58 -07:00
laser 5e727819ad stub the "daemon stop" command 2020-06-02 08:09:18 -07:00
147 changed files with 1892 additions and 1659 deletions
+30 -16
View File
@@ -1,6 +1,6 @@
version: 2.1
orbs:
go: gotest/tools@0.0.13
go: gotest/tools@0.0.9
executors:
golang:
@@ -79,6 +79,7 @@ jobs:
steps:
- install-deps
- prepare
- go/mod-download
- go/mod-tidy-check
build-all:
@@ -86,8 +87,12 @@ 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:
@@ -107,6 +112,10 @@ 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
@@ -125,9 +134,6 @@ 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
@@ -150,6 +156,10 @@ 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
@@ -161,7 +171,6 @@ 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 -- \
@@ -180,11 +189,16 @@ 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
@@ -214,9 +228,10 @@ 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 cargo cache
name: restore go mod and 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
@@ -243,6 +258,7 @@ jobs:
steps:
- install-deps
- prepare
- go/mod-download
- run:
command: "! go fmt ./... 2>&1 | read"
@@ -255,7 +271,7 @@ jobs:
default: golang
golangci-lint-version:
type: string
default: 1.27.0
default: 1.23.8
concurrency:
type: string
default: '2'
@@ -271,6 +287,7 @@ jobs:
steps:
- install-deps
- prepare
- go/mod-download
- run:
command: make deps
no_output_timeout: 30m
@@ -280,7 +297,7 @@ jobs:
- run:
name: Lint
command: |
$HOME/.local/bin/golangci-lint run -v --timeout 2m \
$HOME/.local/bin/golangci-lint run -v \
--concurrency << parameters.concurrency >> << parameters.args >>
lint-changes:
<<: *lint
@@ -314,14 +331,11 @@ workflows:
ci:
jobs:
- lint-changes:
args: "--new-from-rev origin/next"
- mod-tidy-check
- gofmt
args: "--new-from-rev origin/master"
- test:
codecov-upload: true
- test-window-post:
go-test-flags: "-run=TestWindowedPost"
winpost-test: "1"
- mod-tidy-check
- gofmt
- test-short:
go-test-flags: "--timeout 10m --short"
filters:
+1 -15
View File
@@ -22,27 +22,13 @@ 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: build/params_.*\.go
linters:
- golint
- path: api/apistruct/struct.go
linters:
- golint
- path: .*_test.go
- path: ".*_test.go"
linters:
- gosec
+2 -2
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: 2k
pond: build
go build -o pond ./lotuspond
(cd lotuspond/front && npm i && CI=false npm run build)
.PHONY: pond
+3 -1
View File
@@ -25,7 +25,6 @@ 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)
@@ -35,6 +34,9 @@ type Common interface {
LogList(context.Context) ([]string, error)
LogSetLevel(context.Context, string, string) error
// trigger graceful shutdown
Shutdown(context.Context) error
}
// Version provides various build-time information
+1 -2
View File
@@ -154,9 +154,8 @@ 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(ctx context.Context, cid cid.Cid, confidence uint64) (*MsgLookup, error)
StateWaitMsg(context.Context, cid.Cid) (*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)
+2 -1
View File
@@ -8,10 +8,11 @@ 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
+2 -9
View File
@@ -2,9 +2,6 @@ package api
import (
"context"
"io"
"github.com/ipfs/go-cid"
"github.com/filecoin-project/sector-storage/sealtasks"
"github.com/filecoin-project/sector-storage/stores"
@@ -15,7 +12,7 @@ import (
"github.com/filecoin-project/lotus/build"
)
type WorkerAPI interface {
type WorkerApi interface {
Version(context.Context) (build.Version, error)
// TODO: Info() (name, ...) ?
@@ -24,11 +21,7 @@ type WorkerAPI interface {
Info(context.Context) (storiface.WorkerInfo, error)
storage.Sealer
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, bool, stores.AcquireMode) error
Fetch(context.Context, abi.SectorID, stores.SectorFileType, bool) error
Closing(context.Context) (<-chan struct{}, error)
}
+1 -1
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
+28 -43
View File
@@ -2,7 +2,6 @@ package apistruct
import (
"context"
"io"
"github.com/ipfs/go-cid"
"github.com/libp2p/go-libp2p-core/network"
@@ -42,13 +41,14 @@ 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"`
LogList func(context.Context) ([]string, error) `perm:"write"`
LogSetLevel func(context.Context, string, string) error `perm:"write"`
Shutdown func(context.Context) error `perm:"admin"`
}
}
@@ -130,13 +130,12 @@ 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(ctx context.Context, cid cid.Cid, confidence uint64) (*api.MsgLookup, error) `perm:"read"`
StateWaitMsg func(context.Context, cid.Cid) (*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"`
@@ -204,16 +203,16 @@ type StorageMinerStruct struct {
WorkerConnect func(context.Context, string) error `perm:"admin"` // TODO: worker perm
WorkerStats func(context.Context) (map[uint64]storiface.WorkerStats, error) `perm:"admin"`
StorageList func(context.Context) (map[stores.ID][]stores.Decl, error) `perm:"admin"`
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, 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.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 stores.PathType) ([]stores.StorageInfo, error) `perm:"admin"`
StorageReportHealth func(ctx context.Context, id stores.ID, report stores.HealthReport) error `perm:"admin"`
StorageList func(context.Context) (map[stores.ID][]stores.Decl, error) `perm:"admin"`
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"`
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"`
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"`
StorageReportHealth func(ctx context.Context, id stores.ID, report stores.HealthReport) 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"`
@@ -238,10 +237,7 @@ type WorkerStruct struct {
SealCommit2 func(context.Context, abi.SectorID, storage.Commit1Out) (storage.Proof, error) `perm:"admin"`
FinalizeSector func(context.Context, abi.SectorID) 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, bool, stores.AcquireMode) error `perm:"admin"`
Fetch func(context.Context, abi.SectorID, stores.SectorFileType, bool) error `perm:"admin"`
Closing func(context.Context) (<-chan struct{}, error) `perm:"admin"`
}
@@ -257,9 +253,6 @@ 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)
}
@@ -302,6 +295,10 @@ func (c *CommonStruct) LogSetLevel(ctx context.Context, group, level string) err
return c.Internal.LogSetLevel(ctx, group, level)
}
func (c *CommonStruct) Shutdown(ctx context.Context) error {
return c.Internal.Shutdown(ctx)
}
// FullNodeStruct
func (c *FullNodeStruct) ClientListImports(ctx context.Context) ([]api.Import, error) {
@@ -570,10 +567,6 @@ 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)
}
@@ -594,8 +587,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, confidence uint64) (*api.MsgLookup, error) {
return c.Internal.StateWaitMsg(ctx, msgc, confidence)
func (c *FullNodeStruct) StateWaitMsg(ctx context.Context, msgc cid.Cid) (*api.MsgLookup, error) {
return c.Internal.StateWaitMsg(ctx, msgc)
}
func (c *FullNodeStruct) StateSearchMsg(ctx context.Context, msgc cid.Cid) (*api.MsgLookup, error) {
@@ -770,15 +763,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, primary bool) error {
return c.Internal.StorageDeclareSector(ctx, storageId, s, ft, primary)
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) 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.SectorStorageInfo, error) {
func (c *StorageMinerStruct) StorageFindSector(ctx context.Context, si abi.SectorID, types stores.SectorFileType, allowFetch bool) ([]stores.StorageInfo, error) {
return c.Internal.StorageFindSector(ctx, si, types, allowFetch)
}
@@ -798,8 +791,8 @@ 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, pt stores.PathType) ([]stores.StorageInfo, error) {
return c.Internal.StorageBestAlloc(ctx, allocate, spt, pt)
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) StorageReportHealth(ctx context.Context, id stores.ID, report stores.HealthReport) error {
@@ -872,16 +865,8 @@ func (w *WorkerStruct) FinalizeSector(ctx context.Context, sector abi.SectorID)
return w.Internal.FinalizeSector(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, b bool, am stores.AcquireMode) error {
return w.Internal.Fetch(ctx, id, fileType, b, am)
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) Closing(ctx context.Context) (<-chan struct{}, error) {
@@ -891,4 +876,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{}
+1 -1
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{}{
+2 -2
View File
@@ -193,7 +193,8 @@ 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) { //nolint:golint
func parseApiASTInfo() (map[string]string, map[string]string) {
fset := token.NewFileSet()
pkgs, err := parser.ParseDir(fset, "./api", nil, parser.AllErrors|parser.ParseComments)
if err != nil {
@@ -319,7 +320,6 @@ func main() {
})
for _, g := range groupslice {
g := g
fmt.Printf("## %s\n", g.GroupName)
fmt.Printf("%s\n\n", g.Header)
+3 -3
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) //nolint:errcheck
defer os.RemoveAll(rpath)
caddr, err := client.WalletDefaultAddress(ctx)
if err != nil {
+1 -1
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
+4 -6
View File
@@ -4,11 +4,9 @@ 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 {
@@ -23,8 +21,6 @@ type TestStorageNode struct {
var PresealGenesis = -1
const GenesisPreseals = 2
type StorageMiner struct {
Full int
Preseal int
@@ -64,7 +60,9 @@ func (ts *testSuite) testVersion(t *testing.T) {
if err != nil {
t.Fatal(err)
}
require.Equal(t, v.Version, build.BuildVersion)
if v.Version != build.BuildVersion {
t.Error("Version didn't work properly")
}
}
func (ts *testSuite) testID(t *testing.T) {
-169
View File
@@ -1,169 +0,0 @@
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
}
-7
View File
@@ -3,12 +3,10 @@ package api
import (
"encoding/json"
"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) {
@@ -34,8 +32,3 @@ type ObjStat struct {
Size uint64
Links uint64
}
type PubsubScore struct {
ID peer.ID
Score float64
}
+1 -1
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")
}
-2
View File
@@ -16,8 +16,6 @@ func init() {
abi.RegisteredProof_StackedDRG2KiBSeal: {},
}
verifreg.MinVerifiedDealSize = big.NewInt(256)
BuildType |= Build2k
}
// Seconds
-1
View File
@@ -4,7 +4,6 @@ package build
func init() {
InsecurePoStValidation = true
BuildType |= BuildDebug
}
// NOTE: Also includes settings from params_2k
+7 -3
View File
@@ -59,7 +59,6 @@ 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
@@ -119,6 +118,11 @@ const VerifSigCacheSize = 32000
// TODO: If this is gonna stay, it should move to specs-actors
const BlockMessageLimit = 512
const BlockGasLimit = 100_000_000_000
const BlockGasLimit = 100_000_000
var DrandChain = `{"public_key":"922a2e93828ff83345bae533f5172669a26c02dc76d6bf59c80892e12ab1455c229211886f35bb56af6d5bea981024df","period":25,"genesis_time":1590445175,"hash":"138a324aa6540f93d0dad002aa89454b1bec2b6e948682cde6bd4db40f4b7c9b"}`
var DrandCoeffs = []string{
"82c279cce744450e68de98ee08f9698a01dd38f8e3be3c53f2b840fb9d09ad62a0b6b87981e179e1b14bc9a2d284c985",
"82d51308ad346c686f81b8094551597d7b963295cbf313401a93df9baf52d5ae98a87745bee70839a4d6e65c342bd15b",
"94eebfd53f4ba6a3b8304236400a12e73885e5a781509a5c8d41d2e8b476923d8ea6052649b3c17282f596217f96c5de",
"8dc4231e42b4edf39e86ef1579401692480647918275da767d3e558c520d6375ad953530610fd27daf110187877a65d0",
}
+3 -4
View File
@@ -12,11 +12,10 @@ import (
)
func init() {
power.ConsensusMinerMinPower = big.NewInt(1024 << 20)
power.ConsensusMinerMinPower = big.NewInt(1024 << 30)
miner.SupportedProofTypes = map[abi.RegisteredProof]struct{}{
abi.RegisteredProof_StackedDRG512MiBSeal: {},
abi.RegisteredProof_StackedDRG32GiBSeal: {},
abi.RegisteredProof_StackedDRG64GiBSeal: {},
abi.RegisteredProof_StackedDRG32GiBSeal: {},
abi.RegisteredProof_StackedDRG64GiBSeal: {},
}
}
+2 -25
View File
@@ -3,33 +3,11 @@ 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.4.0"
const BuildVersion = "0.3.0"
func UserVersion() string {
return BuildVersion + buildType() + CurrentCommit
}
var UserVersion = BuildVersion + CurrentCommit
type Version uint32
@@ -55,7 +33,6 @@ 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
-1
View File
@@ -50,7 +50,6 @@ 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{
+116 -74
View File
@@ -1,45 +1,45 @@
package drand
import (
"bytes"
"context"
"math/rand"
"sync"
"time"
dchain "github.com/drand/drand/chain"
dclient "github.com/drand/drand/client"
gclient "github.com/drand/drand/cmd/relay-gossip/client"
dlog "github.com/drand/drand/log"
"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{
"https://pl-eu.testnet.drand.sh",
"https://pl-us.testnet.drand.sh",
"https://pl-sin.testnet.drand.sh",
"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",
}
var drandChain *dchain.Info
var drandPubKey *dkey.DistPublic
func init() {
var err error
drandChain, err = dchain.InfoFromJSON(bytes.NewReader([]byte(build.DrandChain)))
drandPubKey = new(dkey.DistPublic)
err := drandPubKey.FromTOML(&dkey.DistPublicTOML{Coefficients: build.DrandCoeffs})
if err != nil {
panic("could not unmarshal chain info: " + err.Error())
panic(err)
}
}
@@ -57,9 +57,13 @@ func (dp *drandPeer) IsTLS() bool {
}
type DrandBeacon struct {
client dclient.Client
client dnet.Client
pubkey kyber.Point
peers []dnet.Peer
peersIndex int
peersIndexMtx sync.Mutex
pubkey *dkey.DistPublic
// seconds
interval time.Duration
@@ -72,83 +76,120 @@ type DrandBeacon struct {
localCache map[uint64]types.BeaconEntry
}
func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub) (*DrandBeacon, error) {
func NewDrandBeacon(genesisTs, interval uint64) (*DrandBeacon, error) {
if genesisTs == 0 {
panic("what are you doing this cant be zero")
}
dlogger := dlog.NewKitLoggerFrom(kzap.NewZapSugarLogger(
log.SugaredLogger.Desugar(), zapcore.InfoLevel))
opts := []dclient.Option{
dclient.WithChainInfo(drandChain),
dclient.WithHTTPEndpoints(drandServers),
dclient.WithCacheSize(1024),
dclient.WithLogger(dlogger),
}
if ps != nil {
opts = append(opts, gclient.WithPubsub(ps))
} else {
log.Info("drand beacon without pubsub")
}
client, err := dclient.New(opts...)
if err != nil {
return nil, xerrors.Errorf("creating drand client")
}
go func() {
// Explicitly Watch until that is fixed in drand
ch := client.Watch(context.Background())
for range ch {
}
log.Error("dranch Watch bork")
}()
db := &DrandBeacon{
client: client,
client: dnet.NewGrpcClient(),
localCache: make(map[uint64]types.BeaconEntry),
}
for _, ds := range drandServers {
db.peers = append(db.peers, &drandPeer{addr: ds, tls: true})
}
db.pubkey = drandChain.PublicKey
db.interval = drandChain.Period
db.drandGenTime = uint64(drandChain.GenesisTime)
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.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) Entry(ctx context.Context, round uint64) <-chan beacon.Response {
out := make(chan beacon.Response, 1)
if round != 0 {
be := db.getCachedValue(round)
if be != nil {
out <- beacon.Response{Entry: *be}
close(out)
return out
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}
close(out)
return out
}
out := make(chan beacon.Response, 1)
go func() {
start := time.Now()
log.Infow("start fetching randomness", "round", round)
resp, err := db.client.Get(ctx, round)
p := db.peers[db.getPeerIndex()]
resp, err := db.client.PublicRand(ctx, p, &dproto.PublicRandRequest{Round: round})
var br beacon.Response
if err != nil {
br.Err = xerrors.Errorf("drand failed Get request: %w", err)
db.rotatePeersIndex()
br.Err = xerrors.Errorf("drand peer %q failed publicRand request: %w", p.Address(), err)
} else {
br.Entry.Round = resp.Round()
br.Entry.Data = resp.Signature()
br.Entry.Round = resp.GetRound()
br.Entry.Data = resp.GetSignature()
}
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()
@@ -170,12 +211,13 @@ func (db *DrandBeacon) VerifyEntry(curr types.BeaconEntry, prev types.BeaconEntr
// TODO handle genesis better
return nil
}
b := &dchain.Beacon{
b := &dbeacon.Beacon{
PreviousSig: prev.Data,
Round: curr.Round,
Signature: curr.Data,
}
err := dchain.VerifyBeacon(db.pubkey, b)
//log.Warnw("VerifyEntry", "beacon", b)
err := dbeacon.VerifyBeacon(db.pubkey.Key(), b)
if err == nil {
db.cacheValue(curr)
}
+7 -15
View File
@@ -1,22 +1,14 @@
package drand
import (
"os"
"fmt"
"testing"
dchain "github.com/drand/drand/chain"
dclient "github.com/drand/drand/client"
"github.com/stretchr/testify/assert"
)
func TestPrintGroupInfo(t *testing.T) {
c, err := dclient.NewHTTPClient(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)
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())
}
+2 -2
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() //nolint:errcheck
defer s.Close()
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
+12 -16
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,30 +561,26 @@ func (bpt *bsPeerTracker) logSuccess(p peer.ID, dur time.Duration) {
bpt.lk.Lock()
defer bpt.lk.Unlock()
var pi *peerStats
var ok bool
if pi, ok = bpt.peers[p]; !ok {
if pi, ok := bpt.peers[p]; !ok {
log.Warnw("log success called on peer not in tracker", "peerid", p.String())
return
}
} else {
pi.successes++
pi.successes++
logTime(pi, dur)
logTime(pi, dur)
}
}
func (bpt *bsPeerTracker) logFailure(p peer.ID, dur time.Duration) {
bpt.lk.Lock()
defer bpt.lk.Unlock()
var pi *peerStats
var ok bool
if pi, ok = bpt.peers[p]; !ok {
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)
}
pi.failures++
logTime(pi, dur)
}
func (bpt *bsPeerTracker) removePeer(p peer.ID) {
+8 -8
View File
@@ -19,7 +19,7 @@ import (
var log = logging.Logger("events")
// HeightHandler `curH`-`ts.Height` = `confidence`
// `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: gcConfidence,
gcConfidence: abi.ChainEpoch(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{},
},
}
+13 -14
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,7 +23,6 @@ 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)
@@ -49,7 +48,7 @@ type callHandler struct {
}
type queuedEvent struct {
trigger triggerID
trigger triggerId
h abi.ChainEpoch
msg *types.Message
@@ -58,7 +57,7 @@ type queuedEvent struct {
}
type calledEvents struct {
cs eventAPI
cs eventApi
tsc *tipSetCache
ctx context.Context
gcConfidence uint64
@@ -67,10 +66,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]
@@ -79,8 +78,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 {
@@ -158,8 +157,8 @@ func (e *calledEvents) checkNewCalls(ts *types.TipSet) {
})
}
func (e *calledEvents) queueForConfidence(trigID uint64, msg *types.Message, ts *types.TipSet) {
trigger := e.triggers[trigID]
func (e *calledEvents) queueForConfidence(triggerId uint64, msg *types.Message, ts *types.TipSet) {
trigger := e.triggers[triggerId]
appliedH := ts.Height()
@@ -172,7 +171,7 @@ func (e *calledEvents) queueForConfidence(trigID uint64, msg *types.Message, ts
}
byOrigH[appliedH] = append(byOrigH[appliedH], &queuedEvent{
trigger: trigID,
trigger: triggerId,
h: appliedH,
msg: msg,
})
@@ -232,11 +231,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
}
+4 -4
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
}
+3 -2
View File
@@ -211,14 +211,15 @@ func (fcs *fakeCS) advance(rev, app int, msgs map[int]cid.Cid, nulls ...int) { /
fcs.sub(revs, apps)
fcs.sync.Lock()
fcs.sync.Unlock() //nolint:staticcheck
fcs.sync.Unlock()
}
func (fcs *fakeCS) notifDone() {
fcs.sync.Unlock()
}
var _ eventAPI = &fakeCS{}
var _ eventApi = &fakeCS{}
func TestAt(t *testing.T) {
fcs := &fakeCS{
+1 -1
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 %d", inmsg.Cid(), inmsg.From, inmsg.Nonce, msg.Nonce)
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 inmsg.Equals(msg), nil
+9 -6
View File
@@ -104,7 +104,7 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
return nil, xerrors.Errorf("failed to get metadata datastore: %w", err)
}
bds, err := lr.Datastore("/chain")
bds, err := lr.Datastore("/blocks")
if err != nil {
return nil, xerrors.Errorf("failed to get blocks datastore: %w", err)
}
@@ -219,10 +219,6 @@ 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 +427,7 @@ func (cg *ChainGen) makeBlock(parents *types.TipSet, m address.Address, vrfticke
return fblk, err
}
// ResyncBankerNonce is used for dealing with messages made when
// This function is awkward. It's used to deal with messages made when
// simulating forks
func (cg *ChainGen) ResyncBankerNonce(ts *types.TipSet) error {
act, err := cg.sm.GetActor(cg.banker, ts)
@@ -538,6 +534,13 @@ func (wpp *wppProvider) ComputeProof(context.Context, []abi.SectorInfo, abi.PoSt
}}, 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) {
-3
View File
@@ -58,8 +58,6 @@ 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 {
@@ -156,7 +154,6 @@ 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
+17 -17
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 {
+2 -2
View File
@@ -21,7 +21,7 @@ import (
var log = logging.Logger("statetree")
// StateTree stores actors state by their ID.
// 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
+1 -4
View File
@@ -255,15 +255,12 @@ func TestStateTreeConsistency(t *testing.T) {
}
for i, a := range addrs {
err := st.SetActor(a, &types.Actor{
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())
+13 -44
View File
@@ -326,7 +326,7 @@ func (sm *StateManager) computeTipSetState(ctx context.Context, blks []*types.Bl
blkmsgs = append(blkmsgs, bm)
}
return sm.ApplyBlocks(ctx, pstate, blkmsgs, blks[0].Height, r, cb)
return sm.ApplyBlocks(ctx, pstate, blkmsgs, abi.ChainEpoch(blks[0].Height), r, cb)
}
func (sm *StateManager) parentState(ts *types.TipSet) cid.Cid {
@@ -382,8 +382,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)
log.Errorw("bad actor head", "error", err, "raw", r.Raw, "address", a)
cst.Get(ctx, act.Head, &r)
fmt.Printf("badhead %x\n", r.Raw)
return nil, err
}
@@ -405,8 +405,8 @@ func (sm *StateManager) LoadActorStateRaw(ctx context.Context, a address.Address
return act, nil
}
// ResolveToKeyAddress is similar to `vm.ResolveToKeyAddr` but does not allow `Actor` type of addresses.
// Uses the `TipSet` `ts` to generate the VM state.
// 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,10 +480,7 @@ func (sm *StateManager) GetReceipt(ctx context.Context, msg cid.Cid, ts *types.T
return r, nil
}
// 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) {
func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid) (*types.TipSet, *types.MessageReceipt, error) {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
@@ -531,11 +528,6 @@ func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confid
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:
@@ -545,44 +537,21 @@ func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confid
for _, val := range notif {
switch val.Type {
case store.HCRevert:
if val.Val.Equals(candidateTs) {
candidateTs = nil
candidateRcp = nil
}
if backSearchWait != nil {
reverts[val.Val.Key()] = true
}
continue
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 {
if confidence == 0 {
return val.Val, r, err
}
candidateTs = val.Val
candidateRcp = r
return val.Val, r, nil
}
heightOfHead = val.Val.Height()
}
}
case <-backSearchWait:
// 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
if backTs != nil {
return backTs, backRcp, nil
}
reverts = nil
backSearchWait = nil
case <-ctx.Done():
return nil, nil, ctx.Err()
@@ -641,9 +610,9 @@ func (sm *StateManager) searchBackForMsg(ctx context.Context, from *types.TipSet
return nil, nil, err
}
if act.Nonce < m.VMMessage().Nonce {
// nonce on chain is before message nonce we're looking for, its
// not going to be here
// we either have no messages from the sender, or the latest message we found has a lower nonce than the one being searched for,
// either way, no reason to lookback, it ain't there
if act.Nonce == 0 || act.Nonce < m.VMMessage().Nonce {
return nil, nil, nil
}
+3 -21
View File
@@ -138,24 +138,6 @@ 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)
@@ -286,7 +268,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
@@ -298,7 +280,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
}
@@ -307,7 +289,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
}
+5 -10
View File
@@ -387,7 +387,7 @@ func (cs *ChainStore) LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error) {
return ts, nil
}
// IsAncestorOf returns true if 'a' is an ancestor of 'b'
// 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
@@ -895,17 +895,11 @@ func DrawRandomness(rbase []byte, pers crypto.DomainSeparationTag, round abi.Cha
return nil, xerrors.Errorf("deriving randomness: %w", err)
}
VRFDigest := blake2b.Sum256(rbase)
_, err := h.Write(VRFDigest[:])
if err != nil {
return nil, xerrors.Errorf("hashing VRFDigest: %w", err)
}
h.Write(VRFDigest[:])
if err := binary.Write(h, binary.BigEndian, round); err != nil {
return nil, xerrors.Errorf("deriving randomness: %w", err)
}
_, err = h.Write(entropy)
if err != nil {
return nil, xerrors.Errorf("hashing entropy: %w", err)
}
h.Write(entropy)
return h.Sum(nil), nil
}
@@ -1154,6 +1148,7 @@ 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)
}
+1 -1
View File
@@ -55,7 +55,7 @@ func BenchmarkGetRandomness(b *testing.B) {
b.Fatal(err)
}
bds, err := lr.Datastore("/chain")
bds, err := lr.Datastore("/blocks")
if err != nil {
b.Fatal(err)
}
+3 -2
View File
@@ -57,7 +57,8 @@ func HandleIncomingBlocks(ctx context.Context, bsub *pubsub.Subscription, s *cha
return
}
src := msg.GetFrom()
//nolint:golint
src := peer.ID(msg.GetFrom())
go func() {
log.Infof("New block over pubsub: %s", blk.Cid())
@@ -206,7 +207,7 @@ func (bv *BlockValidator) Validate(ctx context.Context, pid peer.ID, msg *pubsub
}
}
err = sigs.CheckBlockSignature(ctx, blk.Header, key)
err = sigs.CheckBlockSignature(blk.Header, ctx, key)
if err != nil {
log.Errorf("block signature verification failed: %s", err)
recordFailure("signature_verification_failed")
+2 -2
View File
@@ -526,7 +526,7 @@ func blockSanityChecks(h *types.BlockHeader) error {
return nil
}
// ValidateBlock should match up with 'Semantical Validation' in validation.md in the spec
// Should match up with 'Semantical Validation' in validation.md in the spec
func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) error {
ctx, span := trace.StartSpan(ctx, "validateBlock")
defer span.End()
@@ -665,7 +665,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
})
blockSigCheck := async.Err(func() error {
if err := sigs.CheckBlockSignature(ctx, h, waddr); err != nil {
if err := sigs.CheckBlockSignature(h, ctx, waddr); err != nil {
return xerrors.Errorf("check block signature failed: %w", err)
}
return nil
+2 -2
View File
@@ -417,7 +417,7 @@ func TestSyncBadTimestamp(t *testing.T) {
a1 := tu.mineOnBlock(base, 0, nil, false, true)
tu.g.Timestamper = nil
require.NoError(t, tu.g.ResyncBankerNonce(a1.TipSet()))
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)
require.NoError(t, tu.g.ResyncBankerNonce(a1.TipSet()))
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)
+4 -4
View File
@@ -74,8 +74,8 @@ type BlockHeader struct {
validated bool // true if the signature has been validated
}
func (blk *BlockHeader) ToStorageBlock() (block.Block, error) {
data, err := blk.Serialize()
func (b *BlockHeader) ToStorageBlock() (block.Block, error) {
data, err := b.Serialize()
if err != nil {
return nil, err
}
@@ -89,8 +89,8 @@ func (blk *BlockHeader) ToStorageBlock() (block.Block, error) {
return block.NewBlockWithCid(data, c)
}
func (blk *BlockHeader) Cid() cid.Cid {
sb, err := blk.ToStorageBlock()
func (b *BlockHeader) Cid() cid.Cid {
sb, err := b.ToStorageBlock()
if err != nil {
panic(err) // Not sure i'm entirely comfortable with this one, needs to be checked
}
+2 -3
View File
@@ -4,14 +4,13 @@ import (
"bytes"
"encoding/hex"
"fmt"
"github.com/filecoin-project/specs-actors/actors/abi"
"reflect"
"testing"
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"
cid "github.com/ipfs/go-cid"
)
func testBlockHeader(t testing.TB) *BlockHeader {
+10 -6
View File
@@ -41,16 +41,20 @@ type Message struct {
Params []byte
}
func (m *Message) Caller() address.Address {
return m.From
func (t *Message) BlockMiner() address.Address {
panic("implement me")
}
func (m *Message) Receiver() address.Address {
return m.To
func (t *Message) Caller() address.Address {
return t.From
}
func (m *Message) ValueReceived() abi.TokenAmount {
return m.Value
func (t *Message) Receiver() address.Address {
return t.To
}
func (t *Message) ValueReceived() abi.TokenAmount {
return t.Value
}
func DecodeMessage(b []byte) (*Message, error) {
+8 -8
View File
@@ -9,12 +9,12 @@ import (
"github.com/multiformats/go-multihash"
)
func (sm *SignedMessage) ToStorageBlock() (block.Block, error) {
if sm.Signature.Type == crypto.SigTypeBLS {
return sm.Message.ToStorageBlock()
func (m *SignedMessage) ToStorageBlock() (block.Block, error) {
if m.Signature.Type == crypto.SigTypeBLS {
return m.Message.ToStorageBlock()
}
data, err := sm.Serialize()
data, err := m.Serialize()
if err != nil {
return nil, err
}
@@ -28,12 +28,12 @@ func (sm *SignedMessage) ToStorageBlock() (block.Block, error) {
return block.NewBlockWithCid(data, c)
}
func (sm *SignedMessage) Cid() cid.Cid {
if sm.Signature.Type == crypto.SigTypeBLS {
return sm.Message.Cid()
func (m *SignedMessage) Cid() cid.Cid {
if m.Signature.Type == crypto.SigTypeBLS {
return m.Message.Cid()
}
sb, err := sm.ToStorageBlock()
sb, err := m.ToStorageBlock()
if err != nil {
panic(err)
}
+2 -2
View File
@@ -23,6 +23,8 @@ 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
@@ -30,8 +32,6 @@ 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,
+3 -3
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))
+2 -7
View File
@@ -7,7 +7,6 @@ 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"
@@ -174,18 +173,14 @@ func WriteJsonToFile(fname string, obj interface{}) error {
if err != nil {
return err
}
defer fi.Close() //nolint:errcheck
defer fi.Close()
out, err := json.MarshalIndent(obj, "", " ")
if err != nil {
return err
}
_, err = fi.Write(out)
if err != nil {
return xerrors.Errorf("writing json: %w", err)
}
fi.Write(out)
return nil
}
-6
View File
@@ -3,7 +3,6 @@ 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"
@@ -144,8 +143,3 @@ 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) {
ps.chargeGas(0) // TODO: this is only called by the cron actor. Should we even charge gas?
return ps.under.BatchVerifySeals(inp)
}
+8 -6
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,7 +89,9 @@ type Invokee interface {
Exports() []interface{}
}
func (*Invoker) transform(instance Invokee) (nativeCode, error) {
var tAError = reflect.TypeOf((*aerrors.ActorError)(nil)).Elem()
func (*invoker) transform(instance Invokee) (nativeCode, error) {
itype := reflect.TypeOf(instance)
exports := instance.Exports()
for i, m := range exports {
+1 -1
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)
+1 -2
View File
@@ -2,7 +2,6 @@ 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"
@@ -28,7 +27,7 @@ func init() {
var EmptyObjectCid cid.Cid
// TryCreateAccountActor creates account actors from only BLS/SECP256K1 addresses.
// 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 {
+52 -54
View File
@@ -107,8 +107,8 @@ type notFoundErr interface {
IsNotFound() bool
}
func (rt *Runtime) Get(c cid.Cid, o vmr.CBORUnmarshaler) bool {
if err := rt.cst.Get(context.TODO(), c, o); err != nil {
func (rs *Runtime) Get(c cid.Cid, o vmr.CBORUnmarshaler) bool {
if err := rs.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 +122,8 @@ func (rt *Runtime) Get(c cid.Cid, o vmr.CBORUnmarshaler) bool {
return true
}
func (rt *Runtime) Put(x vmr.CBORMarshaler) cid.Cid {
c, err := rt.cst.Put(context.TODO(), x)
func (rs *Runtime) Put(x vmr.CBORMarshaler) cid.Cid {
c, err := rs.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 +135,7 @@ func (rt *Runtime) Put(x vmr.CBORMarshaler) cid.Cid {
var _ vmr.Runtime = (*Runtime)(nil)
func (rt *Runtime) shimCall(f func() interface{}) (rval []byte, aerr aerrors.ActorError) {
func (rs *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 +150,8 @@ func (rt *Runtime) shimCall(f func() interface{}) (rval []byte, aerr aerrors.Act
ret := f()
if !rt.callerValidated {
rt.Abortf(exitcode.SysErrorIllegalActor, "Caller MUST be validated during method execution")
if !rs.callerValidated {
rs.Abortf(exitcode.SysErrorIllegalActor, "Caller MUST be validated during method execution")
}
switch ret := ret.(type) {
@@ -172,25 +172,25 @@ func (rt *Runtime) shimCall(f func() interface{}) (rval []byte, aerr aerrors.Act
}
}
func (rt *Runtime) Message() vmr.Message {
return rt.vmsg
func (rs *Runtime) Message() vmr.Message {
return rs.vmsg
}
func (rt *Runtime) ValidateImmediateCallerAcceptAny() {
rt.abortIfAlreadyValidated()
func (rs *Runtime) ValidateImmediateCallerAcceptAny() {
rs.abortIfAlreadyValidated()
return
}
func (rt *Runtime) CurrentBalance() abi.TokenAmount {
b, err := rt.GetBalance(rt.Message().Receiver())
func (rs *Runtime) CurrentBalance() abi.TokenAmount {
b, err := rs.GetBalance(rs.Message().Receiver())
if err != nil {
rt.Abortf(err.RetCode(), "get current balance: %v", err)
rs.Abortf(exitcode.ExitCode(err.RetCode()), "get current balance: %v", err)
}
return b
}
func (rt *Runtime) GetActorCodeCID(addr address.Address) (ret cid.Cid, ok bool) {
act, err := rt.state.GetActor(addr)
func (rs *Runtime) GetActorCodeCID(addr address.Address) (ret cid.Cid, ok bool) {
act, err := rs.state.GetActor(addr)
if err != nil {
if xerrors.Is(err, types.ErrActorNotFound) {
return cid.Undef, false
@@ -210,8 +210,8 @@ func (rt *Runtime) GetRandomness(personalization crypto.DomainSeparationTag, ran
return res
}
func (rt *Runtime) Store() vmr.Store {
return rt
func (rs *Runtime) Store() vmr.Store {
return rs
}
func (rt *Runtime) NewActorAddress() address.Address {
@@ -236,12 +236,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.")
}
@@ -253,7 +253,7 @@ func (rt *Runtime) CreateActor(codeID cid.Cid, address address.Address) {
rt.ChargeGas(rt.Pricelist().OnCreateActor())
err = rt.state.SetActor(address, &types.Actor{
Code: codeID,
Code: codeId,
Head: EmptyObjectCid,
Nonce: 0,
Balance: big.Zero(),
@@ -283,12 +283,12 @@ func (rt *Runtime) DeleteActor(addr address.Address) {
}
}
func (rt *Runtime) Syscalls() vmr.Syscalls {
func (rs *Runtime) Syscalls() vmr.Syscalls {
// TODO: Make sure this is wrapped in something that charges gas for each of the calls
return rt.sys
return rs.sys
}
func (rt *Runtime) StartSpan(name string) vmr.TraceSpan {
func (rs *Runtime) StartSpan(name string) vmr.TraceSpan {
panic("implement me")
}
@@ -308,12 +308,12 @@ func (rt *Runtime) Context() context.Context {
return rt.ctx
}
func (rt *Runtime) Abortf(code exitcode.ExitCode, msg string, args ...interface{}) {
func (rs *Runtime) Abortf(code exitcode.ExitCode, msg string, args ...interface{}) {
log.Error("Abortf: ", fmt.Sprintf(msg, args...))
panic(aerrors.NewfSkip(2, code, msg, args...))
}
func (rt *Runtime) AbortStateMsg(msg string) {
func (rs *Runtime) AbortStateMsg(msg string) {
panic(aerrors.NewfSkip(3, 101, msg))
}
@@ -331,8 +331,8 @@ func (rt *Runtime) ValidateImmediateCallerType(ts ...cid.Cid) {
rt.Abortf(exitcode.SysErrForbidden, "caller cid type %q was not one of %v", callerCid, ts)
}
func (rt *Runtime) CurrEpoch() abi.ChainEpoch {
return rt.height
func (rs *Runtime) CurrEpoch() abi.ChainEpoch {
return rs.height
}
type dumbWrapperType struct {
@@ -343,26 +343,26 @@ func (dwt *dumbWrapperType) Into(um vmr.CBORUnmarshaler) error {
return um.UnmarshalCBOR(bytes.NewReader(dwt.val))
}
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")
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")
}
var params []byte
if m != nil {
buf := new(bytes.Buffer)
if err := m.MarshalCBOR(buf); err != nil {
rt.Abortf(exitcode.SysErrInvalidParameters, "failed to marshal input parameters: %s", err)
rs.Abortf(exitcode.SysErrInvalidParameters, "failed to marshal input parameters: %s", err)
}
params = buf.Bytes()
}
ret, err := rt.internalSend(rt.Message().Receiver(), to, method, value, params)
ret, err := rs.internalSend(rs.Message().Receiver(), to, method, types.BigInt(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, err.RetCode()
return nil, exitcode.ExitCode(err.RetCode())
}
return &dumbWrapperType{ret}, 0
}
@@ -402,7 +402,7 @@ func (rt *Runtime) internalSend(from, to address.Address, method abi.MethodNum,
}
mr := types.MessageReceipt{
ExitCode: aerrors.RetCode(errSend),
ExitCode: exitcode.ExitCode(aerrors.RetCode(errSend)),
Return: ret,
GasUsed: 0,
}
@@ -425,48 +425,46 @@ func (rt *Runtime) internalSend(from, to address.Address, method abi.MethodNum,
return ret, errSend
}
func (rt *Runtime) State() vmr.StateHandle {
return &shimStateHandle{rt: rt}
func (rs *Runtime) State() vmr.StateHandle {
return &shimStateHandle{rs: rs}
}
type shimStateHandle struct {
rt *Runtime
rs *Runtime
}
func (ssh *shimStateHandle) Create(obj vmr.CBORMarshaler) {
c := ssh.rt.Put(obj)
// TODO: handle error below
ssh.rt.stateCommit(EmptyObjectCid, c)
c := ssh.rs.Put(obj)
ssh.rs.stateCommit(EmptyObjectCid, c)
}
func (ssh *shimStateHandle) Readonly(obj vmr.CBORUnmarshaler) {
act, err := ssh.rt.state.GetActor(ssh.rt.Message().Receiver())
act, err := ssh.rs.state.GetActor(ssh.rs.Message().Receiver())
if err != nil {
ssh.rt.Abortf(exitcode.SysErrorIllegalArgument, "failed to get actor for Readonly state: %s", err)
ssh.rs.Abortf(exitcode.SysErrorIllegalArgument, "failed to get actor for Readonly state: %s", err)
}
ssh.rt.Get(act.Head, obj)
ssh.rs.Get(act.Head, obj)
}
func (ssh *shimStateHandle) Transaction(obj vmr.CBORer, f func() interface{}) interface{} {
if obj == nil {
ssh.rt.Abortf(exitcode.SysErrorIllegalActor, "Must not pass nil to Transaction()")
ssh.rs.Abortf(exitcode.SysErrorIllegalActor, "Must not pass nil to Transaction()")
}
act, err := ssh.rt.state.GetActor(ssh.rt.Message().Receiver())
act, err := ssh.rs.state.GetActor(ssh.rs.Message().Receiver())
if err != nil {
ssh.rt.Abortf(exitcode.SysErrorIllegalActor, "failed to get actor for Transaction: %s", err)
ssh.rs.Abortf(exitcode.SysErrorIllegalActor, "failed to get actor for Transaction: %s", err)
}
baseState := act.Head
ssh.rt.Get(baseState, obj)
ssh.rs.Get(baseState, obj)
ssh.rt.allowInternal = false
ssh.rs.allowInternal = false
out := f()
ssh.rt.allowInternal = true
ssh.rs.allowInternal = true
c := ssh.rt.Put(obj)
c := ssh.rs.Put(obj)
// TODO: handle error below
ssh.rt.stateCommit(baseState, c)
ssh.rs.stateCommit(baseState, c)
return out
}
+16 -29
View File
@@ -4,7 +4,6 @@ import (
"bytes"
"context"
"fmt"
"sync"
"github.com/filecoin-project/go-address"
"github.com/ipfs/go-cid"
@@ -184,7 +183,7 @@ func (ss *syscallShim) VerifyBlockSig(blk *types.BlockHeader) error {
return err
}
if err := sigs.CheckBlockSignature(ss.ctx, blk, waddr); err != nil {
if err := sigs.CheckBlockSignature(blk, ss.ctx, waddr); err != nil {
return err
}
@@ -202,6 +201,20 @@ 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()
@@ -212,7 +225,7 @@ func (ss *syscallShim) VerifySeal(info abi.SealVerifyInfo) error {
}
ticket := []byte(info.Randomness)
proof := info.Proof
proof := []byte(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)
@@ -239,29 +252,3 @@ func (ss *syscallShim) VerifySignature(sig crypto.Signature, addr address.Addres
return sigs.Verify(&sig, kaddr, input)
}
func (ss *syscallShim) BatchVerifySeals(inp map[address.Address][]abi.SealVerifyInfo) (map[address.Address][]bool, error) {
out := make(map[address.Address][]bool)
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()
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
}
}(addr, i, s, results)
}
}
wg.Wait()
return out, nil
}
-2
View File
@@ -41,7 +41,6 @@ func init() {
func TestChainValidationMessageSuite(t *testing.T) {
f := factory.NewFactories()
for _, testCase := range suites.MessageTestCases() {
testCase := testCase
if TestSuiteSkipper.Skip(testCase) {
continue
}
@@ -54,7 +53,6 @@ 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
}
+9 -23
View File
@@ -131,7 +131,7 @@ type VM struct {
cst *cbor.BasicIpldStore
buf *bufbstore.BufferedBS
blockHeight abi.ChainEpoch
inv *Invoker
inv *invoker
rand Rand
Syscalls runtime.Syscalls
@@ -246,7 +246,7 @@ func (vm *VM) ApplyImplicitMessage(ctx context.Context, msg *types.Message) (*Ap
ret, actorErr, rt := vm.send(ctx, msg, nil, 0)
return &ApplyRet{
MessageReceipt: types.MessageReceipt{
ExitCode: aerrors.RetCode(actorErr),
ExitCode: exitcode.ExitCode(aerrors.RetCode(actorErr)),
Return: ret,
GasUsed: 0,
},
@@ -415,7 +415,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
return &ApplyRet{
MessageReceipt: types.MessageReceipt{
ExitCode: errcode,
ExitCode: exitcode.ExitCode(errcode),
Return: ret,
GasUsed: gasUsed,
},
@@ -454,7 +454,7 @@ func (vm *VM) Flush(ctx context.Context) (cid.Cid, error) {
return root, nil
}
// MutateState usage: MutateState(ctx, idAddr, func(cst cbor.IpldStore, st *ActorStateType) error {...})
// vm.MutateState(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 +591,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,30 +607,16 @@ 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(fromID)
f, err := vm.cstate.GetActor(from)
if err != nil {
return aerrors.Fatalf("transfer failed when retrieving sender actor: %s", err)
}
t, err := vm.cstate.GetActor(toID)
t, err := vm.cstate.GetActor(to)
if err != nil {
return aerrors.Fatalf("transfer failed when retrieving receiver actor: %s", err)
}
@@ -640,11 +626,11 @@ func (vm *VM) transfer(from, to address.Address, amt types.BigInt) aerrors.Actor
}
depositFunds(t, amt)
if err := vm.cstate.SetActor(fromID, f); err != nil {
if err := vm.cstate.SetActor(from, f); err != nil {
return aerrors.Fatalf("transfer failed when setting receiver actor: %s", err)
}
if err := vm.cstate.SetActor(toID, t); err != nil {
if err := vm.cstate.SetActor(to, t); err != nil {
return aerrors.Fatalf("transfer failed when setting sender actor: %s", err)
}
+2 -2
View File
@@ -12,8 +12,8 @@ import (
"github.com/filecoin-project/go-address"
_ "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/lib/sigs/bls"
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/sigs"
+1 -6
View File
@@ -804,12 +804,7 @@ var chainExportCmd = &cli.Command{
if err != nil {
return err
}
defer func() {
err := fi.Close()
if err != nil {
fmt.Printf("error closing output file: %+v", err)
}
}()
defer fi.Close()
ts, err := LoadTipSet(ctx, cctx, api)
if err != nil {
+4 -8
View File
@@ -23,7 +23,6 @@ import (
"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"
)
@@ -118,7 +117,7 @@ var msigCreateCmd = &cli.Command{
}
// wait for it to get mined into a block
wait, err := api.StateWaitMsg(ctx, msgCid, build.MessageConfidence)
wait, err := api.StateWaitMsg(ctx, msgCid)
if err != nil {
return err
}
@@ -207,10 +206,7 @@ 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)
}
if err := w.Flush(); err != nil {
return xerrors.Errorf("flushing output: %+v", err)
}
w.Flush()
}
return nil
@@ -337,7 +333,7 @@ var msigProposeCmd = &cli.Command{
fmt.Println("send proposal in message: ", msgCid)
wait, err := api.StateWaitMsg(ctx, msgCid, build.MessageConfidence)
wait, err := api.StateWaitMsg(ctx, msgCid)
if err != nil {
return err
}
@@ -453,7 +449,7 @@ var msigApproveCmd = &cli.Command{
fmt.Println("sent approval in message: ", msgCid)
wait, err := api.StateWaitMsg(ctx, msgCid, build.MessageConfidence)
wait, err := api.StateWaitMsg(ctx, msgCid)
if err != nil {
return err
}
+1 -25
View File
@@ -21,7 +21,6 @@ var netCmd = &cli.Command{
netListen,
netId,
netFindPeer,
netScores,
},
}
@@ -45,30 +44,7 @@ var netPeers = &cli.Command{
})
for _, peer := range peers {
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)
fmt.Println(peer)
}
return nil
+1 -1
View File
@@ -24,7 +24,7 @@ var fetchParamCmd = &cli.Command{
return err
}
sectorSize := uint64(sectorSizeInt)
err = paramfetch.GetParams(build.ParametersJSON(), sectorSize)
err = paramfetch.GetParams(build.ParametersJson(), sectorSize)
if err != nil {
return xerrors.Errorf("fetching proof parameters: %w", err)
}
+2 -3
View File
@@ -4,7 +4,6 @@ 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"
@@ -362,7 +361,7 @@ var paychVoucherSubmitCmd = &cli.Command{
return err
}
mwait, err := api.StateWaitMsg(ctx, mcid, build.MessageConfidence)
mwait, err := api.StateWaitMsg(ctx, mcid)
if err != nil {
return err
}
@@ -371,7 +370,7 @@ var paychVoucherSubmitCmd = &cli.Command{
return fmt.Errorf("message execution failed (exit code %d)", mwait.Receipt.ExitCode)
}
fmt.Println("channel updated successfully")
fmt.Println("channel updated succesfully")
return nil
},
+2 -3
View File
@@ -35,7 +35,6 @@ import (
"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"
)
@@ -393,7 +392,7 @@ var stateReplaySetCmd = &cli.Command{
ts, err = types.NewTipSet(headers)
} else {
r, err := api.StateWaitMsg(ctx, mcid, build.MessageConfidence)
r, err := api.StateWaitMsg(ctx, mcid)
if err != nil {
return xerrors.Errorf("finding message in chain: %w", err)
}
@@ -1157,7 +1156,7 @@ var stateWaitMsgCmd = &cli.Command{
return err
}
mw, err := api.StateWaitMsg(ctx, msg, build.MessageConfidence)
mw, err := api.StateWaitMsg(ctx, msg)
if err != nil {
return err
}
+1 -3
View File
@@ -23,9 +23,7 @@ var versionCmd = &cli.Command{
if err != nil {
return err
}
fmt.Println("Daemon: ", v)
fmt.Print("Local: ")
fmt.Println(v)
cli.VersionPrinter(cctx)
return nil
},
+2 -1
View File
@@ -53,7 +53,8 @@ var runCmd = &cli.Command{
defer closer()
ctx := lcli.ReqContext(cctx)
return sendSmallFundsTxs(ctx, api, addr, 5)
sendSmallFundsTxs(ctx, api, addr, 5)
return nil
},
}
+3 -3
View File
@@ -55,7 +55,7 @@ var importBenchCmd = &cli.Command{
if err != nil {
return err
}
defer cfi.Close() //nolint:errcheck // read only file
defer cfi.Close()
tdir, err := ioutil.TempDir("", "lotus-import-bench")
if err != nil {
@@ -80,7 +80,7 @@ var importBenchCmd = &cli.Command{
if err != nil {
return err
}
defer prof.Close() //nolint:errcheck
defer prof.Close()
if err := pprof.StartCPUProfile(prof); err != nil {
return err
@@ -146,7 +146,7 @@ var importBenchCmd = &cli.Command{
if err != nil {
return err
}
defer ibj.Close() //nolint:errcheck
defer ibj.Close()
if err := json.NewEncoder(ibj).Encode(out); err != nil {
return err
+12 -16
View File
@@ -78,7 +78,7 @@ func main() {
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,
@@ -141,10 +141,7 @@ var sealBenchCmd = &cli.Command{
},
Action: func(c *cli.Context) error {
if c.Bool("no-gpu") {
err := os.Setenv("BELLMAN_NO_GPU", "1")
if err != nil {
return xerrors.Errorf("setting no-gpu flag: %w", err)
}
os.Setenv("BELLMAN_NO_GPU", "1")
}
robench := c.String("benchmark-existing-sectorbuilder")
@@ -157,10 +154,7 @@ var sealBenchCmd = &cli.Command{
return err
}
err = os.MkdirAll(sdir, 0775) //nolint:gosec
if err != nil {
return xerrors.Errorf("creating sectorbuilder dir: %w", err)
}
os.MkdirAll(sdir, 0775)
tsdir, err := ioutil.TempDir(sdir, "bench")
if err != nil {
@@ -215,7 +209,7 @@ var sealBenchCmd = &cli.Command{
// Only fetch parameters if actually needed
if !c.Bool("skip-commit2") {
if err := paramfetch.GetParams(build.ParametersJSON(), uint64(sectorSize)); err != nil {
if err := paramfetch.GetParams(build.ParametersJson(), uint64(sectorSize)); err != nil {
return xerrors.Errorf("getting params: %w", err)
}
}
@@ -568,10 +562,15 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, mid
}
}
err := sb.UnsealPiece(context.TODO(), abi.SectorID{Miner: mid, Number: 1}, 0, abi.UnpaddedPieceSize(sectorSize), ticket, cids.Unsealed)
// TODO: RM unsealed sector first
rc, err := sb.ReadPieceFromSealedSector(context.TODO(), abi.SectorID{Miner: mid, Number: 1}, 0, abi.UnpaddedPieceSize(sectorSize), ticket, cids.Unsealed)
if err != nil {
return nil, nil, err
}
if err := rc.Close(); err != nil {
return nil, nil, err
}
}
unseal := time.Now()
@@ -600,10 +599,7 @@ var proveCmd = &cli.Command{
},
Action: func(c *cli.Context) error {
if c.Bool("no-gpu") {
err := os.Setenv("BELLMAN_NO_GPU", "1")
if err != nil {
return xerrors.Errorf("setting no-gpu flag: %w", err)
}
os.Setenv("BELLMAN_NO_GPU", "1")
}
if !c.Args().Present() {
@@ -620,7 +616,7 @@ var proveCmd = &cli.Command{
return xerrors.Errorf("unmarshalling input file: %w", err)
}
if err := paramfetch.GetParams(build.ParametersJSON(), c2in.SectorSize); err != nil {
if err := paramfetch.GetParams(build.ParametersJson(), c2in.SectorSize); err != nil {
return xerrors.Errorf("getting params: %w", err)
}
+1 -1
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)
}
}
}
-6
View File
@@ -20,13 +20,7 @@ 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
+3 -3
View File
@@ -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() //nolint:errcheck
defer st.close()
runSyncer(ctx, api, st, maxBatch)
+7 -10
View File
@@ -20,7 +20,6 @@ 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) {
@@ -139,21 +138,21 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS
log.Infof("Syncing %d blocks", len(toSync))
paDone := 0
parmap.Par(50, parmap.MapArr(toSync), func(bh *types.BlockHeader) {
par(50, 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, _ := types.NewTipSet([]*types.BlockHeader{bh})
ts, err := types.NewTipSet([]*types.BlockHeader{bh})
aadrs, err := api.StateListActors(ctx, ts.Key())
if err != nil {
log.Error(err)
return
}
parmap.Par(50, aadrs, func(addr address.Address) {
par(50, aadrs, func(addr address.Address) {
act, err := api.StateGetActor(ctx, addr, ts.Key())
if err != nil {
log.Error(err)
@@ -199,8 +198,6 @@ 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)
@@ -242,7 +239,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS
addresses[message.From] = address.Undef
}
parmap.Par(50, parmap.KMapArr(addresses), func(addr address.Address) {
par(50, kmaparr(addresses), func(addr address.Address) {
raddr, err := api.StateLookupID(ctx, addr, types.EmptyTSK)
if err != nil {
log.Warn(err)
@@ -271,7 +268,7 @@ func syncHead(ctx context.Context, api api.FullNode, st *storage, ts *types.TipS
}
}
parmap.Par(50, parmap.KVMapArr(miners), func(it func() (minerKey, *minerInfo)) {
par(50, kvmaparr(miners), func(it func() (minerKey, *minerInfo)) {
k, info := it()
pow, err := api.StateMinerPower(ctx, k.addr, types.EmptyTSK)
@@ -389,7 +386,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
parmap.Par(50, parmap.MapArr(toSync), func(header *types.BlockHeader) {
par(50, maparr(toSync), func(header *types.BlockHeader) {
msgs, err := api.ChainGetBlockMessages(ctx, header.Cid())
if err != nil {
log.Error(err)
@@ -426,7 +423,7 @@ func fetchParentReceipts(ctx context.Context, api api.FullNode, toSync map[cid.C
var lk sync.Mutex
out := map[mrec]*types.MessageReceipt{}
parmap.Par(50, parmap.MapArr(toSync), func(header *types.BlockHeader) {
par(50, maparr(toSync), func(header *types.BlockHeader) {
recs, err := api.ChainGetParentReceipts(ctx, header.Cid())
if err != nil {
log.Error(err)
@@ -1,12 +1,11 @@
package parmap
package main
import (
"reflect"
"sync"
)
// MapArr transforms map into slice of map values
func MapArr(in interface{}) interface{} {
func maparr(in interface{}) interface{} {
rin := reflect.ValueOf(in)
rout := reflect.MakeSlice(reflect.SliceOf(rin.Type().Elem()), rin.Len(), rin.Len())
var i int
@@ -20,8 +19,7 @@ func MapArr(in interface{}) interface{} {
return rout.Interface()
}
// KMapArr transforms map into slice of map keys
func KMapArr(in interface{}) interface{} {
func kmaparr(in interface{}) interface{} {
rin := reflect.ValueOf(in)
rout := reflect.MakeSlice(reflect.SliceOf(rin.Type().Key()), rin.Len(), rin.Len())
var i int
@@ -35,9 +33,8 @@ func KMapArr(in interface{}) interface{} {
return rout.Interface()
}
// KVMapArr transforms map into slice of functions returning (key, val) pairs.
// map[A]B => []func()(A, B)
func KVMapArr(in interface{}) interface{} {
// map[k]v => []func() (k, v)
func kvmaparr(in interface{}) interface{} {
rin := reflect.ValueOf(in)
t := reflect.FuncOf([]reflect.Type{}, []reflect.Type{
@@ -62,7 +59,7 @@ func KVMapArr(in interface{}) interface{} {
return rout.Interface()
}
func Par(concurrency int, arr interface{}, f interface{}) {
func par(concurrency int, arr interface{}, f interface{}) {
throttle := make(chan struct{}, concurrency)
var wg sync.WaitGroup
+9 -9
View File
@@ -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
}
@@ -334,7 +334,7 @@ func (h *handler) msgwait(w http.ResponseWriter, r *http.Request) {
return
}
mw, err := h.api.StateWaitMsg(r.Context(), c, build.MessageConfidence)
mw, err := h.api.StateWaitMsg(r.Context(), c)
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, build.MessageConfidence)
mw, err := h.api.StateWaitMsg(r.Context(), c)
if err != nil {
w.WriteHeader(400)
w.Write([]byte(err.Error()))
+2 -2
View File
@@ -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 attempts",
Usage: "number of API retry attemps",
},
},
Action: func(c *cli.Context) error {
+5 -7
View File
@@ -26,7 +26,7 @@ import (
lcli "github.com/filecoin-project/lotus/cli"
"github.com/filecoin-project/lotus/lib/lotuslog"
"github.com/filecoin-project/lotus/node/repo"
sectorstorage "github.com/filecoin-project/sector-storage"
"github.com/filecoin-project/sector-storage"
"github.com/filecoin-project/sector-storage/sealtasks"
"github.com/filecoin-project/sector-storage/stores"
)
@@ -47,7 +47,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,9 +107,7 @@ var runCmd = &cli.Command{
},
Action: func(cctx *cli.Context) error {
if !cctx.Bool("enable-gpu-proving") {
if err := os.Setenv("BELLMAN_NO_GPU", "true"); err != nil {
return xerrors.Errorf("could not set no-gpu env: %+v", err)
}
os.Setenv("BELLMAN_NO_GPU", "true")
}
if cctx.String("address") == "" {
@@ -148,7 +146,7 @@ var runCmd = &cli.Command{
}
if cctx.Bool("commit") {
if err := paramfetch.GetParams(build.ParametersJSON(), uint64(ssize)); err != nil {
if err := paramfetch.GetParams(build.ParametersJson(), uint64(ssize)); err != nil {
return xerrors.Errorf("get params: %w", err)
}
}
@@ -292,7 +290,7 @@ var runCmd = &cli.Command{
go func() {
<-ctx.Done()
log.Warn("Shutting down..")
log.Warn("Shutting down...")
if err := srv.Shutdown(context.TODO()); err != nil {
log.Errorf("shutting down RPC server failed: %s", err)
}
+2 -1
View File
@@ -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,6 +145,7 @@ 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
+2 -2
View File
@@ -6,6 +6,7 @@ import (
"encoding/hex"
"encoding/json"
"fmt"
"github.com/minio/blake2b-simd"
"io/ioutil"
"os"
"path/filepath"
@@ -14,7 +15,6 @@ 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"
@@ -48,7 +48,7 @@ func PreSeal(maddr address.Address, pt abi.RegisteredProof, offset abi.SectorNum
SealProofType: spt,
}
if err := os.MkdirAll(sbroot, 0775); err != nil { //nolint:gosec
if err := os.MkdirAll(sbroot, 0775); err != nil {
return nil, nil, err
}
+2 -2
View File
@@ -34,7 +34,7 @@ var importCarCmd = &cli.Command{
if err != nil {
return err
}
defer lr.Close() //nolint:errcheck
defer lr.Close()
cf := cctx.Args().Get(0)
f, err := os.OpenFile(cf, os.O_RDONLY, 0664)
@@ -42,7 +42,7 @@ var importCarCmd = &cli.Command{
return xerrors.Errorf("opening the car file: %w", err)
}
ds, err := lr.Datastore("/chain")
ds, err := lr.Datastore("/blocks")
if err != nil {
return err
}
+1 -1
View File
@@ -24,7 +24,7 @@ var fetchParamCmd = &cli.Command{
return err
}
sectorSize := uint64(sectorSizeInt)
err = paramfetch.GetParams(build.ParametersJSON(), sectorSize)
err = paramfetch.GetParams(build.ParametersJson(), sectorSize)
if err != nil {
return xerrors.Errorf("fetching proof parameters: %w", err)
}
+2 -3
View File
@@ -3,7 +3,6 @@ package main
import (
"bytes"
"fmt"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/go-address"
"gopkg.in/urfave/cli.v2"
@@ -86,7 +85,7 @@ var verifRegAddVerifierCmd = &cli.Command{
fmt.Printf("message sent, now waiting on cid: %s\n", smsg.Cid())
mwait, err := api.StateWaitMsg(ctx, smsg.Cid(), build.MessageConfidence)
mwait, err := api.StateWaitMsg(ctx, smsg.Cid())
if err != nil {
return err
}
@@ -162,7 +161,7 @@ var verifRegVerifyClientCmd = &cli.Command{
fmt.Printf("message sent, now waiting on cid: %s\n", smsg.Cid())
mwait, err := api.StateWaitMsg(ctx, smsg.Cid(), build.MessageConfidence)
mwait, err := api.StateWaitMsg(ctx, smsg.Cid())
if err != nil {
return err
}
+17 -6
View File
@@ -37,6 +37,7 @@ import (
lapi "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/beacon/drand"
"github.com/filecoin-project/lotus/chain/types"
lcli "github.com/filecoin-project/lotus/cli"
"github.com/filecoin-project/lotus/genesis"
@@ -126,7 +127,7 @@ var initCmd = &cli.Command{
}
log.Info("Checking proof parameters")
if err := paramfetch.GetParams(build.ParametersJSON(), uint64(ssize)); err != nil {
if err := paramfetch.GetParams(build.ParametersJson(), uint64(ssize)); err != nil {
return xerrors.Errorf("fetching proof parameters: %w", err)
}
@@ -388,7 +389,7 @@ func storageMinerInit(ctx context.Context, cctx *cli.Context, api lapi.FullNode,
if err != nil {
return err
}
defer lr.Close() //nolint:errcheck
defer lr.Close()
log.Info("Initializing libp2p identity")
@@ -436,7 +437,7 @@ func storageMinerInit(ctx context.Context, cctx *cli.Context, api lapi.FullNode,
smgr, err := sectorstorage.New(ctx, lr, stores.NewIndex(), &ffiwrapper.Config{
SealProofType: spt,
}, sectorstorage.SealerConfig{true, true, true, true}, nil, sa)
}, sectorstorage.SealerConfig{true, true, true}, nil, sa)
if err != nil {
return err
}
@@ -445,7 +446,17 @@ func storageMinerInit(ctx context.Context, cctx *cli.Context, api lapi.FullNode,
return err
}
m := miner.NewMiner(api, epp, a)
gen, err := api.ChainGetGenesis(ctx)
if err != nil {
return err
}
beacon, err := drand.NewDrandBeacon(gen.Blocks()[0].Timestamp, build.BlockDelay)
if err != nil {
return err
}
m := miner.NewMiner(api, epp, beacon, a)
{
if err := m.Start(ctx); err != nil {
return xerrors.Errorf("failed to start up genesis miner: %w", err)
@@ -566,7 +577,7 @@ func configureStorageMiner(ctx context.Context, api lapi.FullNode, addr address.
}
log.Info("Waiting for message: ", smsg.Cid())
ret, err := api.StateWaitMsg(ctx, smsg.Cid(), build.MessageConfidence)
ret, err := api.StateWaitMsg(ctx, smsg.Cid())
if err != nil {
return err
}
@@ -648,7 +659,7 @@ func createStorageMiner(ctx context.Context, api lapi.FullNode, peerid peer.ID,
log.Infof("Pushed StorageMarket.CreateStorageMiner, %s to Mpool", signed.Cid())
log.Infof("Waiting for confirmation")
mw, err := api.StateWaitMsg(ctx, signed.Cid(), build.MessageConfidence)
mw, err := api.StateWaitMsg(ctx, signed.Cid())
if err != nil {
return address.Undef, err
}
+2 -1
View File
@@ -27,6 +27,7 @@ func main() {
initCmd,
rewardsCmd,
runCmd,
stopCmd,
sectorsCmd,
storageCmd,
setPriceCmd,
@@ -57,7 +58,7 @@ func main() {
app := &cli.App{
Name: "lotus-storage-miner",
Usage: "Filecoin decentralized storage network storage miner",
Version: build.UserVersion(),
Version: build.UserVersion,
EnableShellCompletion: true,
Flags: []cli.Flag{
&cli.StringFlag{
+9 -2
View File
@@ -100,9 +100,12 @@ var runCmd = &cli.Command{
return xerrors.Errorf("repo at '%s' is not initialized, run 'lotus-storage-miner init' to set it up", storageRepoPath)
}
shutdownChan := make(chan struct{})
var minerapi api.StorageMiner
stop, err := node.New(ctx,
node.StorageMiner(&minerapi),
node.Override(new(dtypes.ShutdownChan), shutdownChan),
node.Online(),
node.Repo(r),
@@ -156,8 +159,12 @@ var runCmd = &cli.Command{
sigChan := make(chan os.Signal, 2)
go func() {
<-sigChan
log.Warn("Shutting down..")
select {
case <-sigChan:
case <-shutdownChan:
}
log.Warn("Shutting down...")
if err := stop(context.TODO()); err != nil {
log.Errorf("graceful shutting down failed: %s", err)
}
+29
View File
@@ -0,0 +1,29 @@
package main
import (
_ "net/http/pprof"
"gopkg.in/urfave/cli.v2"
lcli "github.com/filecoin-project/lotus/cli"
)
var stopCmd = &cli.Command{
Name: "stop",
Usage: "Stop a running lotus storage miner",
Flags: []cli.Flag{},
Action: func(cctx *cli.Context) error {
api, closer, err := lcli.GetAPI(cctx)
if err != nil {
return err
}
defer closer()
err = api.Shutdown(lcli.ReqContext(cctx))
if err != nil {
return err
}
return nil
},
}
+1 -1
View File
@@ -249,7 +249,7 @@ var storageListCmd = &cli.Command{
type storedSector struct {
id stores.ID
store stores.SectorStorageInfo
store stores.StorageInfo
unsealed, sealed, cache bool
}
+31 -9
View File
@@ -29,6 +29,7 @@ import (
"github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/vm"
lcli "github.com/filecoin-project/lotus/cli"
"github.com/filecoin-project/lotus/lib/peermgr"
"github.com/filecoin-project/lotus/metrics"
"github.com/filecoin-project/lotus/node"
@@ -44,6 +45,26 @@ const (
preTemplateFlag = "genesis-template"
)
var daemonStopCmd = &cli.Command{
Name: "stop",
Usage: "Stop a running lotus daemon",
Flags: []cli.Flag{},
Action: func(cctx *cli.Context) error {
api, closer, err := lcli.GetAPI(cctx)
if err != nil {
return err
}
defer closer()
err = api.Shutdown(lcli.ReqContext(cctx))
if err != nil {
return err
}
return nil
},
}
// DaemonCmd is the `go-lotus daemon` command
var DaemonCmd = &cli.Command{
Name: "daemon",
@@ -134,7 +155,7 @@ var DaemonCmd = &cli.Command{
return xerrors.Errorf("repo init error: %w", err)
}
if err := paramfetch.GetParams(build.ParametersJSON(), 0); err != nil {
if err := paramfetch.GetParams(build.ParametersJson(), 0); err != nil {
return xerrors.Errorf("fetching proof parameters: %w", err)
}
@@ -150,11 +171,6 @@ var DaemonCmd = &cli.Command{
chainfile := cctx.String("import-chain")
if chainfile != "" {
chainfile, err := homedir.Expand(chainfile)
if err != nil {
return err
}
if err := ImportChain(r, chainfile); err != nil {
return err
}
@@ -175,12 +191,15 @@ var DaemonCmd = &cli.Command{
genesis = node.Override(new(modules.Genesis), testing.MakeGenesis(cctx.String(makeGenFlag), cctx.String(preTemplateFlag)))
}
shutdownChan := make(chan struct{})
var api api.FullNode
stop, err := node.New(ctx,
node.FullAPI(&api),
node.Override(new(dtypes.Bootstrapper), isBootstrapper),
node.Override(new(dtypes.ShutdownChan), shutdownChan),
node.Online(),
node.Repo(r),
@@ -226,7 +245,10 @@ var DaemonCmd = &cli.Command{
}
// TODO: properly parse api endpoint (or make it a URL)
return serveRPC(api, stop, endpoint)
return serveRPC(api, stop, endpoint, shutdownChan)
},
Subcommands: []*cli.Command{
daemonStopCmd,
},
}
@@ -274,9 +296,9 @@ func ImportChain(r repo.Repo, fname string) error {
if err != nil {
return err
}
defer lr.Close() //nolint:errcheck
defer lr.Close()
ds, err := lr.Datastore("/chain")
ds, err := lr.Datastore("/blocks")
if err != nil {
return err
}
+1 -1
View File
@@ -52,7 +52,7 @@ func main() {
app := &cli.App{
Name: "lotus",
Usage: "Filecoin decentralized storage network client",
Version: build.UserVersion(),
Version: build.UserVersion,
EnableShellCompletion: true,
Flags: []cli.Flag{
&cli.StringFlag{
+12 -6
View File
@@ -28,7 +28,7 @@ import (
var log = logging.Logger("main")
func serveRPC(a api.FullNode, stop node.StopFunc, addr multiaddr.Multiaddr) error {
func serveRPC(a api.FullNode, stop node.StopFunc, addr multiaddr.Multiaddr, shutdownCh <-chan struct{}) error {
rpcServer := jsonrpc.NewServer()
rpcServer.Register("Filecoin", apistruct.PermissionedFullAPI(a))
@@ -62,17 +62,23 @@ func serveRPC(a api.FullNode, stop node.StopFunc, addr multiaddr.Multiaddr) erro
srv := &http.Server{Handler: http.DefaultServeMux}
sigChan := make(chan os.Signal, 2)
sigCh := make(chan os.Signal, 2)
go func() {
<-sigChan
select {
case <-sigCh:
case <-shutdownCh:
}
log.Warn("Shutting down...")
if err := srv.Shutdown(context.TODO()); err != nil {
log.Errorf("shutting down RPC server failed: %s", err)
}
if err := stop(context.TODO()); err != nil {
log.Errorf("graceful shutting down failed: %s", err)
}
log.Warn("Graceful shutdown successful")
}()
signal.Notify(sigChan, syscall.SIGTERM, syscall.SIGINT)
signal.Notify(sigCh, syscall.SIGTERM, syscall.SIGINT)
return srv.Serve(manet.NetListener(lst))
}
@@ -85,14 +91,14 @@ func handleImport(a *impl.FullNodeAPI) func(w http.ResponseWriter, r *http.Reque
}
if !auth.HasPerm(r.Context(), nil, apistruct.PermWrite) {
w.WriteHeader(401)
_ = json.NewEncoder(w).Encode(struct{ Error string }{"unauthorized: missing write permission"})
json.NewEncoder(w).Encode(struct{ Error string }{"unauthorized: missing write permission"})
return
}
c, err := a.ClientImportLocal(r.Context(), r.Body)
if err != nil {
w.WriteHeader(500)
_ = json.NewEncoder(w).Encode(struct{ Error string }{err.Error()})
json.NewEncoder(w).Encode(struct{ Error string }{err.Error()})
return
}
w.WriteHeader(200)
+70
View File
@@ -0,0 +1,70 @@
# Why does Filecoin mining work best on AMD?
Currently, Filecoin's Proof of Replication (PoRep) prefers to be run on AMD
processors. More accurately, it runs much much slower on Intel CPUs (it runs
competitively fast on some ARM processors, like the ones in newer Samsung
phones, but they lack the RAM to seal the larger sector sizes). The main reason
that we see this benefit on AMD processors is due to their implementation of
the SHA hardware instructions. Now, why do we use the SHA instruction?
## PoRep security assumptions
Our research team has two different models for the security of Proofs of
Replication. These are the Latency Assumption, and the Cost Assumption. These
assumptions are arguments for why an attacker cannot pull off a 'regeneration
attack'. That is, the attacker cannot seal and commit random data (generated by
a function), delete it, and then reseal it on the fly to respond to PoSt
challenges, without actually storing the data for that time period.
### Cost Assumptions
The cost assumption states that the real money cost (hardware, electricity,
etc) of generating a sector is higher than the real money cost of simply
storing it on disks. NSE is a new PoRep our research team is working on that is
based on the cost assumption, and is thus able to be very parallelizable (In
comparison to schemes based on a latency assumption, as will be explained
next). However, cost assumptions vary greatly with available and hypothetical
hardware. For example, someone making an ASIC for NSE could break the cost
assumption by lowering the cost of sealing too much. This is one of our main
hesitations around shipping NSE.
### Latency Assumptions
A Proof of Replication that is secure under a latency assumption is secure
because an attacker cannot regenerate the data in time. We use this assumption
for SDR, where we assume that an attacker cannot regenerate enough of a sector
fast enough to respond to a PoSt. The way we achieve this is through the use
of depth-robust graphs. Without going into too much detail, depth-robust
graphs guarantee a minimum number of serial operations to compute an encoding
based on the graph. Each edge in the graph represents an operation we need to
perform. We thus have a guarantee that someone has to perform some operation
N times in a row in order to compute the encoding. That means that the
computation of the encoding must take at least as long as N times the fastest
someone can do that operation.
Now, to make this secure, we need to choose an operation that can't be made
much faster. There are many potential candidates here, depending on what
hardware you want to require. We opted not to require ASICs in order to mine
Filecoin, so that limits our choices severely. We have to look at what
operations CPUs are really good at. One candidate was AES encryption, which
also has hardware instructions. However, the difference between the performance
of CPU AES instructions, and the hypothetical 'best' performance you get was
still too great. This gap is generally called 'Amax', an attackers maximum
advantage. The higher the Amax of an algorithm we choose, the more expensive
the overall process has to become in order to bound how fast the attacker could
do it.
As we were doing our research, we noticed that AMD shipped their new processors
with a builtin SHA function, and we looked into how fast someone could possibly
compute a SHA hash. We found that AMDs implementation is only around 3 times
slower than anyone could reasonably do (given estimates by the hardware
engineers at [Supranational](https://www.supranational.net/) ). This is
incredibly impressive for something you can get in consumer hardware. With
this, we were able to make SDR sealing reasonably performant for people with
off-the-shelf hardware.
## Super Optimized CPUs
Given all of the above, with a latency assumption that we're basing our proofs
on right now, you need a processor that can do iterated SHA hashes really fast.
As mentioned earlier, this isnt just AMD processors, but many ARM processors
also have support for this. Hopefully, new Intel processors also follow suit.
But for now, Filecoin works best on AMD processors.
+154
View File
@@ -0,0 +1,154 @@
package bitvector
import (
"errors"
"log"
)
var (
// ErrOutOfRange - the index passed is out of range for the BitVector
ErrOutOfRange = errors.New("index out of range")
)
// BitNumbering indicates the ordering of bits, either
// least-significant bit in position 0, or most-significant bit
// in position 0.
//
// It it used in 3 ways with BitVector:
// 1. Ordering of bits within the Buf []byte structure
// 2. What order to add bits when using Extend()
// 3. What order to read bits when using Take()
//
// https://en.wikipedia.org/wiki/Bit_numbering
type BitNumbering int
const (
// LSB0 - bit ordering starts with the low-order bit
LSB0 BitNumbering = iota
// MSB0 - bit ordering starts with the high-order bit
MSB0
)
// BitVector is used to manipulate ordered collections of bits
type BitVector struct {
Buf []byte
// BytePacking is the bit ordering within bytes
BytePacking BitNumbering
// Len is the logical number of bits in the vector.
// The last byte in Buf may have undefined bits if Len is not a multiple of 8
Len uint
}
// NewBitVector constructs a new BitVector from a slice of bytes.
//
// The bytePacking parameter is required to know how to interpret the bit ordering within the bytes.
func NewBitVector(buf []byte, bytePacking BitNumbering) *BitVector {
return &BitVector{
BytePacking: bytePacking,
Buf: buf,
Len: uint(len(buf) * 8),
}
}
// Push adds a single bit to the BitVector.
//
// Although it takes a byte, only the low-order bit is used, so just use 0 or 1.
func (v *BitVector) Push(val byte) {
if v.Len%8 == 0 {
v.Buf = append(v.Buf, 0)
}
lastIdx := v.Len / 8
switch v.BytePacking {
case LSB0:
v.Buf[lastIdx] |= (val & 1) << (v.Len % 8)
default:
v.Buf[lastIdx] |= (val & 1) << (7 - (v.Len % 8))
}
v.Len++
}
// Get returns a single bit as a byte -- either 0 or 1
func (v *BitVector) Get(idx uint) (byte, error) {
if idx >= v.Len {
return 0, ErrOutOfRange
}
blockIdx := idx / 8
switch v.BytePacking {
case LSB0:
return v.Buf[blockIdx] >> (idx % 8) & 1, nil
default:
return v.Buf[blockIdx] >> (7 - idx%8) & 1, nil
}
}
// Extend adds up to 8 bits to the receiver
//
// Given a byte b == 0b11010101
// v.Extend(b, 4, LSB0) would add < 1, 0, 1, 0 >
// v.Extend(b, 4, MSB0) would add < 1, 1, 0, 1 >
//
// Panics if count is out of range
func (v *BitVector) Extend(val byte, count uint, order BitNumbering) {
if count > 8 {
log.Panicf("invalid count")
}
for i := uint(0); i < count; i++ {
switch order {
case LSB0:
v.Push((val >> i) & 1)
default:
v.Push((val >> (7 - i)) & 1)
}
}
}
// Take reads up to 8 bits at the given index.
//
// Given a BitVector < 1, 1, 0, 1, 0, 1, 0, 1 >
// v.Take(0, 4, LSB0) would return 0b00001011
// v.Take(0, 4, MSB0) would return 0b11010000
//
// Panics if count is out of range
func (v *BitVector) Take(index uint, count uint, order BitNumbering) (out byte) {
if count > 8 {
log.Panicf("invalid count")
}
for i := uint(0); i < count; i++ {
val, _ := v.Get(index + i)
switch order {
case LSB0:
out |= val << i
default:
out |= val << (7 - i)
}
}
return
}
// Iterator returns a function, which when invoked, returns the number
// of bits requested, and increments an internal cursor.
//
// When the end of the BitVector is reached, it returns zeroes indefinitely
//
// Panics if count is out of range
func (v *BitVector) Iterator(order BitNumbering) func(uint) byte {
cursor := uint(0)
return func(count uint) (out byte) {
if count > 8 {
log.Panicf("invalid count")
}
out = v.Take(cursor, count, order)
cursor += count
return
}
}
+136
View File
@@ -0,0 +1,136 @@
package bitvector_test
import (
"testing"
"github.com/stretchr/testify/assert"
bitvector "github.com/filecoin-project/lotus/extern/rleplus/internal"
)
func TestBitVector(t *testing.T) {
t.Run("zero value", func(t *testing.T) {
var v bitvector.BitVector
assert.Equal(t, bitvector.LSB0, v.BytePacking)
})
t.Run("Push", func(t *testing.T) {
// MSB0 bit numbering
v := bitvector.BitVector{BytePacking: bitvector.MSB0}
v.Push(1)
v.Push(0)
v.Push(1)
v.Push(1)
assert.Equal(t, byte(176), v.Buf[0])
// LSB0 bit numbering
v = bitvector.BitVector{BytePacking: bitvector.LSB0}
v.Push(1)
v.Push(0)
v.Push(1)
v.Push(1)
assert.Equal(t, byte(13), v.Buf[0])
})
t.Run("Get", func(t *testing.T) {
bits := []byte{1, 0, 1, 1, 0, 0, 1, 0}
for _, numbering := range []bitvector.BitNumbering{bitvector.MSB0, bitvector.LSB0} {
v := bitvector.BitVector{BytePacking: numbering}
for _, bit := range bits {
v.Push(bit)
}
for idx, expected := range bits {
actual, _ := v.Get(uint(idx))
assert.Equal(t, expected, actual)
}
}
})
t.Run("Extend", func(t *testing.T) {
val := byte(171) // 0b10101011
var v bitvector.BitVector
// MSB0 bit numbering
v = bitvector.BitVector{}
v.Extend(val, 4, bitvector.MSB0)
assertBitVector(t, []byte{1, 0, 1, 0}, v)
v.Extend(val, 5, bitvector.MSB0)
assertBitVector(t, []byte{1, 0, 1, 0, 1, 0, 1, 0, 1}, v)
// LSB0 bit numbering
v = bitvector.BitVector{}
v.Extend(val, 4, bitvector.LSB0)
assertBitVector(t, []byte{1, 1, 0, 1}, v)
v.Extend(val, 5, bitvector.LSB0)
assertBitVector(t, []byte{1, 1, 0, 1, 1, 1, 0, 1, 0}, v)
})
t.Run("invalid counts to Take/Extend/Iterator cause panics", func(t *testing.T) {
v := bitvector.BitVector{BytePacking: bitvector.LSB0}
assert.Panics(t, func() { v.Extend(0xff, 9, bitvector.LSB0) })
assert.Panics(t, func() { v.Take(0, 9, bitvector.LSB0) })
next := v.Iterator(bitvector.LSB0)
assert.Panics(t, func() { next(9) })
})
t.Run("Take", func(t *testing.T) {
var v bitvector.BitVector
bits := []byte{1, 0, 1, 0, 1, 0, 1, 1}
for _, bit := range bits {
v.Push(bit)
}
assert.Equal(t, byte(176), v.Take(4, 4, bitvector.MSB0))
assert.Equal(t, byte(13), v.Take(4, 4, bitvector.LSB0))
})
t.Run("Iterator", func(t *testing.T) {
var buf []byte
// make a bitvector of 256 sample bits
for i := 0; i < 32; i++ {
buf = append(buf, 128+32)
}
v := bitvector.NewBitVector(buf, bitvector.LSB0)
next := v.Iterator(bitvector.LSB0)
// compare to Get()
for i := uint(0); i < v.Len; i++ {
expected, _ := v.Get(i)
assert.Equal(t, expected, next(1))
}
// out of range should return zero
assert.Equal(t, byte(0), next(1))
assert.Equal(t, byte(0), next(8))
// compare to Take()
next = v.Iterator(bitvector.LSB0)
assert.Equal(t, next(5), v.Take(0, 5, bitvector.LSB0))
assert.Equal(t, next(8), v.Take(5, 8, bitvector.LSB0))
})
}
// Note: When using this helper assertion, expectedBits should *only* be 0s and 1s.
func assertBitVector(t *testing.T, expectedBits []byte, actual bitvector.BitVector) {
assert.Equal(t, uint(len(expectedBits)), actual.Len)
for idx, bit := range expectedBits {
actualBit, err := actual.Get(uint(idx))
assert.NoError(t, err)
assert.Equal(t, bit, actualBit)
}
}
+204
View File
@@ -0,0 +1,204 @@
package rleplus
import (
"encoding/binary"
"errors"
"fmt"
"sort"
bitvector "github.com/filecoin-project/lotus/extern/rleplus/internal"
)
// Version is the 2 lowest bits of this constant
const Version = 0
var (
// ErrRunLengthTooLarge - data implies a run-length which isn't supported
ErrRunLengthTooLarge = fmt.Errorf("run length too large for RLE+ version %d", Version)
// ErrDecode - invalid encoding for this version
ErrDecode = fmt.Errorf("invalid encoding for RLE+ version %d", Version)
// ErrWrongVersion - wrong version of RLE+
ErrWrongVersion = errors.New("invalid RLE+ version")
)
// Encode returns the RLE+ representation of the provided integers.
// Also returned is the number of bits required by this encoding,
// which is not necessarily on a byte boundary.
//
// The RLE+ spec is here: https://github.com/filecoin-project/specs/blob/master/data-structures.md#rle-bitset-encoding
// and is described by the BNF Grammar:
//
// <encoding> ::= <header> <blocks>
// <header> ::= <version> <bit>
// <version> ::= "00"
// <blocks> ::= <block> <blocks> | ""
// <block> ::= <block_single> | <block_short> | <block_long>
// <block_single> ::= "1"
// <block_short> ::= "01" <bit> <bit> <bit> <bit>
// <block_long> ::= "00" <unsigned_varint>
// <bit> ::= "0" | "1"
//
// Filecoin specific:
// The encoding is returned as a []byte, each byte packed starting with the low-order bit (LSB0)
func Encode(ints []uint64) ([]byte, uint, error) {
v := bitvector.BitVector{BytePacking: bitvector.LSB0}
firstBit, runs := RunLengths(ints)
// Add version header
v.Extend(Version, 2, bitvector.LSB0)
v.Push(firstBit)
for _, run := range runs {
switch {
case run == 1:
v.Push(1)
case run < 16:
v.Push(0)
v.Push(1)
v.Extend(byte(run), 4, bitvector.LSB0)
case run >= 16:
v.Push(0)
v.Push(0)
// 10 bytes needed to encode MaxUint64
buf := make([]byte, 10)
numBytes := binary.PutUvarint(buf, run)
for i := 0; i < numBytes; i++ {
v.Extend(buf[i], 8, bitvector.LSB0)
}
default:
return nil, 0, ErrRunLengthTooLarge
}
}
return v.Buf, v.Len, nil
}
// Decode returns integers represented by the given RLE+ encoding
//
// The length of the encoding is not specified. It is inferred by
// reading zeroes from the (possibly depleted) BitVector, by virtue
// of the behavior of BitVector.Take() returning 0 when the end of
// the BitVector has been reached. This has the downside of not
// being able to detect corrupt encodings.
//
// The passed []byte should be packed in LSB0 bit numbering
func Decode(buf []byte) (ints []uint64, err error) {
if len(buf) == 0 {
return
}
v := bitvector.NewBitVector(buf, bitvector.LSB0)
take := v.Iterator(bitvector.LSB0)
// Read version and check
// Version check
ver := take(2)
if ver != Version {
return nil, ErrWrongVersion
}
curIdx := uint64(0)
curBit := take(1)
var runLength int
done := false
for done == false {
y := take(1)
switch y {
case 1:
runLength = 1
case 0:
val := take(1)
if val == 1 {
// short block
runLength = int(take(4))
} else {
// long block
var buf []byte
for {
b := take(8)
buf = append(buf, b)
if b&0x80 == 0 {
break
}
// 10 bytes is required to store math.MaxUint64 in a uvarint
if len(buf) > 10 {
return nil, ErrDecode
}
}
x, _ := binary.Uvarint(buf)
if x == 0 {
done = true
}
runLength = int(x)
}
}
if curBit == 1 {
for j := 0; j < runLength; j++ {
ints = append(ints, curIdx+uint64(j))
}
}
curIdx += uint64(runLength)
curBit = 1 - curBit
}
return
}
// RunLengths transforms integers into its bit-set-run-length representation.
//
// A set of unsigned integers { 0, 2, 4, 5, 6 } can be thought of as
// indices into a bitset { 1, 0, 1, 0, 1, 1, 1 } where bitset[index] == 1.
//
// The bit set run lengths of this set would then be { 1, 1, 1, 1, 3 },
// representing lengths of runs alternating between 1 and 0, starting
// with a first bit of 1.
//
// Duplicated numbers are ignored.
//
// This is a helper function for Encode()
func RunLengths(ints []uint64) (firstBit byte, runs []uint64) {
if len(ints) == 0 {
return
}
// Sort our incoming numbers
sort.Slice(ints, func(i, j int) bool { return ints[i] < ints[j] })
prev := ints[0]
// Initialize our return value
if prev == 0 {
firstBit = 1
}
if firstBit == 0 {
// first run of zeroes
runs = append(runs, prev)
}
runs = append(runs, 1)
for _, cur := range ints[1:] {
delta := cur - prev
switch {
case delta == 1:
runs[len(runs)-1]++
case delta > 1:
// add run of zeroes if there is a gap
runs = append(runs, delta-1)
runs = append(runs, 1)
default:
// repeated number?
}
prev = cur
}
return
}
+213
View File
@@ -0,0 +1,213 @@
package rleplus_test
import (
"fmt"
"math"
"sort"
"testing"
"github.com/filecoin-project/lotus/extern/rleplus"
bitvector "github.com/filecoin-project/lotus/extern/rleplus/internal"
"gotest.tools/assert"
)
func TestRleplus(t *testing.T) {
t.Run("Encode", func(t *testing.T) {
// Encode an intset
ints := []uint64{
// run of 1
0,
// gap of 1
// run of 1
2,
// gap of 1
// run of 3
4, 5, 6,
// gap of 4
// run of 17
11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
}
expectedBits := []byte{
0, 0, // version
1, // first bit
1, // run of 1
1, // gap of 1
1, // run of 1
1, // gap of 1
0, 1, 1, 1, 0, 0, // run of 3
0, 1, 0, 0, 1, 0, // gap of 4
// run of 17 < 0 0 (varint) >
0, 0,
1, 0, 0, 0, 1, 0, 0, 0,
}
v := bitvector.BitVector{}
for _, bit := range expectedBits {
v.Push(bit)
}
actualBytes, _, err := rleplus.Encode(ints)
assert.NilError(t, err)
assert.Equal(t, len(v.Buf), len(actualBytes))
for idx, expected := range v.Buf {
assert.Equal(
t,
fmt.Sprintf("%08b", expected),
fmt.Sprintf("%08b", actualBytes[idx]),
)
}
})
t.Run("Encode allows all runs sizes possible uint64", func(t *testing.T) {
// create a run of math.MaxUint64
ints := []uint64{math.MaxUint64}
// There would be 64 bits(1) for the UvarInt, totally 9 bytes.
expected := []byte{0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x20}
encodeBytes, _, err := rleplus.Encode(ints)
assert.NilError(t, err)
for idx, v := range encodeBytes {
assert.Equal(
t,
fmt.Sprintf("%8b", v),
fmt.Sprintf("%8b", expected[idx]),
)
}
})
t.Run("Encode for some big numbers", func(t *testing.T) {
// create a run of math.MaxUint64
ints := make([]uint64, 1024)
// ints {2^63 .. 2^63+1023}
for i := uint64(0); i < 1024; i++ {
ints[i] = uint64(1)<<63 + i
}
expected := []byte{0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x40, 0x04}
encodeBytes, _, err := rleplus.Encode(ints)
assert.NilError(t, err)
for idx, v := range encodeBytes {
// fmt.Println(v, expected[idx])
assert.Equal(
t,
fmt.Sprintf("%8b", v),
fmt.Sprintf("%8b", expected[idx]),
)
}
})
t.Run("Decode", func(t *testing.T) {
testCases := [][]uint64{
{},
{1},
{0},
{0, 1, 2, 3},
{
// run of 1
0,
// gap of 1
// run of 1
2,
// gap of 1
// run of 3
4, 5, 6,
// gap of 4
// run of 17
11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
},
}
for _, tc := range testCases {
encoded, _, err := rleplus.Encode(tc)
assert.NilError(t, err)
result, err := rleplus.Decode(encoded)
assert.NilError(t, err)
sort.Slice(tc, func(i, j int) bool { return tc[i] < tc[j] })
sort.Slice(result, func(i, j int) bool { return result[i] < result[j] })
assert.Equal(t, len(tc), len(result))
for idx, expected := range tc {
assert.Equal(t, expected, result[idx])
}
}
})
t.Run("Decode version check", func(t *testing.T) {
_, err := rleplus.Decode([]byte{0xff})
assert.Error(t, err, "invalid RLE+ version")
})
t.Run("Decode returns an error with a bad encoding", func(t *testing.T) {
// create an encoding with a buffer with a run which is too long
_, err := rleplus.Decode([]byte{0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff})
assert.Error(t, err, "invalid encoding for RLE+ version 0")
})
t.Run("outputs same as reference implementation", func(t *testing.T) {
// Encoding bitvec![LittleEndian; 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
// in the Rust reference implementation gives an encoding of [223, 145, 136, 0] (without version field)
// The bit vector is equivalent to the integer set { 0, 2, 4, 5, 6, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 }
// This is the above reference output with a version header "00" manually added
referenceEncoding := []byte{124, 71, 34, 2}
expectedNumbers := []uint64{0, 2, 4, 5, 6, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27}
encoded, _, err := rleplus.Encode(expectedNumbers)
assert.NilError(t, err)
// Our encoded bytes are the same as the ref bytes
assert.Equal(t, len(referenceEncoding), len(encoded))
for idx, expected := range referenceEncoding {
assert.Equal(t, expected, encoded[idx])
}
decoded, err := rleplus.Decode(referenceEncoding)
assert.NilError(t, err)
// Our decoded integers are the same as expected
sort.Slice(decoded, func(i, j int) bool { return decoded[i] < decoded[j] })
assert.Equal(t, len(expectedNumbers), len(decoded))
for idx, expected := range expectedNumbers {
assert.Equal(t, expected, decoded[idx])
}
})
t.Run("RunLengths", func(t *testing.T) {
testCases := []struct {
ints []uint64
first byte
runs []uint64
}{
// empty
{},
// leading with ones
{[]uint64{0}, 1, []uint64{1}},
{[]uint64{0, 1}, 1, []uint64{2}},
{[]uint64{0, 0xffffffff, 0xffffffff + 1}, 1, []uint64{1, 0xffffffff - 1, 2}},
// leading with zeroes
{[]uint64{1}, 0, []uint64{1, 1}},
{[]uint64{2}, 0, []uint64{2, 1}},
{[]uint64{10, 11, 13, 20}, 0, []uint64{10, 2, 1, 1, 6, 1}},
{[]uint64{10, 11, 11, 13, 20, 10, 11, 13, 20}, 0, []uint64{10, 2, 1, 1, 6, 1}},
}
for _, testCase := range testCases {
first, runs := rleplus.RunLengths(testCase.ints)
assert.Equal(t, testCase.first, first)
assert.Equal(t, len(testCase.runs), len(runs))
for idx, runLength := range testCase.runs {
assert.Equal(t, runLength, runs[idx])
}
}
})
}
+1 -1
View File
@@ -28,7 +28,7 @@ type PreSeal struct {
type Miner struct {
Owner address.Address
Worker address.Address
PeerId peer.ID //nolint:golint
PeerId peer.ID
MarketBalance abi.TokenAmount
PowerBalance abi.TokenAmount
+22 -26
View File
@@ -11,14 +11,13 @@ require (
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect
github.com/coreos/go-systemd/v22 v22.0.0
github.com/docker/go-units v0.4.0
github.com/drand/drand v0.9.2-0.20200529123141-6b138aefaef2
github.com/drand/kyber v1.0.2
github.com/drand/drand v0.8.2-0.20200518165838-d61135e6e2c8
github.com/fatih/color v1.8.0
github.com/filecoin-project/chain-validation v0.0.6-0.20200528212128-d4578ae4f874
github.com/filecoin-project/chain-validation v0.0.6-0.20200526171800-c56c1882dc99
github.com/filecoin-project/filecoin-ffi v0.26.1-0.20200508175440-05b30afeb00d
github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef
github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200424220931-6263827e49f2
github.com/filecoin-project/go-bitfield v0.0.2-0.20200518150651-562fdb554b6e
github.com/filecoin-project/go-bitfield v0.0.1
github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2
github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03
github.com/filecoin-project/go-data-transfer v0.3.0
@@ -29,27 +28,24 @@ require (
github.com/filecoin-project/go-paramfetch v0.0.2-0.20200505180321-973f8949ea8e
github.com/filecoin-project/go-statestore v0.1.0
github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b
github.com/filecoin-project/sector-storage v0.0.0-20200529175241-9df0cdf19326
github.com/filecoin-project/specs-actors v0.5.4
github.com/filecoin-project/sector-storage v0.0.0-20200522011946-a59ca7536a95
github.com/filecoin-project/specs-actors v0.5.4-0.20200521014528-0df536f7e461
github.com/filecoin-project/specs-storage v0.0.0-20200417134612-61b2d91a6102
github.com/filecoin-project/storage-fsm v0.0.0-20200528050623-cdada6e88960
github.com/filecoin-project/storage-fsm v0.0.0-20200522010518-83fd743db8bc
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1
github.com/go-kit/kit v0.10.0
github.com/go-ole/go-ole v1.2.4 // indirect
github.com/google/uuid v1.1.1
github.com/gorilla/mux v1.7.4
github.com/gorilla/websocket v1.4.2
github.com/hashicorp/go-multierror v1.1.0
github.com/hashicorp/golang-lru v0.5.4
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d
github.com/influxdata/influxdb1-client v0.0.0-20190809212627-fc22c7df067e
github.com/ipfs/go-bitswap v0.2.8
github.com/ipfs/go-block-format v0.0.2
github.com/ipfs/go-blockservice v0.1.3
github.com/ipfs/go-cid v0.0.6-0.20200501230655-7c82f3b81c00
github.com/ipfs/go-datastore v0.4.4
github.com/ipfs/go-ds-badger2 v0.1.0
github.com/ipfs/go-ds-leveldb v0.4.2
github.com/ipfs/go-ds-measure v0.1.0
github.com/ipfs/go-filestore v1.0.0
github.com/ipfs/go-fs-lock v0.0.1
github.com/ipfs/go-graphsync v0.0.6-0.20200504202014-9d5f2c26a103
@@ -65,33 +61,33 @@ require (
github.com/ipfs/go-ipld-cbor v0.0.5-0.20200428170625-a0bd04d3cbdf
github.com/ipfs/go-ipld-format v0.2.0
github.com/ipfs/go-log v1.0.4
github.com/ipfs/go-log/v2 v2.1.1
github.com/ipfs/go-log/v2 v2.0.8
github.com/ipfs/go-merkledag v0.3.1
github.com/ipfs/go-path v0.0.7
github.com/ipfs/go-unixfs v0.2.4
github.com/ipfs/interface-go-ipfs-core v0.2.3
github.com/ipld/go-car v0.1.1-0.20200526133713-1c7508d55aae
github.com/ipld/go-car v0.1.1-0.20200430185908-8ff2e52a4c88
github.com/ipld/go-ipld-prime v0.0.2-0.20200428162820-8b59dc292b8e
github.com/kelseyhightower/envconfig v1.4.0
github.com/lib/pq v1.2.0
github.com/libp2p/go-eventbus v0.1.0
github.com/libp2p/go-libp2p v0.9.2
github.com/libp2p/go-libp2p-connmgr v0.2.3
github.com/libp2p/go-libp2p-core v0.5.6
github.com/libp2p/go-eventbus v0.2.1
github.com/libp2p/go-libp2p v0.9.4
github.com/libp2p/go-libp2p-connmgr v0.2.4
github.com/libp2p/go-libp2p-core v0.5.7
github.com/libp2p/go-libp2p-discovery v0.4.0
github.com/libp2p/go-libp2p-kad-dht v0.7.6
github.com/libp2p/go-libp2p-kad-dht v0.8.1
github.com/libp2p/go-libp2p-mplex v0.2.3
github.com/libp2p/go-libp2p-peer v0.2.0
github.com/libp2p/go-libp2p-peerstore v0.2.4
github.com/libp2p/go-libp2p-pubsub v0.3.1
github.com/libp2p/go-libp2p-quic-transport v0.1.1
github.com/libp2p/go-libp2p-pubsub v0.3.2
github.com/libp2p/go-libp2p-quic-transport v0.5.0
github.com/libp2p/go-libp2p-record v0.1.2
github.com/libp2p/go-libp2p-routing-helpers v0.2.1
github.com/libp2p/go-libp2p-routing-helpers v0.2.3
github.com/libp2p/go-libp2p-secio v0.2.2
github.com/libp2p/go-libp2p-swarm v0.2.4
github.com/libp2p/go-libp2p-swarm v0.2.6
github.com/libp2p/go-libp2p-tls v0.1.3
github.com/libp2p/go-libp2p-yamux v0.2.7
github.com/libp2p/go-maddr-filter v0.0.5
github.com/libp2p/go-libp2p-yamux v0.2.8
github.com/libp2p/go-maddr-filter v0.1.0
github.com/mattn/go-isatty v0.0.12 // indirect
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1
github.com/mitchellh/go-homedir v1.1.0
@@ -103,7 +99,6 @@ require (
github.com/opentracing/opentracing-go v1.1.0
github.com/stretchr/objx v0.2.0 // indirect
github.com/stretchr/testify v1.5.1
github.com/syndtr/goleveldb v1.0.0
github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba
github.com/whyrusleeping/cbor-gen v0.0.0-20200504204219-64967432584d
github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7
@@ -115,9 +110,10 @@ require (
go.uber.org/zap v1.15.0
go4.org v0.0.0-20190313082347-94abd6928b1d // indirect
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299
golang.org/x/time v0.0.0-20191024005414-555d28b269f0
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543
gopkg.in/urfave/cli.v2 v2.0.0-20180128182452-d3ae77c26ac8
gotest.tools v2.2.0+incompatible
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 // indirect
)
+228 -259
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -11,7 +11,7 @@ import (
madns "github.com/multiformats/go-multiaddr-dns"
)
// ParseAddresses is a function that takes in a slice of string peer addresses
// parseAddresses is a function that takes in a slice of string peer addresses
// (multiaddr + peerid) and returns a slice of properly constructed peers
func ParseAddresses(ctx context.Context, addrs []string) ([]peer.AddrInfo, error) {
// resolve addresses

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