Merge branch 'feat/election-post' into feat/remote-workers

This commit is contained in:
Łukasz Magiera 2019-11-30 09:41:52 +01:00
commit 8767d8c16b
113 changed files with 3588 additions and 1512 deletions

View File

@ -46,6 +46,15 @@ jobs:
- go/mod-download - go/mod-download
- go/mod-tidy-check - go/mod-tidy-check
build-all:
executor: golang
steps:
- install-deps
- prepare
- go/mod-download
- run:
command: make buildall
test: test:
description: | description: |
Run tests with gotestsum. Run tests with gotestsum.
@ -166,3 +175,4 @@ workflows:
- test: - test:
codecov-upload: true codecov-upload: true
- mod-tidy-check - mod-tidy-check
- build-all

4
.gitignore vendored
View File

@ -1,9 +1,13 @@
/lotus /lotus
/lotus-storage-miner /lotus-storage-miner
/lotus-seal-worker /lotus-seal-worker
/lotus-seed
/pond /pond
/townhall /townhall
/fountain /fountain
/stats
/bench
/bench.json
/lotuspond/front/node_modules /lotuspond/front/node_modules
/lotuspond/front/build /lotuspond/front/build
/cmd/lotus-townhall/townhall/node_modules /cmd/lotus-townhall/townhall/node_modules

10
.gitmodules vendored
View File

@ -1,6 +1,4 @@
[submodule "extern/go-bls-sigs"] [submodule "extern/filecoin-ffi"]
path = extern/go-bls-sigs path = extern/filecoin-ffi
url = https://github.com/filecoin-project/go-bls-sigs.git url = https://github.com/filecoin-project/filecoin-ffi.git
[submodule "extern/go-sectorbuilder"] branch = master
path = extern/go-sectorbuilder
url = https://github.com/filecoin-project/go-sectorbuilder

View File

@ -12,37 +12,21 @@ MODULES:=
CLEAN:= CLEAN:=
## BLS ## FFI
BLS_PATH:=extern/go-bls-sigs/ FFI_PATH:=extern/filecoin-ffi/
BLS_DEPS:=libbls_signatures.a libbls_signatures.pc libbls_signatures.h FFI_DEPS:=libfilecoin.a filecoin.pc filecoin.h
BLS_DEPS:=$(addprefix $(BLS_PATH),$(BLS_DEPS)) FFI_DEPS:=$(addprefix $(FFI_PATH),$(FFI_DEPS))
$(BLS_DEPS): build/.bls-install ; $(FFI_DEPS): build/.filecoin-install ;
build/.bls-install: $(BLS_PATH) build/.filecoin-install: $(FFI_PATH)
$(MAKE) -C $(BLS_PATH) $(BLS_DEPS:$(BLS_PATH)%=%) $(MAKE) -C $(FFI_PATH) $(FFI_DEPS:$(FFI_PATH)%=%)
@touch $@ @touch $@
MODULES+=$(BLS_PATH) MODULES+=$(FFI_PATH)
BUILD_DEPS+=build/.bls-install BUILD_DEPS+=build/.filecoin-install
CLEAN+=build/.bls-install CLEAN+=build/.filecoin-install
## SECTOR BUILDER
SECTOR_BUILDER_PATH:=extern/go-sectorbuilder/
SECTOR_BUILDER_DEPS:=libsector_builder_ffi.a sector_builder_ffi.pc sector_builder_ffi.h
SECTOR_BUILDER_DEPS:=$(addprefix $(SECTOR_BUILDER_PATH),$(SECTOR_BUILDER_DEPS))
$(SECTOR_BUILDER_DEPS): build/.sector-builder-install ;
build/.sector-builder-install: $(SECTOR_BUILDER_PATH)
$(MAKE) -C $(SECTOR_BUILDER_PATH) $(SECTOR_BUILDER_DEPS:$(SECTOR_BUILDER_PATH)%=%)
@touch $@
MODULES+=$(SECTOR_BUILDER_PATH)
BUILD_DEPS+=build/.sector-builder-install
CLEAN+=build/.sector-builder-install
$(MODULES): build/.update-modules ; $(MODULES): build/.update-modules ;
@ -53,43 +37,55 @@ build/.update-modules:
# end git modules # end git modules
## PROOFS ## MAIN BINARIES
CLEAN+=build/.update-modules CLEAN+=build/.update-modules
deps: $(BUILD_DEPS) deps: $(BUILD_DEPS)
.PHONY: deps .PHONY: deps
debug: GOFLAGS=-tags=debug
debug: lotus lotus-storage-miner
lotus: $(BUILD_DEPS) lotus: $(BUILD_DEPS)
rm -f lotus rm -f lotus
go build -o lotus ./cmd/lotus go build $(GOFLAGS) -o lotus ./cmd/lotus
go run github.com/GeertJohan/go.rice/rice append --exec lotus -i ./build go run github.com/GeertJohan/go.rice/rice append --exec lotus -i ./build
.PHONY: lotus .PHONY: lotus
CLEAN+=lotus BINS+=lotus
lotus-storage-miner: $(BUILD_DEPS) lotus-storage-miner: $(BUILD_DEPS)
rm -f lotus-storage-miner rm -f lotus-storage-miner
go build -o lotus-storage-miner ./cmd/lotus-storage-miner go build $(GOFLAGS) -o lotus-storage-miner ./cmd/lotus-storage-miner
go run github.com/GeertJohan/go.rice/rice append --exec lotus-storage-miner -i ./build go run github.com/GeertJohan/go.rice/rice append --exec lotus-storage-miner -i ./build
.PHONY: lotus-storage-miner .PHONY: lotus-storage-miner
BINS+=lotus-storage-miner
lotus-seal-worker: $(BUILD_DEPS) lotus-seal-worker: $(BUILD_DEPS)
rm -f lotus-seal-worker rm -f lotus-seal-worker
go build -o lotus-seal-worker ./cmd/lotus-seal-worker go build -o lotus-seal-worker ./cmd/lotus-seal-worker
go run github.com/GeertJohan/go.rice/rice append --exec lotus-seal-worker -i ./build go run github.com/GeertJohan/go.rice/rice append --exec lotus-seal-worker -i ./build
.PHONY: lotus-seal-worker .PHONY: lotus-seal-worker
BINS+=lotus-seal-worker
CLEAN+=lotus-storage-miner
build: lotus lotus-storage-miner build: lotus lotus-storage-miner
.PHONY: build .PHONY: build
install: install:
install -C ./lotus /usr/local/bin/lotus install -C ./lotus /usr/local/bin/lotus
install -C ./lotus-storage-miner /usr/local/bin/lotus-storage-miner install -C ./lotus-storage-miner /usr/local/bin/lotus-storage-miner
# TOOLS
lotus-seed: $(BUILD_DEPS)
rm -f lotus-seed
go build -o lotus-seed ./cmd/lotus-seed
go run github.com/GeertJohan/go.rice/rice append --exec lotus-seed -i ./build
.PHONY: lotus-seed
BINS+=lotus-seed
benchmarks: benchmarks:
go run github.com/whyrusleeping/bencher ./... > bench.json go run github.com/whyrusleeping/bencher ./... > bench.json
@echo Submitting results @echo Submitting results
@ -100,6 +96,7 @@ pond: build
go build -o pond ./lotuspond go build -o pond ./lotuspond
(cd lotuspond/front && npm i && npm run build) (cd lotuspond/front && npm i && npm run build)
.PHONY: pond .PHONY: pond
BINS+=pond
townhall: townhall:
rm -f townhall rm -f townhall
@ -107,28 +104,42 @@ townhall:
(cd ./cmd/lotus-townhall/townhall && npm i && npm run build) (cd ./cmd/lotus-townhall/townhall && npm i && npm run build)
go run github.com/GeertJohan/go.rice/rice append --exec townhall -i ./cmd/lotus-townhall -i ./build go run github.com/GeertJohan/go.rice/rice append --exec townhall -i ./cmd/lotus-townhall -i ./build
.PHONY: townhall .PHONY: townhall
BINS+=townhall
fountain: fountain:
rm -f fountain rm -f fountain
go build -o fountain ./cmd/lotus-fountain go build -o fountain ./cmd/lotus-fountain
go run github.com/GeertJohan/go.rice/rice append --exec fountain -i ./cmd/lotus-fountain go run github.com/GeertJohan/go.rice/rice append --exec fountain -i ./cmd/lotus-fountain
.PHONY: fountain .PHONY: fountain
BINS+=fountain
chainwatch: chainwatch:
rm -f chainwatch rm -f chainwatch
go build -o chainwatch ./cmd/lotus-chainwatch go build -o chainwatch ./cmd/lotus-chainwatch
go run github.com/GeertJohan/go.rice/rice append --exec chainwatch -i ./cmd/lotus-chainwatch go run github.com/GeertJohan/go.rice/rice append --exec chainwatch -i ./cmd/lotus-chainwatch
.PHONY: chainwatch .PHONY: chainwatch
BINS+=chainwatch
bench:
rm -f bench
go build -o bench ./cmd/lotus-bench
go run github.com/GeertJohan/go.rice/rice append --exec bench -i ./build
.PHONY: bench
BINS+=bench
stats: stats:
rm -f stats rm -f stats
go build -o stats ./tools/stats go build -o stats ./tools/stats
.PHONY: stats .PHONY: stats
BINS+=stats
# MISC
buildall: $(BINS)
clean: clean:
rm -rf $(CLEAN) rm -rf $(CLEAN) $(BINS)
-$(MAKE) -C $(BLS_PATH) clean -$(MAKE) -C $(FFI_PATH) clean
-$(MAKE) -C $(SECTOR_BUILDER_PATH) clean
.PHONY: clean .PHONY: clean
dist-clean: dist-clean:

View File

@ -23,7 +23,7 @@ type FullNode interface {
// First message is guaranteed to be of len == 1, and type == 'current' // First message is guaranteed to be of len == 1, and type == 'current'
ChainNotify(context.Context) (<-chan []*store.HeadChange, error) ChainNotify(context.Context) (<-chan []*store.HeadChange, error)
ChainHead(context.Context) (*types.TipSet, error) ChainHead(context.Context) (*types.TipSet, error)
ChainGetRandomness(context.Context, types.TipSetKey, []*types.Ticket, int) ([]byte, error) ChainGetRandomness(context.Context, types.TipSetKey, int64) ([]byte, error)
ChainGetBlock(context.Context, cid.Cid) (*types.BlockHeader, error) ChainGetBlock(context.Context, cid.Cid) (*types.BlockHeader, error)
ChainGetTipSet(context.Context, types.TipSetKey) (*types.TipSet, error) ChainGetTipSet(context.Context, types.TipSetKey) (*types.TipSet, error)
ChainGetBlockMessages(context.Context, cid.Cid) (*BlockMessages, error) ChainGetBlockMessages(context.Context, cid.Cid) (*BlockMessages, error)
@ -51,10 +51,7 @@ type FullNode interface {
// miner // miner
MinerRegister(context.Context, address.Address) error MinerCreateBlock(context.Context, address.Address, *types.TipSet, *types.Ticket, *types.EPostProof, []*types.SignedMessage, uint64, uint64) (*types.BlockMsg, error)
MinerUnregister(context.Context, address.Address) error
MinerAddresses(context.Context) ([]address.Address, error)
MinerCreateBlock(context.Context, address.Address, *types.TipSet, []*types.Ticket, types.ElectionProof, []*types.SignedMessage, uint64) (*types.BlockMsg, error)
// // UX ? // // UX ?
@ -102,7 +99,7 @@ type FullNode interface {
StateMinerPower(context.Context, address.Address, *types.TipSet) (MinerPower, error) StateMinerPower(context.Context, address.Address, *types.TipSet) (MinerPower, error)
StateMinerWorker(context.Context, address.Address, *types.TipSet) (address.Address, error) StateMinerWorker(context.Context, address.Address, *types.TipSet) (address.Address, error)
StateMinerPeerID(ctx context.Context, m address.Address, ts *types.TipSet) (peer.ID, error) StateMinerPeerID(ctx context.Context, m address.Address, ts *types.TipSet) (peer.ID, error)
StateMinerProvingPeriodEnd(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error) StateMinerElectionPeriodStart(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error)
StateMinerSectorSize(context.Context, address.Address, *types.TipSet) (uint64, error) StateMinerSectorSize(context.Context, address.Address, *types.TipSet) (uint64, error)
StatePledgeCollateral(context.Context, *types.TipSet) (types.BigInt, error) StatePledgeCollateral(context.Context, *types.TipSet) (types.BigInt, error)
StateWaitMsg(context.Context, cid.Cid) (*MsgWait, error) StateWaitMsg(context.Context, cid.Cid) (*MsgWait, error)

View File

@ -38,19 +38,19 @@ type FullNodeStruct struct {
CommonStruct CommonStruct
Internal struct { Internal struct {
ChainNotify func(context.Context) (<-chan []*store.HeadChange, error) `perm:"read"` ChainNotify func(context.Context) (<-chan []*store.HeadChange, error) `perm:"read"`
ChainHead func(context.Context) (*types.TipSet, error) `perm:"read"` ChainHead func(context.Context) (*types.TipSet, error) `perm:"read"`
ChainGetRandomness func(context.Context, types.TipSetKey, []*types.Ticket, int) ([]byte, error) `perm:"read"` ChainGetRandomness func(context.Context, types.TipSetKey, int64) ([]byte, error) `perm:"read"`
ChainGetBlock func(context.Context, cid.Cid) (*types.BlockHeader, error) `perm:"read"` ChainGetBlock func(context.Context, cid.Cid) (*types.BlockHeader, error) `perm:"read"`
ChainGetTipSet func(context.Context, types.TipSetKey) (*types.TipSet, error) `perm:"read"` ChainGetTipSet func(context.Context, types.TipSetKey) (*types.TipSet, error) `perm:"read"`
ChainGetBlockMessages func(context.Context, cid.Cid) (*BlockMessages, error) `perm:"read"` ChainGetBlockMessages func(context.Context, cid.Cid) (*BlockMessages, error) `perm:"read"`
ChainGetParentReceipts func(context.Context, cid.Cid) ([]*types.MessageReceipt, error) `perm:"read"` ChainGetParentReceipts func(context.Context, cid.Cid) ([]*types.MessageReceipt, error) `perm:"read"`
ChainGetParentMessages func(context.Context, cid.Cid) ([]Message, error) `perm:"read"` ChainGetParentMessages func(context.Context, cid.Cid) ([]Message, error) `perm:"read"`
ChainGetTipSetByHeight func(context.Context, uint64, *types.TipSet) (*types.TipSet, error) `perm:"read"` ChainGetTipSetByHeight func(context.Context, uint64, *types.TipSet) (*types.TipSet, error) `perm:"read"`
ChainReadObj func(context.Context, cid.Cid) ([]byte, error) `perm:"read"` ChainReadObj func(context.Context, cid.Cid) ([]byte, error) `perm:"read"`
ChainSetHead func(context.Context, *types.TipSet) error `perm:"admin"` ChainSetHead func(context.Context, *types.TipSet) error `perm:"admin"`
ChainGetGenesis func(context.Context) (*types.TipSet, error) `perm:"read"` ChainGetGenesis func(context.Context) (*types.TipSet, error) `perm:"read"`
ChainTipSetWeight func(context.Context, *types.TipSet) (types.BigInt, error) `perm:"read"` ChainTipSetWeight func(context.Context, *types.TipSet) (types.BigInt, error) `perm:"read"`
SyncState func(context.Context) (*SyncState, error) `perm:"read"` SyncState func(context.Context) (*SyncState, error) `perm:"read"`
SyncSubmitBlock func(ctx context.Context, blk *types.BlockMsg) error `perm:"write"` SyncSubmitBlock func(ctx context.Context, blk *types.BlockMsg) error `perm:"write"`
@ -62,10 +62,7 @@ type FullNodeStruct struct {
MpoolGetNonce func(context.Context, address.Address) (uint64, error) `perm:"read"` MpoolGetNonce func(context.Context, address.Address) (uint64, error) `perm:"read"`
MpoolSub func(context.Context) (<-chan MpoolUpdate, error) `perm:"read"` MpoolSub func(context.Context) (<-chan MpoolUpdate, error) `perm:"read"`
MinerRegister func(context.Context, address.Address) error `perm:"admin"` MinerCreateBlock func(context.Context, address.Address, *types.TipSet, *types.Ticket, *types.EPostProof, []*types.SignedMessage, uint64, uint64) (*types.BlockMsg, error) `perm:"write"`
MinerUnregister func(context.Context, address.Address) error `perm:"admin"`
MinerAddresses func(context.Context) ([]address.Address, error) `perm:"write"`
MinerCreateBlock func(context.Context, address.Address, *types.TipSet, []*types.Ticket, types.ElectionProof, []*types.SignedMessage, uint64) (*types.BlockMsg, error) `perm:"write"`
WalletNew func(context.Context, string) (address.Address, error) `perm:"write"` WalletNew func(context.Context, string) (address.Address, error) `perm:"write"`
WalletHas func(context.Context, address.Address) (bool, error) `perm:"write"` WalletHas func(context.Context, address.Address) (bool, error) `perm:"write"`
@ -88,28 +85,28 @@ type FullNodeStruct struct {
ClientRetrieve func(ctx context.Context, order RetrievalOrder, path string) error `perm:"admin"` ClientRetrieve func(ctx context.Context, order RetrievalOrder, path string) error `perm:"admin"`
ClientQueryAsk func(ctx context.Context, p peer.ID, miner address.Address) (*types.SignedStorageAsk, error) `perm:"read"` ClientQueryAsk func(ctx context.Context, p peer.ID, miner address.Address) (*types.SignedStorageAsk, error) `perm:"read"`
StateMinerSectors func(context.Context, address.Address, *types.TipSet) ([]*ChainSectorInfo, error) `perm:"read"` StateMinerSectors func(context.Context, address.Address, *types.TipSet) ([]*ChainSectorInfo, error) `perm:"read"`
StateMinerProvingSet func(context.Context, address.Address, *types.TipSet) ([]*ChainSectorInfo, error) `perm:"read"` StateMinerProvingSet func(context.Context, address.Address, *types.TipSet) ([]*ChainSectorInfo, error) `perm:"read"`
StateMinerPower func(context.Context, address.Address, *types.TipSet) (MinerPower, error) `perm:"read"` StateMinerPower func(context.Context, address.Address, *types.TipSet) (MinerPower, error) `perm:"read"`
StateMinerWorker func(context.Context, address.Address, *types.TipSet) (address.Address, error) `perm:"read"` StateMinerWorker func(context.Context, address.Address, *types.TipSet) (address.Address, error) `perm:"read"`
StateMinerPeerID func(ctx context.Context, m address.Address, ts *types.TipSet) (peer.ID, error) `perm:"read"` StateMinerPeerID func(ctx context.Context, m address.Address, ts *types.TipSet) (peer.ID, error) `perm:"read"`
StateMinerProvingPeriodEnd func(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error) `perm:"read"` StateMinerElectionPeriodStart func(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error) `perm:"read"`
StateMinerSectorSize func(context.Context, address.Address, *types.TipSet) (uint64, error) `perm:"read"` StateMinerSectorSize func(context.Context, address.Address, *types.TipSet) (uint64, error) `perm:"read"`
StateCall func(context.Context, *types.Message, *types.TipSet) (*types.MessageReceipt, error) `perm:"read"` StateCall func(context.Context, *types.Message, *types.TipSet) (*types.MessageReceipt, error) `perm:"read"`
StateReplay func(context.Context, *types.TipSet, cid.Cid) (*ReplayResults, error) `perm:"read"` StateReplay func(context.Context, *types.TipSet, cid.Cid) (*ReplayResults, error) `perm:"read"`
StateGetActor func(context.Context, address.Address, *types.TipSet) (*types.Actor, error) `perm:"read"` StateGetActor func(context.Context, address.Address, *types.TipSet) (*types.Actor, error) `perm:"read"`
StateReadState func(context.Context, *types.Actor, *types.TipSet) (*ActorState, error) `perm:"read"` StateReadState func(context.Context, *types.Actor, *types.TipSet) (*ActorState, error) `perm:"read"`
StatePledgeCollateral func(context.Context, *types.TipSet) (types.BigInt, error) `perm:"read"` StatePledgeCollateral func(context.Context, *types.TipSet) (types.BigInt, error) `perm:"read"`
StateWaitMsg func(context.Context, cid.Cid) (*MsgWait, error) `perm:"read"` StateWaitMsg func(context.Context, cid.Cid) (*MsgWait, error) `perm:"read"`
StateListMiners func(context.Context, *types.TipSet) ([]address.Address, error) `perm:"read"` StateListMiners func(context.Context, *types.TipSet) ([]address.Address, error) `perm:"read"`
StateListActors func(context.Context, *types.TipSet) ([]address.Address, error) `perm:"read"` StateListActors func(context.Context, *types.TipSet) ([]address.Address, error) `perm:"read"`
StateMarketBalance func(context.Context, address.Address, *types.TipSet) (actors.StorageParticipantBalance, error) `perm:"read"` StateMarketBalance func(context.Context, address.Address, *types.TipSet) (actors.StorageParticipantBalance, error) `perm:"read"`
StateMarketParticipants func(context.Context, *types.TipSet) (map[string]actors.StorageParticipantBalance, error) `perm:"read"` StateMarketParticipants func(context.Context, *types.TipSet) (map[string]actors.StorageParticipantBalance, error) `perm:"read"`
StateMarketDeals func(context.Context, *types.TipSet) (map[string]actors.OnChainDeal, error) `perm:"read"` StateMarketDeals func(context.Context, *types.TipSet) (map[string]actors.OnChainDeal, error) `perm:"read"`
StateMarketStorageDeal func(context.Context, uint64, *types.TipSet) (*actors.OnChainDeal, error) `perm:"read"` StateMarketStorageDeal func(context.Context, uint64, *types.TipSet) (*actors.OnChainDeal, error) `perm:"read"`
StateLookupID func(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) `perm:"read"` StateLookupID func(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) `perm:"read"`
StateChangedActors func(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error) `perm:"read"` StateChangedActors func(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error) `perm:"read"`
StateGetReceipt func(context.Context, cid.Cid, *types.TipSet) (*types.MessageReceipt, error) `perm:"read"` StateGetReceipt func(context.Context, cid.Cid, *types.TipSet) (*types.MessageReceipt, error) `perm:"read"`
MarketEnsureAvailable func(context.Context, address.Address, types.BigInt) error `perm:"sign"` MarketEnsureAvailable func(context.Context, address.Address, types.BigInt) error `perm:"sign"`
@ -238,28 +235,16 @@ func (c *FullNodeStruct) MpoolSub(ctx context.Context) (<-chan MpoolUpdate, erro
return c.Internal.MpoolSub(ctx) return c.Internal.MpoolSub(ctx)
} }
func (c *FullNodeStruct) MinerRegister(ctx context.Context, addr address.Address) error { func (c *FullNodeStruct) MinerCreateBlock(ctx context.Context, addr address.Address, base *types.TipSet, ticket *types.Ticket, eproof *types.EPostProof, msgs []*types.SignedMessage, height, ts uint64) (*types.BlockMsg, error) {
return c.Internal.MinerRegister(ctx, addr) return c.Internal.MinerCreateBlock(ctx, addr, base, ticket, eproof, msgs, height, ts)
}
func (c *FullNodeStruct) MinerUnregister(ctx context.Context, addr address.Address) error {
return c.Internal.MinerUnregister(ctx, addr)
}
func (c *FullNodeStruct) MinerAddresses(ctx context.Context) ([]address.Address, error) {
return c.Internal.MinerAddresses(ctx)
}
func (c *FullNodeStruct) MinerCreateBlock(ctx context.Context, addr address.Address, base *types.TipSet, tickets []*types.Ticket, eproof types.ElectionProof, msgs []*types.SignedMessage, ts uint64) (*types.BlockMsg, error) {
return c.Internal.MinerCreateBlock(ctx, addr, base, tickets, eproof, msgs, ts)
} }
func (c *FullNodeStruct) ChainHead(ctx context.Context) (*types.TipSet, error) { func (c *FullNodeStruct) ChainHead(ctx context.Context) (*types.TipSet, error) {
return c.Internal.ChainHead(ctx) return c.Internal.ChainHead(ctx)
} }
func (c *FullNodeStruct) ChainGetRandomness(ctx context.Context, pts types.TipSetKey, ticks []*types.Ticket, lb int) ([]byte, error) { func (c *FullNodeStruct) ChainGetRandomness(ctx context.Context, pts types.TipSetKey, round int64) ([]byte, error) {
return c.Internal.ChainGetRandomness(ctx, pts, ticks, lb) return c.Internal.ChainGetRandomness(ctx, pts, round)
} }
func (c *FullNodeStruct) ChainGetTipSetByHeight(ctx context.Context, h uint64, ts *types.TipSet) (*types.TipSet, error) { func (c *FullNodeStruct) ChainGetTipSetByHeight(ctx context.Context, h uint64, ts *types.TipSet) (*types.TipSet, error) {
@ -382,8 +367,8 @@ func (c *FullNodeStruct) StateMinerPeerID(ctx context.Context, m address.Address
return c.Internal.StateMinerPeerID(ctx, m, ts) return c.Internal.StateMinerPeerID(ctx, m, ts)
} }
func (c *FullNodeStruct) StateMinerProvingPeriodEnd(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error) { func (c *FullNodeStruct) StateMinerElectionPeriodStart(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error) {
return c.Internal.StateMinerProvingPeriodEnd(ctx, actor, ts) return c.Internal.StateMinerElectionPeriodStart(ctx, actor, ts)
} }
func (c *FullNodeStruct) StateMinerSectorSize(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error) { func (c *FullNodeStruct) StateMinerSectorSize(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error) {

View File

@ -42,7 +42,7 @@ func TestDealFlow(t *testing.T, b APIBuilder) {
t.Fatal(err) t.Fatal(err)
} }
maddr, err := address.NewFromString("t0101") maddr, err := address.NewFromString("t0102")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -2,10 +2,11 @@ package build
import ( import (
"context" "context"
"github.com/filecoin-project/lotus/lib/addrutil"
"os" "os"
"strings" "strings"
"github.com/filecoin-project/lotus/lib/addrutil"
rice "github.com/GeertJohan/go.rice" rice "github.com/GeertJohan/go.rice"
"github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/peer"
) )

View File

@ -1 +0,0 @@
/ip4/147.75.80.17/tcp/1347/p2p/12D3KooWFCkQdiJEMBVA6RrWq22ZXVFfM41YX8soQ5QVvNFjMJT8

View File

@ -1 +0,0 @@
/ip4/147.75.80.29/tcp/1347/p2p/12D3KooWSw9h3e6YrYZfRWDcir8qMV7ctZG9VmtXwSaP2ntsKXYf

View File

@ -156,6 +156,8 @@ func doFetch(out string, info paramFile) error {
if err != nil { if err != nil {
return err return err
} }
log.Infof("GET %s", url)
req := http.Request{ req := http.Request{
Method: "GET", Method: "GET",
URL: url, URL: url,

27
build/params_debug.go Normal file
View File

@ -0,0 +1,27 @@
// +build debug
package build
import "os"
// Seconds
const BlockDelay = 6
// FallbackPoStDelay is the number of epochs the miner needs to wait after
// ElectionPeriodStart before starting fallback post computation
//
// Epochs
const FallbackPoStDelay = 10
// SlashablePowerDelay is the number of epochs after ElectionPeriodStart, after
// which the miner is slashed
//
// Epochs
const SlashablePowerDelay = 20
// Epochs
const InteractivePoRepDelay = 2
func init() {
os.Setenv("TRUST_PARAMS", "1")
}

21
build/params_devnet.go Normal file
View File

@ -0,0 +1,21 @@
// +build !debug
package build
// Seconds
const BlockDelay = 12
// FallbackPoStDelay is the number of epochs the miner needs to wait after
// ElectionPeriodStart before starting fallback post computation
//
// Epochs
const FallbackPoStDelay = 1000
// SlashablePowerDelay is the number of epochs after ElectionPeriodStart, after
// which the miner is slashed
//
// Epochs
const SlashablePowerDelay = 2000
// Epochs
const InteractivePoRepDelay = 10

View File

@ -13,6 +13,7 @@ const UnixfsChunkSize uint64 = 1 << 20
const UnixfsLinksPerLevel = 1024 const UnixfsLinksPerLevel = 1024
var SectorSizes = []uint64{ var SectorSizes = []uint64{
1 << 10,
16 << 20, 16 << 20,
256 << 20, 256 << 20,
1 << 30, 1 << 30,
@ -30,25 +31,22 @@ func SupportedSectorSize(ssize uint64) bool {
// ///// // /////
// Payments // Payments
// Blocks // Epochs
const PaymentChannelClosingDelay = 6 * 60 * 2 // six hours const PaymentChannelClosingDelay = 6 * 60 * 2 // six hours
// ///// // /////
// Consensus / Network // Consensus / Network
// Seconds
const BlockDelay = 2
// Seconds // Seconds
const AllowableClockDrift = BlockDelay * 2 const AllowableClockDrift = BlockDelay * 2
// Blocks // Epochs
const ForkLengthThreshold = Finality const ForkLengthThreshold = Finality
// Blocks (e) // Blocks (e)
const BlocksPerEpoch = 5 const BlocksPerEpoch = 5
// Blocks // Epochs
const Finality = 500 const Finality = 500
// constants for Weight calculation // constants for Weight calculation
@ -59,39 +57,27 @@ const WRatioDen = 2
// ///// // /////
// Proofs // Proofs
// Blocks // Epochs
const ProvingPeriodDuration uint64 = 30
// PoStChallangeTime sets the window in which post computation should happen
// Blocks
const PoStChallangeTime = ProvingPeriodDuration - 6
// PoStRandomnessLookback is additional randomness lookback for PoSt computation
// To compute randomness epoch in a given proving period:
// RandH = PPE - PoStChallangeTime - PoStRandomnessLookback
//
// Blocks
const PoStRandomnessLookback = 1
// Blocks
const SealRandomnessLookback = Finality const SealRandomnessLookback = Finality
// Blocks // Epochs
const SealRandomnessLookbackLimit = SealRandomnessLookback + 2000 const SealRandomnessLookbackLimit = SealRandomnessLookback + 2000
// 1 / n
const SectorChallengeRatioDiv = 25
const MaxFallbackPostChallengeCount = 10
// ///// // /////
// Mining // Mining
// Blocks // Epochs
const EcRandomnessLookback = 300 const EcRandomnessLookback = 300
const PowerCollateralProportion = 5 const PowerCollateralProportion = 5
const PerCapitaCollateralProportion = 1 const PerCapitaCollateralProportion = 1
const CollateralPrecision = 1000 const CollateralPrecision = 1000
// Blocks
const InteractivePoRepDelay = 10
// ///// // /////
// Devnet settings // Devnet settings
@ -105,8 +91,8 @@ var InitialReward *big.Int
const FilecoinPrecision = 1_000_000_000_000_000_000 const FilecoinPrecision = 1_000_000_000_000_000_000
// six years // six years
// Blocks // Epochs
const HalvingPeriodBlocks = 6 * 365 * 24 * 60 * 2 const HalvingPeriodEpochs = 6 * 365 * 24 * 60 * 2
// TODO: Move other important consts here // TODO: Move other important consts here
@ -124,6 +110,6 @@ func init() {
// Sync // Sync
const BadBlockCacheSize = 1 << 15 const BadBlockCacheSize = 1 << 15
// assuming 4000 blocks per round, this lets us not lose any messages across a // assuming 4000 messages per round, this lets us not lose any messages across a
// 10 block reorg. // 10 block reorg.
const BlsSignatureCacheSize = 40000 const BlsSignatureCacheSize = 40000

View File

@ -1,82 +1,82 @@
{ {
"v15-proof-of-spacetime-rational-535d1050e3adca2a0dfe6c3c0c4fa12097c9a7835fb969042f82a507b13310e0.params": { "v19-proof-of-spacetime-election-09ae025de08399327e14f0cb6b4c907b6fe1e8b77046e31de8921bde588de900.params": {
"cid": "QmT22f1Np1GpW29NXD7Zrv3Ae4poMYhmkDjyscqL8QrJXY", "cid": "QmZEKhzKbC7SPngjL85ghyuxabPmiEuUh4fpkC7CDK1J5q",
"digest": "989fd8d989e0f7f1fe21bb010cf1b231", "digest": "1c81338b8afeaae514fd5d6c08c9c6e5",
"sector_size": 16777216
},
"v15-proof-of-spacetime-rational-535d1050e3adca2a0dfe6c3c0c4fa12097c9a7835fb969042f82a507b13310e0.vk": {
"cid": "QmVqSdc23to4UwduCCb25223rpSccvtcgPMfRKY1qjucDc",
"digest": "c6d258c37243b8544238a98100e3e399",
"sector_size": 16777216
},
"v15-proof-of-spacetime-rational-b99f15d0bdaaf4ffb68b2ca72b69ea8d915f66a2a56f667430ad69d87aa5febd.params": {
"cid": "QmRTCqgokEGTMfWVaSr7qFXTNotmpd2QBEi8RsvSQKmPLz",
"digest": "ff77a5e270afc6e1c7fbc19e48348fac",
"sector_size": 1073741824
},
"v15-proof-of-spacetime-rational-b99f15d0bdaaf4ffb68b2ca72b69ea8d915f66a2a56f667430ad69d87aa5febd.vk": {
"cid": "QmRssVAXRN3xp9VdSpTq1pNjkob3QiikoFZiM5hqrmh1VU",
"digest": "b41f35ac26224258e366327716a835a4",
"sector_size": 1073741824
},
"v15-proof-of-spacetime-rational-ba14a058a9dea194f68596f8ecf6537074f038a15c8d1a8550e10e31d4728912.params": {
"cid": "QmYNVRVzjXkuxJfnHTU5vmEcUBQf8dabXZ4m53SzqMkBv5",
"digest": "d156b685e4a1fe3a1f7230b6a39b5ad4",
"sector_size": 1024
},
"v15-proof-of-spacetime-rational-ba14a058a9dea194f68596f8ecf6537074f038a15c8d1a8550e10e31d4728912.vk": {
"cid": "QmaCEcsCFVuepMKdC5WURbr5ucEyLMNGxQaB7HqSnr2KGh",
"digest": "06ff067ac78cdab5d7bbc82170882241",
"sector_size": 1024
},
"v15-proof-of-spacetime-rational-c2ae2b440e693ee69fd6da9e85c4294c5c70c1a46d5785ca5f2a676d6cd4c8de.params": {
"cid": "QmVuabRvJ797NwLisGKwRURASGxopBBgg4rfNsbZoSYzAc",
"digest": "0e1ceb79a459a60508f480e5b1fed7ac",
"sector_size": 268435456 "sector_size": 268435456
}, },
"v15-proof-of-spacetime-rational-c2ae2b440e693ee69fd6da9e85c4294c5c70c1a46d5785ca5f2a676d6cd4c8de.vk": { "v19-proof-of-spacetime-election-09ae025de08399327e14f0cb6b4c907b6fe1e8b77046e31de8921bde588de900.vk": {
"cid": "QmdWENZBAbuUty1vVNn9vmvj1XbJ5UC8qzpcVD35s5AJxG", "cid": "Qmf5XQuM58jNmxudXeZMuZtGGiNzcd56Fiyn9h76wpX5dN",
"digest": "1b755c74b9d6823c014f6a7ef76249f2", "digest": "bb0f07b6071cd28e9348223c6a9c46d1",
"sector_size": 268435456 "sector_size": 268435456
}, },
"v15-stacked-proof-of-replication-0c0b444c6f31d11c8e98003cc99a3b938db26b77a296d4253cda8945c234266d.params": { "v19-proof-of-spacetime-election-4a2342062706429612fac099694f77294e355c6c9265b80feaff12a0268b0a92.params": {
"cid": "QmZDVpWTw5Eti5pE7N5z1Cmqsw8hPXhUcvG3cQuceK56LH", "cid": "QmaHs5CHcSD6QhaGAp4ysJP4HTZaxPxybCGmUVDk3TNocA",
"digest": "6aa80306018ea1328f2d6faf8c080734", "digest": "727fb2896a5668d04ba6e0ce71eb50d7",
"sector_size": 16777216
},
"v15-stacked-proof-of-replication-0c0b444c6f31d11c8e98003cc99a3b938db26b77a296d4253cda8945c234266d.vk": {
"cid": "QmaoXV7iVSJcfZ5qubYy7NBcXDSdnTzxH85d7M4bdDtfGZ",
"digest": "f6832eb736faf2960e920d32e9780b12",
"sector_size": 16777216
},
"v15-stacked-proof-of-replication-967b11bb59be11b7dc6f2b627520ba450a3aa50846dbbf886cb8b735fe25c4e7.params": {
"cid": "QmbUW3a3q5DHBb7Ufk8iSbnSCZgbwpe3serqfwKmcTd11w",
"digest": "64024e461b07c869df2463d33dd28035",
"sector_size": 268435456
},
"v15-stacked-proof-of-replication-967b11bb59be11b7dc6f2b627520ba450a3aa50846dbbf886cb8b735fe25c4e7.vk": {
"cid": "Qme3QgBBE7hUgrK7G9ZfJhzkbvViN5HALFpFduYs5K1piv",
"digest": "32496f4dc434b0ed9ef49cb62497a7d1",
"sector_size": 268435456
},
"v15-stacked-proof-of-replication-d01cd22091627b721c60a3375b5219af653fb9f6928c70aa7400587d396bc07a.params": {
"cid": "QmZzgJmb8WXYDKxS22HDgnoBYcZzXDC7s2c2zsV7kouNZ9",
"digest": "cd91f7ccb2ff57a06f3375946dcbdc68",
"sector_size": 1073741824
},
"v15-stacked-proof-of-replication-d01cd22091627b721c60a3375b5219af653fb9f6928c70aa7400587d396bc07a.vk": {
"cid": "QmRUMVzFnENbvyNb6aN2AJ2dnnewr1ESGA1UQLMVZZdsJM",
"digest": "92fc84b76dbe69c731518aebcb82ac82",
"sector_size": 1073741824
},
"v15-stacked-proof-of-replication-f464b92d805d03de6e2c20e2530135b2c8ec96045ec58f342d6feb90282bff8a.params": {
"cid": "QmSixsGkxJXTAuFfWKy5aEXEDJEnpcb1GkdQVF8TCPWoHy",
"digest": "f8339ae93478ded3840d0bc7efa19953",
"sector_size": 1024 "sector_size": 1024
}, },
"v15-stacked-proof-of-replication-f464b92d805d03de6e2c20e2530135b2c8ec96045ec58f342d6feb90282bff8a.vk": { "v19-proof-of-spacetime-election-4a2342062706429612fac099694f77294e355c6c9265b80feaff12a0268b0a92.vk": {
"cid": "QmTMC8hdZ2TkZ9BFuzHzRLM9SuR2PQdUrSAwABeCuHyV2f", "cid": "QmVg8mUXMb6MiZQseAyCmHzEgNkPbV72xQoRmdFr1yJA4w",
"digest": "f27f08ce1246ee6612c250bb12803ef1", "digest": "3fdf4e65a7baf1a2bab5b8a717f3379a",
"sector_size": 1024 "sector_size": 1024
},
"v19-proof-of-spacetime-election-512f5e6dc00a37fa13c8b0e468188f85957b7bf1ab36d17fb9fe9ed49ae8d657.params": {
"cid": "QmYf1532WoeXhy8AoduWNxpBuwn5DEkpU6YFDGCXh1mqBX",
"digest": "983e641f9df01799bc33d5fb3c3020b2",
"sector_size": 1073741824
},
"v19-proof-of-spacetime-election-512f5e6dc00a37fa13c8b0e468188f85957b7bf1ab36d17fb9fe9ed49ae8d657.vk": {
"cid": "QmVig7LUpNSXUcfjkSxUKsFaxqYxEZdaEARWvi14sbihJ4",
"digest": "e1f7a46b60217f1dddf56671dd86e6a7",
"sector_size": 1073741824
},
"v19-proof-of-spacetime-election-6c7cbfe7eed40b6c0b23a213a70648770aed65d9ca03ae85451573c18532304b.params": {
"cid": "QmSTF7C6vQbV6qjEQknXpBDuixBkxYeMshX25NonjJxjbi",
"digest": "b434ece6a37e588ca11ed117f1c14325",
"sector_size": 16777216
},
"v19-proof-of-spacetime-election-6c7cbfe7eed40b6c0b23a213a70648770aed65d9ca03ae85451573c18532304b.vk": {
"cid": "QmaFV9n5scuYxKc9QpJnbBUf4sjhkUzpZ7QkoTqL8XsNQz",
"digest": "9c2e40b6635470d3674324b01c9a3976",
"sector_size": 16777216
},
"v19-stacked-proof-of-replication-5a438611c880423c4f5199787cd531b197846ef46af40af69222467ab9073226.params": {
"cid": "QmQb5mc3ksZh2K5GsNwJrkwuHoWXh8adBdJV3qTbFaRvGe",
"digest": "a187287b1d03cd7ec4f1fccd57f3f3d1",
"sector_size": 1024
},
"v19-stacked-proof-of-replication-5a438611c880423c4f5199787cd531b197846ef46af40af69222467ab9073226.vk": {
"cid": "QmYUjFHzeX22dfzv9wQxF4Qn8wS67bqBwr1Wcz2rga9rAZ",
"digest": "747792363f08d7b53be1a2f51f91582a",
"sector_size": 1024
},
"v19-stacked-proof-of-replication-6ae8ae8998ef393ffd171487bc5141fa3642e9fd39e3a7dbada4f6e7bacffb9b.params": {
"cid": "QmRUZqCwYdcVfQ49Z97g2xkJnaSh4b9SHWwfB3kgZiPo9L",
"digest": "b9494e0ae432a0ebde9c8c877c914583",
"sector_size": 16777216
},
"v19-stacked-proof-of-replication-6ae8ae8998ef393ffd171487bc5141fa3642e9fd39e3a7dbada4f6e7bacffb9b.vk": {
"cid": "QmXngrBy74h8LYhYrbBpefXsXQFWLU3WX3LTXnVQnu1Sdc",
"digest": "af2c0d6834fa581b6f507f8266244dfb",
"sector_size": 16777216
},
"v19-stacked-proof-of-replication-d2ca0f634aebcecba88904612ff82f2349b080b1290879f3fba73c1d9a13d84e.params": {
"cid": "QmfNstuJFKnBt4yJHsNfoKahn1LafBdpJju23U5UNZd9Xy",
"digest": "3911d84ca2b86f491bc7c6372d7d9285",
"sector_size": 268435456
},
"v19-stacked-proof-of-replication-d2ca0f634aebcecba88904612ff82f2349b080b1290879f3fba73c1d9a13d84e.vk": {
"cid": "QmQgSRQBbp7udHDp5pNA3GSCjSyXktUHBw15wx9meL4wgc",
"digest": "ecd2a9bdd178b0ebc9110f568fd70d07",
"sector_size": 268435456
},
"v19-stacked-proof-of-replication-f7b95455d6b7a5e967388a97c2ddc01807eff4c1736e84be4554853bf7783105.params": {
"cid": "QmV5mAkhohUHPRWoNtS3Uo4yvmF23CR2u8JxeeCqthMCdX",
"digest": "9306d91c3518b87016d5efc19428b25e",
"sector_size": 1073741824
},
"v19-stacked-proof-of-replication-f7b95455d6b7a5e967388a97c2ddc01807eff4c1736e84be4554853bf7783105.vk": {
"cid": "QmPjwPdUQJmqp2rQuJX2dy57AC9YCwYtMHdpZzW5BG9JWh",
"digest": "a2004fca043da423df51f6c4bb65788c",
"sector_size": 1073741824
} }
} }

3
build/testing_flags.go Normal file
View File

@ -0,0 +1,3 @@
package build
var InsecurePoStValidation = false

View File

@ -40,7 +40,6 @@ func init() {
type InitActor struct{} type InitActor struct{}
type InitActorState struct { type InitActorState struct {
// TODO: this needs to be a HAMT, its a dumb map for now
AddressMap cid.Cid AddressMap cid.Cid
NextID uint64 NextID uint64

View File

@ -6,6 +6,8 @@ import (
"encoding/binary" "encoding/binary"
"fmt" "fmt"
ffi "github.com/filecoin-project/filecoin-ffi"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors/aerrors" "github.com/filecoin-project/lotus/chain/actors/aerrors"
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/address"
@ -29,12 +31,16 @@ type StorageMinerActorState struct {
PreCommittedSectors map[string]*PreCommittedSector PreCommittedSectors map[string]*PreCommittedSector
// All sectors this miner has committed. // All sectors this miner has committed.
//
// AMT[sectorID]ffi.PublicSectorInfo
Sectors cid.Cid Sectors cid.Cid
// TODO: Spec says 'StagedCommittedSectors', which one is it? // TODO: Spec says 'StagedCommittedSectors', which one is it?
// Sectors this miner is currently mining. It is only updated // Sectors this miner is currently mining. It is only updated
// when a PoSt is submitted (not as each new sector commitment is added). // when a PoSt is submitted (not as each new sector commitment is added).
//
// AMT[sectorID]ffi.PublicSectorInfo
ProvingSet cid.Cid ProvingSet cid.Cid
// TODO: these: // TODO: these:
@ -54,12 +60,6 @@ type StorageMinerActorState struct {
// These become the currentFaultSet when a PoSt is submitted. // These become the currentFaultSet when a PoSt is submitted.
NextFaultSet types.BitField NextFaultSet types.BitField
// Sectors reported during the last PoSt submission as being 'done'.
// The collateral for them is still being held until
// the next PoSt submission in case early sector
// removal penalization is needed.
NextDoneSet types.BitField
// Amount of power this miner has. // Amount of power this miner has.
Power types.BigInt Power types.BigInt
@ -69,7 +69,7 @@ type StorageMinerActorState struct {
// The height at which this miner was slashed at. // The height at which this miner was slashed at.
SlashedAt uint64 SlashedAt uint64
ProvingPeriodEnd uint64 ElectionPeriodStart uint64
} }
type MinerInfo struct { type MinerInfo struct {
@ -117,7 +117,7 @@ type maMethods struct {
Constructor uint64 Constructor uint64
PreCommitSector uint64 PreCommitSector uint64
ProveCommitSector uint64 ProveCommitSector uint64
SubmitPoSt uint64 SubmitFallbackPoSt uint64
SlashStorageFault uint64 SlashStorageFault uint64
GetCurrentProvingSet uint64 GetCurrentProvingSet uint64
ArbitrateDeal uint64 ArbitrateDeal uint64
@ -133,16 +133,17 @@ type maMethods struct {
CheckMiner uint64 CheckMiner uint64
DeclareFaults uint64 DeclareFaults uint64
SlashConsensusFault uint64 SlashConsensusFault uint64
SubmitElectionPoSt uint64
} }
var MAMethods = maMethods{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19} var MAMethods = maMethods{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
func (sma StorageMinerActor) Exports() []interface{} { func (sma StorageMinerActor) Exports() []interface{} {
return []interface{}{ return []interface{}{
1: sma.StorageMinerConstructor, 1: sma.StorageMinerConstructor,
2: sma.PreCommitSector, 2: sma.PreCommitSector,
3: sma.ProveCommitSector, 3: sma.ProveCommitSector,
4: sma.SubmitPoSt, 4: sma.SubmitFallbackPoSt,
//5: sma.SlashStorageFault, //5: sma.SlashStorageFault,
//6: sma.GetCurrentProvingSet, //6: sma.GetCurrentProvingSet,
//7: sma.ArbitrateDeal, //7: sma.ArbitrateDeal,
@ -158,6 +159,7 @@ func (sma StorageMinerActor) Exports() []interface{} {
17: sma.CheckMiner, 17: sma.CheckMiner,
18: sma.DeclareFaults, 18: sma.DeclareFaults,
19: sma.SlashConsensusFault, 19: sma.SlashConsensusFault,
20: sma.SubmitElectionPoSt,
} }
} }
@ -345,7 +347,7 @@ func (sma StorageMinerActor) ProveCommitSector(act *types.Actor, vmctx types.VMC
// Note: There must exist a unique index in the miner's sector set for each // Note: There must exist a unique index in the miner's sector set for each
// sector ID. The `faults`, `recovered`, and `done` parameters of the // sector ID. The `faults`, `recovered`, and `done` parameters of the
// SubmitPoSt method express indices into this sector set. // SubmitPoSt method express indices into this sector set.
nssroot, err := AddToSectorSet(ctx, vmctx.Storage(), self.Sectors, params.SectorID, us.Info.CommR, commD) nssroot, err := AddToSectorSet(ctx, types.WrapStorage(vmctx.Storage()), self.Sectors, params.SectorID, us.Info.CommR, commD)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -366,7 +368,9 @@ func (sma StorageMinerActor) ProveCommitSector(act *types.Actor, vmctx types.VMC
if pss.Count == 0 { if pss.Count == 0 {
self.ProvingSet = self.Sectors self.ProvingSet = self.Sectors
self.ProvingPeriodEnd = vmctx.BlockHeight() + build.ProvingPeriodDuration // TODO: probably want to wait until the miner is above a certain
// threshold before starting this
self.ElectionPeriodStart = vmctx.BlockHeight()
} }
nstate, err := vmctx.Storage().Put(self) nstate, err := vmctx.Storage().Put(self)
@ -388,23 +392,12 @@ func (sma StorageMinerActor) ProveCommitSector(act *types.Actor, vmctx types.VMC
return nil, err return nil, err
} }
type SubmitPoStParams struct { type SubmitFallbackPoStParams struct {
Proof []byte Proof []byte
DoneSet types.BitField Candidates []types.EPostTicket
// TODO: once the spec changes finish, we have more work to do here...
} }
func ProvingPeriodEnd(setPeriodEnd, height uint64) (uint64, uint64) { func (sma StorageMinerActor) SubmitFallbackPoSt(act *types.Actor, vmctx types.VMContext, params *SubmitFallbackPoStParams) ([]byte, ActorError) {
offset := setPeriodEnd % build.ProvingPeriodDuration
period := ((height - offset - 1) / build.ProvingPeriodDuration) + 1
end := (period * build.ProvingPeriodDuration) + offset
return end, period
}
// TODO: this is a dummy method that allows us to plumb in other parts of the
// system for now.
func (sma StorageMinerActor) SubmitPoSt(act *types.Actor, vmctx types.VMContext, params *SubmitPoStParams) ([]byte, ActorError) {
oldstate, self, err := loadState(vmctx) oldstate, self, err := loadState(vmctx)
if err != nil { if err != nil {
return nil, err return nil, err
@ -419,36 +412,28 @@ func (sma StorageMinerActor) SubmitPoSt(act *types.Actor, vmctx types.VMContext,
return nil, aerrors.New(1, "not authorized to submit post for miner") return nil, aerrors.New(1, "not authorized to submit post for miner")
} }
currentProvingPeriodEnd, _ := ProvingPeriodEnd(self.ProvingPeriodEnd, vmctx.BlockHeight()) /*
// TODO: handle fees
feesRequired := types.NewInt(0) msgVal := vmctx.Message().Value
if msgVal.LessThan(feesRequired) {
if currentProvingPeriodEnd > self.ProvingPeriodEnd { return nil, aerrors.New(2, "not enough funds to pay post submission fees")
//TODO late fee calc
feesRequired = types.BigAdd(feesRequired, types.NewInt(1000))
}
//TODO temporary sector failure fees
msgVal := vmctx.Message().Value
if msgVal.LessThan(feesRequired) {
return nil, aerrors.New(2, "not enough funds to pay post submission fees")
}
if msgVal.GreaterThan(feesRequired) {
_, err := vmctx.Send(vmctx.Message().From, 0,
types.BigSub(msgVal, feesRequired), nil)
if err != nil {
return nil, aerrors.Wrap(err, "could not refund excess fees")
} }
}
if msgVal.GreaterThan(feesRequired) {
_, err := vmctx.Send(vmctx.Message().From, 0,
types.BigSub(msgVal, feesRequired), nil)
if err != nil {
return nil, aerrors.Wrap(err, "could not refund excess fees")
}
}
*/
var seed [sectorbuilder.CommLen]byte var seed [sectorbuilder.CommLen]byte
{ {
randHeight := currentProvingPeriodEnd - build.PoStChallangeTime - build.PoStRandomnessLookback randHeight := self.ElectionPeriodStart + build.FallbackPoStDelay
if vmctx.BlockHeight() <= randHeight { if vmctx.BlockHeight() <= randHeight {
// TODO: spec, retcode // TODO: spec, retcode
return nil, aerrors.Newf(1, "submit PoSt called outside submission window (%d < %d)", vmctx.BlockHeight(), randHeight) return nil, aerrors.Newf(1, "submit fallback PoSt called too early (%d < %d)", vmctx.BlockHeight(), randHeight)
} }
rand, err := vmctx.GetRandomness(randHeight) rand, err := vmctx.GetRandomness(randHeight)
@ -468,13 +453,13 @@ func (sma StorageMinerActor) SubmitPoSt(act *types.Actor, vmctx types.VMContext,
return nil, aerrors.HandleExternalError(lerr, "could not load proving set node") return nil, aerrors.HandleExternalError(lerr, "could not load proving set node")
} }
var sectorInfos []sectorbuilder.SectorInfo var sectorInfos []ffi.PublicSectorInfo
if err := pss.ForEach(func(id uint64, v *cbg.Deferred) error { if err := pss.ForEach(func(id uint64, v *cbg.Deferred) error {
var comms [][]byte var comms [][]byte
if err := cbor.DecodeInto(v.Raw, &comms); err != nil { if err := cbor.DecodeInto(v.Raw, &comms); err != nil {
return xerrors.New("could not decode comms") return xerrors.New("could not decode comms")
} }
si := sectorbuilder.SectorInfo{ si := ffi.PublicSectorInfo{
SectorID: id, SectorID: id,
} }
commR := comms[0] commR := comms[0]
@ -491,10 +476,23 @@ func (sma StorageMinerActor) SubmitPoSt(act *types.Actor, vmctx types.VMContext,
} }
faults := self.CurrentFaultSet.All() faults := self.CurrentFaultSet.All()
_ = faults
if ok, lerr := sectorbuilder.VerifyPost(vmctx.Context(), mi.SectorSize, proverID := vmctx.Message().To // TODO: normalize to ID address
sectorbuilder.NewSortedSectorInfo(sectorInfos), seed, params.Proof,
faults); !ok || lerr != nil { var candidates []sectorbuilder.EPostCandidate
for _, t := range params.Candidates {
var partial [32]byte
copy(partial[:], t.Partial)
candidates = append(candidates, sectorbuilder.EPostCandidate{
PartialTicket: partial,
SectorID: t.SectorID,
SectorChallengeIndex: t.ChallengeIndex,
})
}
if ok, lerr := sectorbuilder.VerifyFallbackPost(vmctx.Context(), mi.SectorSize,
sectorbuilder.NewSortedPublicSectorInfo(sectorInfos), seed[:], params.Proof, candidates, proverID); !ok || lerr != nil {
if lerr != nil { if lerr != nil {
// TODO: study PoST errors // TODO: study PoST errors
return nil, aerrors.Absorb(lerr, 4, "PoST error") return nil, aerrors.Absorb(lerr, 4, "PoST error")
@ -503,60 +501,12 @@ func (sma StorageMinerActor) SubmitPoSt(act *types.Actor, vmctx types.VMContext,
return nil, aerrors.New(4, "PoST invalid") return nil, aerrors.New(4, "PoST invalid")
} }
} }
self.CurrentFaultSet = self.NextFaultSet
self.NextFaultSet = types.NewBitField()
ss, lerr := amt.LoadAMT(types.WrapStorage(vmctx.Storage()), self.ProvingSet) // Post submission is successful!
if lerr != nil { if err := onSuccessfulPoSt(self, vmctx); err != nil {
return nil, aerrors.HandleExternalError(lerr, "could not load proving set node")
}
if err := ss.BatchDelete(params.DoneSet.All()); err != nil {
// TODO: this could fail for system reasons (block not found) or for
// bad user input reasons (e.g. bad doneset). The latter should be a
// non-fatal error
return nil, aerrors.HandleExternalError(err, "failed to delete sectors in done set")
}
self.ProvingSet, lerr = ss.Flush()
if lerr != nil {
return nil, aerrors.HandleExternalError(lerr, "could not flush AMT")
}
oldPower := self.Power
self.Power = types.BigMul(types.NewInt(pss.Count-uint64(len(faults))),
types.NewInt(mi.SectorSize))
delta := types.BigSub(self.Power, oldPower)
if self.SlashedAt != 0 {
self.SlashedAt = 0
delta = self.Power
}
prevPE := self.ProvingPeriodEnd
if !self.Active {
self.Active = true
prevPE = 0
}
enc, err := SerializeParams(&UpdateStorageParams{
Delta: delta,
NextProvingPeriodEnd: currentProvingPeriodEnd + build.ProvingPeriodDuration,
PreviousProvingPeriodEnd: prevPE,
})
if err != nil {
return nil, err return nil, err
} }
_, err = vmctx.Send(StoragePowerAddress, SPAMethods.UpdateStorage, types.NewInt(0), enc)
if err != nil {
return nil, err
}
self.ProvingSet = self.Sectors
self.ProvingPeriodEnd = currentProvingPeriodEnd + build.ProvingPeriodDuration
self.NextDoneSet = params.DoneSet
c, err := vmctx.Storage().Put(self) c, err := vmctx.Storage().Put(self)
if err != nil { if err != nil {
return nil, err return nil, err
@ -586,8 +536,8 @@ func SectorIsUnique(ctx context.Context, s types.Storage, sroot cid.Cid, sid uin
return !found, nil return !found, nil
} }
func AddToSectorSet(ctx context.Context, s types.Storage, ss cid.Cid, sectorID uint64, commR, commD []byte) (cid.Cid, ActorError) { func AddToSectorSet(ctx context.Context, blks amt.Blocks, ss cid.Cid, sectorID uint64, commR, commD []byte) (cid.Cid, ActorError) {
ssr, err := amt.LoadAMT(types.WrapStorage(s), ss) ssr, err := amt.LoadAMT(blks, ss)
if err != nil { if err != nil {
return cid.Undef, aerrors.HandleExternalError(err, "could not load sector set node") return cid.Undef, aerrors.HandleExternalError(err, "could not load sector set node")
} }
@ -749,7 +699,7 @@ func (sma StorageMinerActor) GetSectorSize(act *types.Actor, vmctx types.VMConte
} }
func isLate(height uint64, self *StorageMinerActorState) bool { func isLate(height uint64, self *StorageMinerActorState) bool {
return self.ProvingPeriodEnd > 0 && height >= self.ProvingPeriodEnd // TODO: review: maybe > ? return self.ElectionPeriodStart > 0 && height >= self.ElectionPeriodStart+build.SlashablePowerDelay
} }
func (sma StorageMinerActor) IsSlashed(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) { func (sma StorageMinerActor) IsSlashed(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) {
@ -817,32 +767,34 @@ type DeclareFaultsParams struct {
} }
func (sma StorageMinerActor) DeclareFaults(act *types.Actor, vmctx types.VMContext, params *DeclareFaultsParams) ([]byte, ActorError) { func (sma StorageMinerActor) DeclareFaults(act *types.Actor, vmctx types.VMContext, params *DeclareFaultsParams) ([]byte, ActorError) {
oldstate, self, aerr := loadState(vmctx) /*
if aerr != nil { oldstate, self, aerr := loadState(vmctx)
return nil, aerr if aerr != nil {
} return nil, aerr
challengeHeight := self.ProvingPeriodEnd - build.PoStChallangeTime
if vmctx.BlockHeight() < challengeHeight {
// TODO: optimized bitfield methods
for _, v := range params.Faults.All() {
self.CurrentFaultSet.Set(v)
} }
} else {
for _, v := range params.Faults.All() { challengeHeight := self.ProvingPeriodEnd - build.PoStChallangeTime
self.NextFaultSet.Set(v)
if vmctx.BlockHeight() < challengeHeight {
// TODO: optimized bitfield methods
for _, v := range params.Faults.All() {
self.CurrentFaultSet.Set(v)
}
} else {
for _, v := range params.Faults.All() {
self.NextFaultSet.Set(v)
}
} }
}
nstate, err := vmctx.Storage().Put(self) nstate, err := vmctx.Storage().Put(self)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if err := vmctx.Storage().Commit(oldstate, nstate); err != nil { if err := vmctx.Storage().Commit(oldstate, nstate); err != nil {
return nil, err return nil, err
} }
*/
return nil, nil return nil, nil
} }
@ -892,6 +844,88 @@ func (sma StorageMinerActor) SlashConsensusFault(act *types.Actor, vmctx types.V
return nil, nil return nil, nil
} }
func (sma StorageMinerActor) SubmitElectionPoSt(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, aerrors.ActorError) {
if vmctx.Message().From != NetworkAddress {
return nil, aerrors.Newf(1, "submit election post can only be called by the storage power actor")
}
oldstate, self, aerr := loadState(vmctx)
if aerr != nil {
return nil, aerr
}
if self.SlashedAt != 0 {
return nil, aerrors.New(1, "slashed miners can't perform election PoSt")
}
if err := onSuccessfulPoSt(self, vmctx); err != nil {
return nil, err
}
ncid, err := vmctx.Storage().Put(self)
if err != nil {
return nil, err
}
if err := vmctx.Storage().Commit(oldstate, ncid); err != nil {
return nil, err
}
return nil, nil
}
func onSuccessfulPoSt(self *StorageMinerActorState, vmctx types.VMContext) aerrors.ActorError {
// TODO: some sector upkeep stuff that is very haphazard and unclear in the spec
var mi MinerInfo
if err := vmctx.Storage().Get(self.Info, &mi); err != nil {
return err
}
pss, nerr := amt.LoadAMT(types.WrapStorage(vmctx.Storage()), self.ProvingSet)
if nerr != nil {
return aerrors.HandleExternalError(nerr, "failed to load proving set")
}
self.CurrentFaultSet = self.NextFaultSet
self.NextFaultSet = types.NewBitField()
faults := []uint64{} // TODO
oldPower := self.Power
self.Power = types.BigMul(types.NewInt(pss.Count-uint64(len(faults))),
types.NewInt(mi.SectorSize))
delta := types.BigSub(self.Power, oldPower)
if self.SlashedAt != 0 {
self.SlashedAt = 0
delta = self.Power
}
prevSlashingDeadline := self.ElectionPeriodStart + build.SlashablePowerDelay
if !self.Active {
self.Active = true
prevSlashingDeadline = 0
}
enc, err := SerializeParams(&UpdateStorageParams{
Delta: delta,
NextProvingPeriodEnd: vmctx.BlockHeight() + build.SlashablePowerDelay,
PreviousProvingPeriodEnd: prevSlashingDeadline,
})
if err != nil {
return err
}
_, err = vmctx.Send(StoragePowerAddress, SPAMethods.UpdateStorage, types.NewInt(0), enc)
if err != nil {
return err
}
self.ProvingSet = self.Sectors
self.ElectionPeriodStart = vmctx.BlockHeight()
return nil
}
func slasherShare(total types.BigInt, elapsed uint64) types.BigInt { func slasherShare(total types.BigInt, elapsed uint64) types.BigInt {
// [int(pow(1.26, n) * 10) for n in range(30)] // [int(pow(1.26, n) * 10) for n in range(30)]
fracs := []uint64{10, 12, 15, 20, 25, 31, 40, 50, 63, 80, 100, 127, 160, 201, 254, 320, 403, 508, 640, 807, 1017, 1281, 1614, 2034, 2563, 3230, 4070, 5128, 6462, 8142} fracs := []uint64{10, 12, 15, 20, 25, 31, 40, 50, 63, 80, 100, 127, 160, 201, 254, 320, 403, 508, 640, 807, 1017, 1281, 1614, 2034, 2563, 3230, 4070, 5128, 6462, 8142}

View File

@ -3,16 +3,17 @@ package actors
import ( import (
"bytes" "bytes"
"context" "context"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-amt-ipld" "github.com/filecoin-project/go-amt-ipld"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
"github.com/ipfs/go-hamt-ipld" "github.com/ipfs/go-hamt-ipld"
"golang.org/x/xerrors"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors/aerrors" "github.com/filecoin-project/lotus/chain/actors/aerrors"
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/cborutil"
"github.com/filecoin-project/lotus/lib/sectorbuilder" "github.com/filecoin-project/lotus/lib/sectorbuilder"
) )
@ -110,6 +111,15 @@ func (sdp *StorageDealProposal) Sign(ctx context.Context, sign SignFunc) error {
return nil return nil
} }
func (sdp *StorageDealProposal) Cid() (cid.Cid, error) {
nd, err := cborutil.AsIpld(sdp)
if err != nil {
return cid.Undef, err
}
return nd.Cid(), nil
}
func (sdp *StorageDealProposal) Verify() error { func (sdp *StorageDealProposal) Verify() error {
unsigned := *sdp unsigned := *sdp
unsigned.ProposerSignature = nil unsigned.ProposerSignature = nil
@ -538,9 +548,7 @@ func (sma StorageMarketActor) ProcessStorageDealsPayment(act *types.Actor, vmctx
return nil, nil return nil, nil
} }
// todo: check math (written on a plane, also tired) toPay := types.BigMul(dealInfo.Deal.Proposal.StoragePricePerEpoch, types.NewInt(build.SlashablePowerDelay))
// TODO: division is hard, this more than likely has some off-by-one issue
toPay := types.BigMul(dealInfo.Deal.Proposal.StoragePricePerEpoch, types.NewInt(build.ProvingPeriodDuration))
b, bnd, aerr := GetMarketBalances(vmctx.Context(), vmctx.Ipld(), self.Balances, dealInfo.Deal.Proposal.Client, providerWorker) b, bnd, aerr := GetMarketBalances(vmctx.Context(), vmctx.Ipld(), self.Balances, dealInfo.Deal.Proposal.Client, providerWorker)
if aerr != nil { if aerr != nil {

View File

@ -289,8 +289,8 @@ func (spa StoragePowerActor) UpdateStorage(act *types.Actor, vmctx types.VMConte
self.TotalStorage = types.BigAdd(self.TotalStorage, params.Delta) self.TotalStorage = types.BigAdd(self.TotalStorage, params.Delta)
previousBucket := params.PreviousProvingPeriodEnd % build.ProvingPeriodDuration previousBucket := params.PreviousProvingPeriodEnd % build.SlashablePowerDelay
nextBucket := params.NextProvingPeriodEnd % build.ProvingPeriodDuration nextBucket := params.NextProvingPeriodEnd % build.SlashablePowerDelay
if previousBucket == nextBucket && params.PreviousProvingPeriodEnd != 0 { if previousBucket == nextBucket && params.PreviousProvingPeriodEnd != 0 {
nroot, err := vmctx.Storage().Put(&self) nroot, err := vmctx.Storage().Put(&self)
@ -601,7 +601,7 @@ func (spa StoragePowerActor) CheckProofSubmissions(act *types.Actor, vmctx types
} }
func checkProofSubmissionsAtH(vmctx types.VMContext, self *StoragePowerState, height uint64) aerrors.ActorError { func checkProofSubmissionsAtH(vmctx types.VMContext, self *StoragePowerState, height uint64) aerrors.ActorError {
bucketID := height % build.ProvingPeriodDuration bucketID := height % build.SlashablePowerDelay
buckets, eerr := amt.LoadAMT(types.WrapStorage(vmctx.Storage()), self.ProvingBuckets) buckets, eerr := amt.LoadAMT(types.WrapStorage(vmctx.Storage()), self.ProvingBuckets)
if eerr != nil { if eerr != nil {

View File

@ -170,5 +170,5 @@ func signBlock(t *testing.T, w *wallet.Wallet, worker address.Address, blk *type
t.Fatal(err) t.Fatal(err)
} }
blk.BlockSig = *sig blk.BlockSig = sig
} }

View File

@ -198,7 +198,7 @@ func (t *StorageMinerActorState) MarshalCBOR(w io.Writer) error {
_, err := w.Write(cbg.CborNull) _, err := w.Write(cbg.CborNull)
return err return err
} }
if _, err := w.Write([]byte{139}); err != nil { if _, err := w.Write([]byte{138}); err != nil {
return err return err
} }
@ -258,11 +258,6 @@ func (t *StorageMinerActorState) MarshalCBOR(w io.Writer) error {
return err return err
} }
// t.t.NextDoneSet (types.BitField) (struct)
if err := t.NextDoneSet.MarshalCBOR(w); err != nil {
return err
}
// t.t.Power (types.BigInt) (struct) // t.t.Power (types.BigInt) (struct)
if err := t.Power.MarshalCBOR(w); err != nil { if err := t.Power.MarshalCBOR(w); err != nil {
return err return err
@ -278,8 +273,8 @@ func (t *StorageMinerActorState) MarshalCBOR(w io.Writer) error {
return err return err
} }
// t.t.ProvingPeriodEnd (uint64) (uint64) // t.t.ElectionPeriodStart (uint64) (uint64)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.ProvingPeriodEnd))); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.ElectionPeriodStart))); err != nil {
return err return err
} }
return nil return nil
@ -296,7 +291,7 @@ func (t *StorageMinerActorState) UnmarshalCBOR(r io.Reader) error {
return fmt.Errorf("cbor input should be of type array") return fmt.Errorf("cbor input should be of type array")
} }
if extra != 11 { if extra != 10 {
return fmt.Errorf("cbor input had wrong number of fields") return fmt.Errorf("cbor input had wrong number of fields")
} }
@ -406,15 +401,6 @@ func (t *StorageMinerActorState) UnmarshalCBOR(r io.Reader) error {
return err return err
} }
}
// t.t.NextDoneSet (types.BitField) (struct)
{
if err := t.NextDoneSet.UnmarshalCBOR(br); err != nil {
return err
}
} }
// t.t.Power (types.BigInt) (struct) // t.t.Power (types.BigInt) (struct)
@ -452,7 +438,7 @@ func (t *StorageMinerActorState) UnmarshalCBOR(r io.Reader) error {
return fmt.Errorf("wrong type for uint64 field") return fmt.Errorf("wrong type for uint64 field")
} }
t.SlashedAt = uint64(extra) t.SlashedAt = uint64(extra)
// t.t.ProvingPeriodEnd (uint64) (uint64) // t.t.ElectionPeriodStart (uint64) (uint64)
maj, extra, err = cbg.CborReadHeader(br) maj, extra, err = cbg.CborReadHeader(br)
if err != nil { if err != nil {
@ -461,7 +447,7 @@ func (t *StorageMinerActorState) UnmarshalCBOR(r io.Reader) error {
if maj != cbg.MajUnsignedInt { if maj != cbg.MajUnsignedInt {
return fmt.Errorf("wrong type for uint64 field") return fmt.Errorf("wrong type for uint64 field")
} }
t.ProvingPeriodEnd = uint64(extra) t.ElectionPeriodStart = uint64(extra)
return nil return nil
} }
@ -827,7 +813,7 @@ func (t *MinerInfo) UnmarshalCBOR(r io.Reader) error {
return nil return nil
} }
func (t *SubmitPoStParams) MarshalCBOR(w io.Writer) error { func (t *SubmitFallbackPoStParams) MarshalCBOR(w io.Writer) error {
if t == nil { if t == nil {
_, err := w.Write(cbg.CborNull) _, err := w.Write(cbg.CborNull)
return err return err
@ -844,14 +830,19 @@ func (t *SubmitPoStParams) MarshalCBOR(w io.Writer) error {
return err return err
} }
// t.t.DoneSet (types.BitField) (struct) // t.t.Candidates ([]types.EPostTicket) (slice)
if err := t.DoneSet.MarshalCBOR(w); err != nil { if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Candidates)))); err != nil {
return err return err
} }
for _, v := range t.Candidates {
if err := v.MarshalCBOR(w); err != nil {
return err
}
}
return nil return nil
} }
func (t *SubmitPoStParams) UnmarshalCBOR(r io.Reader) error { func (t *SubmitFallbackPoStParams) UnmarshalCBOR(r io.Reader) error {
br := cbg.GetPeeker(r) br := cbg.GetPeeker(r)
maj, extra, err := cbg.CborReadHeader(br) maj, extra, err := cbg.CborReadHeader(br)
@ -883,15 +874,32 @@ func (t *SubmitPoStParams) UnmarshalCBOR(r io.Reader) error {
if _, err := io.ReadFull(br, t.Proof); err != nil { if _, err := io.ReadFull(br, t.Proof); err != nil {
return err return err
} }
// t.t.DoneSet (types.BitField) (struct) // t.t.Candidates ([]types.EPostTicket) (slice)
{ maj, extra, err = cbg.CborReadHeader(br)
if err != nil {
return err
}
if extra > 8192 {
return fmt.Errorf("t.Candidates: array too large (%d)", extra)
}
if err := t.DoneSet.UnmarshalCBOR(br); err != nil { if maj != cbg.MajArray {
return fmt.Errorf("expected cbor array")
}
if extra > 0 {
t.Candidates = make([]types.EPostTicket, extra)
}
for i := 0; i < int(extra); i++ {
var v types.EPostTicket
if err := v.UnmarshalCBOR(br); err != nil {
return err return err
} }
t.Candidates[i] = v
} }
return nil return nil
} }

View File

@ -7,7 +7,7 @@ import (
"io" "io"
"strconv" "strconv"
"github.com/filecoin-project/go-bls-sigs" bls "github.com/filecoin-project/filecoin-ffi"
"github.com/filecoin-project/go-leb128" "github.com/filecoin-project/go-leb128"
cbor "github.com/ipfs/go-ipld-cbor" cbor "github.com/ipfs/go-ipld-cbor"
"github.com/minio/blake2b-simd" "github.com/minio/blake2b-simd"
@ -389,3 +389,11 @@ func (a *Address) UnmarshalCBOR(br io.Reader) error {
return nil return nil
} }
func IDFromAddress(addr Address) (uint64, error) {
if addr.Protocol() != ID {
return 0, xerrors.Errorf("cannot get id from non id address")
}
return leb128.ToUInt64(addr.Payload()), nil
}

View File

@ -10,7 +10,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/filecoin-project/go-bls-sigs" ffi "github.com/filecoin-project/filecoin-ffi"
"github.com/filecoin-project/go-leb128" "github.com/filecoin-project/go-leb128"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -285,7 +285,7 @@ func TestVectorActorAddress(t *testing.T) {
func TestRandomBLSAddress(t *testing.T) { func TestRandomBLSAddress(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
pk := bls.PrivateKeyPublicKey(bls.PrivateKeyGenerate()) pk := ffi.PrivateKeyPublicKey(ffi.PrivateKeyGenerate())
addr, err := NewBLSAddress(pk[:]) addr, err := NewBLSAddress(pk[:])
assert.NoError(err) assert.NoError(err)
@ -410,8 +410,8 @@ func TestInvalidByteAddresses(t *testing.T) {
{append([]byte{2}, make([]byte, PayloadHashLength+1)...), ErrInvalidPayload}, {append([]byte{2}, make([]byte, PayloadHashLength+1)...), ErrInvalidPayload},
// BLS Protocol // BLS Protocol
{append([]byte{3}, make([]byte, bls.PublicKeyBytes-1)...), ErrInvalidPayload}, {append([]byte{3}, make([]byte, ffi.PublicKeyBytes-1)...), ErrInvalidPayload},
{append([]byte{3}, make([]byte, bls.PrivateKeyBytes+1)...), ErrInvalidPayload}, {append([]byte{3}, make([]byte, ffi.PrivateKeyBytes+1)...), ErrInvalidPayload},
} }
for _, tc := range testCases { for _, tc := range testCases {

View File

@ -2,9 +2,9 @@ package address
import ( import (
"encoding/base32" "encoding/base32"
"errors"
"github.com/minio/blake2b-simd" "github.com/minio/blake2b-simd"
errors "github.com/pkg/errors"
) )
func init() { func init() {

View File

@ -5,7 +5,7 @@ import (
"io" "io"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
cid "github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
cbg "github.com/whyrusleeping/cbor-gen" cbg "github.com/whyrusleeping/cbor-gen"
xerrors "golang.org/x/xerrors" xerrors "golang.org/x/xerrors"
) )

View File

@ -24,6 +24,8 @@ import (
"github.com/filecoin-project/lotus/storage/sectorblocks" "github.com/filecoin-project/lotus/storage/sectorblocks"
) )
var ProviderDsPrefix = "/deals/provider"
type MinerDeal struct { type MinerDeal struct {
Client peer.ID Client peer.ID
Proposal actors.StorageDealProposal Proposal actors.StorageDealProposal
@ -110,7 +112,7 @@ func NewProvider(ds dtypes.MetadataDS, sminer *storage.Miner, secb *sectorblocks
actor: minerAddress, actor: minerAddress,
deals: statestore.New(namespace.Wrap(ds, datastore.NewKey("/deals/client"))), deals: statestore.New(namespace.Wrap(ds, datastore.NewKey(ProviderDsPrefix))),
ds: ds, ds: ds,
} }

View File

@ -6,7 +6,9 @@ import (
"sync" "sync"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
"golang.org/x/xerrors"
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
) )
@ -302,9 +304,10 @@ func (e *calledEvents) Called(check CheckFunc, hnd CalledHandler, rev RevertHand
e.lk.Lock() e.lk.Lock()
defer e.lk.Unlock() defer e.lk.Unlock()
done, more, err := check(e.tsc.best()) ts := e.tsc.best()
done, more, err := check(ts)
if err != nil { if err != nil {
return err return xerrors.Errorf("called check error (h: %d): %w", ts.Height(), err)
} }
if done { if done {
timeout = NoTimeout timeout = NoTimeout
@ -335,6 +338,6 @@ func (e *calledEvents) Called(check CheckFunc, hnd CalledHandler, rev RevertHand
return nil return nil
} }
func (e *calledEvents) CalledMsg(ctx context.Context, hnd CalledHandler, rev RevertHandler, confidence int, timeout uint64, msg *types.Message) error { func (e *calledEvents) CalledMsg(ctx context.Context, hnd CalledHandler, rev RevertHandler, confidence int, timeout uint64, msg store.ChainMsg) error {
return e.Called(e.CheckMsg(ctx, msg, hnd), hnd, rev, confidence, timeout, e.MatchMsg(msg)) return e.Called(e.CheckMsg(ctx, msg, hnd), hnd, rev, confidence, timeout, e.MatchMsg(msg.VMMessage()))
} }

View File

@ -96,7 +96,7 @@ func (e *heightEvents) headChangeAt(rev, app []*types.TipSet) error {
span.End() span.End()
if err != nil { if err != nil {
log.Errorf("chain trigger (@H %d, called @ %d) failed: %s", triggerH, ts.Height(), err) log.Errorf("chain trigger (@H %d, called @ %d) failed: %+v", triggerH, ts.Height(), err)
} }
} }
return nil return nil

View File

@ -60,26 +60,26 @@ func makeTs(t *testing.T, h uint64, msgcid cid.Cid) *types.TipSet {
Height: h, Height: h,
Miner: a, Miner: a,
Tickets: []*types.Ticket{{[]byte{byte(h % 2)}}}, Ticket: &types.Ticket{[]byte{byte(h % 2)}},
ParentStateRoot: dummyCid, ParentStateRoot: dummyCid,
Messages: msgcid, Messages: msgcid,
ParentMessageReceipts: dummyCid, ParentMessageReceipts: dummyCid,
BlockSig: types.Signature{Type: types.KTBLS}, BlockSig: &types.Signature{Type: types.KTBLS},
BLSAggregate: types.Signature{Type: types.KTBLS}, BLSAggregate: types.Signature{Type: types.KTBLS},
}, },
{ {
Height: h, Height: h,
Miner: b, Miner: b,
Tickets: []*types.Ticket{{[]byte{byte((h + 1) % 2)}}}, Ticket: &types.Ticket{[]byte{byte((h + 1) % 2)}},
ParentStateRoot: dummyCid, ParentStateRoot: dummyCid,
Messages: msgcid, Messages: msgcid,
ParentMessageReceipts: dummyCid, ParentMessageReceipts: dummyCid,
BlockSig: types.Signature{Type: types.KTBLS}, BlockSig: &types.Signature{Type: types.KTBLS},
BLSAggregate: types.Signature{Type: types.KTBLS}, BLSAggregate: types.Signature{Type: types.KTBLS},
}, },
}) })

View File

@ -27,7 +27,7 @@ func TestTsCache(t *testing.T) {
ParentStateRoot: dummyCid, ParentStateRoot: dummyCid,
Messages: dummyCid, Messages: dummyCid,
ParentMessageReceipts: dummyCid, ParentMessageReceipts: dummyCid,
BlockSig: types.Signature{Type: types.KTBLS}, BlockSig: &types.Signature{Type: types.KTBLS},
BLSAggregate: types.Signature{Type: types.KTBLS}, BLSAggregate: types.Signature{Type: types.KTBLS},
}}) }})
if err != nil { if err != nil {
@ -69,7 +69,7 @@ func TestTsCacheNulls(t *testing.T) {
ParentStateRoot: dummyCid, ParentStateRoot: dummyCid,
Messages: dummyCid, Messages: dummyCid,
ParentMessageReceipts: dummyCid, ParentMessageReceipts: dummyCid,
BlockSig: types.Signature{Type: types.KTBLS}, BlockSig: &types.Signature{Type: types.KTBLS},
BLSAggregate: types.Signature{Type: types.KTBLS}, BLSAggregate: types.Signature{Type: types.KTBLS},
}}) }})
if err != nil { if err != nil {

View File

@ -5,28 +5,32 @@ import (
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
) )
func (e *calledEvents) CheckMsg(ctx context.Context, msg *types.Message, hnd CalledHandler) CheckFunc { func (e *calledEvents) CheckMsg(ctx context.Context, smsg store.ChainMsg, hnd CalledHandler) CheckFunc {
msg := smsg.VMMessage()
return func(ts *types.TipSet) (done bool, more bool, err error) { return func(ts *types.TipSet) (done bool, more bool, err error) {
fa, err := e.cs.StateGetActor(ctx, msg.From, ts) fa, err := e.cs.StateGetActor(ctx, msg.From, ts)
if err != nil { if err != nil {
return false, true, err return false, true, err
} }
// TODO: probably want to look at the chain to make sure it's // >= because actor nonce is actually the next nonce that is expected to appear on chain
// the right message, but this is probably good enough for now if msg.Nonce >= fa.Nonce {
done = fa.Nonce >= msg.Nonce return false, true, nil
}
rec, err := e.cs.StateGetReceipt(ctx, msg.Cid(), ts) rec, err := e.cs.StateGetReceipt(ctx, smsg.VMMessage().Cid(), ts)
if err != nil { if err != nil {
return false, true, err return false, true, xerrors.Errorf("getting receipt in CheckMsg: %w", err)
} }
more, err = hnd(msg, rec, ts, ts.Height()) more, err = hnd(msg, rec, ts, ts.Height())
return done, more, err return true, more, err
} }
} }

View File

@ -3,14 +3,20 @@ package gen
import ( import (
"bytes" "bytes"
"context" "context"
"crypto/sha256"
"encoding/binary"
"fmt" "fmt"
"io/ioutil"
"sync/atomic" "sync/atomic"
ffi "github.com/filecoin-project/filecoin-ffi"
"github.com/ipfs/go-blockservice" "github.com/ipfs/go-blockservice"
"github.com/ipfs/go-car" "github.com/ipfs/go-car"
offline "github.com/ipfs/go-ipfs-exchange-offline" offline "github.com/ipfs/go-ipfs-exchange-offline"
"github.com/ipfs/go-merkledag" "github.com/ipfs/go-merkledag"
peer "github.com/libp2p/go-libp2p-peer" peer "github.com/libp2p/go-libp2p-peer"
"go.opencensus.io/trace"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api"
@ -20,6 +26,9 @@ import (
"github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/wallet" "github.com/filecoin-project/lotus/chain/wallet"
"github.com/filecoin-project/lotus/cmd/lotus-seed/seed"
"github.com/filecoin-project/lotus/genesis"
"github.com/filecoin-project/lotus/lib/sectorbuilder"
"github.com/filecoin-project/lotus/node/repo" "github.com/filecoin-project/lotus/node/repo"
block "github.com/ipfs/go-block-format" block "github.com/ipfs/go-block-format"
@ -46,10 +55,11 @@ type ChainGen struct {
genesis *types.BlockHeader genesis *types.BlockHeader
CurTipset *store.FullTipSet CurTipset *store.FullTipSet
Timestamper func(*types.TipSet, int) uint64 Timestamper func(*types.TipSet, uint64) uint64
w *wallet.Wallet w *wallet.Wallet
eppProvs map[address.Address]ElectionPoStProver
Miners []address.Address Miners []address.Address
mworkers []address.Address mworkers []address.Address
receivers []address.Address receivers []address.Address
@ -102,16 +112,6 @@ func NewGenerator() (*ChainGen, error) {
return nil, xerrors.Errorf("creating memrepo wallet failed: %w", err) return nil, xerrors.Errorf("creating memrepo wallet failed: %w", err)
} }
worker1, err := w.GenerateKey(types.KTBLS)
if err != nil {
return nil, xerrors.Errorf("failed to generate worker key: %w", err)
}
worker2, err := w.GenerateKey(types.KTBLS)
if err != nil {
return nil, xerrors.Errorf("failed to generate worker key: %w", err)
}
banker, err := w.GenerateKey(types.KTSecp256k1) banker, err := w.GenerateKey(types.KTSecp256k1)
if err != nil { if err != nil {
return nil, xerrors.Errorf("failed to generate banker key: %w", err) return nil, xerrors.Errorf("failed to generate banker key: %w", err)
@ -125,16 +125,60 @@ func NewGenerator() (*ChainGen, error) {
} }
} }
// TODO: this is really weird, we have to guess the miner addresses that
// will be created in order to preseal data for them
maddr1, err := address.NewFromString("t0300")
if err != nil {
return nil, err
}
m1temp, err := ioutil.TempDir("", "preseal")
if err != nil {
return nil, err
}
genm1, err := seed.PreSeal(maddr1, 1024, 1, m1temp, []byte("some randomness"))
if err != nil {
return nil, err
}
maddr2, err := address.NewFromString("t0301")
if err != nil {
return nil, err
}
m2temp, err := ioutil.TempDir("", "preseal")
if err != nil {
return nil, err
}
genm2, err := seed.PreSeal(maddr2, 1024, 1, m2temp, []byte("some randomness"))
if err != nil {
return nil, err
}
mk1, err := w.Import(&genm1.Key)
if err != nil {
return nil, err
}
mk2, err := w.Import(&genm2.Key)
if err != nil {
return nil, err
}
minercfg := &GenMinerCfg{ minercfg := &GenMinerCfg{
Workers: []address.Address{worker1, worker2},
Owners: []address.Address{worker1, worker2},
PeerIDs: []peer.ID{"peerID1", "peerID2"}, PeerIDs: []peer.ID{"peerID1", "peerID2"},
PreSeals: map[string]genesis.GenesisMiner{
maddr1.String(): *genm1,
maddr2.String(): *genm2,
},
MinerAddrs: []address.Address{maddr1, maddr2},
} }
genb, err := MakeGenesisBlock(bs, map[address.Address]types.BigInt{ genb, err := MakeGenesisBlock(bs, map[address.Address]types.BigInt{
worker1: types.FromFil(40000), mk1: types.FromFil(40000),
worker2: types.FromFil(40000), mk2: types.FromFil(40000),
banker: types.FromFil(50000), banker: types.FromFil(50000),
}, minercfg, 100000) }, minercfg, 100000)
if err != nil { if err != nil {
return nil, xerrors.Errorf("make genesis block failed: %w", err) return nil, xerrors.Errorf("make genesis block failed: %w", err)
@ -153,6 +197,11 @@ func NewGenerator() (*ChainGen, error) {
return nil, xerrors.Errorf("MakeGenesisBlock failed to set miner address") return nil, xerrors.Errorf("MakeGenesisBlock failed to set miner address")
} }
mgen := make(map[address.Address]ElectionPoStProver)
for _, m := range minercfg.MinerAddrs {
mgen[m] = &eppProvider{}
}
sm := stmgr.NewStateManager(cs) sm := stmgr.NewStateManager(cs)
gen := &ChainGen{ gen := &ChainGen{
@ -163,8 +212,9 @@ func NewGenerator() (*ChainGen, error) {
genesis: genb.Genesis, genesis: genb.Genesis,
w: w, w: w,
Miners: minercfg.MinerAddrs, Miners: minercfg.MinerAddrs,
mworkers: minercfg.Workers, eppProvs: mgen,
//mworkers: minercfg.Workers,
banker: banker, banker: banker,
receivers: receievers, receivers: receievers,
@ -189,20 +239,15 @@ func (cg *ChainGen) GenesisCar() ([]byte, error) {
out := new(bytes.Buffer) out := new(bytes.Buffer)
if err := car.WriteCar(context.TODO(), dserv, []cid.Cid{cg.Genesis().Cid()}, out); err != nil { if err := car.WriteCar(context.TODO(), dserv, []cid.Cid{cg.Genesis().Cid()}, out); err != nil {
return nil, err return nil, xerrors.Errorf("genesis car write car failed: %w", err)
} }
return out.Bytes(), nil return out.Bytes(), nil
} }
func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m address.Address, ticks []*types.Ticket) (types.ElectionProof, *types.Ticket, error) { func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m address.Address, round int64) (*types.EPostProof, *types.Ticket, error) {
var lastTicket *types.Ticket lastTicket := pts.MinTicket()
if len(ticks) == 0 {
lastTicket = pts.MinTicket()
} else {
lastTicket = ticks[len(ticks)-1]
}
st := pts.ParentState() st := pts.ParentState()
@ -211,7 +256,8 @@ func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m add
return nil, nil, xerrors.Errorf("get miner worker: %w", err) return nil, nil, xerrors.Errorf("get miner worker: %w", err)
} }
vrfout, err := ComputeVRF(ctx, cg.w.Sign, worker, lastTicket.VRFProof) log.Warnf("compute VRF ROUND: %d %s %s", round, m, worker)
vrfout, err := ComputeVRF(ctx, cg.w.Sign, worker, m, DSepTicket, lastTicket.VRFProof)
if err != nil { if err != nil {
return nil, nil, xerrors.Errorf("compute VRF: %w", err) return nil, nil, xerrors.Errorf("compute VRF: %w", err)
} }
@ -220,7 +266,7 @@ func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m add
VRFProof: vrfout, VRFProof: vrfout,
} }
win, eproof, err := IsRoundWinner(ctx, pts, append(ticks, tick), m, &mca{w: cg.w, sm: cg.sm}) win, eproof, err := IsRoundWinner(ctx, pts, round, m, cg.eppProvs[m], &mca{w: cg.w, sm: cg.sm})
if err != nil { if err != nil {
return nil, nil, xerrors.Errorf("checking round winner failed: %w", err) return nil, nil, xerrors.Errorf("checking round winner failed: %w", err)
} }
@ -248,23 +294,22 @@ func (cg *ChainGen) NextTipSet() (*MinedTipSet, error) {
func (cg *ChainGen) NextTipSetFromMiners(base *types.TipSet, miners []address.Address) (*MinedTipSet, error) { func (cg *ChainGen) NextTipSetFromMiners(base *types.TipSet, miners []address.Address) (*MinedTipSet, error) {
var blks []*types.FullBlock var blks []*types.FullBlock
ticketSets := make([][]*types.Ticket, len(miners))
msgs, err := cg.getRandomMessages() msgs, err := cg.getRandomMessages()
if err != nil { if err != nil {
return nil, xerrors.Errorf("get random messages: %w", err) return nil, xerrors.Errorf("get random messages: %w", err)
} }
for len(blks) == 0 { for round := int64(base.Height() + 1); len(blks) == 0; round++ {
for i, m := range miners { for _, m := range miners {
proof, t, err := cg.nextBlockProof(context.TODO(), base, m, ticketSets[i]) proof, t, err := cg.nextBlockProof(context.TODO(), base, m, round)
if err != nil { if err != nil {
return nil, xerrors.Errorf("next block proof: %w", err) return nil, xerrors.Errorf("next block proof: %w", err)
} }
ticketSets[i] = append(ticketSets[i], t)
if proof != nil { if proof != nil {
fblk, err := cg.makeBlock(base, m, proof, ticketSets[i], msgs) log.Warn("making block, ticket: ", t.VRFProof)
fblk, err := cg.makeBlock(base, m, proof, t, uint64(round), msgs)
if err != nil { if err != nil {
return nil, xerrors.Errorf("making a block for next tipset failed: %w", err) return nil, xerrors.Errorf("making a block for next tipset failed: %w", err)
} }
@ -286,16 +331,16 @@ func (cg *ChainGen) NextTipSetFromMiners(base *types.TipSet, miners []address.Ad
}, nil }, nil
} }
func (cg *ChainGen) makeBlock(parents *types.TipSet, m address.Address, eproof types.ElectionProof, tickets []*types.Ticket, msgs []*types.SignedMessage) (*types.FullBlock, error) { func (cg *ChainGen) makeBlock(parents *types.TipSet, m address.Address, eproof *types.EPostProof, ticket *types.Ticket, height uint64, msgs []*types.SignedMessage) (*types.FullBlock, error) {
var ts uint64 var ts uint64
if cg.Timestamper != nil { if cg.Timestamper != nil {
ts = cg.Timestamper(parents, len(tickets)) ts = cg.Timestamper(parents, height-parents.Height())
} else { } else {
ts = parents.MinTimestamp() + (uint64(len(tickets)) * build.BlockDelay) ts = parents.MinTimestamp() + ((height - parents.Height()) * build.BlockDelay)
} }
fblk, err := MinerCreateBlock(context.TODO(), cg.sm, cg.w, m, parents, tickets, eproof, msgs, ts) fblk, err := MinerCreateBlock(context.TODO(), cg.sm, cg.w, m, parents, ticket, eproof, msgs, height, ts)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -354,12 +399,16 @@ func (cg *ChainGen) YieldRepo() (repo.Repo, error) {
} }
type MiningCheckAPI interface { type MiningCheckAPI interface {
ChainGetRandomness(context.Context, types.TipSetKey, []*types.Ticket, int) ([]byte, error) ChainGetRandomness(context.Context, types.TipSetKey, int64) ([]byte, error)
StateMinerPower(context.Context, address.Address, *types.TipSet) (api.MinerPower, error) StateMinerPower(context.Context, address.Address, *types.TipSet) (api.MinerPower, error)
StateMinerWorker(context.Context, address.Address, *types.TipSet) (address.Address, error) StateMinerWorker(context.Context, address.Address, *types.TipSet) (address.Address, error)
StateMinerSectorSize(context.Context, address.Address, *types.TipSet) (uint64, error)
StateMinerProvingSet(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error)
WalletSign(context.Context, address.Address, []byte) (*types.Signature, error) WalletSign(context.Context, address.Address, []byte) (*types.Signature, error)
} }
@ -368,8 +417,8 @@ type mca struct {
sm *stmgr.StateManager sm *stmgr.StateManager
} }
func (mca mca) ChainGetRandomness(ctx context.Context, pts types.TipSetKey, ticks []*types.Ticket, lb int) ([]byte, error) { func (mca mca) ChainGetRandomness(ctx context.Context, pts types.TipSetKey, lb int64) ([]byte, error) {
return mca.sm.ChainStore().GetRandomness(ctx, pts.Cids(), ticks, int64(lb)) return mca.sm.ChainStore().GetRandomness(ctx, pts.Cids(), int64(lb))
} }
func (mca mca) StateMinerPower(ctx context.Context, maddr address.Address, ts *types.TipSet) (api.MinerPower, error) { func (mca mca) StateMinerPower(ctx context.Context, maddr address.Address, ts *types.TipSet) (api.MinerPower, error) {
@ -388,12 +437,45 @@ func (mca mca) StateMinerWorker(ctx context.Context, maddr address.Address, ts *
return stmgr.GetMinerWorkerRaw(ctx, mca.sm, ts.ParentState(), maddr) return stmgr.GetMinerWorkerRaw(ctx, mca.sm, ts.ParentState(), maddr)
} }
func (mca mca) StateMinerSectorSize(ctx context.Context, maddr address.Address, ts *types.TipSet) (uint64, error) {
return stmgr.GetMinerSectorSize(ctx, mca.sm, ts, maddr)
}
func (mca mca) StateMinerProvingSet(ctx context.Context, maddr address.Address, ts *types.TipSet) ([]*api.ChainSectorInfo, error) {
return stmgr.GetMinerProvingSet(ctx, mca.sm, ts, maddr)
}
func (mca mca) WalletSign(ctx context.Context, a address.Address, v []byte) (*types.Signature, error) { func (mca mca) WalletSign(ctx context.Context, a address.Address, v []byte) (*types.Signature, error) {
return mca.w.Sign(ctx, a, v) return mca.w.Sign(ctx, a, v)
} }
func IsRoundWinner(ctx context.Context, ts *types.TipSet, ticks []*types.Ticket, miner address.Address, a MiningCheckAPI) (bool, types.ElectionProof, error) { type ElectionPoStProver interface {
r, err := a.ChainGetRandomness(ctx, ts.Key(), ticks, build.EcRandomnessLookback) GenerateCandidates(context.Context, sectorbuilder.SortedPublicSectorInfo, []byte) ([]sectorbuilder.EPostCandidate, error)
ComputeProof(context.Context, sectorbuilder.SortedPublicSectorInfo, []byte, []sectorbuilder.EPostCandidate) ([]byte, error)
}
type eppProvider struct {
sectors []ffi.PublicSectorInfo
}
func (epp *eppProvider) GenerateCandidates(ctx context.Context, _ sectorbuilder.SortedPublicSectorInfo, eprand []byte) ([]sectorbuilder.EPostCandidate, error) {
return []sectorbuilder.EPostCandidate{
sectorbuilder.EPostCandidate{
SectorID: 1,
PartialTicket: [32]byte{},
Ticket: [32]byte{},
SectorChallengeIndex: 1,
},
}, nil
}
func (epp *eppProvider) ComputeProof(ctx context.Context, _ sectorbuilder.SortedPublicSectorInfo, eprand []byte, winners []sectorbuilder.EPostCandidate) ([]byte, error) {
return []byte("valid proof"), nil
}
func IsRoundWinner(ctx context.Context, ts *types.TipSet, round int64, miner address.Address, epp ElectionPoStProver, a MiningCheckAPI) (bool, *types.EPostProof, error) {
r, err := a.ChainGetRandomness(ctx, ts.Key(), round-build.EcRandomnessLookback)
if err != nil { if err != nil {
return false, nil, xerrors.Errorf("chain get randomness: %w", err) return false, nil, xerrors.Errorf("chain get randomness: %w", err)
} }
@ -403,30 +485,153 @@ func IsRoundWinner(ctx context.Context, ts *types.TipSet, ticks []*types.Ticket,
return false, nil, xerrors.Errorf("failed to get miner worker: %w", err) return false, nil, xerrors.Errorf("failed to get miner worker: %w", err)
} }
vrfout, err := ComputeVRF(ctx, a.WalletSign, mworker, r) vrfout, err := ComputeVRF(ctx, a.WalletSign, mworker, miner, DSepElectionPost, r)
if err != nil { if err != nil {
return false, nil, xerrors.Errorf("failed to compute VRF: %w", err) return false, nil, xerrors.Errorf("failed to compute VRF: %w", err)
} }
pset, err := a.StateMinerProvingSet(ctx, miner, ts)
if err != nil {
return false, nil, xerrors.Errorf("failed to load proving set for miner: %w", err)
}
if len(pset) == 0 {
return false, nil, nil
}
var sinfos []ffi.PublicSectorInfo
for _, s := range pset {
var commRa [32]byte
copy(commRa[:], s.CommR)
sinfos = append(sinfos, ffi.PublicSectorInfo{
SectorID: s.SectorID,
CommR: commRa,
})
}
sectors := sectorbuilder.NewSortedPublicSectorInfo(sinfos)
hvrf := sha256.Sum256(vrfout)
log.Info("Replicas: ", sectors)
candidates, err := epp.GenerateCandidates(ctx, sectors, hvrf[:])
if err != nil {
return false, nil, xerrors.Errorf("failed to generate electionPoSt candidates: %w", err)
}
pow, err := a.StateMinerPower(ctx, miner, ts) pow, err := a.StateMinerPower(ctx, miner, ts)
if err != nil { if err != nil {
return false, nil, xerrors.Errorf("failed to check power: %w", err) return false, nil, xerrors.Errorf("failed to check power: %w", err)
} }
return types.PowerCmp(vrfout, pow.MinerPower, pow.TotalPower), vrfout, nil ssize, err := a.StateMinerSectorSize(ctx, miner, ts)
if err != nil {
return false, nil, xerrors.Errorf("failed to look up miners sector size: %w", err)
}
var winners []sectorbuilder.EPostCandidate
for _, c := range candidates {
if types.IsTicketWinner(c.PartialTicket[:], ssize, pow.TotalPower, 1) {
winners = append(winners, c)
}
}
// no winners, sad
if len(winners) == 0 {
return false, nil, nil
}
proof, err := epp.ComputeProof(ctx, sectors, hvrf[:], winners)
if err != nil {
return false, nil, xerrors.Errorf("failed to compute snark for election proof: %w", err)
}
ept := types.EPostProof{
Proof: proof,
PostRand: vrfout,
}
for _, win := range winners {
ept.Candidates = append(ept.Candidates, types.EPostTicket{
Partial: win.PartialTicket[:],
SectorID: win.SectorID,
ChallengeIndex: win.SectorChallengeIndex,
})
}
return true, &ept, nil
} }
type SignFunc func(context.Context, address.Address, []byte) (*types.Signature, error) type SignFunc func(context.Context, address.Address, []byte) (*types.Signature, error)
func ComputeVRF(ctx context.Context, sign SignFunc, w address.Address, input []byte) ([]byte, error) { const (
sig, err := sign(ctx, w, input) DSepTicket = 1
DSepElectionPost = 2
)
func hashVRFBase(personalization uint64, miner address.Address, input []byte) ([]byte, error) {
if miner.Protocol() != address.ID {
return nil, xerrors.Errorf("miner address for compute VRF must be an ID address")
}
var persbuf [8]byte
binary.LittleEndian.PutUint64(persbuf[:], personalization)
h := sha256.New()
h.Write(persbuf[:])
h.Write([]byte{0})
h.Write(input)
h.Write([]byte{0})
h.Write(miner.Bytes())
return h.Sum(nil), nil
}
func VerifyVRF(ctx context.Context, worker, miner address.Address, p uint64, input, vrfproof []byte) error {
ctx, span := trace.StartSpan(ctx, "VerifyVRF")
defer span.End()
vrfBase, err := hashVRFBase(p, miner, input)
if err != nil {
return xerrors.Errorf("computing vrf base failed: %w", err)
}
sig := &types.Signature{
Type: types.KTBLS,
Data: vrfproof,
}
if err := sig.Verify(worker, vrfBase); err != nil {
return xerrors.Errorf("vrf was invalid: %w", err)
}
return nil
}
func ComputeVRF(ctx context.Context, sign SignFunc, worker, miner address.Address, p uint64, input []byte) ([]byte, error) {
sigInput, err := hashVRFBase(p, miner, input)
if err != nil { if err != nil {
return nil, err return nil, err
} }
sig, err := sign(ctx, worker, sigInput)
if err != nil {
return nil, err
}
log.Warnf("making ticket: %x %s %s %x %x", sig.Data, worker, miner, input, sigInput)
if sig.Type != types.KTBLS { if sig.Type != types.KTBLS {
return nil, fmt.Errorf("miner worker address was not a BLS key") return nil, fmt.Errorf("miner worker address was not a BLS key")
} }
return sig.Data, nil return sig.Data, nil
} }
func TicketHash(t *types.Ticket, addr address.Address) []byte {
h := sha256.New()
h.Write(t.VRFProof)
// Field Delimeter
h.Write([]byte{0})
h.Write(addr.Bytes())
return h.Sum(nil)
}

View File

@ -12,18 +12,12 @@ func testGeneration(t testing.TB, n int, msgs int) {
g.msgsPerBlock = msgs g.msgsPerBlock = msgs
var height int
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
mts, err := g.NextTipSet() mts, err := g.NextTipSet()
if err != nil { if err != nil {
t.Fatalf("error at H:%d, %s", i, err) t.Fatalf("error at H:%d, %s", i, err)
} }
_ = mts
ts := mts.TipSet.TipSet()
if ts.Height() != uint64(height+len(ts.Blocks()[0].Tickets)) {
t.Fatal("wrong height", ts.Height(), i, len(ts.Blocks()[0].Tickets), len(ts.Blocks()))
}
height += len(ts.Blocks()[0].Tickets)
} }
} }

View File

@ -3,8 +3,8 @@ package gen
import ( import (
"context" "context"
bls "github.com/filecoin-project/filecoin-ffi"
amt "github.com/filecoin-project/go-amt-ipld" amt "github.com/filecoin-project/go-amt-ipld"
bls "github.com/filecoin-project/go-bls-sigs"
cid "github.com/ipfs/go-cid" cid "github.com/ipfs/go-cid"
hamt "github.com/ipfs/go-hamt-ipld" hamt "github.com/ipfs/go-hamt-ipld"
cbg "github.com/whyrusleeping/cbor-gen" cbg "github.com/whyrusleeping/cbor-gen"
@ -18,14 +18,12 @@ import (
"github.com/filecoin-project/lotus/chain/wallet" "github.com/filecoin-project/lotus/chain/wallet"
) )
func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w *wallet.Wallet, miner address.Address, parents *types.TipSet, tickets []*types.Ticket, proof types.ElectionProof, msgs []*types.SignedMessage, timestamp uint64) (*types.FullBlock, error) { func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w *wallet.Wallet, miner address.Address, parents *types.TipSet, ticket *types.Ticket, proof *types.EPostProof, msgs []*types.SignedMessage, height, timestamp uint64) (*types.FullBlock, error) {
st, recpts, err := sm.TipSetState(ctx, parents) st, recpts, err := sm.TipSetState(ctx, parents)
if err != nil { if err != nil {
return nil, xerrors.Errorf("failed to load tipset state: %w", err) return nil, xerrors.Errorf("failed to load tipset state: %w", err)
} }
height := parents.Height() + uint64(len(tickets))
worker, err := stmgr.GetMinerWorkerRaw(ctx, sm, st, miner) worker, err := stmgr.GetMinerWorkerRaw(ctx, sm, st, miner)
if err != nil { if err != nil {
return nil, xerrors.Errorf("failed to get miner worker: %w", err) return nil, xerrors.Errorf("failed to get miner worker: %w", err)
@ -34,10 +32,10 @@ func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w *wallet.Wal
next := &types.BlockHeader{ next := &types.BlockHeader{
Miner: miner, Miner: miner,
Parents: parents.Cids(), Parents: parents.Cids(),
Tickets: tickets, Ticket: ticket,
Height: height, Height: height,
Timestamp: timestamp, Timestamp: timestamp,
ElectionProof: proof, EPostProof: *proof,
ParentStateRoot: st, ParentStateRoot: st,
ParentMessageReceipts: recpts, ParentMessageReceipts: recpts,
} }
@ -122,7 +120,7 @@ func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w *wallet.Wal
return nil, xerrors.Errorf("failed to sign new block: %w", err) return nil, xerrors.Errorf("failed to sign new block: %w", err)
} }
next.BlockSig = *sig next.BlockSig = sig
fullBlock := &types.FullBlock{ fullBlock := &types.FullBlock{
Header: next, Header: next,

View File

@ -1,6 +1,7 @@
package gen package gen
import ( import (
"bytes"
"context" "context"
"fmt" "fmt"
@ -8,6 +9,7 @@ import (
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
"github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore"
hamt "github.com/ipfs/go-hamt-ipld" hamt "github.com/ipfs/go-hamt-ipld"
blockstore "github.com/ipfs/go-ipfs-blockstore"
bstore "github.com/ipfs/go-ipfs-blockstore" bstore "github.com/ipfs/go-ipfs-blockstore"
peer "github.com/libp2p/go-libp2p-peer" peer "github.com/libp2p/go-libp2p-peer"
cbg "github.com/whyrusleeping/cbor-gen" cbg "github.com/whyrusleeping/cbor-gen"
@ -20,8 +22,17 @@ import (
"github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm" "github.com/filecoin-project/lotus/chain/vm"
"github.com/filecoin-project/lotus/genesis"
) )
var validSsizes = map[uint64]struct{}{}
func init() {
for _, size := range build.SectorSizes {
validSsizes[size] = struct{}{}
}
}
type GenesisBootstrap struct { type GenesisBootstrap struct {
Genesis *types.BlockHeader Genesis *types.BlockHeader
} }
@ -98,15 +109,6 @@ func MakeInitialStateTree(bs bstore.Blockstore, actmap map[address.Address]types
return nil, xerrors.Errorf("set storage market actor: %w", err) return nil, xerrors.Errorf("set storage market actor: %w", err)
} }
smact, err := SetupStorageMarketActor(bs)
if err != nil {
return nil, xerrors.Errorf("setup storage market actor: %w", err)
}
if err := state.SetActor(actors.StorageMarketAddress, smact); err != nil {
return nil, xerrors.Errorf("set storage market actor: %w", err)
}
netAmt := types.FromFil(build.TotalFilecoin) netAmt := types.FromFil(build.TotalFilecoin)
for _, amt := range actmap { for _, amt := range actmap {
netAmt = types.BigSub(netAmt, amt) netAmt = types.BigSub(netAmt, amt)
@ -177,46 +179,61 @@ func SetupStoragePowerActor(bs bstore.Blockstore) (*types.Actor, error) {
}, nil }, nil
} }
func SetupStorageMarketActor(bs bstore.Blockstore) (*types.Actor, error) { func SetupStorageMarketActor(bs bstore.Blockstore, sroot cid.Cid, deals []actors.StorageDeal) (cid.Cid, error) {
cst := hamt.CSTFromBstore(bs) cst := hamt.CSTFromBstore(bs)
nd := hamt.NewNode(cst) nd := hamt.NewNode(cst)
emptyHAMT, err := cst.Put(context.TODO(), nd) emptyHAMT, err := cst.Put(context.TODO(), nd)
if err != nil { if err != nil {
return nil, err return cid.Undef, err
} }
blks := amt.WrapBlockstore(bs) blks := amt.WrapBlockstore(bs)
emptyAMT, err := amt.FromArray(blks, nil) cdeals := make([]cbg.CBORMarshaler, len(deals))
for i, deal := range deals {
cdeals[i] = &actors.OnChainDeal{
Deal: deal,
ActivationEpoch: 1,
}
}
dealAmt, err := amt.FromArray(blks, cdeals)
if err != nil { if err != nil {
return nil, xerrors.Errorf("amt build failed: %w", err) return cid.Undef, xerrors.Errorf("amt build failed: %w", err)
} }
sms := &actors.StorageMarketState{ sms := &actors.StorageMarketState{
Balances: emptyHAMT, Balances: emptyHAMT,
Deals: emptyAMT, Deals: dealAmt,
NextDealID: 0, NextDealID: 0,
} }
stcid, err := cst.Put(context.TODO(), sms) stcid, err := cst.Put(context.TODO(), sms)
if err != nil { if err != nil {
return nil, err return cid.Undef, err
} }
return &types.Actor{ act := &types.Actor{
Code: actors.StorageMarketCodeCid, Code: actors.StorageMarketCodeCid,
Head: stcid, Head: stcid,
Nonce: 0, Nonce: 0,
Balance: types.NewInt(0), Balance: types.NewInt(0),
}, nil }
state, err := state.LoadStateTree(cst, sroot)
if err != nil {
return cid.Undef, xerrors.Errorf("making new state tree: %w", err)
}
if err := state.SetActor(actors.StorageMarketAddress, act); err != nil {
return cid.Undef, xerrors.Errorf("set storage market actor: %w", err)
}
return state.Flush()
} }
type GenMinerCfg struct { type GenMinerCfg struct {
Owners []address.Address PreSeals map[string]genesis.GenesisMiner
Workers []address.Address
// not quite generating real sectors yet, but this will be necessary
//SectorDir string
// The addresses of the created miner, this is set by the genesis setup // The addresses of the created miner, this is set by the genesis setup
MinerAddrs []address.Address MinerAddrs []address.Address
@ -232,78 +249,250 @@ func mustEnc(i cbg.CBORMarshaler) []byte {
return enc return enc
} }
func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid, gmcfg *GenMinerCfg) (cid.Cid, error) { func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid, gmcfg *GenMinerCfg) (cid.Cid, []actors.StorageDeal, error) {
vm, err := vm.NewVM(sroot, 0, nil, actors.NetworkAddress, cs.Blockstore()) vm, err := vm.NewVM(sroot, 0, nil, actors.NetworkAddress, cs.Blockstore())
if err != nil { if err != nil {
return cid.Undef, xerrors.Errorf("failed to create NewVM: %w", err) return cid.Undef, nil, xerrors.Errorf("failed to create NewVM: %w", err)
} }
for i := 0; i < len(gmcfg.Workers); i++ { if len(gmcfg.MinerAddrs) != len(gmcfg.PreSeals) {
owner := gmcfg.Owners[i] return cid.Undef, nil, xerrors.Errorf("miner address list, and preseal count doesn't match (%d != %d)", len(gmcfg.MinerAddrs), len(gmcfg.PreSeals))
worker := gmcfg.Workers[i] }
pid := gmcfg.PeerIDs[i]
params := mustEnc(&actors.CreateStorageMinerParams{ var deals []actors.StorageDeal
Owner: owner,
Worker: worker,
SectorSize: build.SectorSizes[0],
PeerID: pid,
})
// TODO: hardcoding 7000000 here is a little fragile, it changes any for i, maddr := range gmcfg.MinerAddrs {
ps, psok := gmcfg.PreSeals[maddr.String()]
if !psok {
return cid.Undef, nil, xerrors.Errorf("no preseal for miner %s", maddr)
}
minerParams := &actors.CreateStorageMinerParams{
Owner: ps.Owner,
Worker: ps.Worker,
SectorSize: ps.SectorSize,
PeerID: gmcfg.PeerIDs[i], // TODO: grab from preseal too
}
params := mustEnc(minerParams)
// TODO: hardcoding 6500 here is a little fragile, it changes any
// time anyone changes the initial account allocations // time anyone changes the initial account allocations
rval, err := doExecValue(ctx, vm, actors.StoragePowerAddress, owner, types.FromFil(6500), actors.SPAMethods.CreateStorageMiner, params) rval, err := doExecValue(ctx, vm, actors.StoragePowerAddress, ps.Worker, types.FromFil(6500), actors.SPAMethods.CreateStorageMiner, params)
if err != nil { if err != nil {
return cid.Undef, xerrors.Errorf("failed to create genesis miner: %w", err) return cid.Undef, nil, xerrors.Errorf("failed to create genesis miner: %w", err)
} }
maddr, err := address.NewFromBytes(rval) maddrret, err := address.NewFromBytes(rval)
if err != nil { if err != nil {
return cid.Undef, err return cid.Undef, nil, err
} }
gmcfg.MinerAddrs = append(gmcfg.MinerAddrs, maddr) _, err = vm.Flush(ctx)
if err != nil {
return cid.Undef, nil, err
}
params = mustEnc(&actors.UpdateStorageParams{Delta: types.NewInt(5000)}) cst := hamt.CSTFromBstore(cs.Blockstore())
if err := reassignMinerActorAddress(vm, cst, maddrret, maddr); err != nil {
return cid.Undef, nil, err
}
power := types.BigMul(types.NewInt(minerParams.SectorSize), types.NewInt(uint64(len(ps.Sectors))))
params = mustEnc(&actors.UpdateStorageParams{Delta: power})
_, err = doExec(ctx, vm, actors.StoragePowerAddress, maddr, actors.SPAMethods.UpdateStorage, params) _, err = doExec(ctx, vm, actors.StoragePowerAddress, maddr, actors.SPAMethods.UpdateStorage, params)
if err != nil { if err != nil {
return cid.Undef, xerrors.Errorf("failed to update total storage: %w", err) return cid.Undef, nil, xerrors.Errorf("failed to update total storage: %w", err)
} }
// UGLY HACKY MODIFICATION OF MINER POWER
// we have to flush the vm here because it buffers stuff internally for perf reasons // we have to flush the vm here because it buffers stuff internally for perf reasons
if _, err := vm.Flush(ctx); err != nil { if _, err := vm.Flush(ctx); err != nil {
return cid.Undef, xerrors.Errorf("vm.Flush failed: %w", err) return cid.Undef, nil, xerrors.Errorf("vm.Flush failed: %w", err)
} }
st := vm.StateTree() st := vm.StateTree()
mact, err := st.GetActor(maddr) mact, err := st.GetActor(maddr)
if err != nil { if err != nil {
return cid.Undef, xerrors.Errorf("get miner actor failed: %w", err) return cid.Undef, nil, xerrors.Errorf("get miner actor failed: %w", err)
} }
cst := hamt.CSTFromBstore(cs.Blockstore())
var mstate actors.StorageMinerActorState var mstate actors.StorageMinerActorState
if err := cst.Get(ctx, mact.Head, &mstate); err != nil { if err := cst.Get(ctx, mact.Head, &mstate); err != nil {
return cid.Undef, xerrors.Errorf("getting miner actor state failed: %w", err) return cid.Undef, nil, xerrors.Errorf("getting miner actor state failed: %w", err)
}
mstate.Power = types.NewInt(build.SectorSizes[0])
blks := amt.WrapBlockstore(cs.Blockstore())
for _, s := range ps.Sectors {
nssroot, err := actors.AddToSectorSet(ctx, blks, mstate.Sectors, s.SectorID, s.CommR[:], s.CommD[:])
if err != nil {
return cid.Undef, nil, xerrors.Errorf("failed to add fake sector to sector set: %w", err)
}
mstate.Sectors = nssroot
mstate.ProvingSet = nssroot
deals = append(deals, s.Deal)
} }
mstate.Power = types.NewInt(5000)
nstate, err := cst.Put(ctx, &mstate) nstate, err := cst.Put(ctx, &mstate)
if err != nil { if err != nil {
return cid.Undef, err return cid.Undef, nil, err
} }
mact.Head = nstate mact.Head = nstate
if err := st.SetActor(maddr, mact); err != nil { if err := st.SetActor(maddr, mact); err != nil {
return cid.Undef, err return cid.Undef, nil, err
} }
// End of super haxx
} }
return vm.Flush(ctx) c, err := vm.Flush(ctx)
return c, deals, err
}
func reassignMinerActorAddress(vm *vm.VM, cst *hamt.CborIpldStore, from, to address.Address) error {
if from == to {
return nil
}
act, err := vm.StateTree().GetActor(from)
if err != nil {
return xerrors.Errorf("reassign: failed to get 'from' actor: %w", err)
}
_, err = vm.StateTree().GetActor(to)
if err == nil {
return xerrors.Errorf("cannot reassign actor, target address taken")
}
if err := vm.StateTree().SetActor(to, act); err != nil {
return xerrors.Errorf("failed to reassign actor: %w", err)
}
if err := adjustStorageMarketTracking(vm, cst, from, to); err != nil {
return xerrors.Errorf("adjusting storage market tracking: %w", err)
}
// Now, adjust the tracking in the init actor
return initActorReassign(vm, cst, from, to)
}
func adjustStorageMarketTracking(vm *vm.VM, cst *hamt.CborIpldStore, from, to address.Address) error {
ctx := context.TODO()
act, err := vm.StateTree().GetActor(actors.StoragePowerAddress)
if err != nil {
return xerrors.Errorf("loading storage power actor: %w", err)
}
var spst actors.StoragePowerState
if err := cst.Get(ctx, act.Head, &spst); err != nil {
return xerrors.Errorf("loading storage power actor state: %w", err)
}
miners, err := hamt.LoadNode(ctx, cst, spst.Miners)
if err != nil {
return xerrors.Errorf("loading miner set: %w", err)
}
if err := miners.Delete(ctx, string(from.Bytes())); err != nil {
return xerrors.Errorf("deleting from spa set: %w", err)
}
if err := miners.Set(ctx, string(to.Bytes()), uint64(1)); err != nil {
return xerrors.Errorf("failed setting miner: %w", err)
}
if err := miners.Flush(ctx); err != nil {
return err
}
nminerscid, err := cst.Put(ctx, miners)
if err != nil {
return err
}
spst.Miners = nminerscid
nhead, err := cst.Put(ctx, &spst)
if err != nil {
return err
}
act.Head = nhead
return nil
}
func initActorReassign(vm *vm.VM, cst *hamt.CborIpldStore, from, to address.Address) error {
ctx := context.TODO()
initact, err := vm.StateTree().GetActor(actors.InitAddress)
if err != nil {
return xerrors.Errorf("couldnt get init actor: %w", err)
}
var st actors.InitActorState
if err := cst.Get(ctx, initact.Head, &st); err != nil {
return xerrors.Errorf("reassign loading init actor state: %w", err)
}
amap, err := hamt.LoadNode(ctx, cst, st.AddressMap)
if err != nil {
return xerrors.Errorf("failed to load init actor map: %w", err)
}
target, err := address.IDFromAddress(from)
if err != nil {
return xerrors.Errorf("failed to extract ID: %w", err)
}
var out string
halt := xerrors.Errorf("halt")
err = amap.ForEach(ctx, func(k string, v interface{}) error {
_, val, err := cbg.CborReadHeader(bytes.NewReader(v.(*cbg.Deferred).Raw))
if err != nil {
return xerrors.Errorf("parsing int in map failed: %w", err)
}
if val == target {
out = k
return halt
}
return nil
})
if err == nil {
return xerrors.Errorf("could not find from address in init ID map")
}
if !xerrors.Is(err, halt) {
return xerrors.Errorf("finding address in ID map failed: %w", err)
}
if err := amap.Delete(ctx, out); err != nil {
return xerrors.Errorf("deleting 'from' entry in amap: %w", err)
}
if err := amap.Set(ctx, out, target); err != nil {
return xerrors.Errorf("setting 'to' entry in amap: %w", err)
}
if err := amap.Flush(ctx); err != nil {
return xerrors.Errorf("failed to flush amap: %w", err)
}
ncid, err := cst.Put(ctx, amap)
if err != nil {
return err
}
st.AddressMap = ncid
nacthead, err := cst.Put(ctx, &st)
if err != nil {
return err
}
initact.Head = nacthead
return nil
} }
func doExec(ctx context.Context, vm *vm.VM, to, from address.Address, method uint64, params []byte) ([]byte, error) { func doExec(ctx context.Context, vm *vm.VM, to, from address.Address, method uint64, params []byte) ([]byte, error) {
@ -352,11 +541,21 @@ func MakeGenesisBlock(bs bstore.Blockstore, balances map[address.Address]types.B
// temp chainstore // temp chainstore
cs := store.NewChainStore(bs, datastore.NewMapDatastore()) cs := store.NewChainStore(bs, datastore.NewMapDatastore())
stateroot, err = SetupStorageMiners(ctx, cs, stateroot, gmcfg) stateroot, deals, err := SetupStorageMiners(ctx, cs, stateroot, gmcfg)
if err != nil { if err != nil {
return nil, xerrors.Errorf("setup storage miners failed: %w", err) return nil, xerrors.Errorf("setup storage miners failed: %w", err)
} }
stateroot, err = SetupStorageMarketActor(bs, stateroot, deals)
if err != nil {
return nil, xerrors.Errorf("setup storage market actor: %w", err)
}
stateroot, err = AdjustInitActorStartID(ctx, bs, stateroot, 1000)
if err != nil {
return nil, xerrors.Errorf("failed to adjust init actor start ID: %w", err)
}
blks := amt.WrapBlockstore(bs) blks := amt.WrapBlockstore(bs)
emptyroot, err := amt.FromArray(blks, nil) emptyroot, err := amt.FromArray(blks, nil)
@ -383,9 +582,12 @@ func MakeGenesisBlock(bs bstore.Blockstore, balances map[address.Address]types.B
} }
b := &types.BlockHeader{ b := &types.BlockHeader{
Miner: actors.InitAddress, Miner: actors.InitAddress,
Tickets: []*types.Ticket{genesisticket}, Ticket: genesisticket,
ElectionProof: []byte("the Genesis block"), EPostProof: types.EPostProof{
Proof: []byte("not a real proof"),
PostRand: []byte("i guess this is kinda random"),
},
Parents: []cid.Cid{}, Parents: []cid.Cid{},
Height: 0, Height: 0,
ParentWeight: types.NewInt(0), ParentWeight: types.NewInt(0),
@ -393,7 +595,7 @@ func MakeGenesisBlock(bs bstore.Blockstore, balances map[address.Address]types.B
Messages: mmb.Cid(), Messages: mmb.Cid(),
ParentMessageReceipts: emptyroot, ParentMessageReceipts: emptyroot,
BLSAggregate: types.Signature{Type: types.KTBLS, Data: []byte("signatureeee")}, BLSAggregate: types.Signature{Type: types.KTBLS, Data: []byte("signatureeee")},
BlockSig: types.Signature{Type: types.KTBLS, Data: []byte("block signatureeee")}, BlockSig: &types.Signature{Type: types.KTBLS, Data: []byte("block signatureeee")},
Timestamp: ts, Timestamp: ts,
} }
@ -410,3 +612,37 @@ func MakeGenesisBlock(bs bstore.Blockstore, balances map[address.Address]types.B
Genesis: b, Genesis: b,
}, nil }, nil
} }
func AdjustInitActorStartID(ctx context.Context, bs blockstore.Blockstore, stateroot cid.Cid, val uint64) (cid.Cid, error) {
cst := hamt.CSTFromBstore(bs)
tree, err := state.LoadStateTree(cst, stateroot)
if err != nil {
return cid.Undef, err
}
act, err := tree.GetActor(actors.InitAddress)
if err != nil {
return cid.Undef, err
}
var st actors.InitActorState
if err := cst.Get(ctx, act.Head, &st); err != nil {
return cid.Undef, err
}
st.NextID = val
nstate, err := cst.Put(ctx, &st)
if err != nil {
return cid.Undef, err
}
act.Head = nstate
if err := tree.SetActor(actors.InitAddress, act); err != nil {
return cid.Undef, err
}
return tree.Flush()
}

View File

@ -1,6 +1,7 @@
package chain package chain
import ( import (
"bytes"
"context" "context"
"errors" "errors"
"sort" "sort"
@ -8,6 +9,9 @@ import (
"time" "time"
lru "github.com/hashicorp/golang-lru" lru "github.com/hashicorp/golang-lru"
"github.com/ipfs/go-datastore"
"github.com/ipfs/go-datastore/namespace"
"github.com/ipfs/go-datastore/query"
pubsub "github.com/libp2p/go-libp2p-pubsub" pubsub "github.com/libp2p/go-libp2p-pubsub"
lps "github.com/whyrusleeping/pubsub" lps "github.com/whyrusleeping/pubsub"
"go.uber.org/multierr" "go.uber.org/multierr"
@ -18,6 +22,7 @@ import (
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/node/modules/dtypes"
) )
var ( var (
@ -35,6 +40,8 @@ var (
const ( const (
msgTopic = "/fil/messages" msgTopic = "/fil/messages"
localMsgsDs = "/mpool/local"
localUpdates = "update" localUpdates = "update"
) )
@ -60,6 +67,8 @@ type MessagePool struct {
blsSigCache *lru.TwoQueueCache blsSigCache *lru.TwoQueueCache
changes *lps.PubSub changes *lps.PubSub
localMsgs datastore.Datastore
} }
type msgSet struct { type msgSet struct {
@ -89,7 +98,7 @@ func (ms *msgSet) add(m *types.SignedMessage) error {
return nil return nil
} }
func NewMessagePool(sm *stmgr.StateManager, ps *pubsub.PubSub) *MessagePool { func NewMessagePool(sm *stmgr.StateManager, ps *pubsub.PubSub, ds dtypes.MetadataDS) (*MessagePool, error) {
cache, _ := lru.New2Q(build.BlsSignatureCacheSize) cache, _ := lru.New2Q(build.BlsSignatureCacheSize)
mp := &MessagePool{ mp := &MessagePool{
closer: make(chan struct{}), closer: make(chan struct{}),
@ -99,10 +108,18 @@ func NewMessagePool(sm *stmgr.StateManager, ps *pubsub.PubSub) *MessagePool {
sm: sm, sm: sm,
ps: ps, ps: ps,
minGasPrice: types.NewInt(0), minGasPrice: types.NewInt(0),
maxTxPoolSize: 100000, maxTxPoolSize: 5000,
blsSigCache: cache, blsSigCache: cache,
changes: lps.New(50), changes: lps.New(50),
localMsgs: namespace.Wrap(ds, datastore.NewKey(localMsgsDs)),
} }
if err := mp.loadLocal(); err != nil {
return nil, xerrors.Errorf("loading local messages: %w", err)
}
go mp.repubLocal()
sm.ChainStore().SubscribeHeadChanges(func(rev, app []*types.TipSet) error { sm.ChainStore().SubscribeHeadChanges(func(rev, app []*types.TipSet) error {
err := mp.HeadChange(rev, app) err := mp.HeadChange(rev, app)
if err != nil { if err != nil {
@ -111,7 +128,7 @@ func NewMessagePool(sm *stmgr.StateManager, ps *pubsub.PubSub) *MessagePool {
return err return err
}) })
return mp return mp, nil
} }
func (mp *MessagePool) Close() error { func (mp *MessagePool) Close() error {
@ -134,13 +151,13 @@ func (mp *MessagePool) repubLocal() {
for _, msg := range msgs { for _, msg := range msgs {
msgb, err := msg.Serialize() msgb, err := msg.Serialize()
if err != nil { if err != nil {
multierr.Append(errout, xerrors.Errorf("could not serialize: %w", err)) errout = multierr.Append(errout, xerrors.Errorf("could not serialize: %w", err))
continue continue
} }
err = mp.ps.Publish(msgTopic, msgb) err = mp.ps.Publish(msgTopic, msgb)
if err != nil { if err != nil {
multierr.Append(errout, xerrors.Errorf("could not publish: %w", err)) errout = multierr.Append(errout, xerrors.Errorf("could not publish: %w", err))
continue continue
} }
} }
@ -156,8 +173,14 @@ func (mp *MessagePool) repubLocal() {
} }
func (mp *MessagePool) addLocal(a address.Address) { func (mp *MessagePool) addLocal(m *types.SignedMessage, msgb []byte) error {
mp.localAddrs[a] = struct{}{} mp.localAddrs[m.Message.From] = struct{}{}
if err := mp.localMsgs.Put(datastore.NewKey(string(m.Cid().Bytes())), msgb); err != nil {
return xerrors.Errorf("persisting local message: %w", err)
}
return nil
} }
func (mp *MessagePool) Push(m *types.SignedMessage) error { func (mp *MessagePool) Push(m *types.SignedMessage) error {
@ -171,7 +194,10 @@ func (mp *MessagePool) Push(m *types.SignedMessage) error {
} }
mp.lk.Lock() mp.lk.Lock()
mp.addLocal(m.Message.From) if err := mp.addLocal(m, msgb); err != nil {
mp.lk.Unlock()
return err
}
mp.lk.Unlock() mp.lk.Unlock()
return mp.ps.Publish(msgTopic, msgb) return mp.ps.Publish(msgTopic, msgb)
@ -231,13 +257,20 @@ func (mp *MessagePool) addLocked(m *types.SignedMessage) error {
return err return err
} }
if _, err := mp.sm.ChainStore().PutMessage(&m.Message); err != nil {
log.Warnf("mpooladd cs.PutMessage failed: %s", err)
return err
}
mset, ok := mp.pending[m.Message.From] mset, ok := mp.pending[m.Message.From]
if !ok { if !ok {
mset = newMsgSet() mset = newMsgSet()
mp.pending[m.Message.From] = mset mp.pending[m.Message.From] = mset
} }
mset.add(m) if err := mset.add(m); err != nil {
log.Error(err)
}
mp.changes.Pub(api.MpoolUpdate{ mp.changes.Pub(api.MpoolUpdate{
Type: api.MpoolAdd, Type: api.MpoolAdd,
@ -254,12 +287,23 @@ func (mp *MessagePool) GetNonce(addr address.Address) (uint64, error) {
} }
func (mp *MessagePool) getNonceLocked(addr address.Address) (uint64, error) { func (mp *MessagePool) getNonceLocked(addr address.Address) (uint64, error) {
stateNonce, err := mp.getStateNonce(addr) // sanity check
if err != nil {
return 0, err
}
mset, ok := mp.pending[addr] mset, ok := mp.pending[addr]
if ok { if ok {
if stateNonce > mset.nextNonce {
log.Errorf("state nonce was larger than mset.nextNonce (%d > %d)", stateNonce, mset.nextNonce)
return stateNonce, nil
}
return mset.nextNonce, nil return mset.nextNonce, nil
} }
return mp.getStateNonce(addr) return stateNonce, nil
} }
func (mp *MessagePool) getStateNonce(addr address.Address) (uint64, error) { func (mp *MessagePool) getStateNonce(addr address.Address) (uint64, error) {
@ -302,7 +346,9 @@ func (mp *MessagePool) PushWithNonce(addr address.Address, cb func(uint64) (*typ
if err := mp.addLocked(msg); err != nil { if err := mp.addLocked(msg); err != nil {
return nil, err return nil, err
} }
mp.addLocal(msg.Message.From) if err := mp.addLocal(msg, msgb); err != nil {
log.Errorf("addLocal failed: %+v", err)
}
return msg, mp.ps.Publish(msgTopic, msgb) return msg, mp.ps.Publish(msgTopic, msgb)
} }
@ -328,8 +374,7 @@ func (mp *MessagePool) Remove(from address.Address, nonce uint64) {
delete(mset.msgs, nonce) delete(mset.msgs, nonce)
if len(mset.msgs) == 0 { if len(mset.msgs) == 0 {
// FIXME: This is racy delete(mp.pending, from)
//delete(mp.pending, from)
} else { } else {
var max uint64 var max uint64
for nonce := range mset.msgs { for nonce := range mset.msgs {
@ -337,6 +382,10 @@ func (mp *MessagePool) Remove(from address.Address, nonce uint64) {
max = nonce max = nonce
} }
} }
if max < nonce {
max = nonce // we could have not seen the removed message before
}
mset.nextNonce = max + 1 mset.nextNonce = max + 1
} }
} }
@ -380,7 +429,7 @@ func (mp *MessagePool) HeadChange(revert []*types.TipSet, apply []*types.TipSet)
} }
for _, msg := range smsgs { for _, msg := range smsgs {
if err := mp.Add(msg); err != nil { if err := mp.Add(msg); err != nil {
return err log.Error(err) // TODO: probably lots of spam in multi-block tsets
} }
} }
@ -388,7 +437,7 @@ func (mp *MessagePool) HeadChange(revert []*types.TipSet, apply []*types.TipSet)
smsg := mp.RecoverSig(msg) smsg := mp.RecoverSig(msg)
if smsg != nil { if smsg != nil {
if err := mp.Add(smsg); err != nil { if err := mp.Add(smsg); err != nil {
return err log.Error(err) // TODO: probably lots of spam in multi-block tsets
} }
} else { } else {
log.Warnf("could not recover signature for bls message %s during a reorg revert", msg.Cid()) log.Warnf("could not recover signature for bls message %s during a reorg revert", msg.Cid())
@ -423,7 +472,7 @@ func (mp *MessagePool) RecoverSig(msg *types.Message) *types.SignedMessage {
} }
sig, ok := val.(types.Signature) sig, ok := val.(types.Signature)
if !ok { if !ok {
log.Warnf("value in signature cache was not a signature (got %T)", val) log.Errorf("value in signature cache was not a signature (got %T)", val)
return nil return nil
} }
@ -456,3 +505,31 @@ func (mp *MessagePool) Updates(ctx context.Context) (<-chan api.MpoolUpdate, err
return out, nil return out, nil
} }
func (mp *MessagePool) loadLocal() error {
res, err := mp.localMsgs.Query(query.Query{})
if err != nil {
return xerrors.Errorf("query local messages: %w", err)
}
for r := range res.Next() {
if r.Error != nil {
return xerrors.Errorf("r.Error: %w", r.Error)
}
var sm types.SignedMessage
if err := sm.UnmarshalCBOR(bytes.NewReader(r.Value)); err != nil {
return xerrors.Errorf("unmarshaling local message: %w", err)
}
if err := mp.Add(&sm); err != nil {
if xerrors.Is(err, ErrNonceTooLow) {
continue // todo: drop the message from local cache (if above certain confidence threshold)
}
return xerrors.Errorf("adding local message: %w", err)
}
}
return nil
}

View File

@ -68,7 +68,7 @@ func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types.
state := ts.ParentState() state := ts.ParentState()
r := store.NewChainRand(sm.cs, ts.Cids(), ts.Height(), nil) r := store.NewChainRand(sm.cs, ts.Cids(), ts.Height())
return sm.CallRaw(ctx, msg, state, r, ts.Height()) return sm.CallRaw(ctx, msg, state, r, ts.Height())
} }

View File

@ -15,7 +15,7 @@ import (
cbg "github.com/whyrusleeping/cbor-gen" cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors" "golang.org/x/xerrors"
bls "github.com/filecoin-project/go-bls-sigs" bls "github.com/filecoin-project/filecoin-ffi"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
hamt "github.com/ipfs/go-hamt-ipld" hamt "github.com/ipfs/go-hamt-ipld"
logging "github.com/ipfs/go-log" logging "github.com/ipfs/go-log"
@ -102,7 +102,7 @@ func (sm *StateManager) computeTipSetState(ctx context.Context, blks []*types.Bl
cids[i] = v.Cid() cids[i] = v.Cid()
} }
r := store.NewChainRand(sm.cs, cids, blks[0].Height, nil) r := store.NewChainRand(sm.cs, cids, blks[0].Height)
vmi, err := vm.NewVM(pstate, blks[0].Height, r, address.Undef, sm.cs.Blockstore()) vmi, err := vm.NewVM(pstate, blks[0].Height, r, address.Undef, sm.cs.Blockstore())
if err != nil { if err != nil {
@ -113,9 +113,14 @@ func (sm *StateManager) computeTipSetState(ctx context.Context, blks []*types.Bl
if err != nil { if err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("failed to get network actor: %w", err) return cid.Undef, cid.Undef, xerrors.Errorf("failed to get network actor: %w", err)
} }
reward := vm.MiningReward(netact.Balance) reward := vm.MiningReward(netact.Balance)
for _, b := range blks { for _, b := range blks {
netact, err = vmi.StateTree().GetActor(actors.NetworkAddress)
if err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("failed to get network actor: %w", err)
}
vmi.SetBlockMiner(b.Miner)
owner, err := GetMinerOwner(ctx, sm, pstate, b.Miner) owner, err := GetMinerOwner(ctx, sm, pstate, b.Miner)
if err != nil { if err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("failed to get owner for miner %s: %w", b.Miner, err) return cid.Undef, cid.Undef, xerrors.Errorf("failed to get owner for miner %s: %w", b.Miner, err)
@ -130,6 +135,23 @@ func (sm *StateManager) computeTipSetState(ctx context.Context, blks []*types.Bl
return cid.Undef, cid.Undef, xerrors.Errorf("failed to deduct funds from network actor: %w", err) return cid.Undef, cid.Undef, xerrors.Errorf("failed to deduct funds from network actor: %w", err)
} }
// all block miners created a valid post, go update the actor state
postSubmitMsg := &types.Message{
From: actors.NetworkAddress,
Nonce: netact.Nonce,
To: b.Miner,
Method: actors.MAMethods.SubmitElectionPoSt,
GasPrice: types.NewInt(0),
GasLimit: types.NewInt(10000000000),
Value: types.NewInt(0),
}
ret, err := vmi.ApplyMessage(ctx, postSubmitMsg)
if err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("submit election post message invocation failed: %w", err)
}
if ret.ExitCode != 0 {
return cid.Undef, cid.Undef, xerrors.Errorf("submit election post invocation returned nonzero exit code: %d", ret.ExitCode)
}
} }
// TODO: can't use method from chainstore because it doesnt let us know who the block miners were // TODO: can't use method from chainstore because it doesnt let us know who the block miners were
@ -322,7 +344,12 @@ func (sm *StateManager) GetBlsPublicKey(ctx context.Context, addr address.Addres
} }
func (sm *StateManager) GetReceipt(ctx context.Context, msg cid.Cid, ts *types.TipSet) (*types.MessageReceipt, error) { func (sm *StateManager) GetReceipt(ctx context.Context, msg cid.Cid, ts *types.TipSet) (*types.MessageReceipt, error) {
r, err := sm.tipsetExecutedMessage(ts, msg) m, err := sm.cs.GetCMessage(msg)
if err != nil {
return nil, fmt.Errorf("failed to load message: %w", err)
}
r, err := sm.tipsetExecutedMessage(ts, msg, m.VMMessage())
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -331,11 +358,6 @@ func (sm *StateManager) GetReceipt(ctx context.Context, msg cid.Cid, ts *types.T
return r, nil return r, nil
} }
m, err := sm.cs.GetCMessage(msg)
if err != nil {
return nil, fmt.Errorf("failed to load message: %w", err)
}
_, r, err = sm.searchBackForMsg(ctx, ts, m) _, r, err = sm.searchBackForMsg(ctx, ts, m)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to look back through chain for message: %w", err) return nil, fmt.Errorf("failed to look back through chain for message: %w", err)
@ -368,7 +390,7 @@ func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid) (*type
return nil, nil, fmt.Errorf("expected current head on SHC stream (got %s)", head[0].Type) return nil, nil, fmt.Errorf("expected current head on SHC stream (got %s)", head[0].Type)
} }
r, err := sm.tipsetExecutedMessage(head[0].Val, mcid) r, err := sm.tipsetExecutedMessage(head[0].Val, mcid, msg.VMMessage())
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -403,7 +425,7 @@ func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid) (*type
case store.HCRevert: case store.HCRevert:
continue continue
case store.HCApply: case store.HCApply:
r, err := sm.tipsetExecutedMessage(val.Val, mcid) r, err := sm.tipsetExecutedMessage(val.Val, mcid, msg.VMMessage())
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -454,7 +476,7 @@ func (sm *StateManager) searchBackForMsg(ctx context.Context, from *types.TipSet
return nil, nil, fmt.Errorf("failed to load tipset during msg wait searchback: %w", err) return nil, nil, fmt.Errorf("failed to load tipset during msg wait searchback: %w", err)
} }
r, err := sm.tipsetExecutedMessage(ts, m.Cid()) r, err := sm.tipsetExecutedMessage(ts, m.Cid(), m.VMMessage())
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("checking for message execution during lookback: %w", err) return nil, nil, fmt.Errorf("checking for message execution during lookback: %w", err)
} }
@ -467,7 +489,7 @@ func (sm *StateManager) searchBackForMsg(ctx context.Context, from *types.TipSet
} }
} }
func (sm *StateManager) tipsetExecutedMessage(ts *types.TipSet, msg cid.Cid) (*types.MessageReceipt, error) { func (sm *StateManager) tipsetExecutedMessage(ts *types.TipSet, msg cid.Cid, vmm *types.Message) (*types.MessageReceipt, error) {
// The genesis block did not execute any messages // The genesis block did not execute any messages
if ts.Height() == 0 { if ts.Height() == 0 {
return nil, nil return nil, nil
@ -483,9 +505,24 @@ func (sm *StateManager) tipsetExecutedMessage(ts *types.TipSet, msg cid.Cid) (*t
return nil, err return nil, err
} }
for i, m := range cm { for ii := range cm {
if m.Cid() == msg { // iterate in reverse because we going backwards through the chain
return sm.cs.GetParentReceipt(ts.Blocks()[0], i) i := len(cm) - ii - 1
m := cm[i]
if m.VMMessage().From == vmm.From { // cheaper to just check origin first
if m.VMMessage().Nonce == vmm.Nonce {
if m.Cid() == msg {
return sm.cs.GetParentReceipt(ts.Blocks()[0], i)
}
// this should be that message
return nil, xerrors.Errorf("found message with equal nonce as the one we are looking for (F:%s n %d, TS: %s n%d)",
msg, vmm.Nonce, m.Cid(), m.VMMessage().Nonce)
}
if m.VMMessage().Nonce < vmm.Nonce {
return nil, nil // don't bother looking further
}
} }
} }

View File

@ -3,10 +3,13 @@ package stmgr
import ( import (
"context" "context"
ffi "github.com/filecoin-project/filecoin-ffi"
"github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/sectorbuilder"
amt "github.com/filecoin-project/go-amt-ipld" amt "github.com/filecoin-project/go-amt-ipld"
cid "github.com/ipfs/go-cid" cid "github.com/ipfs/go-cid"
@ -147,21 +150,21 @@ func GetMinerWorker(ctx context.Context, sm *StateManager, ts *types.TipSet, mad
return address.NewFromBytes(recp.Return) return address.NewFromBytes(recp.Return)
} }
func GetMinerProvingPeriodEnd(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (uint64, error) { func GetMinerElectionPeriodStart(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (uint64, error) {
var mas actors.StorageMinerActorState var mas actors.StorageMinerActorState
_, err := sm.LoadActorState(ctx, maddr, &mas, ts) _, err := sm.LoadActorState(ctx, maddr, &mas, ts)
if err != nil { if err != nil {
return 0, xerrors.Errorf("failed to load miner actor state: %w", err) return 0, xerrors.Errorf("(get eps) failed to load miner actor state: %w", err)
} }
return mas.ProvingPeriodEnd, nil return mas.ElectionPeriodStart, nil
} }
func GetMinerProvingSet(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) ([]*api.ChainSectorInfo, error) { func GetMinerProvingSet(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) ([]*api.ChainSectorInfo, error) {
var mas actors.StorageMinerActorState var mas actors.StorageMinerActorState
_, err := sm.LoadActorState(ctx, maddr, &mas, ts) _, err := sm.LoadActorState(ctx, maddr, &mas, ts)
if err != nil { if err != nil {
return nil, xerrors.Errorf("failed to load miner actor state: %w", err) return nil, xerrors.Errorf("(get pset) failed to load miner actor state: %w", err)
} }
return LoadSectorsFromSet(ctx, sm.ChainStore().Blockstore(), mas.ProvingSet) return LoadSectorsFromSet(ctx, sm.ChainStore().Blockstore(), mas.ProvingSet)
@ -171,17 +174,37 @@ func GetMinerSectorSet(ctx context.Context, sm *StateManager, ts *types.TipSet,
var mas actors.StorageMinerActorState var mas actors.StorageMinerActorState
_, err := sm.LoadActorState(ctx, maddr, &mas, ts) _, err := sm.LoadActorState(ctx, maddr, &mas, ts)
if err != nil { if err != nil {
return nil, xerrors.Errorf("failed to load miner actor state: %w", err) return nil, xerrors.Errorf("(get sset) failed to load miner actor state: %w", err)
} }
return LoadSectorsFromSet(ctx, sm.ChainStore().Blockstore(), mas.Sectors) return LoadSectorsFromSet(ctx, sm.ChainStore().Blockstore(), mas.Sectors)
} }
func GetSectorsForElectionPost(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (*sectorbuilder.SortedPublicSectorInfo, error) {
sectors, err := GetMinerProvingSet(ctx, sm, ts, maddr)
if err != nil {
return nil, xerrors.Errorf("failed to get sector set for miner: %w", err)
}
var uselessOtherArray []ffi.PublicSectorInfo
for _, s := range sectors {
var uselessBuffer [32]byte
copy(uselessBuffer[:], s.CommR)
uselessOtherArray = append(uselessOtherArray, ffi.PublicSectorInfo{
SectorID: s.SectorID,
CommR: uselessBuffer,
})
}
ssi := sectorbuilder.NewSortedPublicSectorInfo(uselessOtherArray)
return &ssi, nil
}
func GetMinerSectorSize(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (uint64, error) { func GetMinerSectorSize(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (uint64, error) {
var mas actors.StorageMinerActorState var mas actors.StorageMinerActorState
_, err := sm.LoadActorState(ctx, maddr, &mas, ts) _, err := sm.LoadActorState(ctx, maddr, &mas, ts)
if err != nil { if err != nil {
return 0, xerrors.Errorf("failed to load miner actor state: %w", err) return 0, xerrors.Errorf("(get ssize) failed to load miner actor state: %w", err)
} }
cst := hamt.CSTFromBstore(sm.cs.Blockstore()) cst := hamt.CSTFromBstore(sm.cs.Blockstore())
@ -197,7 +220,7 @@ func GetMinerSlashed(ctx context.Context, sm *StateManager, ts *types.TipSet, ma
var mas actors.StorageMinerActorState var mas actors.StorageMinerActorState
_, err := sm.LoadActorState(ctx, maddr, &mas, ts) _, err := sm.LoadActorState(ctx, maddr, &mas, ts)
if err != nil { if err != nil {
return 0, xerrors.Errorf("failed to load miner actor state: %w", err) return 0, xerrors.Errorf("(get mslash) failed to load miner actor state: %w", err)
} }
return mas.SlashedAt, nil return mas.SlashedAt, nil

View File

@ -3,8 +3,8 @@ package store
import ( import (
"context" "context"
"crypto/sha256" "crypto/sha256"
"encoding/binary"
"encoding/json" "encoding/json"
"fmt"
"sync" "sync"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
@ -12,7 +12,7 @@ import (
"github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/vm" "github.com/filecoin-project/lotus/chain/vm"
"go.opencensus.io/trace" "go.opencensus.io/trace"
"go.uber.org/zap" "go.uber.org/multierr"
amt "github.com/filecoin-project/go-amt-ipld" amt "github.com/filecoin-project/go-amt-ipld"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
@ -24,7 +24,6 @@ import (
hamt "github.com/ipfs/go-hamt-ipld" hamt "github.com/ipfs/go-hamt-ipld"
bstore "github.com/ipfs/go-ipfs-blockstore" bstore "github.com/ipfs/go-ipfs-blockstore"
logging "github.com/ipfs/go-log" logging "github.com/ipfs/go-log"
"github.com/pkg/errors"
cbg "github.com/whyrusleeping/cbor-gen" cbg "github.com/whyrusleeping/cbor-gen"
pubsub "github.com/whyrusleeping/pubsub" pubsub "github.com/whyrusleeping/pubsub"
"golang.org/x/xerrors" "golang.org/x/xerrors"
@ -100,12 +99,12 @@ func (cs *ChainStore) Load() error {
return nil return nil
} }
if err != nil { if err != nil {
return errors.Wrap(err, "failed to load chain state from datastore") return xerrors.Errorf("failed to load chain state from datastore: %w", err)
} }
var tscids []cid.Cid var tscids []cid.Cid
if err := json.Unmarshal(head, &tscids); err != nil { if err := json.Unmarshal(head, &tscids); err != nil {
return errors.Wrap(err, "failed to unmarshal stored chain head") return xerrors.Errorf("failed to unmarshal stored chain head: %w", err)
} }
ts, err := cs.LoadTipSet(tscids) ts, err := cs.LoadTipSet(tscids)
@ -121,11 +120,11 @@ func (cs *ChainStore) Load() error {
func (cs *ChainStore) writeHead(ts *types.TipSet) error { func (cs *ChainStore) writeHead(ts *types.TipSet) error {
data, err := json.Marshal(ts.Cids()) data, err := json.Marshal(ts.Cids())
if err != nil { if err != nil {
return errors.Wrap(err, "failed to marshal tipset") return xerrors.Errorf("failed to marshal tipset: %w", err)
} }
if err := cs.ds.Put(chainHeadKey, data); err != nil { if err := cs.ds.Put(chainHeadKey, data); err != nil {
return errors.Wrap(err, "failed to write chain head to datastore") return xerrors.Errorf("failed to write chain head to datastore: %w", err)
} }
return nil return nil
@ -209,7 +208,7 @@ func (cs *ChainStore) PutTipSet(ctx context.Context, ts *types.TipSet) error {
log.Debugf("expanded %s into %s\n", ts.Cids(), expanded.Cids()) log.Debugf("expanded %s into %s\n", ts.Cids(), expanded.Cids())
if err := cs.MaybeTakeHeavierTipSet(ctx, expanded); err != nil { if err := cs.MaybeTakeHeavierTipSet(ctx, expanded); err != nil {
return errors.Wrap(err, "MaybeTakeHeavierTipSet failed in PutTipSet") return xerrors.Errorf("MaybeTakeHeavierTipSet failed in PutTipSet: %w", err)
} }
return nil return nil
} }
@ -429,17 +428,32 @@ func (cs *ChainStore) AddToTipSetTracker(b *types.BlockHeader) error {
return nil return nil
} }
func (cs *ChainStore) PersistBlockHeaders(b ...*types.BlockHeader) (err error) { func (cs *ChainStore) PersistBlockHeaders(b ...*types.BlockHeader) error {
sbs := make([]block.Block, len(b)) sbs := make([]block.Block, len(b))
for i, header := range b { for i, header := range b {
var err error
sbs[i], err = header.ToStorageBlock() sbs[i], err = header.ToStorageBlock()
if err != nil { if err != nil {
return err return err
} }
} }
return cs.bs.PutMany(sbs) batchSize := 256
calls := len(b) / batchSize
var err error
for i := 0; i <= calls; i++ {
start := batchSize * i
end := start + batchSize
if end > len(b) {
end = len(b)
}
err = multierr.Append(err, cs.bs.PutMany(sbs[start:end]))
}
return err
} }
type storable interface { type storable interface {
@ -507,7 +521,7 @@ func (cs *ChainStore) AddBlock(ctx context.Context, b *types.BlockHeader) error
} }
if err := cs.MaybeTakeHeavierTipSet(ctx, ts); err != nil { if err := cs.MaybeTakeHeavierTipSet(ctx, ts); err != nil {
return errors.Wrap(err, "MaybeTakeHeavierTipSet failed") return xerrors.Errorf("MaybeTakeHeavierTipSet failed: %w", err)
} }
return nil return nil
@ -537,6 +551,9 @@ func (cs *ChainStore) GetCMessage(c cid.Cid) (ChainMsg, error) {
if err == nil { if err == nil {
return m, nil return m, nil
} }
if err != bstore.ErrNotFound {
log.Warn("GetCMessage: unexpected error getting unsigned message: %s", err)
}
return cs.GetSignedMessage(c) return cs.GetSignedMessage(c)
} }
@ -667,12 +684,12 @@ func (cs *ChainStore) readMsgMetaCids(mmc cid.Cid) ([]cid.Cid, []cid.Cid, error)
blscids, err := cs.readAMTCids(msgmeta.BlsMessages) blscids, err := cs.readAMTCids(msgmeta.BlsMessages)
if err != nil { if err != nil {
return nil, nil, errors.Wrap(err, "loading bls message cids for block") return nil, nil, xerrors.Errorf("loading bls message cids for block: %w", err)
} }
secpkcids, err := cs.readAMTCids(msgmeta.SecpkMessages) secpkcids, err := cs.readAMTCids(msgmeta.SecpkMessages)
if err != nil { if err != nil {
return nil, nil, errors.Wrap(err, "loading secpk message cids for block") return nil, nil, xerrors.Errorf("loading secpk message cids for block: %w", err)
} }
cs.mmCache.Add(mmc, &mmCids{ cs.mmCache.Add(mmc, &mmCids{
@ -691,12 +708,12 @@ func (cs *ChainStore) MessagesForBlock(b *types.BlockHeader) ([]*types.Message,
blsmsgs, err := cs.LoadMessagesFromCids(blscids) blsmsgs, err := cs.LoadMessagesFromCids(blscids)
if err != nil { if err != nil {
return nil, nil, errors.Wrap(err, "loading bls messages for block") return nil, nil, xerrors.Errorf("loading bls messages for block: %w", err)
} }
secpkmsgs, err := cs.LoadSignedMessagesFromCids(secpkcids) secpkmsgs, err := cs.LoadSignedMessagesFromCids(secpkcids)
if err != nil { if err != nil {
return nil, nil, errors.Wrap(err, "loading secpk messages for block") return nil, nil, xerrors.Errorf("loading secpk messages for block: %w", err)
} }
return blsmsgs, secpkmsgs, nil return blsmsgs, secpkmsgs, nil
@ -706,7 +723,7 @@ func (cs *ChainStore) GetParentReceipt(b *types.BlockHeader, i int) (*types.Mess
bs := amt.WrapBlockstore(cs.bs) bs := amt.WrapBlockstore(cs.bs)
a, err := amt.LoadAMT(bs, b.ParentMessageReceipts) a, err := amt.LoadAMT(bs, b.ParentMessageReceipts)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "amt load") return nil, xerrors.Errorf("amt load: %w", err)
} }
var r types.MessageReceipt var r types.MessageReceipt
@ -722,7 +739,7 @@ func (cs *ChainStore) LoadMessagesFromCids(cids []cid.Cid) ([]*types.Message, er
for i, c := range cids { for i, c := range cids {
m, err := cs.GetMessage(c) m, err := cs.GetMessage(c)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "failed to get message: (%s):%d", c, i) return nil, xerrors.Errorf("failed to get message: (%s):%d: %w", err, c, i)
} }
msgs = append(msgs, m) msgs = append(msgs, m)
@ -736,7 +753,7 @@ func (cs *ChainStore) LoadSignedMessagesFromCids(cids []cid.Cid) ([]*types.Signe
for i, c := range cids { for i, c := range cids {
m, err := cs.GetSignedMessage(c) m, err := cs.GetSignedMessage(c)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "failed to get message: (%s):%d", c, i) return nil, xerrors.Errorf("failed to get message: (%s):%d: %w", err, c, i)
} }
msgs = append(msgs, m) msgs = append(msgs, m)
@ -771,24 +788,21 @@ func (cs *ChainStore) TryFillTipSet(ts *types.TipSet) (*FullTipSet, error) {
return NewFullTipSet(out), nil return NewFullTipSet(out), nil
} }
func (cs *ChainStore) GetRandomness(ctx context.Context, blks []cid.Cid, tickets []*types.Ticket, lb int64) ([]byte, error) { func drawRandomness(t *types.Ticket, round int64) []byte {
h := sha256.New()
var buf [8]byte
binary.LittleEndian.PutUint64(buf[:], uint64(round))
h.Write(t.VRFProof)
h.Write(buf[:])
return h.Sum(nil)
}
func (cs *ChainStore) GetRandomness(ctx context.Context, blks []cid.Cid, round int64) ([]byte, error) {
ctx, span := trace.StartSpan(ctx, "store.GetRandomness") ctx, span := trace.StartSpan(ctx, "store.GetRandomness")
defer span.End() defer span.End()
span.AddAttributes(trace.Int64Attribute("lb", lb)) span.AddAttributes(trace.Int64Attribute("round", round))
if lb < 0 {
return nil, fmt.Errorf("negative lookback parameters are not valid (got %d)", lb)
}
lt := int64(len(tickets))
if lb < lt {
log.Desugar().Warn("self sampling randomness. this should be extremely rare, if you see this often it may be a bug", zap.Stack("stacktrace"))
t := tickets[lt-(1+lb)]
return t.VRFProof, nil
}
nv := lb - lt
for { for {
nts, err := cs.LoadTipSet(blks) nts, err := cs.LoadTipSet(blks)
@ -797,26 +811,21 @@ func (cs *ChainStore) GetRandomness(ctx context.Context, blks []cid.Cid, tickets
} }
mtb := nts.MinTicketBlock() mtb := nts.MinTicketBlock()
lt := int64(len(mtb.Tickets))
if nv < lt {
t := mtb.Tickets[lt-(1+nv)]
return t.VRFProof, nil
}
nv -= lt if int64(nts.Height()) <= round {
return drawRandomness(nts.MinTicketBlock().Ticket, round), nil
}
// special case for lookback behind genesis block // special case for lookback behind genesis block
// TODO(spec): this is not in the spec, need to sync that // TODO(spec): this is not in the spec, need to sync that
if mtb.Height == 0 { if mtb.Height == 0 {
t := mtb.Tickets[0] // round is negative
thash := drawRandomness(mtb.Ticket, round*-1)
rval := t.VRFProof // for negative lookbacks, just use the hash of the positive tickethash value
for i := int64(0); i < nv; i++ { h := sha256.Sum256(thash)
h := sha256.Sum256(rval) return h[:], nil
rval = h[:]
}
return rval, nil
} }
blks = mtb.Parents blks = mtb.Parents
@ -837,36 +846,33 @@ func (cs *ChainStore) GetTipsetByHeight(ctx context.Context, h uint64, ts *types
} }
for { for {
mtb := ts.MinTicketBlock()
if h >= ts.Height()-uint64(len(mtb.Tickets)) {
return ts, nil
}
pts, err := cs.LoadTipSet(ts.Parents()) pts, err := cs.LoadTipSet(ts.Parents())
if err != nil { if err != nil {
return nil, err return nil, err
} }
if h > pts.Height() {
return ts, nil
}
ts = pts ts = pts
} }
} }
type chainRand struct { type chainRand struct {
cs *ChainStore cs *ChainStore
blks []cid.Cid blks []cid.Cid
bh uint64 bh uint64
tickets []*types.Ticket
} }
func NewChainRand(cs *ChainStore, blks []cid.Cid, bheight uint64, tickets []*types.Ticket) vm.Rand { func NewChainRand(cs *ChainStore, blks []cid.Cid, bheight uint64) vm.Rand {
return &chainRand{ return &chainRand{
cs: cs, cs: cs,
blks: blks, blks: blks,
bh: bheight, bh: bheight,
tickets: tickets,
} }
} }
func (cr *chainRand) GetRandomness(ctx context.Context, h int64) ([]byte, error) { func (cr *chainRand) GetRandomness(ctx context.Context, round int64) ([]byte, error) {
lb := (int64(cr.bh) + int64(len(cr.tickets))) - h return cr.cs.GetRandomness(ctx, cr.blks, round)
return cr.cs.GetRandomness(ctx, cr.blks, cr.tickets, lb)
} }

View File

@ -2,12 +2,13 @@ package store
import ( import (
"context" "context"
"math/big"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm" "github.com/filecoin-project/lotus/chain/vm"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"math/big"
) )
var zero = types.NewInt(0) var zero = types.NewInt(0)
@ -39,6 +40,7 @@ func (cs *ChainStore) Weight(ctx context.Context, ts *types.TipSet) (types.BigIn
log2P = int64(tpow.BitLen() - 1) log2P = int64(tpow.BitLen() - 1)
} else { } else {
// Not really expect to be here ... // Not really expect to be here ...
panic("where are we")
return types.EmptyInt, xerrors.Errorf("All power in the net is gone. You network might be disconnected, or the net is dead!") return types.EmptyInt, xerrors.Errorf("All power in the net is gone. You network might be disconnected, or the net is dead!")
} }
@ -57,7 +59,7 @@ func (cs *ChainStore) Weight(ctx context.Context, ts *types.TipSet) (types.BigIn
func (cs *ChainStore) call(ctx context.Context, msg *types.Message, ts *types.TipSet) (*types.MessageReceipt, error) { func (cs *ChainStore) call(ctx context.Context, msg *types.Message, ts *types.TipSet) (*types.MessageReceipt, error) {
bstate := ts.ParentState() bstate := ts.ParentState()
r := NewChainRand(cs, ts.Cids(), ts.Height(), nil) r := NewChainRand(cs, ts.Cids(), ts.Height())
vmi, err := vm.NewVM(bstate, ts.Height(), r, actors.NetworkAddress, cs.bs) vmi, err := vm.NewVM(bstate, ts.Height(), r, actors.NetworkAddress, cs.bs)
if err != nil { if err != nil {

View File

@ -3,14 +3,15 @@ package chain
import ( import (
"bytes" "bytes"
"context" "context"
"crypto/sha256"
"errors" "errors"
"fmt" "fmt"
"sync" "sync"
"time" "time"
"github.com/Gurpartap/async" "github.com/Gurpartap/async"
bls "github.com/filecoin-project/filecoin-ffi"
amt "github.com/filecoin-project/go-amt-ipld" amt "github.com/filecoin-project/go-amt-ipld"
"github.com/filecoin-project/go-bls-sigs"
"github.com/hashicorp/go-multierror" "github.com/hashicorp/go-multierror"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
dstore "github.com/ipfs/go-datastore" dstore "github.com/ipfs/go-datastore"
@ -28,10 +29,12 @@ import (
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/blocksync" "github.com/filecoin-project/lotus/chain/blocksync"
"github.com/filecoin-project/lotus/chain/gen"
"github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/sectorbuilder"
) )
var log = logging.Logger("chain") var log = logging.Logger("chain")
@ -506,33 +509,8 @@ func (syncer *Syncer) minerIsValid(ctx context.Context, maddr address.Address, b
return nil return nil
} }
func (syncer *Syncer) validateTickets(ctx context.Context, mworker address.Address, tickets []*types.Ticket, base *types.TipSet) error { func (syncer *Syncer) validateTicket(ctx context.Context, maddr, mworker address.Address, ticket *types.Ticket, base *types.TipSet) error {
ctx, span := trace.StartSpan(ctx, "validateTickets") return gen.VerifyVRF(ctx, mworker, maddr, gen.DSepTicket, base.MinTicket().VRFProof, ticket.VRFProof)
defer span.End()
span.AddAttributes(trace.Int64Attribute("tickets", int64(len(tickets))))
if len(tickets) == 0 {
return xerrors.Errorf("block had no tickets")
}
cur := base.MinTicket()
for i := 0; i < len(tickets); i++ {
next := tickets[i]
sig := &types.Signature{
Type: types.KTBLS,
Data: next.VRFProof,
}
// TODO: ticket signatures should also include miner address
if err := sig.Verify(mworker, cur.VRFProof); err != nil {
return xerrors.Errorf("invalid ticket, VRFProof invalid: %w", err)
}
cur = next
}
return nil
} }
var ErrTemporal = errors.New("temporal error") var ErrTemporal = errors.New("temporal error")
@ -541,6 +519,9 @@ var ErrTemporal = errors.New("temporal error")
func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) error { func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) error {
ctx, span := trace.StartSpan(ctx, "validateBlock") ctx, span := trace.StartSpan(ctx, "validateBlock")
defer span.End() defer span.End()
if build.InsecurePoStValidation {
log.Warn("insecure test validation is enabled, if you see this outside of a test, it is a severe bug!")
}
h := b.Header h := b.Header
@ -550,23 +531,34 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
} }
// fast checks first // fast checks first
if h.BlockSig == nil {
return xerrors.Errorf("block had nil signature")
}
if h.Timestamp > uint64(time.Now().Unix()+build.AllowableClockDrift) { if h.Timestamp > uint64(time.Now().Unix()+build.AllowableClockDrift) {
return xerrors.Errorf("block was from the future") return xerrors.Errorf("block was from the future")
} }
if h.Timestamp < baseTs.MinTimestamp()+uint64(build.BlockDelay*len(h.Tickets)) { if h.Timestamp < baseTs.MinTimestamp()+(build.BlockDelay*(h.Height-baseTs.Height())) {
log.Warn("timestamp funtimes: ", h.Timestamp, baseTs.MinTimestamp(), len(h.Tickets)) log.Warn("timestamp funtimes: ", h.Timestamp, baseTs.MinTimestamp(), h.Height, baseTs.Height())
return xerrors.Errorf("block was generated too soon (h.ts:%d < base.mints:%d + BLOCK_DELAY:%d * tkts.len:%d)", h.Timestamp, baseTs.MinTimestamp(), build.BlockDelay, len(h.Tickets)) return xerrors.Errorf("block was generated too soon (h.ts:%d < base.mints:%d + BLOCK_DELAY:%d * deltaH:%d)", h.Timestamp, baseTs.MinTimestamp(), build.BlockDelay, h.Height-baseTs.Height())
} }
winnerCheck := async.Err(func() error { winnerCheck := async.Err(func() error {
mpow, tpow, err := stmgr.GetPower(ctx, syncer.sm, baseTs, h.Miner) _, tpow, err := stmgr.GetPower(ctx, syncer.sm, baseTs, h.Miner)
if err != nil { if err != nil {
return xerrors.Errorf("failed getting power: %w", err) return xerrors.Errorf("failed getting power: %w", err)
} }
if !types.PowerCmp(h.ElectionProof, mpow, tpow) { ssize, err := stmgr.GetMinerSectorSize(ctx, syncer.sm, baseTs, h.Miner)
return xerrors.Errorf("miner created a block but was not a winner") if err != nil {
return xerrors.Errorf("failed to get sector size for block miner: %w", err)
}
for _, t := range h.EPostProof.Candidates {
if !types.IsTicketWinner(t.Partial, ssize, tpow, 1) {
return xerrors.Errorf("miner created a block but was not a winner")
}
} }
return nil return nil
}) })
@ -623,20 +615,20 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
}) })
tktsCheck := async.Err(func() error { tktsCheck := async.Err(func() error {
if err := syncer.validateTickets(ctx, waddr, h.Tickets, baseTs); err != nil { vrfBase := baseTs.MinTicket().VRFProof
err := gen.VerifyVRF(ctx, waddr, h.Miner, gen.DSepTicket, vrfBase, h.Ticket.VRFProof)
if err != nil {
log.Warnf("BAD TICKET: %d %x %x %s %s %x", h.Height, h.Ticket.VRFProof, vrfBase, waddr, h.Miner, baseTs.MinTicket().VRFProof)
return xerrors.Errorf("validating block tickets failed: %w", err) return xerrors.Errorf("validating block tickets failed: %w", err)
} }
return nil return nil
}) })
eproofCheck := async.Err(func() error { eproofCheck := async.Err(func() error {
rand, err := syncer.sm.ChainStore().GetRandomness(ctx, baseTs.Cids(), h.Tickets, build.EcRandomnessLookback) if err := syncer.VerifyElectionPoStProof(ctx, h, baseTs, waddr); err != nil {
if err != nil { return xerrors.Errorf("invalid election post: %w", err)
return xerrors.Errorf("failed to get randomness for verifying election proof: %w", err)
}
if err := VerifyElectionProof(ctx, h.ElectionProof, rand, waddr); err != nil {
return xerrors.Errorf("checking eproof failed: %w", err)
} }
return nil return nil
}) })
@ -660,6 +652,56 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
return merr return merr
} }
func (syncer *Syncer) VerifyElectionPoStProof(ctx context.Context, h *types.BlockHeader, baseTs *types.TipSet, waddr address.Address) error {
rand, err := syncer.sm.ChainStore().GetRandomness(ctx, baseTs.Cids(), int64(h.Height-build.EcRandomnessLookback))
if err != nil {
return xerrors.Errorf("failed to get randomness for verifying election proof: %w", err)
}
if err := VerifyElectionPoStVRF(ctx, h.EPostProof.PostRand, rand, waddr, h.Miner); err != nil {
return xerrors.Errorf("checking eproof failed: %w", err)
}
ssize, err := stmgr.GetMinerSectorSize(ctx, syncer.sm, baseTs, h.Miner)
if err != nil {
return xerrors.Errorf("failed to get sector size for miner: %w", err)
}
var winners []sectorbuilder.EPostCandidate
for _, t := range h.EPostProof.Candidates {
var partial [32]byte
copy(partial[:], t.Partial)
winners = append(winners, sectorbuilder.EPostCandidate{
PartialTicket: partial,
SectorID: t.SectorID,
SectorChallengeIndex: t.ChallengeIndex,
})
}
sectorInfo, err := stmgr.GetSectorsForElectionPost(ctx, syncer.sm, baseTs, h.Miner)
if err != nil {
return xerrors.Errorf("getting election post sector set: %w", err)
}
if build.InsecurePoStValidation {
if string(h.EPostProof.Proof) == "valid proof" {
return nil
}
return xerrors.Errorf("[TESTING] election post was invalid")
}
hvrf := sha256.Sum256(h.EPostProof.PostRand)
ok, err := sectorbuilder.VerifyElectionPost(ctx, ssize, *sectorInfo, hvrf[:], h.EPostProof.Proof, winners, h.Miner)
if err != nil {
return xerrors.Errorf("failed to verify election post: %w", err)
}
if !ok {
return xerrors.Errorf("election post was invalid")
}
return nil
}
func (syncer *Syncer) checkBlockMessages(ctx context.Context, b *types.FullBlock, baseTs *types.TipSet) error { func (syncer *Syncer) checkBlockMessages(ctx context.Context, b *types.FullBlock, baseTs *types.TipSet) error {
nonces := make(map[address.Address]uint64) nonces := make(map[address.Address]uint64)
balances := make(map[address.Address]types.BigInt) balances := make(map[address.Address]types.BigInt)
@ -1103,14 +1145,9 @@ func (syncer *Syncer) collectChain(ctx context.Context, ts *types.TipSet) error
return nil return nil
} }
func VerifyElectionProof(ctx context.Context, eproof []byte, rand []byte, worker address.Address) error { func VerifyElectionPoStVRF(ctx context.Context, evrf []byte, rand []byte, worker, miner address.Address) error {
sig := types.Signature{ if err := gen.VerifyVRF(ctx, worker, miner, gen.DSepElectionPost, rand, evrf); err != nil {
Data: eproof, return xerrors.Errorf("failed to verify post_randomness vrf: %w", err)
Type: types.KTBLS,
}
if err := sig.Verify(worker, rand); err != nil {
return xerrors.Errorf("failed to verify election proof signature: %w", err)
} }
return nil return nil

View File

@ -23,6 +23,10 @@ import (
"github.com/filecoin-project/lotus/node/repo" "github.com/filecoin-project/lotus/node/repo"
) )
func init() {
build.InsecurePoStValidation = true
}
const source = 0 const source = 0
func (tu *syncTestUtil) repoWithChain(t testing.TB, h int) (repo.Repo, []byte, []*store.FullTipSet) { func (tu *syncTestUtil) repoWithChain(t testing.TB, h int) (repo.Repo, []byte, []*store.FullTipSet) {
@ -342,7 +346,7 @@ func (tu *syncTestUtil) waitUntilSyncTarget(to int, target *types.TipSet) {
} }
func TestSyncSimple(t *testing.T) { func TestSyncSimple(t *testing.T) {
H := 50 H := 2
tu := prepSyncTest(t, H) tu := prepSyncTest(t, H)
client := tu.addClientNode() client := tu.addClientNode()
@ -390,7 +394,7 @@ func TestSyncBadTimestamp(t *testing.T) {
tu.waitUntilSync(0, client) tu.waitUntilSync(0, client)
base := tu.g.CurTipset base := tu.g.CurTipset
tu.g.Timestamper = func(pts *types.TipSet, tl int) uint64 { tu.g.Timestamper = func(pts *types.TipSet, tl uint64) uint64 {
return pts.MinTimestamp() + (build.BlockDelay / 2) return pts.MinTimestamp() + (build.BlockDelay / 2)
} }

View File

@ -20,14 +20,24 @@ type Ticket struct {
VRFProof []byte VRFProof []byte
} }
type ElectionProof []byte type EPostTicket struct {
Partial []byte
SectorID uint64
ChallengeIndex uint64
}
type EPostProof struct {
Proof []byte
PostRand []byte
Candidates []EPostTicket
}
type BlockHeader struct { type BlockHeader struct {
Miner address.Address Miner address.Address
Tickets []*Ticket Ticket *Ticket
ElectionProof []byte EPostProof EPostProof
Parents []cid.Cid Parents []cid.Cid
@ -45,7 +55,7 @@ type BlockHeader struct {
Timestamp uint64 Timestamp uint64
BlockSig Signature BlockSig *Signature
} }
func (b *BlockHeader) ToStorageBlock() (block.Block, error) { func (b *BlockHeader) ToStorageBlock() (block.Block, error) {
@ -91,12 +101,12 @@ func (blk *BlockHeader) Serialize() ([]byte, error) {
} }
func (blk *BlockHeader) LastTicket() *Ticket { func (blk *BlockHeader) LastTicket() *Ticket {
return blk.Tickets[len(blk.Tickets)-1] return blk.Ticket
} }
func (blk *BlockHeader) SigningBytes() ([]byte, error) { func (blk *BlockHeader) SigningBytes() ([]byte, error) {
blkcopy := *blk blkcopy := *blk
blkcopy.BlockSig = Signature{} blkcopy.BlockSig = nil
return blkcopy.Serialize() return blkcopy.Serialize()
} }
@ -162,29 +172,31 @@ func CidArrsEqual(a, b []cid.Cid) bool {
var blocksPerEpoch = NewInt(build.BlocksPerEpoch) var blocksPerEpoch = NewInt(build.BlocksPerEpoch)
func PowerCmp(eproof ElectionProof, mpow, totpow BigInt) bool { func IsTicketWinner(partialTicket []byte, ssizeI uint64, totpow BigInt, sampleRate int64) bool {
ssize := NewInt(ssizeI)
/* /*
Need to check that Need to check that
(h(vrfout) + 1) / (max(h) + 1) <= e * minerPower / totalPower (h(vrfout) + 1) / (max(h) + 1) <= e * sectorSize / totalPower
max(h) == 2^256-1 max(h) == 2^256-1
which in terms of integer math means: which in terms of integer math means:
(h(vrfout) + 1) * totalPower <= e * minerPower * 2^256 (h(vrfout) + 1) * totalPower <= e * sectorSize * 2^256
in 2^256 space, it is equivalent to: in 2^256 space, it is equivalent to:
h(vrfout) * totalPower < e * minerPower * 2^256 h(vrfout) * totalPower < e * sectorSize * 2^256
*/ */
h := sha256.Sum256(eproof) h := sha256.Sum256(partialTicket)
lhs := BigFromBytes(h[:]).Int lhs := BigFromBytes(h[:]).Int
lhs = lhs.Mul(lhs, totpow.Int) lhs = lhs.Mul(lhs, totpow.Int)
lhs = lhs.Mul(lhs, big.NewInt(sampleRate))
// rhs = minerPower * 2^256 // rhs = sectorSize * 2^256
// rhs = minerPower << 256 // rhs = sectorSize << 256
rhs := new(big.Int).Lsh(mpow.Int, 256) rhs := new(big.Int).Lsh(ssize.Int, 256)
rhs = rhs.Mul(rhs, blocksPerEpoch.Int) rhs = rhs.Mul(rhs, blocksPerEpoch.Int)
// h(vrfout) * totalPower < e * minerPower * 2^256? // h(vrfout) * totalPower < e * sectorSize * 2^256?
return lhs.Cmp(rhs) == -1 return lhs.Cmp(rhs) == -1
} }

View File

@ -2,6 +2,7 @@ package types
import ( import (
"bytes" "bytes"
"fmt"
"reflect" "reflect"
"testing" "testing"
@ -23,12 +24,13 @@ func testBlockHeader(t testing.TB) *BlockHeader {
} }
return &BlockHeader{ return &BlockHeader{
Miner: addr, Miner: addr,
ElectionProof: []byte("cats won the election"), EPostProof: EPostProof{
Tickets: []*Ticket{ Proof: []byte("pruuf"),
&Ticket{ PostRand: []byte("random"),
VRFProof: []byte("vrf proof0000000vrf proof0000000"), },
}, Ticket: &Ticket{
VRFProof: []byte("vrf proof0000000vrf proof0000000"),
}, },
Parents: []cid.Cid{c, c}, Parents: []cid.Cid{c, c},
ParentMessageReceipts: c, ParentMessageReceipts: c,
@ -37,7 +39,7 @@ func testBlockHeader(t testing.TB) *BlockHeader {
Messages: c, Messages: c,
Height: 85919298723, Height: 85919298723,
ParentStateRoot: c, ParentStateRoot: c,
BlockSig: Signature{Type: KTBLS, Data: []byte("boo! im a signature")}, BlockSig: &Signature{Type: KTBLS, Data: []byte("boo! im a signature")},
} }
} }
@ -55,6 +57,8 @@ func TestBlockHeaderSerialization(t *testing.T) {
} }
if !reflect.DeepEqual(&out, bh) { if !reflect.DeepEqual(&out, bh) {
fmt.Printf("%#v\n", &out)
fmt.Printf("%#v\n", bh)
t.Fatal("not equal") t.Fatal("not equal")
} }
} }

View File

@ -5,7 +5,7 @@ import (
"io" "io"
"math" "math"
cid "github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
cbg "github.com/whyrusleeping/cbor-gen" cbg "github.com/whyrusleeping/cbor-gen"
xerrors "golang.org/x/xerrors" xerrors "golang.org/x/xerrors"
) )
@ -28,21 +28,13 @@ func (t *BlockHeader) MarshalCBOR(w io.Writer) error {
return err return err
} }
// t.t.Tickets ([]*types.Ticket) (slice) // t.t.Ticket (types.Ticket) (struct)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Tickets)))); err != nil { if err := t.Ticket.MarshalCBOR(w); err != nil {
return err return err
} }
for _, v := range t.Tickets {
if err := v.MarshalCBOR(w); err != nil {
return err
}
}
// t.t.ElectionProof ([]uint8) (slice) // t.t.EPostProof (types.EPostProof) (struct)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.ElectionProof)))); err != nil { if err := t.EPostProof.MarshalCBOR(w); err != nil {
return err
}
if _, err := w.Write(t.ElectionProof); err != nil {
return err return err
} }
@ -125,48 +117,35 @@ func (t *BlockHeader) UnmarshalCBOR(r io.Reader) error {
} }
} }
// t.t.Tickets ([]*types.Ticket) (slice) // t.t.Ticket (types.Ticket) (struct)
maj, extra, err = cbg.CborReadHeader(br) {
if err != nil {
return err
}
if extra > 8192 {
return fmt.Errorf("t.Tickets: array too large (%d)", extra)
}
if maj != cbg.MajArray { pb, err := br.PeekByte()
return fmt.Errorf("expected cbor array") if err != nil {
} return err
if extra > 0 { }
t.Tickets = make([]*Ticket, extra) if pb == cbg.CborNull[0] {
} var nbuf [1]byte
for i := 0; i < int(extra); i++ { if _, err := br.Read(nbuf[:]); err != nil {
return err
}
} else {
t.Ticket = new(Ticket)
if err := t.Ticket.UnmarshalCBOR(br); err != nil {
return err
}
}
var v Ticket }
if err := v.UnmarshalCBOR(br); err != nil { // t.t.EPostProof (types.EPostProof) (struct)
{
if err := t.EPostProof.UnmarshalCBOR(br); err != nil {
return err return err
} }
t.Tickets[i] = &v
}
// t.t.ElectionProof ([]uint8) (slice)
maj, extra, err = cbg.CborReadHeader(br)
if err != nil {
return err
}
if extra > 8192 {
return fmt.Errorf("t.ElectionProof: array too large (%d)", extra)
}
if maj != cbg.MajByteString {
return fmt.Errorf("expected byte array")
}
t.ElectionProof = make([]byte, extra)
if _, err := io.ReadFull(br, t.ElectionProof); err != nil {
return err
} }
// t.t.Parents ([]cid.Cid) (slice) // t.t.Parents ([]cid.Cid) (slice)
@ -271,9 +250,21 @@ func (t *BlockHeader) UnmarshalCBOR(r io.Reader) error {
{ {
if err := t.BlockSig.UnmarshalCBOR(br); err != nil { pb, err := br.PeekByte()
if err != nil {
return err return err
} }
if pb == cbg.CborNull[0] {
var nbuf [1]byte
if _, err := br.Read(nbuf[:]); err != nil {
return err
}
} else {
t.BlockSig = new(Signature)
if err := t.BlockSig.UnmarshalCBOR(br); err != nil {
return err
}
}
} }
return nil return nil
@ -333,6 +324,205 @@ func (t *Ticket) UnmarshalCBOR(r io.Reader) error {
return nil return nil
} }
func (t *EPostProof) MarshalCBOR(w io.Writer) error {
if t == nil {
_, err := w.Write(cbg.CborNull)
return err
}
if _, err := w.Write([]byte{131}); err != nil {
return err
}
// t.t.Proof ([]uint8) (slice)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Proof)))); err != nil {
return err
}
if _, err := w.Write(t.Proof); err != nil {
return err
}
// t.t.PostRand ([]uint8) (slice)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.PostRand)))); err != nil {
return err
}
if _, err := w.Write(t.PostRand); err != nil {
return err
}
// t.t.Candidates ([]types.EPostTicket) (slice)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Candidates)))); err != nil {
return err
}
for _, v := range t.Candidates {
if err := v.MarshalCBOR(w); err != nil {
return err
}
}
return nil
}
func (t *EPostProof) UnmarshalCBOR(r io.Reader) error {
br := cbg.GetPeeker(r)
maj, extra, err := cbg.CborReadHeader(br)
if err != nil {
return err
}
if maj != cbg.MajArray {
return fmt.Errorf("cbor input should be of type array")
}
if extra != 3 {
return fmt.Errorf("cbor input had wrong number of fields")
}
// t.t.Proof ([]uint8) (slice)
maj, extra, err = cbg.CborReadHeader(br)
if err != nil {
return err
}
if extra > 8192 {
return fmt.Errorf("t.Proof: array too large (%d)", extra)
}
if maj != cbg.MajByteString {
return fmt.Errorf("expected byte array")
}
t.Proof = make([]byte, extra)
if _, err := io.ReadFull(br, t.Proof); err != nil {
return err
}
// t.t.PostRand ([]uint8) (slice)
maj, extra, err = cbg.CborReadHeader(br)
if err != nil {
return err
}
if extra > 8192 {
return fmt.Errorf("t.PostRand: array too large (%d)", extra)
}
if maj != cbg.MajByteString {
return fmt.Errorf("expected byte array")
}
t.PostRand = make([]byte, extra)
if _, err := io.ReadFull(br, t.PostRand); err != nil {
return err
}
// t.t.Candidates ([]types.EPostTicket) (slice)
maj, extra, err = cbg.CborReadHeader(br)
if err != nil {
return err
}
if extra > 8192 {
return fmt.Errorf("t.Candidates: array too large (%d)", extra)
}
if maj != cbg.MajArray {
return fmt.Errorf("expected cbor array")
}
if extra > 0 {
t.Candidates = make([]EPostTicket, extra)
}
for i := 0; i < int(extra); i++ {
var v EPostTicket
if err := v.UnmarshalCBOR(br); err != nil {
return err
}
t.Candidates[i] = v
}
return nil
}
func (t *EPostTicket) MarshalCBOR(w io.Writer) error {
if t == nil {
_, err := w.Write(cbg.CborNull)
return err
}
if _, err := w.Write([]byte{131}); err != nil {
return err
}
// t.t.Partial ([]uint8) (slice)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Partial)))); err != nil {
return err
}
if _, err := w.Write(t.Partial); err != nil {
return err
}
// t.t.SectorID (uint64) (uint64)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SectorID))); err != nil {
return err
}
// t.t.ChallengeIndex (uint64) (uint64)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.ChallengeIndex))); err != nil {
return err
}
return nil
}
func (t *EPostTicket) UnmarshalCBOR(r io.Reader) error {
br := cbg.GetPeeker(r)
maj, extra, err := cbg.CborReadHeader(br)
if err != nil {
return err
}
if maj != cbg.MajArray {
return fmt.Errorf("cbor input should be of type array")
}
if extra != 3 {
return fmt.Errorf("cbor input had wrong number of fields")
}
// t.t.Partial ([]uint8) (slice)
maj, extra, err = cbg.CborReadHeader(br)
if err != nil {
return err
}
if extra > 8192 {
return fmt.Errorf("t.Partial: array too large (%d)", extra)
}
if maj != cbg.MajByteString {
return fmt.Errorf("expected byte array")
}
t.Partial = make([]byte, extra)
if _, err := io.ReadFull(br, t.Partial); err != nil {
return err
}
// t.t.SectorID (uint64) (uint64)
maj, extra, err = cbg.CborReadHeader(br)
if err != nil {
return err
}
if maj != cbg.MajUnsignedInt {
return fmt.Errorf("wrong type for uint64 field")
}
t.SectorID = uint64(extra)
// t.t.ChallengeIndex (uint64) (uint64)
maj, extra, err = cbg.CborReadHeader(br)
if err != nil {
return err
}
if maj != cbg.MajUnsignedInt {
return fmt.Errorf("wrong type for uint64 field")
}
t.ChallengeIndex = uint64(extra)
return nil
}
func (t *Message) MarshalCBOR(w io.Writer) error { func (t *Message) MarshalCBOR(w io.Writer) error {
if t == nil { if t == nil {
_, err := w.Write(cbg.CborNull) _, err := w.Write(cbg.CborNull)

View File

@ -34,12 +34,12 @@ func MkBlock(parents *types.TipSet, weightInc uint64, ticketNonce uint64) *types
} }
return &types.BlockHeader{ return &types.BlockHeader{
Miner: addr, Miner: addr,
ElectionProof: []byte("cats won the election"), EPostProof: types.EPostProof{
Tickets: []*types.Ticket{ Proof: []byte("election post proof proof"),
{ },
VRFProof: []byte(fmt.Sprintf("====%d=====", ticketNonce)), Ticket: &types.Ticket{
}, VRFProof: []byte(fmt.Sprintf("====%d=====", ticketNonce)),
}, },
Parents: pcids, Parents: pcids,
ParentMessageReceipts: c, ParentMessageReceipts: c,
@ -48,7 +48,7 @@ func MkBlock(parents *types.TipSet, weightInc uint64, ticketNonce uint64) *types
Messages: c, Messages: c,
Height: height, Height: height,
ParentStateRoot: c, ParentStateRoot: c,
BlockSig: types.Signature{Type: types.KTBLS, Data: []byte("boo! im a signature")}, BlockSig: &types.Signature{Type: types.KTBLS, Data: []byte("boo! im a signature")},
} }
} }

View File

@ -5,7 +5,7 @@ package types
import ( import (
"fmt" "fmt"
bls "github.com/filecoin-project/go-bls-sigs" bls "github.com/filecoin-project/filecoin-ffi"
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/lib/crypto" "github.com/filecoin-project/lotus/lib/crypto"
"github.com/minio/blake2b-simd" "github.com/minio/blake2b-simd"

View File

@ -165,8 +165,7 @@ func (t *Ticket) Less(o *Ticket) bool {
} }
func (ts *TipSet) MinTicket() *Ticket { func (ts *TipSet) MinTicket() *Ticket {
b := ts.MinTicketBlock() return ts.MinTicketBlock().Ticket
return b.Tickets[len(b.Tickets)-1]
} }
func (ts *TipSet) MinTimestamp() uint64 { func (ts *TipSet) MinTimestamp() uint64 {

View File

@ -3,7 +3,7 @@ package types
import ( import (
"context" "context"
amt "github.com/filecoin-project/go-amt-ipld" "github.com/filecoin-project/go-amt-ipld"
"github.com/filecoin-project/lotus/chain/actors/aerrors" "github.com/filecoin-project/lotus/chain/actors/aerrors"
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/address"
cid "github.com/ipfs/go-cid" cid "github.com/ipfs/go-cid"
@ -48,8 +48,8 @@ type storageWrapper struct {
s Storage s Storage
} }
func (sw *storageWrapper) Put(i interface{}) (cid.Cid, error) { func (sw *storageWrapper) Put(i cbg.CBORMarshaler) (cid.Cid, error) {
c, err := sw.s.Put(i.(cbg.CBORMarshaler)) c, err := sw.s.Put(i)
if err != nil { if err != nil {
return cid.Undef, err return cid.Undef, err
} }
@ -57,8 +57,8 @@ func (sw *storageWrapper) Put(i interface{}) (cid.Cid, error) {
return c, nil return c, nil
} }
func (sw *storageWrapper) Get(c cid.Cid, out interface{}) error { func (sw *storageWrapper) Get(c cid.Cid, out cbg.CBORUnmarshaler) error {
if err := sw.s.Get(c, out.(cbg.CBORUnmarshaler)); err != nil { if err := sw.s.Get(c, out); err != nil {
return err return err
} }

View File

@ -3,11 +3,10 @@ package validation
import ( import (
"context" "context"
"github.com/pkg/errors"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"golang.org/x/xerrors"
"github.com/filecoin-project/chain-validation/pkg/chain" "github.com/filecoin-project/chain-validation/pkg/chain"
"github.com/filecoin-project/chain-validation/pkg/state" "github.com/filecoin-project/chain-validation/pkg/state"
@ -43,7 +42,7 @@ func (mf *MessageFactory) MakeMessage(from, to state.Address, method chain.Metho
} }
if int(method) >= len(methods) { if int(method) >= len(methods) {
return nil, errors.Errorf("No method name for method %v", method) return nil, xerrors.Errorf("No method name for method %v", method)
} }
methodId := methods[method] methodId := methods[method]
msg := &types.Message{ msg := &types.Message{

View File

@ -5,11 +5,10 @@ import (
"fmt" "fmt"
"math/rand" "math/rand"
"github.com/pkg/errors"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/gen"
"github.com/filecoin-project/lotus/chain/vm" "github.com/filecoin-project/lotus/chain/vm"
"golang.org/x/xerrors"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
"github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore"
@ -109,7 +108,7 @@ func (s *StateWrapper) SetActor(addr vstate.Address, code vstate.ActorCodeID, ba
// The ID-based address is dropped here, but should be reported back to the caller. // The ID-based address is dropped here, but should be reported back to the caller.
_, err = tree.RegisterNewAddress(addrInt, &actr.Actor) _, err = tree.RegisterNewAddress(addrInt, &actr.Actor)
if err != nil { if err != nil {
return nil, nil, errors.Wrapf(err, "register new address for actor") return nil, nil, xerrors.Errorf("register new address for actor: %w", err)
} }
return actr, s.storage, s.flush(tree) return actr, s.storage, s.flush(tree)
} }
@ -131,17 +130,24 @@ func (s *StateWrapper) SetSingletonActor(addr vstate.SingletonActorID, balance v
return nil, nil, err return nil, nil, err
} }
if err := tree.SetActor(actors.InitAddress, initact); err != nil { if err := tree.SetActor(actors.InitAddress, initact); err != nil {
return nil, nil, errors.Wrapf(err, "set init actor") return nil, nil, xerrors.Errorf("set init actor: %w", err)
} }
return &actorWrapper{*initact}, s.storage, s.flush(tree) return &actorWrapper{*initact}, s.storage, s.flush(tree)
case actors.StorageMarketAddress: case actors.StorageMarketAddress:
smact, err := gen.SetupStorageMarketActor(s.bs) nsroot, err := gen.SetupStorageMarketActor(s.bs, s.stateRoot, nil)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
if err := tree.SetActor(actors.StorageMarketAddress, smact); err != nil { s.stateRoot = nsroot
return nil, nil, errors.Wrapf(err, "set network storage market actor")
tree, err = state.LoadStateTree(s.cst, s.stateRoot)
if err != nil {
return nil, nil, err
}
smact, err := tree.GetActor(actors.StorageMarketAddress)
if err != nil {
return nil, nil, err
} }
return &actorWrapper{*smact}, s.storage, s.flush(tree) return &actorWrapper{*smact}, s.storage, s.flush(tree)
case actors.StoragePowerAddress: case actors.StoragePowerAddress:
@ -150,7 +156,7 @@ func (s *StateWrapper) SetSingletonActor(addr vstate.SingletonActorID, balance v
return nil, nil, err return nil, nil, err
} }
if err := tree.SetActor(actors.StoragePowerAddress, spact); err != nil { if err := tree.SetActor(actors.StoragePowerAddress, spact); err != nil {
return nil, nil, errors.Wrapf(err, "set network storage market actor") return nil, nil, xerrors.Errorf("set network storage market actor: %w", err)
} }
return &actorWrapper{*spact}, s.storage, s.flush(tree) return &actorWrapper{*spact}, s.storage, s.flush(tree)
case actors.NetworkAddress: case actors.NetworkAddress:
@ -160,7 +166,7 @@ func (s *StateWrapper) SetSingletonActor(addr vstate.SingletonActorID, balance v
Head: vm.EmptyObjectCid, Head: vm.EmptyObjectCid,
} }
if err := tree.SetActor(actors.NetworkAddress, ntwkact); err != nil { if err := tree.SetActor(actors.NetworkAddress, ntwkact); err != nil {
return nil, nil, errors.Wrapf(err, "set network actor") return nil, nil, xerrors.Errorf("set network actor: %w", err)
} }
return &actorWrapper{*ntwkact}, s.storage, s.flush(tree) return &actorWrapper{*ntwkact}, s.storage, s.flush(tree)
case actors.BurntFundsAddress: case actors.BurntFundsAddress:
@ -170,11 +176,11 @@ func (s *StateWrapper) SetSingletonActor(addr vstate.SingletonActorID, balance v
Head: vm.EmptyObjectCid, Head: vm.EmptyObjectCid,
} }
if err := tree.SetActor(actors.BurntFundsAddress, ntwkact); err != nil { if err := tree.SetActor(actors.BurntFundsAddress, ntwkact); err != nil {
return nil, nil, errors.Wrapf(err, "set network actor") return nil, nil, xerrors.Errorf("set network actor: %w", err)
} }
return &actorWrapper{*ntwkact}, s.storage, s.flush(tree) return &actorWrapper{*ntwkact}, s.storage, s.flush(tree)
default: default:
return nil, nil, errors.Errorf("%v is not a singleton actor address", addr) return nil, nil, xerrors.Errorf("%v is not a singleton actor address", addr)
} }
} }

View File

@ -42,9 +42,13 @@ func newInvoker() *invoker {
func (inv *invoker) Invoke(act *types.Actor, vmctx types.VMContext, method uint64, params []byte) ([]byte, aerrors.ActorError) { func (inv *invoker) Invoke(act *types.Actor, vmctx types.VMContext, method uint64, params []byte) ([]byte, aerrors.ActorError) {
if act.Code == actors.AccountCodeCid {
return nil, aerrors.Newf(254, "cannot invoke methods on account actors")
}
code, ok := inv.builtInCode[act.Code] code, ok := inv.builtInCode[act.Code]
if !ok { if !ok {
log.Errorf("no code for actor %s", act.Code) log.Errorf("no code for actor %s (Addr: %s)", act.Code, vmctx.Message().To)
return nil, aerrors.Newf(255, "no code for actor %s(%d)(%s)", act.Code, method, hex.EncodeToString(params)) return nil, aerrors.Newf(255, "no code for actor %s(%d)(%s)", act.Code, method, hex.EncodeToString(params))
} }
if method >= uint64(len(code)) || code[method] == nil { if method >= uint64(len(code)) || code[method] == nil {
@ -159,7 +163,7 @@ func DumpActorState(code cid.Cid, b []byte) (interface{}, error) {
typ, ok := i.builtInState[code] typ, ok := i.builtInState[code]
if !ok { if !ok {
return nil, xerrors.New("state type for actor not found") return nil, xerrors.Errorf("state type for actor %s not found", code)
} }
rv := reflect.New(typ) rv := reflect.New(typ)

View File

@ -12,7 +12,7 @@ import (
func TestBlockReward(t *testing.T) { func TestBlockReward(t *testing.T) {
coffer := types.FromFil(build.MiningRewardTotal).Int coffer := types.FromFil(build.MiningRewardTotal).Int
sum := new(big.Int) sum := new(big.Int)
N := build.HalvingPeriodBlocks N := build.HalvingPeriodEpochs
for i := 0; i < N; i++ { for i := 0; i < N; i++ {
a := MiningReward(types.BigInt{coffer}) a := MiningReward(types.BigInt{coffer})
sum = sum.Add(sum, a.Int) sum = sum.Add(sum, a.Int)

View File

@ -7,7 +7,7 @@ import (
"strings" "strings"
"sync" "sync"
"github.com/filecoin-project/go-bls-sigs" bls "github.com/filecoin-project/filecoin-ffi"
logging "github.com/ipfs/go-log" logging "github.com/ipfs/go-log"
"github.com/minio/blake2b-simd" "github.com/minio/blake2b-simd"
@ -41,6 +41,17 @@ func NewWallet(keystore types.KeyStore) (*Wallet, error) {
return w, nil return w, nil
} }
func KeyWallet(keys ...*Key) *Wallet {
m := make(map[address.Address]*Key)
for _, key := range keys {
m[key.Address] = key
}
return &Wallet{
keys: m,
}
}
func (w *Wallet) Sign(ctx context.Context, addr address.Address, msg []byte) (*types.Signature, error) { func (w *Wallet) Sign(ctx context.Context, addr address.Address, msg []byte) (*types.Signature, error) {
ki, err := w.findKey(addr) ki, err := w.findKey(addr)
if err != nil { if err != nil {
@ -85,6 +96,11 @@ func (w *Wallet) findKey(addr address.Address) (*Key, error) {
if ok { if ok {
return k, nil return k, nil
} }
if w.keystore == nil {
log.Warn("findKey didn't find the key in in-memory wallet")
return nil, nil
}
ki, err := w.keystore.Get(KNamePrefix + addr.String()) ki, err := w.keystore.Get(KNamePrefix + addr.String())
if err != nil { if err != nil {
if xerrors.Is(err, types.ErrKeyInfoNotFound) { if xerrors.Is(err, types.ErrKeyInfoNotFound) {

View File

@ -143,7 +143,6 @@ var Commands = []*cli.Command{
sendCmd, sendCmd,
stateCmd, stateCmd,
syncCmd, syncCmd,
unregisterMinerCmd,
versionCmd, versionCmd,
walletCmd, walletCmd,
} }

View File

@ -1,32 +0,0 @@
package cli
import (
"fmt"
"github.com/filecoin-project/lotus/chain/address"
"gopkg.in/urfave/cli.v2"
)
var unregisterMinerCmd = &cli.Command{
Name: "unregister-miner",
Usage: "Manually unregister miner actor",
Action: func(cctx *cli.Context) error {
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)
if !cctx.Args().Present() {
return fmt.Errorf("must pass address of miner to unregister")
}
maddr, err := address.NewFromString(cctx.Args().First())
if err != nil {
return err
}
return api.MinerUnregister(ctx, maddr)
},
}

View File

@ -4,7 +4,11 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"golang.org/x/xerrors"
"gopkg.in/urfave/cli.v2" "gopkg.in/urfave/cli.v2"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/types"
) )
var mpoolCmd = &cli.Command{ var mpoolCmd = &cli.Command{
@ -13,6 +17,7 @@ var mpoolCmd = &cli.Command{
Subcommands: []*cli.Command{ Subcommands: []*cli.Command{
mpoolPending, mpoolPending,
mpoolSub, mpoolSub,
mpoolStat,
}, },
} }
@ -76,3 +81,75 @@ var mpoolSub = &cli.Command{
} }
}, },
} }
type statBucket struct {
msgs map[uint64]*types.SignedMessage
}
var mpoolStat = &cli.Command{
Name: "stat",
Usage: "print mempool stats",
Action: func(cctx *cli.Context) error {
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)
ts, err := api.ChainHead(ctx)
if err != nil {
return xerrors.Errorf("getting chain head: %w", err)
}
msgs, err := api.MpoolPending(ctx, nil)
if err != nil {
return err
}
buckets := map[address.Address]*statBucket{}
for _, v := range msgs {
bkt, ok := buckets[v.Message.From]
if !ok {
bkt = &statBucket{
msgs: map[uint64]*types.SignedMessage{},
}
buckets[v.Message.From] = bkt
}
bkt.msgs[v.Message.Nonce] = v
}
for a, bkt := range buckets {
act, err := api.StateGetActor(ctx, a, ts)
if err != nil {
return err
}
cur := act.Nonce
for {
_, ok := bkt.msgs[cur]
if !ok {
break
}
cur++
}
past := 0
future := 0
for _, m := range bkt.msgs {
if m.Message.Nonce < act.Nonce {
past++
}
if m.Message.Nonce > cur {
future++
}
}
fmt.Printf("%s, past: %d, cur: %d, future: %d\n", a, past, cur-act.Nonce, future)
}
return nil
},
}

264
cmd/lotus-bench/main.go Normal file
View File

@ -0,0 +1,264 @@
package main
import (
"bytes"
"context"
"crypto/sha256"
"fmt"
"io/ioutil"
"math/rand"
"os"
"path/filepath"
"time"
ffi "github.com/filecoin-project/filecoin-ffi"
"github.com/ipfs/go-datastore"
logging "github.com/ipfs/go-log"
"github.com/mitchellh/go-homedir"
"golang.org/x/xerrors"
"gopkg.in/urfave/cli.v2"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/lib/sectorbuilder"
)
var log = logging.Logger("lotus-bench")
type BenchResults struct {
SectorSize uint64
SealingResults []SealingResult
PostGenerateCandidates time.Duration
PostEProofCold time.Duration
PostEProofHot time.Duration
VerifyEPostCold time.Duration
VerifyEPostHot time.Duration
}
type SealingResult struct {
AddPiece time.Duration
PreCommit time.Duration
Commit time.Duration
Verify time.Duration
}
func main() {
logging.SetLogLevel("*", "INFO")
log.Info("Starting lotus-bench")
app := &cli.App{
Name: "lotus-bench",
Usage: "Benchmark performance of lotus on your hardware",
Version: build.Version,
Flags: []cli.Flag{
&cli.StringFlag{
Name: "storage-dir",
Value: "~/.lotus-bench",
Usage: "Path to the storage directory that will store sectors long term",
},
&cli.Uint64Flag{
Name: "sector-size",
Value: 1024,
},
},
Action: func(c *cli.Context) error {
sdir, err := homedir.Expand(c.String("storage-dir"))
if err != nil {
return err
}
os.MkdirAll(sdir, 0775)
tsdir, err := ioutil.TempDir(sdir, "bench")
if err != nil {
return err
}
defer func() {
if err := os.RemoveAll(tsdir); err != nil {
log.Warn("remove all: ", err)
}
}()
maddr, err := address.NewFromString("t0101")
if err != nil {
return err
}
sectorSize := c.Uint64("sector-size")
mds := datastore.NewMapDatastore()
cfg := &sectorbuilder.Config{
Miner: maddr,
SectorSize: sectorSize,
WorkerThreads: 2,
CacheDir: filepath.Join(tsdir, "cache"),
SealedDir: filepath.Join(tsdir, "sealed"),
StagedDir: filepath.Join(tsdir, "staged"),
MetadataDir: filepath.Join(tsdir, "meta"),
}
for _, d := range []string{cfg.CacheDir, cfg.SealedDir, cfg.StagedDir, cfg.MetadataDir} {
if err := os.MkdirAll(d, 0775); err != nil {
return err
}
}
if err := build.GetParams(true, false); err != nil {
return xerrors.Errorf("getting params: %w", err)
}
sb, err := sectorbuilder.New(cfg, mds)
if err != nil {
return err
}
r := rand.New(rand.NewSource(101))
size := sectorbuilder.UserBytesForSectorSize(sectorSize)
var sealTimings []SealingResult
var sealedSectors []ffi.PublicSectorInfo
numSectors := uint64(1)
for i := uint64(1); i <= numSectors; i++ {
start := time.Now()
log.Info("Writing piece into sector...")
pi, err := sb.AddPiece(size, i, r, nil)
if err != nil {
return err
}
addpiece := time.Now()
trand := sha256.Sum256([]byte(c.String("ticket-preimage")))
ticket := sectorbuilder.SealTicket{
TicketBytes: trand,
}
log.Info("Running replication...")
pieces := []sectorbuilder.PublicPieceInfo{pi}
pco, err := sb.SealPreCommit(i, ticket, pieces)
if err != nil {
return xerrors.Errorf("commit: %w", err)
}
precommit := time.Now()
sealedSectors = append(sealedSectors, ffi.PublicSectorInfo{
CommR: pco.CommR,
SectorID: i,
})
seed := sectorbuilder.SealSeed{
BlockHeight: 101,
TicketBytes: [32]byte{1, 2, 3, 4, 5},
}
log.Info("Generating PoRep for sector")
proof, err := sb.SealCommit(i, ticket, seed, pieces, pco)
if err != nil {
return err
}
sealcommit := time.Now()
commD := pi.CommP
ok, err := sectorbuilder.VerifySeal(sectorSize, pco.CommR[:], commD[:], maddr, ticket.TicketBytes[:], seed.TicketBytes[:], i, proof)
if err != nil {
return err
}
if !ok {
return xerrors.Errorf("porep proof for sector %d was invalid", i)
}
verifySeal := time.Now()
sealTimings = append(sealTimings, SealingResult{
AddPiece: addpiece.Sub(start),
PreCommit: precommit.Sub(addpiece),
Commit: sealcommit.Sub(precommit),
Verify: verifySeal.Sub(sealcommit),
})
}
beforePost := time.Now()
var challenge [32]byte
rand.Read(challenge[:])
log.Info("generating election post candidates")
sinfos := sectorbuilder.NewSortedPublicSectorInfo(sealedSectors)
candidates, err := sb.GenerateEPostCandidates(sinfos, challenge, []uint64{})
if err != nil {
return err
}
gencandidates := time.Now()
log.Info("computing election post snark (cold)")
proof1, err := sb.ComputeElectionPoSt(sinfos, challenge[:], candidates[:1])
if err != nil {
return err
}
epost1 := time.Now()
log.Info("computing election post snark (hot)")
proof2, err := sb.ComputeElectionPoSt(sinfos, challenge[:], candidates[:1])
if err != nil {
return err
}
epost2 := time.Now()
if !bytes.Equal(proof1, proof2) {
log.Warn("separate epost calls returned different proof values (this might be bad)")
}
ok, err := sectorbuilder.VerifyElectionPost(context.TODO(), sectorSize, sinfos, challenge[:], proof1, candidates[:1], maddr)
if err != nil {
return err
}
if !ok {
log.Error("post verification failed")
}
verifypost1 := time.Now()
ok, err = sectorbuilder.VerifyElectionPost(context.TODO(), sectorSize, sinfos, challenge[:], proof2, candidates[:1], maddr)
if err != nil {
return err
}
if !ok {
log.Error("post verification failed")
}
verifypost2 := time.Now()
benchout := BenchResults{
SectorSize: cfg.SectorSize,
SealingResults: sealTimings,
PostGenerateCandidates: gencandidates.Sub(beforePost),
PostEProofCold: epost1.Sub(gencandidates),
PostEProofHot: epost2.Sub(epost1),
VerifyEPostCold: verifypost1.Sub(epost2),
VerifyEPostHot: verifypost2.Sub(verifypost1),
} // TODO: optionally write this as json to a file
fmt.Println("results")
fmt.Printf("seal: addPiece: %s\n", benchout.SealingResults[0].AddPiece) // TODO: average across multiple sealings
fmt.Printf("seal: preCommit: %s\n", benchout.SealingResults[0].PreCommit)
fmt.Printf("seal: Commit: %s\n", benchout.SealingResults[0].Commit)
fmt.Printf("seal: Verify: %s\n", benchout.SealingResults[0].Verify)
fmt.Printf("generate candidates: %s\n", benchout.PostGenerateCandidates)
fmt.Printf("compute epost proof (cold): %s\n", benchout.PostEProofCold)
fmt.Printf("compute epost proof (hot): %s\n", benchout.PostEProofHot)
fmt.Printf("verify epost proof (cold): %s\n", benchout.VerifyEPostCold)
fmt.Printf("verify epost proof (hot): %s\n", benchout.VerifyEPostHot)
return nil
},
}
if err := app.Run(os.Args); err != nil {
log.Warn(err)
return
}
}

View File

@ -252,7 +252,7 @@ func (st *storage) storeMiners(miners map[minerKey]*minerInfo) error {
i.info.SectorSize, i.info.SectorSize,
i.state.Power.String(), i.state.Power.String(),
i.state.Active, i.state.Active,
i.state.ProvingPeriodEnd, i.state.ElectionPeriodStart,
i.state.SlashedAt, i.state.SlashedAt,
); err != nil { ); err != nil {
return err return err

View File

@ -4,9 +4,10 @@ import (
"bytes" "bytes"
"container/list" "container/list"
"context" "context"
"sync"
actors2 "github.com/filecoin-project/lotus/chain/actors" actors2 "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/address"
"sync"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"

89
cmd/lotus-seed/main.go Normal file
View File

@ -0,0 +1,89 @@
package main
import (
"os"
logging "github.com/ipfs/go-log"
"github.com/mitchellh/go-homedir"
"gopkg.in/urfave/cli.v2"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/cmd/lotus-seed/seed"
)
var log = logging.Logger("lotus-seed")
func main() {
logging.SetLogLevel("*", "INFO")
log.Info("Starting seed")
local := []*cli.Command{
preSealCmd,
}
app := &cli.App{
Name: "lotus-seed",
Usage: "Seal sectors for genesis miner",
Version: build.Version,
Flags: []cli.Flag{
&cli.StringFlag{
Name: "sectorbuilder-dir",
Value: "~/.genesis-sectors",
},
},
Commands: local,
}
if err := app.Run(os.Args); err != nil {
log.Warn(err)
return
}
}
var preSealCmd = &cli.Command{
Name: "pre-seal",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "miner-addr",
Value: "t0101",
Usage: "specify the future address of your miner",
},
&cli.Uint64Flag{
Name: "sector-size",
Value: build.SectorSizes[0],
Usage: "specify size of sectors to pre-seal",
},
&cli.StringFlag{
Name: "ticket-preimage",
Value: "lotus is fire",
Usage: "set the ticket preimage for sealing randomness",
},
&cli.Uint64Flag{
Name: "num-sectors",
Value: 1,
Usage: "select number of sectors to pre-seal",
},
},
Action: func(c *cli.Context) error {
sdir := c.String("sectorbuilder-dir")
sbroot, err := homedir.Expand(sdir)
if err != nil {
return err
}
maddr, err := address.NewFromString(c.String("miner-addr"))
if err != nil {
return err
}
gm, err := seed.PreSeal(maddr, c.Uint64("sector-size"), c.Uint64("num-sectors"), sbroot, []byte(c.String("ticket-preimage")))
if err != nil {
return err
}
return seed.WriteGenesisMiner(maddr, sbroot, gm)
},
}

167
cmd/lotus-seed/seed/seed.go Normal file
View File

@ -0,0 +1,167 @@
package seed
import (
"context"
"crypto/sha256"
"encoding/json"
"fmt"
"io/ioutil"
"math/rand"
"os"
"path/filepath"
badger "github.com/ipfs/go-ds-badger"
"golang.org/x/xerrors"
"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/address"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/wallet"
"github.com/filecoin-project/lotus/genesis"
"github.com/filecoin-project/lotus/lib/sectorbuilder"
)
func PreSeal(maddr address.Address, ssize uint64, sectors uint64, sbroot string, preimage []byte) (*genesis.GenesisMiner, error) {
cfg := &sectorbuilder.Config{
Miner: maddr,
SectorSize: ssize,
CacheDir: filepath.Join(sbroot, "cache"),
SealedDir: filepath.Join(sbroot, "sealed"),
StagedDir: filepath.Join(sbroot, "staging"),
MetadataDir: filepath.Join(sbroot, "meta"),
WorkerThreads: 2,
}
for _, d := range []string{cfg.CacheDir, cfg.SealedDir, cfg.StagedDir, cfg.MetadataDir} {
if err := os.MkdirAll(d, 0775); err != nil {
return nil, err
}
}
mds, err := badger.NewDatastore(filepath.Join(sbroot, "badger"), nil)
if err != nil {
return nil, err
}
if err := build.GetParams(true, false); err != nil {
return nil, xerrors.Errorf("getting params: %w", err)
}
sb, err := sectorbuilder.New(cfg, mds)
if err != nil {
return nil, err
}
r := rand.New(rand.NewSource(101))
size := sectorbuilder.UserBytesForSectorSize(ssize)
var sealedSectors []*genesis.PreSeal
for i := uint64(1); i <= sectors; i++ {
sid, err := sb.AcquireSectorId()
if err != nil {
return nil, err
}
pi, err := sb.AddPiece(size, sid, r, nil)
if err != nil {
return nil, err
}
trand := sha256.Sum256(preimage)
ticket := sectorbuilder.SealTicket{
TicketBytes: trand,
}
fmt.Println("Piece info: ", pi)
pco, err := sb.SealPreCommit(sid, ticket, []sectorbuilder.PublicPieceInfo{pi})
if err != nil {
return nil, xerrors.Errorf("commit: %w", err)
}
sealedSectors = append(sealedSectors, &genesis.PreSeal{
CommR: pco.CommR,
CommD: pco.CommD,
SectorID: sid,
})
}
minerAddr, err := wallet.GenerateKey(types.KTBLS)
if err != nil {
return nil, err
}
miner := &genesis.GenesisMiner{
Owner: minerAddr.Address,
Worker: minerAddr.Address,
SectorSize: ssize,
Sectors: sealedSectors,
Key: minerAddr.KeyInfo,
}
if err := createDeals(miner, minerAddr, ssize); err != nil {
return nil, xerrors.Errorf("creating deals: %w", err)
}
if err := mds.Close(); err != nil {
return nil, xerrors.Errorf("closing datastore: %w", err)
}
return miner, nil
}
func WriteGenesisMiner(maddr address.Address, sbroot string, gm *genesis.GenesisMiner) error {
output := map[string]genesis.GenesisMiner{
maddr.String(): *gm,
}
out, err := json.MarshalIndent(output, "", " ")
if err != nil {
return err
}
if err := ioutil.WriteFile(filepath.Join(sbroot, "pre-seal-"+maddr.String()+".json"), out, 0664); err != nil {
return err
}
return nil
}
func createDeals(m *genesis.GenesisMiner, k *wallet.Key, ssize uint64) error {
for _, sector := range m.Sectors {
proposal := &actors.StorageDealProposal{
PieceRef: sector.CommD[:], // just one deal so this == CommP
PieceSize: ssize,
PieceSerialization: actors.SerializationUnixFSv0,
Client: k.Address,
Provider: k.Address,
ProposalExpiration: 9000, // TODO: allow setting
Duration: 9000,
StoragePricePerEpoch: types.NewInt(0),
StorageCollateral: types.NewInt(0),
ProposerSignature: nil,
}
if err := api.SignWith(context.TODO(), wallet.KeyWallet(k).Sign, k.Address, proposal); err != nil {
return err
}
deal := &actors.StorageDeal{
Proposal: *proposal,
CounterSignature: nil,
}
if err := api.SignWith(context.TODO(), wallet.KeyWallet(k).Sign, k.Address, deal); err != nil {
return err
}
sector.Deal = *deal
}
return nil
}

View File

@ -63,7 +63,7 @@ var infoCmd = &cli.Command{
fmt.Printf("\tLocal: %d / %d (+%d reserved)\n", wstat.LocalTotal-wstat.LocalReserved-wstat.LocalFree, wstat.LocalTotal-wstat.LocalReserved, wstat.LocalReserved) fmt.Printf("\tLocal: %d / %d (+%d reserved)\n", wstat.LocalTotal-wstat.LocalReserved-wstat.LocalFree, wstat.LocalTotal-wstat.LocalReserved, wstat.LocalReserved)
fmt.Printf("\tRemote: %d / %d\n", wstat.RemotesTotal-wstat.RemotesFree, wstat.RemotesTotal) fmt.Printf("\tRemote: %d / %d\n", wstat.RemotesTotal-wstat.RemotesFree, wstat.RemotesTotal)
ppe, err := api.StateMinerProvingPeriodEnd(ctx, maddr, nil) ppe, err := api.StateMinerElectionPeriodStart(ctx, maddr, nil)
if err != nil { if err != nil {
return err return err
} }

View File

@ -3,22 +3,36 @@ package main
import ( import (
"context" "context"
"crypto/rand" "crypto/rand"
"encoding/json"
"fmt"
"io/ioutil"
"os" "os"
"path/filepath"
"strconv"
"github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore"
badger "github.com/ipfs/go-ds-badger"
"github.com/libp2p/go-libp2p-core/crypto" "github.com/libp2p/go-libp2p-core/crypto"
"github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/peer"
"github.com/mitchellh/go-homedir" "github.com/mitchellh/go-homedir"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"gopkg.in/urfave/cli.v2" "gopkg.in/urfave/cli.v2"
"github.com/filecoin-project/lotus/api" lapi "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/deals"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
lcli "github.com/filecoin-project/lotus/cli" lcli "github.com/filecoin-project/lotus/cli"
"github.com/filecoin-project/lotus/genesis"
"github.com/filecoin-project/lotus/lib/cborutil"
"github.com/filecoin-project/lotus/lib/sectorbuilder"
"github.com/filecoin-project/lotus/miner"
"github.com/filecoin-project/lotus/node/modules"
"github.com/filecoin-project/lotus/node/modules/dtypes"
"github.com/filecoin-project/lotus/node/repo" "github.com/filecoin-project/lotus/node/repo"
"github.com/filecoin-project/lotus/storage"
) )
var initCmd = &cli.Command{ var initCmd = &cli.Command{
@ -53,6 +67,10 @@ var initCmd = &cli.Command{
Usage: "specify sector size to use", Usage: "specify sector size to use",
Value: build.SectorSizes[0], Value: build.SectorSizes[0],
}, },
&cli.StringFlag{
Name: "pre-sealed-sectors",
Usage: "specify set of presealed sectors for starting as a genesis miner",
},
}, },
Action: func(cctx *cli.Context) error { Action: func(cctx *cli.Context) error {
log.Info("Initializing lotus storage miner") log.Info("Initializing lotus storage miner")
@ -104,6 +122,25 @@ var initCmd = &cli.Command{
return err return err
} }
if pssb := cctx.String("pre-sealed-sectors"); pssb != "" {
log.Infof("moving pre-sealed-sectors from %s into newly created storage miner repo", pssb)
lr, err := r.Lock(repo.StorageMiner)
if err != nil {
return err
}
mds, err := lr.Datastore("/metadata")
if err != nil {
return err
}
if err := migratePreSealedSectors(pssb, repoPath, mds); err != nil {
return err
}
if err := lr.Close(); err != nil {
return xerrors.Errorf("unlocking repo after preseal migration: %w", err)
}
}
if err := storageMinerInit(ctx, cctx, api, r); err != nil { if err := storageMinerInit(ctx, cctx, api, r); err != nil {
log.Errorf("Failed to initialize lotus-storage-miner: %+v", err) log.Errorf("Failed to initialize lotus-storage-miner: %+v", err)
path, err := homedir.Expand(repoPath) path, err := homedir.Expand(repoPath)
@ -124,7 +161,161 @@ var initCmd = &cli.Command{
}, },
} }
func storageMinerInit(ctx context.Context, cctx *cli.Context, api api.FullNode, r repo.Repo) error { // TODO: this method should be a lot more robust for mainnet. For testnet, its
// fine if we mess things up a few times
// Also probably makes sense for this method to be in the sectorbuilder package
func migratePreSealedSectors(presealsb string, repoPath string, mds dtypes.MetadataDS) error {
pspath, err := homedir.Expand(presealsb)
if err != nil {
return err
}
srcds, err := badger.NewDatastore(filepath.Join(pspath, "badger"), nil)
if err != nil {
return xerrors.Errorf("openning presealed sectors datastore: %w", err)
}
expRepo, err := homedir.Expand(repoPath)
if err != nil {
return err
}
if stat, err := os.Stat(pspath); err != nil {
return xerrors.Errorf("failed to stat presealed sectors directory: %w", err)
} else if !stat.IsDir() {
return xerrors.Errorf("given presealed sectors path was not a directory: %w", err)
}
for _, dir := range []string{"meta", "sealed", "staging", "cache"} {
from := filepath.Join(pspath, dir)
to := filepath.Join(expRepo, dir)
if err := os.Rename(from, to); err != nil {
return err
}
}
val, err := srcds.Get(sectorbuilder.LastSectorIdKey)
if err != nil {
return xerrors.Errorf("getting source last sector ID: %w", err)
}
if err := mds.Put(sectorbuilder.LastSectorIdKey, val); err != nil {
return xerrors.Errorf("failed to write last sector ID key to target datastore: %w", err)
}
return nil
}
func migratePreSealMeta(ctx context.Context, api lapi.FullNode, presealDir string, maddr address.Address, mds dtypes.MetadataDS) error {
b, err := ioutil.ReadFile(filepath.Join(presealDir, "pre-seal-"+maddr.String()+".json"))
if err != nil {
return xerrors.Errorf("reading preseal metadata: %w", err)
}
preseals := map[string]genesis.GenesisMiner{}
if err := json.Unmarshal(b, &preseals); err != nil {
return xerrors.Errorf("unmarshaling preseal metadata: %w", err)
}
meta, ok := preseals[maddr.String()]
if !ok {
return xerrors.New("got wrong preseal info")
}
for _, sector := range meta.Sectors {
sectorKey := datastore.NewKey(storage.SectorStorePrefix).ChildString(fmt.Sprint(sector.SectorID))
dealID, err := findMarketDealID(ctx, api, sector.Deal)
if err != nil {
return xerrors.Errorf("finding storage deal for pre-sealed sector %d: %w", sector.SectorID, err)
}
info := &storage.SectorInfo{
State: lapi.Proving,
SectorID: sector.SectorID,
Pieces: []storage.Piece{
{
DealID: dealID,
Ref: fmt.Sprintf("preseal-%d", sector.SectorID),
Size: meta.SectorSize,
CommP: sector.CommD[:],
},
},
CommC: nil,
CommD: sector.CommD[:],
CommR: sector.CommR[:],
CommRLast: nil,
Proof: nil,
Ticket: storage.SealTicket{},
PreCommitMessage: nil,
Seed: storage.SealSeed{},
CommitMessage: nil,
}
b, err := cborutil.Dump(info)
if err != nil {
return err
}
if err := mds.Put(sectorKey, b); err != nil {
return err
}
proposalCid, err := sector.Deal.Proposal.Cid()
if err != nil {
return err
}
dealKey := datastore.NewKey(deals.ProviderDsPrefix).ChildString(proposalCid.String())
deal := &deals.MinerDeal{
Proposal: sector.Deal.Proposal,
ProposalCid: proposalCid,
State: lapi.DealComplete,
Ref: proposalCid, // TODO: This is super wrong, but there
// are no params for CommP CIDs, we can't recover unixfs cid easily,
// and this isn't even used after the deal enters Complete state
DealID: dealID,
SectorID: sector.SectorID,
}
b, err = cborutil.Dump(deal)
if err != nil {
return err
}
if err := mds.Put(dealKey, b); err != nil {
return err
}
}
return nil
}
func findMarketDealID(ctx context.Context, api lapi.FullNode, deal actors.StorageDeal) (uint64, error) {
// TODO: find a better way
// (this is only used by genesis miners)
deals, err := api.StateMarketDeals(ctx, nil)
if err != nil {
return 0, xerrors.Errorf("getting market deals: %w", err)
}
for k, v := range deals {
eq, err := cborutil.Equals(&v.Deal, &deal)
if err != nil {
return 0, err
}
if eq {
return strconv.ParseUint(k, 10, 64)
}
}
return 0, xerrors.New("deal not found")
}
func storageMinerInit(ctx context.Context, cctx *cli.Context, api lapi.FullNode, r repo.Repo) error {
lr, err := r.Lock(repo.StorageMiner) lr, err := r.Lock(repo.StorageMiner)
if err != nil { if err != nil {
return err return err
@ -143,6 +334,11 @@ func storageMinerInit(ctx context.Context, cctx *cli.Context, api api.FullNode,
return xerrors.Errorf("peer ID from private key: %w", err) return xerrors.Errorf("peer ID from private key: %w", err)
} }
mds, err := lr.Datastore("/metadata")
if err != nil {
return err
}
var addr address.Address var addr address.Address
if act := cctx.String("actor"); act != "" { if act := cctx.String("actor"); act != "" {
a, err := address.NewFromString(act) a, err := address.NewFromString(act)
@ -150,8 +346,51 @@ func storageMinerInit(ctx context.Context, cctx *cli.Context, api api.FullNode,
return xerrors.Errorf("failed parsing actor flag value (%q): %w", act, err) return xerrors.Errorf("failed parsing actor flag value (%q): %w", act, err)
} }
if err := configureStorageMiner(ctx, api, a, peerid, cctx.Bool("genesis-miner")); err != nil { if cctx.Bool("genesis-miner") {
return xerrors.Errorf("failed to configure storage miner: %w", err) if err := mds.Put(datastore.NewKey("miner-address"), a.Bytes()); err != nil {
return err
}
sbcfg, err := modules.SectorBuilderConfig(lr.Path(), 2)(mds, api)
if err != nil {
return xerrors.Errorf("getting genesis miner sector builder config: %w", err)
}
sb, err := sectorbuilder.New(sbcfg, mds)
if err != nil {
return xerrors.Errorf("failed to set up sectorbuilder for genesis mining: %w", err)
}
epp := storage.NewElectionPoStProver(sb)
m := miner.NewMiner(api, epp)
{
if err := m.Register(a); err != nil {
return xerrors.Errorf("failed to start up genesis miner: %w", err)
}
defer func() {
if err := m.Unregister(ctx, a); err != nil {
log.Error("failed to shut down storage miner: ", err)
}
}()
if err := configureStorageMiner(ctx, api, a, peerid); err != nil {
return xerrors.Errorf("failed to configure storage miner: %w", err)
}
}
if pssb := cctx.String("pre-sealed-sectors"); pssb != "" {
log.Infof("Importing pre-sealed sector metadata for %s", a)
if err := migratePreSealMeta(ctx, api, cctx.String("pre-sealed-sectors"), a, mds); err != nil {
return xerrors.Errorf("migrating presealed sector metadata: %w", err)
}
}
return nil
} else {
if err := configureStorageMiner(ctx, api, a, peerid); err != nil {
return xerrors.Errorf("failed to configure storage miner: %w", err)
}
} }
addr = a addr = a
@ -165,12 +404,7 @@ func storageMinerInit(ctx context.Context, cctx *cli.Context, api api.FullNode,
} }
log.Infof("Created new storage miner: %s", addr) log.Infof("Created new storage miner: %s", addr)
if err := mds.Put(datastore.NewKey("miner-address"), addr.Bytes()); err != nil {
ds, err := lr.Datastore("/metadata")
if err != nil {
return err
}
if err := ds.Put(datastore.NewKey("miner-address"), addr.Bytes()); err != nil {
return err return err
} }
@ -203,22 +437,7 @@ func makeHostKey(lr repo.LockedRepo) (crypto.PrivKey, error) {
return pk, nil return pk, nil
} }
func configureStorageMiner(ctx context.Context, api api.FullNode, addr address.Address, peerid peer.ID, genmine bool) error { func configureStorageMiner(ctx context.Context, api lapi.FullNode, addr address.Address, peerid peer.ID) error {
if genmine {
log.Warn("Starting genesis mining. This shouldn't happen when connecting to the real network.")
// We may be one of genesis miners, start mining before trying to do any chain operations
// (otherwise our messages won't be mined)
if err := api.MinerRegister(ctx, addr); err != nil {
return err
}
defer func() {
if err := api.MinerUnregister(ctx, addr); err != nil {
log.Errorf("failed to call api.MinerUnregister: %s", err)
}
}()
}
// This really just needs to be an api call at this point... // This really just needs to be an api call at this point...
recp, err := api.StateCall(ctx, &types.Message{ recp, err := api.StateCall(ctx, &types.Message{
To: addr, To: addr,
@ -271,7 +490,7 @@ func configureStorageMiner(ctx context.Context, api api.FullNode, addr address.A
return nil return nil
} }
func createStorageMiner(ctx context.Context, api api.FullNode, peerid peer.ID, cctx *cli.Context) (addr address.Address, err error) { func createStorageMiner(ctx context.Context, api lapi.FullNode, peerid peer.ID, cctx *cli.Context) (addr address.Address, err error) {
log.Info("Creating StorageMarket.CreateStorageMiner message") log.Info("Creating StorageMarket.CreateStorageMiner message")
var owner address.Address var owner address.Address

View File

@ -70,7 +70,7 @@ func main() {
} }
if err := app.Run(os.Args); err != nil { if err := app.Run(os.Args); err != nil {
log.Warn(err) log.Warnf("%+v", err)
os.Exit(1) os.Exit(1)
} }
} }

View File

@ -35,6 +35,7 @@ var runCmd = &cli.Command{
&cli.BoolFlag{ &cli.BoolFlag{
Name: "enable-gpu-proving", Name: "enable-gpu-proving",
Usage: "Enable use of GPU for mining operations", Usage: "Enable use of GPU for mining operations",
Value: true,
}, },
}, },
Action: func(cctx *cli.Context) error { Action: func(cctx *cli.Context) error {

View File

@ -21,7 +21,8 @@ import (
) )
const ( const (
makeGenFlag = "lotus-make-random-genesis" makeGenFlag = "lotus-make-random-genesis"
preSealedSectorsFlag = "genesis-presealed-sectors"
) )
// DaemonCmd is the `go-lotus daemon` command // DaemonCmd is the `go-lotus daemon` command
@ -38,6 +39,10 @@ var DaemonCmd = &cli.Command{
Value: "", Value: "",
Hidden: true, Hidden: true,
}, },
&cli.StringFlag{
Name: preSealedSectorsFlag,
Hidden: true,
},
&cli.StringFlag{ &cli.StringFlag{
Name: "genesis", Name: "genesis",
Usage: "genesis file to use for first node run", Usage: "genesis file to use for first node run",
@ -51,11 +56,11 @@ var DaemonCmd = &cli.Command{
ctx := context.Background() ctx := context.Background()
r, err := repo.NewFS(cctx.String("repo")) r, err := repo.NewFS(cctx.String("repo"))
if err != nil { if err != nil {
return err return xerrors.Errorf("opening fs repo: %w", err)
} }
if err := r.Init(repo.FullNode); err != nil && err != repo.ErrRepoExists { if err := r.Init(repo.FullNode); err != nil && err != repo.ErrRepoExists {
return err return xerrors.Errorf("repo init error: %w", err)
} }
if err := build.GetParams(false, false); err != nil { if err := build.GetParams(false, false); err != nil {
@ -67,9 +72,8 @@ var DaemonCmd = &cli.Command{
if cctx.String("genesis") != "" { if cctx.String("genesis") != "" {
genBytes, err = ioutil.ReadFile(cctx.String("genesis")) genBytes, err = ioutil.ReadFile(cctx.String("genesis"))
if err != nil { if err != nil {
return err return xerrors.Errorf("reading genesis: %w", err)
} }
} }
genesis := node.Options() genesis := node.Options()
@ -77,7 +81,10 @@ var DaemonCmd = &cli.Command{
genesis = node.Override(new(modules.Genesis), modules.LoadGenesis(genBytes)) genesis = node.Override(new(modules.Genesis), modules.LoadGenesis(genBytes))
} }
if cctx.String(makeGenFlag) != "" { if cctx.String(makeGenFlag) != "" {
genesis = node.Override(new(modules.Genesis), testing.MakeGenesis(cctx.String(makeGenFlag))) if cctx.String(preSealedSectorsFlag) == "" {
return xerrors.Errorf("must also pass file with miner preseal info to `--%s`", preSealedSectorsFlag)
}
genesis = node.Override(new(modules.Genesis), testing.MakeGenesis(cctx.String(makeGenFlag), cctx.String(preSealedSectorsFlag)))
} }
var api api.FullNode var api api.FullNode
@ -105,12 +112,12 @@ var DaemonCmd = &cli.Command{
), ),
) )
if err != nil { if err != nil {
return err return xerrors.Errorf("initializing node: %w", err)
} }
endpoint, err := r.APIEndpoint() endpoint, err := r.APIEndpoint()
if err != nil { if err != nil {
return err return xerrors.Errorf("getting api endpoint: %w", err)
} }
// TODO: properly parse api endpoint (or make it a URL) // TODO: properly parse api endpoint (or make it a URL)

View File

@ -69,7 +69,7 @@ func main() {
Code: trace.StatusCodeFailedPrecondition, Code: trace.StatusCodeFailedPrecondition,
Message: err.Error(), Message: err.Error(),
}) })
log.Warn(err) log.Warnf("%+v", err)
os.Exit(1) os.Exit(1)
} }
return return

1
extern/filecoin-ffi vendored Submodule

@ -0,0 +1 @@
Subproject commit 0e71b164cf4b2e1c0f53ca25145e3ea57cc53e90

1
extern/go-bls-sigs vendored

@ -1 +0,0 @@
Subproject commit 98479d3c79620f18783da0c2c6a15f8b8eb4fa2e

@ -1 +0,0 @@
Subproject commit 40278d4a6623e4c81003e20444871c9362bedd61

View File

@ -20,6 +20,8 @@ func main() {
err := gen.WriteTupleEncodersToFile("./chain/types/cbor_gen.go", "types", err := gen.WriteTupleEncodersToFile("./chain/types/cbor_gen.go", "types",
types.BlockHeader{}, types.BlockHeader{},
types.Ticket{}, types.Ticket{},
types.EPostProof{},
types.EPostTicket{},
types.Message{}, types.Message{},
types.SignedMessage{}, types.SignedMessage{},
types.MsgMeta{}, types.MsgMeta{},
@ -91,7 +93,7 @@ func main() {
actors.SectorPreCommitInfo{}, actors.SectorPreCommitInfo{},
actors.PreCommittedSector{}, actors.PreCommittedSector{},
actors.MinerInfo{}, actors.MinerInfo{},
actors.SubmitPoStParams{}, actors.SubmitFallbackPoStParams{},
actors.PaymentVerifyParams{}, actors.PaymentVerifyParams{},
actors.UpdatePeerIDParams{}, actors.UpdatePeerIDParams{},
actors.MultiSigActorState{}, actors.MultiSigActorState{},

25
genesis/types.go Normal file
View File

@ -0,0 +1,25 @@
package genesis
import (
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/types"
)
type PreSeal struct {
CommR [32]byte
CommD [32]byte
SectorID uint64
Deal actors.StorageDeal
}
type GenesisMiner struct {
Owner address.Address
Worker address.Address
SectorSize uint64
Sectors []*PreSeal
Key types.KeyInfo // TODO: separate file
}

37
go.mod
View File

@ -8,19 +8,17 @@ require (
github.com/GeertJohan/go.rice v1.0.0 github.com/GeertJohan/go.rice v1.0.0
github.com/Gurpartap/async v0.0.0-20180927173644-4f7f499dd9ee github.com/Gurpartap/async v0.0.0-20180927173644-4f7f499dd9ee
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect
github.com/btcsuite/btcd v0.0.0-20190807005414-4063feeff79a // indirect
github.com/fatih/color v1.7.0 // indirect github.com/fatih/color v1.7.0 // indirect
github.com/filecoin-project/chain-validation v0.0.0-20191106200742-11986803c0f7 github.com/filecoin-project/chain-validation v0.0.0-20191106200742-11986803c0f7
github.com/filecoin-project/go-amt-ipld v0.0.0-20190919045431-3650716fff16 github.com/filecoin-project/filecoin-ffi v0.0.0-00010101000000-000000000000
github.com/filecoin-project/go-bls-sigs v0.0.0-20190718224239-4bc4b8a7bbf8 github.com/filecoin-project/go-amt-ipld v0.0.0-20191122035745-59b9dfc0efc7
github.com/filecoin-project/go-leb128 v0.0.0-20190212224330-8d79a5489543 github.com/filecoin-project/go-leb128 v0.0.0-20190212224330-8d79a5489543
github.com/filecoin-project/go-sectorbuilder v0.0.0-00010101000000-000000000000
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1
github.com/go-ole/go-ole v1.2.4 // indirect github.com/go-ole/go-ole v1.2.4 // indirect
github.com/google/go-cmp v0.3.1 // indirect github.com/google/go-cmp v0.3.1 // indirect
github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f // indirect github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f // indirect
github.com/gorilla/mux v1.7.3 github.com/gorilla/mux v1.7.3
github.com/gorilla/websocket v1.4.0 github.com/gorilla/websocket v1.4.1
github.com/hashicorp/go-multierror v1.0.0 github.com/hashicorp/go-multierror v1.0.0
github.com/hashicorp/golang-lru v0.5.3 github.com/hashicorp/golang-lru v0.5.3
github.com/influxdata/influxdb1-client v0.0.0-20190809212627-fc22c7df067e github.com/influxdata/influxdb1-client v0.0.0-20190809212627-fc22c7df067e
@ -44,17 +42,16 @@ require (
github.com/ipfs/go-ipfs-routing v0.1.0 github.com/ipfs/go-ipfs-routing v0.1.0
github.com/ipfs/go-ipld-cbor v0.0.3 github.com/ipfs/go-ipld-cbor v0.0.3
github.com/ipfs/go-ipld-format v0.0.2 github.com/ipfs/go-ipld-format v0.0.2
github.com/ipfs/go-log v0.0.2-0.20190920042044-a609c1ae5144 github.com/ipfs/go-log v1.0.0
github.com/ipfs/go-merkledag v0.2.4 github.com/ipfs/go-merkledag v0.2.4
github.com/ipfs/go-unixfs v0.2.2-0.20190827150610-868af2e9e5cb github.com/ipfs/go-unixfs v0.2.2-0.20190827150610-868af2e9e5cb
github.com/ipld/go-ipld-prime v0.0.2-0.20191025154717-8dff1cbec43b github.com/ipld/go-ipld-prime v0.0.2-0.20191025154717-8dff1cbec43b
github.com/ipsn/go-secp256k1 v0.0.0-20180726113642-9d62b9f0bc52 github.com/ipsn/go-secp256k1 v0.0.0-20180726113642-9d62b9f0bc52
github.com/libp2p/go-eventbus v0.1.0 // indirect
github.com/libp2p/go-libp2p v0.3.0 github.com/libp2p/go-libp2p v0.3.0
github.com/libp2p/go-libp2p-circuit v0.1.1 github.com/libp2p/go-libp2p-circuit v0.1.1
github.com/libp2p/go-libp2p-connmgr v0.1.0 github.com/libp2p/go-libp2p-connmgr v0.1.0
github.com/libp2p/go-libp2p-core v0.2.2 github.com/libp2p/go-libp2p-core v0.2.4
github.com/libp2p/go-libp2p-discovery v0.1.0 github.com/libp2p/go-libp2p-discovery v0.2.0
github.com/libp2p/go-libp2p-host v0.1.0 github.com/libp2p/go-libp2p-host v0.1.0
github.com/libp2p/go-libp2p-kad-dht v0.1.1 github.com/libp2p/go-libp2p-kad-dht v0.1.1
github.com/libp2p/go-libp2p-mplex v0.2.1 github.com/libp2p/go-libp2p-mplex v0.2.1
@ -62,31 +59,30 @@ require (
github.com/libp2p/go-libp2p-peerstore v0.1.3 github.com/libp2p/go-libp2p-peerstore v0.1.3
github.com/libp2p/go-libp2p-pnet v0.1.0 github.com/libp2p/go-libp2p-pnet v0.1.0
github.com/libp2p/go-libp2p-protocol v0.1.0 github.com/libp2p/go-libp2p-protocol v0.1.0
github.com/libp2p/go-libp2p-pubsub v0.1.0 github.com/libp2p/go-libp2p-pubsub v0.2.3
github.com/libp2p/go-libp2p-quic-transport v0.1.1 github.com/libp2p/go-libp2p-quic-transport v0.1.1
github.com/libp2p/go-libp2p-record v0.1.1 github.com/libp2p/go-libp2p-record v0.1.1
github.com/libp2p/go-libp2p-routing-helpers v0.1.0 github.com/libp2p/go-libp2p-routing-helpers v0.1.0
github.com/libp2p/go-libp2p-secio v0.2.0 github.com/libp2p/go-libp2p-secio v0.2.0
github.com/libp2p/go-libp2p-swarm v0.2.1 // indirect
github.com/libp2p/go-libp2p-tls v0.1.0 github.com/libp2p/go-libp2p-tls v0.1.0
github.com/libp2p/go-libp2p-yamux v0.2.1 github.com/libp2p/go-libp2p-yamux v0.2.1
github.com/libp2p/go-maddr-filter v0.0.5 github.com/libp2p/go-maddr-filter v0.0.5
github.com/libp2p/go-ws-transport v0.1.2 // indirect
github.com/mattn/go-isatty v0.0.9 // indirect github.com/mattn/go-isatty v0.0.9 // indirect
github.com/mattn/go-runewidth v0.0.4 // indirect github.com/mattn/go-runewidth v0.0.4 // indirect
github.com/mattn/go-sqlite3 v1.12.0 github.com/mattn/go-sqlite3 v1.12.0
github.com/miekg/dns v1.1.16 // indirect github.com/miekg/dns v1.1.16 // indirect
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1
github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771 github.com/minio/sha256-simd v0.1.1
github.com/mitchellh/go-homedir v1.1.0 github.com/mitchellh/go-homedir v1.1.0
github.com/multiformats/go-base32 v0.0.3 github.com/multiformats/go-base32 v0.0.3
github.com/multiformats/go-multiaddr v0.0.4 github.com/multiformats/go-multiaddr v0.1.1
github.com/multiformats/go-multiaddr-dns v0.0.3 github.com/multiformats/go-multiaddr-dns v0.2.0
github.com/multiformats/go-multiaddr-net v0.0.1 github.com/multiformats/go-multiaddr-net v0.1.0
github.com/multiformats/go-multihash v0.0.9 github.com/multiformats/go-multihash v0.0.9
github.com/onsi/ginkgo v1.9.0 // indirect github.com/onsi/ginkgo v1.9.0 // indirect
github.com/onsi/gomega v1.6.0 // indirect github.com/onsi/gomega v1.6.0 // indirect
github.com/opentracing/opentracing-go v1.1.0 github.com/opentracing/opentracing-go v1.1.0
github.com/pkg/errors v0.8.1
github.com/polydawn/refmt v0.0.0-20190809202753-05966cbd336a github.com/polydawn/refmt v0.0.0-20190809202753-05966cbd336a
github.com/smartystreets/assertions v1.0.1 // indirect github.com/smartystreets/assertions v1.0.1 // indirect
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 // indirect github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 // indirect
@ -95,16 +91,15 @@ require (
github.com/whyrusleeping/cbor-gen v0.0.0-20191116002219-891f55cd449d github.com/whyrusleeping/cbor-gen v0.0.0-20191116002219-891f55cd449d
github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7
github.com/whyrusleeping/pubsub v0.0.0-20131020042734-02de8aa2db3d github.com/whyrusleeping/pubsub v0.0.0-20131020042734-02de8aa2db3d
go.opencensus.io v0.22.0 go.opencensus.io v0.22.1
go.uber.org/dig v1.7.0 // indirect go.uber.org/dig v1.7.0 // indirect
go.uber.org/fx v1.9.0 go.uber.org/fx v1.9.0
go.uber.org/goleak v0.10.0 // indirect go.uber.org/goleak v0.10.0 // indirect
go.uber.org/multierr v1.1.0 go.uber.org/multierr v1.1.0
go.uber.org/zap v1.10.0 go.uber.org/zap v1.10.0
go4.org v0.0.0-20190313082347-94abd6928b1d // indirect go4.org v0.0.0-20190313082347-94abd6928b1d // indirect
golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 // indirect
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898
google.golang.org/api v0.9.0 // indirect google.golang.org/api v0.9.0 // indirect
gopkg.in/cheggaaa/pb.v1 v1.0.28 gopkg.in/cheggaaa/pb.v1 v1.0.28
gopkg.in/urfave/cli.v2 v2.0.0-20180128182452-d3ae77c26ac8 gopkg.in/urfave/cli.v2 v2.0.0-20180128182452-d3ae77c26ac8
@ -114,6 +109,4 @@ require (
replace github.com/golangci/golangci-lint => github.com/golangci/golangci-lint v1.18.0 replace github.com/golangci/golangci-lint => github.com/golangci/golangci-lint v1.18.0
replace github.com/filecoin-project/go-bls-sigs => ./extern/go-bls-sigs replace github.com/filecoin-project/filecoin-ffi => ./extern/filecoin-ffi
replace github.com/filecoin-project/go-sectorbuilder => ./extern/go-sectorbuilder

78
go.sum
View File

@ -33,8 +33,8 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24
github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8=
github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
github.com/btcsuite/btcd v0.0.0-20190605094302-a0d1e3e36d50/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.0.0-20190605094302-a0d1e3e36d50/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
github.com/btcsuite/btcd v0.0.0-20190807005414-4063feeff79a h1:We35J+0yvVFrEXbtViYUW8H/wNOhqjIF3PsrW4yYmGw= github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3 h1:A/EVblehb75cUgXA5njHPn0kLAsykn6mJGz7rnmW5W0=
github.com/btcsuite/btcd v0.0.0-20190807005414-4063feeff79a/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
@ -78,8 +78,8 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv
github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E= github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E=
github.com/filecoin-project/chain-validation v0.0.0-20191106200742-11986803c0f7 h1:Ags/z6ZubzKonQ9PsY9fO439yGdVg07qpdxfv/AEUno= github.com/filecoin-project/chain-validation v0.0.0-20191106200742-11986803c0f7 h1:Ags/z6ZubzKonQ9PsY9fO439yGdVg07qpdxfv/AEUno=
github.com/filecoin-project/chain-validation v0.0.0-20191106200742-11986803c0f7/go.mod h1:0/0/QUNqpF/jVzLHFncGeT3NvGPODBhGzQlNgzmoZew= github.com/filecoin-project/chain-validation v0.0.0-20191106200742-11986803c0f7/go.mod h1:0/0/QUNqpF/jVzLHFncGeT3NvGPODBhGzQlNgzmoZew=
github.com/filecoin-project/go-amt-ipld v0.0.0-20190919045431-3650716fff16 h1:NzojcJU1VbS6zdLG13JMYis/cQy/MrN3rxmZRq56jKA= github.com/filecoin-project/go-amt-ipld v0.0.0-20191122035745-59b9dfc0efc7 h1:lKSMm8Go6qI7+Dk3rWCNIh57wBOqVNJ21re/p7D58gc=
github.com/filecoin-project/go-amt-ipld v0.0.0-20190919045431-3650716fff16/go.mod h1:lKjJYPg2kwbav5f78i5YA8kGccnZn18IySbpneXvaQs= github.com/filecoin-project/go-amt-ipld v0.0.0-20191122035745-59b9dfc0efc7/go.mod h1:lKjJYPg2kwbav5f78i5YA8kGccnZn18IySbpneXvaQs=
github.com/filecoin-project/go-leb128 v0.0.0-20190212224330-8d79a5489543 h1:aMJGfgqe1QDhAVwxRg5fjCRF533xHidiKsugk7Vvzug= github.com/filecoin-project/go-leb128 v0.0.0-20190212224330-8d79a5489543 h1:aMJGfgqe1QDhAVwxRg5fjCRF533xHidiKsugk7Vvzug=
github.com/filecoin-project/go-leb128 v0.0.0-20190212224330-8d79a5489543/go.mod h1:mjrHv1cDGJWDlGmC0eDc1E5VJr8DmL9XMUcaFwiuKg8= github.com/filecoin-project/go-leb128 v0.0.0-20190212224330-8d79a5489543/go.mod h1:mjrHv1cDGJWDlGmC0eDc1E5VJr8DmL9XMUcaFwiuKg8=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
@ -97,7 +97,12 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk= github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
@ -127,6 +132,8 @@ github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU=
github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48=
github.com/gxed/pubsub v0.0.0-20180201040156-26ebdf44f824/go.mod h1:OiEWyHgK+CWrmOlVquHaIK1vhpUJydC9m0Je6mhaiNE= github.com/gxed/pubsub v0.0.0-20180201040156-26ebdf44f824/go.mod h1:OiEWyHgK+CWrmOlVquHaIK1vhpUJydC9m0Je6mhaiNE=
@ -220,8 +227,8 @@ github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dC
github.com/ipfs/go-ipld-format v0.0.2 h1:OVAGlyYT6JPZ0pEfGntFPS40lfrDmaDbQwNHEY2G9Zs= github.com/ipfs/go-ipld-format v0.0.2 h1:OVAGlyYT6JPZ0pEfGntFPS40lfrDmaDbQwNHEY2G9Zs=
github.com/ipfs/go-ipld-format v0.0.2/go.mod h1:4B6+FM2u9OJ9zCV+kSbgFAZlOrv1Hqbf0INGQgiKf9k= github.com/ipfs/go-ipld-format v0.0.2/go.mod h1:4B6+FM2u9OJ9zCV+kSbgFAZlOrv1Hqbf0INGQgiKf9k=
github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM=
github.com/ipfs/go-log v0.0.2-0.20190920042044-a609c1ae5144 h1:5WM8S1nwquWQ3zEuNhK82NE5Di6Pd41qz9JxxvxTAIA= github.com/ipfs/go-log v1.0.0 h1:BW3LQIiZzpNyolt84yvKNCd3FU+AK4VDw1hnHR+1aiI=
github.com/ipfs/go-log v0.0.2-0.20190920042044-a609c1ae5144/go.mod h1:azGN5dH7ailfREknDDNYB0Eq4qZ/4I4Y3gO0ivjJNyM= github.com/ipfs/go-log v1.0.0/go.mod h1:JO7RzlMK6rA+CIxFMLOuB6Wf5b81GDiKElL7UPSIKjA=
github.com/ipfs/go-merkledag v0.1.0/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB3ClKnBAlk= github.com/ipfs/go-merkledag v0.1.0/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB3ClKnBAlk=
github.com/ipfs/go-merkledag v0.2.3/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB3ClKnBAlk= github.com/ipfs/go-merkledag v0.2.3/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB3ClKnBAlk=
github.com/ipfs/go-merkledag v0.2.4 h1:ZSHQSe9BENfixUjT+MaLeHEeZGxrZQfgo3KT3SLosF8= github.com/ipfs/go-merkledag v0.2.4 h1:ZSHQSe9BENfixUjT+MaLeHEeZGxrZQfgo3KT3SLosF8=
@ -265,6 +272,7 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0= github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@ -298,6 +306,8 @@ github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3Pt
github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro= github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro=
github.com/libp2p/go-libp2p-blankhost v0.1.3 h1:0KycuXvPDhmehw0ASsg+s1o3IfXgCUDqfzAl94KEBOg= github.com/libp2p/go-libp2p-blankhost v0.1.3 h1:0KycuXvPDhmehw0ASsg+s1o3IfXgCUDqfzAl94KEBOg=
github.com/libp2p/go-libp2p-blankhost v0.1.3/go.mod h1:KML1//wiKR8vuuJO0y3LUd1uLv+tlkGTAr3jC0S5cLg= github.com/libp2p/go-libp2p-blankhost v0.1.3/go.mod h1:KML1//wiKR8vuuJO0y3LUd1uLv+tlkGTAr3jC0S5cLg=
github.com/libp2p/go-libp2p-blankhost v0.1.4 h1:I96SWjR4rK9irDHcHq3XHN6hawCRTPUADzkJacgZLvk=
github.com/libp2p/go-libp2p-blankhost v0.1.4/go.mod h1:oJF0saYsAXQCSfDq254GMNmLNz6ZTHTOvtF4ZydUvwU=
github.com/libp2p/go-libp2p-circuit v0.1.0/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8= github.com/libp2p/go-libp2p-circuit v0.1.0/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8=
github.com/libp2p/go-libp2p-circuit v0.1.1 h1:eopfG9fAg6rEHWQO1TSrLosXDgYbbbu/RTva/tBANus= github.com/libp2p/go-libp2p-circuit v0.1.1 h1:eopfG9fAg6rEHWQO1TSrLosXDgYbbbu/RTva/tBANus=
github.com/libp2p/go-libp2p-circuit v0.1.1/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8= github.com/libp2p/go-libp2p-circuit v0.1.1/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8=
@ -311,11 +321,15 @@ github.com/libp2p/go-libp2p-core v0.0.6/go.mod h1:0d9xmaYAVY5qmbp/fcgxHT3ZJsLjYe
github.com/libp2p/go-libp2p-core v0.2.0/go.mod h1:X0eyB0Gy93v0DZtSYbEM7RnMChm9Uv3j7yRXjO77xSI= github.com/libp2p/go-libp2p-core v0.2.0/go.mod h1:X0eyB0Gy93v0DZtSYbEM7RnMChm9Uv3j7yRXjO77xSI=
github.com/libp2p/go-libp2p-core v0.2.2 h1:Sv1ggdoMx9c7v7FOFkR7agraHCnAgqYsXrU1ARSRUMs= github.com/libp2p/go-libp2p-core v0.2.2 h1:Sv1ggdoMx9c7v7FOFkR7agraHCnAgqYsXrU1ARSRUMs=
github.com/libp2p/go-libp2p-core v0.2.2/go.mod h1:8fcwTbsG2B+lTgRJ1ICZtiM5GWCWZVoVrLaDRvIRng0= github.com/libp2p/go-libp2p-core v0.2.2/go.mod h1:8fcwTbsG2B+lTgRJ1ICZtiM5GWCWZVoVrLaDRvIRng0=
github.com/libp2p/go-libp2p-core v0.2.4 h1:Et6ykkTwI6PU44tr8qUF9k43vP0aduMNniShAbUJJw8=
github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g=
github.com/libp2p/go-libp2p-crypto v0.0.1/go.mod h1:yJkNyDmO341d5wwXxDUGO0LykUVT72ImHNUqh5D/dBE= github.com/libp2p/go-libp2p-crypto v0.0.1/go.mod h1:yJkNyDmO341d5wwXxDUGO0LykUVT72ImHNUqh5D/dBE=
github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ=
github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI=
github.com/libp2p/go-libp2p-discovery v0.1.0 h1:j+R6cokKcGbnZLf4kcNwpx6mDEUPF3N6SrqMymQhmvs= github.com/libp2p/go-libp2p-discovery v0.1.0 h1:j+R6cokKcGbnZLf4kcNwpx6mDEUPF3N6SrqMymQhmvs=
github.com/libp2p/go-libp2p-discovery v0.1.0/go.mod h1:4F/x+aldVHjHDHuX85x1zWoFTGElt8HnoDzwkFZm29g= github.com/libp2p/go-libp2p-discovery v0.1.0/go.mod h1:4F/x+aldVHjHDHuX85x1zWoFTGElt8HnoDzwkFZm29g=
github.com/libp2p/go-libp2p-discovery v0.2.0 h1:1p3YSOq7VsgaL+xVHPi8XAmtGyas6D2J6rWBEfz/aiY=
github.com/libp2p/go-libp2p-discovery v0.2.0/go.mod h1:s4VGaxYMbw4+4+tsoQTqh7wfxg97AEdo4GYBt6BadWg=
github.com/libp2p/go-libp2p-host v0.0.1/go.mod h1:qWd+H1yuU0m5CwzAkvbSjqKairayEHdR5MMl7Cwa7Go= github.com/libp2p/go-libp2p-host v0.0.1/go.mod h1:qWd+H1yuU0m5CwzAkvbSjqKairayEHdR5MMl7Cwa7Go=
github.com/libp2p/go-libp2p-host v0.1.0 h1:OZwENiFm6JOK3YR5PZJxkXlJE8a5u8g4YvAUrEV2MjM= github.com/libp2p/go-libp2p-host v0.1.0 h1:OZwENiFm6JOK3YR5PZJxkXlJE8a5u8g4YvAUrEV2MjM=
github.com/libp2p/go-libp2p-host v0.1.0/go.mod h1:5+fWuLbDn8OxoxPN3CV0vsLe1hAKScSMbT84qRfxum8= github.com/libp2p/go-libp2p-host v0.1.0/go.mod h1:5+fWuLbDn8OxoxPN3CV0vsLe1hAKScSMbT84qRfxum8=
@ -348,8 +362,8 @@ github.com/libp2p/go-libp2p-pnet v0.1.0/go.mod h1:ZkyZw3d0ZFOex71halXRihWf9WH/j3
github.com/libp2p/go-libp2p-protocol v0.0.1/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1VZNHYcK8cLgFJLZ4s= github.com/libp2p/go-libp2p-protocol v0.0.1/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1VZNHYcK8cLgFJLZ4s=
github.com/libp2p/go-libp2p-protocol v0.1.0 h1:HdqhEyhg0ToCaxgMhnOmUO8snQtt/kQlcjVk3UoJU3c= github.com/libp2p/go-libp2p-protocol v0.1.0 h1:HdqhEyhg0ToCaxgMhnOmUO8snQtt/kQlcjVk3UoJU3c=
github.com/libp2p/go-libp2p-protocol v0.1.0/go.mod h1:KQPHpAabB57XQxGrXCNvbL6UEXfQqUgC/1adR2Xtflk= github.com/libp2p/go-libp2p-protocol v0.1.0/go.mod h1:KQPHpAabB57XQxGrXCNvbL6UEXfQqUgC/1adR2Xtflk=
github.com/libp2p/go-libp2p-pubsub v0.1.0 h1:SmQeMa7IUv5vadh0fYgYsafWCBA1sCy5d/68kIYqGcU= github.com/libp2p/go-libp2p-pubsub v0.2.3 h1:qJRnRnM7Z4xnHb4i6EBb3DKQXRPgtFWlKP4AmfJudLQ=
github.com/libp2p/go-libp2p-pubsub v0.1.0/go.mod h1:ZwlKzRSe1eGvSIdU5bD7+8RZN/Uzw0t1Bp9R1znpR/Q= github.com/libp2p/go-libp2p-pubsub v0.2.3/go.mod h1:Jscj3fk23R5mCrOwb625xjVs5ZEyTZcx/OlTwMDqU+g=
github.com/libp2p/go-libp2p-quic-transport v0.1.1 h1:MFMJzvsxIEDEVKzO89BnB/FgvMj9WI4GDGUW2ArDPUA= github.com/libp2p/go-libp2p-quic-transport v0.1.1 h1:MFMJzvsxIEDEVKzO89BnB/FgvMj9WI4GDGUW2ArDPUA=
github.com/libp2p/go-libp2p-quic-transport v0.1.1/go.mod h1:wqG/jzhF3Pu2NrhJEvE+IE0NTHNXslOPn9JQzyCAxzU= github.com/libp2p/go-libp2p-quic-transport v0.1.1/go.mod h1:wqG/jzhF3Pu2NrhJEvE+IE0NTHNXslOPn9JQzyCAxzU=
github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q=
@ -365,8 +379,8 @@ github.com/libp2p/go-libp2p-secio v0.2.0 h1:ywzZBsWEEz2KNTn5RtzauEDq5RFEefPsttXY
github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g= github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g=
github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4= github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4=
github.com/libp2p/go-libp2p-swarm v0.2.0/go.mod h1:x07b4zkMFo2EvgPV2bMTlNmdQc8i+74Jjio7xGvsTgU= github.com/libp2p/go-libp2p-swarm v0.2.0/go.mod h1:x07b4zkMFo2EvgPV2bMTlNmdQc8i+74Jjio7xGvsTgU=
github.com/libp2p/go-libp2p-swarm v0.2.1 h1:9A8oQqPIZvbaRyrjViHeDYS7fE7fNtP7BRWdJrBHbe8= github.com/libp2p/go-libp2p-swarm v0.2.2 h1:T4hUpgEs2r371PweU3DuH7EOmBIdTBCwWs+FLcgx3bQ=
github.com/libp2p/go-libp2p-swarm v0.2.1/go.mod h1:x07b4zkMFo2EvgPV2bMTlNmdQc8i+74Jjio7xGvsTgU= github.com/libp2p/go-libp2p-swarm v0.2.2/go.mod h1:fvmtQ0T1nErXym1/aa1uJEyN7JzaTNyBcHImCxRpPKU=
github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E=
github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E=
github.com/libp2p/go-libp2p-testing v0.0.4/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.0.4/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E=
@ -394,6 +408,8 @@ github.com/libp2p/go-nat v0.0.3 h1:l6fKV+p0Xa354EqQOQP+d8CivdLM4kl5GxC1hSc/UeI=
github.com/libp2p/go-nat v0.0.3/go.mod h1:88nUEt0k0JD45Bk93NIwDqjlhiOwOoV36GchpcVc1yI= github.com/libp2p/go-nat v0.0.3/go.mod h1:88nUEt0k0JD45Bk93NIwDqjlhiOwOoV36GchpcVc1yI=
github.com/libp2p/go-openssl v0.0.2 h1:9pP2d3Ubaxkv7ZisLjx9BFwgOGnQdQYnfcH29HNY3ls= github.com/libp2p/go-openssl v0.0.2 h1:9pP2d3Ubaxkv7ZisLjx9BFwgOGnQdQYnfcH29HNY3ls=
github.com/libp2p/go-openssl v0.0.2/go.mod h1:v8Zw2ijCSWBQi8Pq5GAixw6DbFfa9u6VIYDXnvOXkc0= github.com/libp2p/go-openssl v0.0.2/go.mod h1:v8Zw2ijCSWBQi8Pq5GAixw6DbFfa9u6VIYDXnvOXkc0=
github.com/libp2p/go-openssl v0.0.3 h1:wjlG7HvQkt4Fq4cfH33Ivpwp0omaElYEi9z26qaIkIk=
github.com/libp2p/go-openssl v0.0.3/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc=
github.com/libp2p/go-reuseport v0.0.1 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FWpFLw= github.com/libp2p/go-reuseport v0.0.1 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FWpFLw=
github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA=
github.com/libp2p/go-reuseport-transport v0.0.2 h1:WglMwyXyBu61CMkjCCtnmqNqnjib0GIEjMiHTwR/KN4= github.com/libp2p/go-reuseport-transport v0.0.2 h1:WglMwyXyBu61CMkjCCtnmqNqnjib0GIEjMiHTwR/KN4=
@ -403,9 +419,13 @@ github.com/libp2p/go-stream-muxer-multistream v0.2.0 h1:714bRJ4Zy9mdhyTLJ+ZKiROm
github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc= github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc=
github.com/libp2p/go-tcp-transport v0.1.0 h1:IGhowvEqyMFknOar4FWCKSWE0zL36UFKQtiRQD60/8o= github.com/libp2p/go-tcp-transport v0.1.0 h1:IGhowvEqyMFknOar4FWCKSWE0zL36UFKQtiRQD60/8o=
github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc= github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc=
github.com/libp2p/go-tcp-transport v0.1.1 h1:yGlqURmqgNA2fvzjSgZNlHcsd/IulAnKM8Ncu+vlqnw=
github.com/libp2p/go-tcp-transport v0.1.1/go.mod h1:3HzGvLbx6etZjnFlERyakbaYPdfjg2pWP97dFZworkY=
github.com/libp2p/go-testutil v0.1.0/go.mod h1:81b2n5HypcVyrCg/MJx4Wgfp/VHojytjVe/gLzZ2Ehc= github.com/libp2p/go-testutil v0.1.0/go.mod h1:81b2n5HypcVyrCg/MJx4Wgfp/VHojytjVe/gLzZ2Ehc=
github.com/libp2p/go-ws-transport v0.1.0 h1:F+0OvvdmPTDsVc4AjPHjV7L7Pk1B7D5QwtDcKE2oag4= github.com/libp2p/go-ws-transport v0.1.0 h1:F+0OvvdmPTDsVc4AjPHjV7L7Pk1B7D5QwtDcKE2oag4=
github.com/libp2p/go-ws-transport v0.1.0/go.mod h1:rjw1MG1LU9YDC6gzmwObkPd/Sqwhw7yT74kj3raBFuo= github.com/libp2p/go-ws-transport v0.1.0/go.mod h1:rjw1MG1LU9YDC6gzmwObkPd/Sqwhw7yT74kj3raBFuo=
github.com/libp2p/go-ws-transport v0.1.2 h1:VnxQcLfSGtqupqPpBNu8fUiCv+IN1RJ2BcVqQEM+z8E=
github.com/libp2p/go-ws-transport v0.1.2/go.mod h1:dsh2Ld8F+XNmzpkaAijmg5Is+e9l6/1tK/6VFOdN69Y=
github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow=
github.com/libp2p/go-yamux v1.2.3 h1:xX8A36vpXb59frIzWFdEgptLMsOANMFq2K7fPRlunYI= github.com/libp2p/go-yamux v1.2.3 h1:xX8A36vpXb59frIzWFdEgptLMsOANMFq2K7fPRlunYI=
github.com/libp2p/go-yamux v1.2.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= github.com/libp2p/go-yamux v1.2.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow=
@ -417,9 +437,8 @@ github.com/marten-seemann/qtls v0.2.3 h1:0yWJ43C62LsZt08vuQJDK1uC1czUc3FJeCLPoNA
github.com/marten-seemann/qtls v0.2.3/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk= github.com/marten-seemann/qtls v0.2.3/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
@ -441,6 +460,8 @@ github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+
github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U=
github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771 h1:MHkK1uRtFbVqvAgvWxafZe54+5uBxLluGylDiKgdhwo= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771 h1:MHkK1uRtFbVqvAgvWxafZe54+5uBxLluGylDiKgdhwo=
github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU=
github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
@ -454,18 +475,26 @@ github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lg
github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44=
github.com/multiformats/go-multiaddr v0.0.4 h1:WgMSI84/eRLdbptXMkMWDXPjPq7SPLIgGUVm2eroyU4= github.com/multiformats/go-multiaddr v0.0.4 h1:WgMSI84/eRLdbptXMkMWDXPjPq7SPLIgGUVm2eroyU4=
github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44=
github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44=
github.com/multiformats/go-multiaddr v0.1.1 h1:rVAztJYMhCQ7vEFr8FvxW3mS+HF2eY/oPbOMeS0ZDnE=
github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo=
github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q=
github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q=
github.com/multiformats/go-multiaddr-dns v0.0.3 h1:P19q/k9jwmtgh+qXFkKfgFM7rCg/9l5AVqh7VNxSXhs= github.com/multiformats/go-multiaddr-dns v0.2.0 h1:YWJoIDwLePniH7OU5hBnDZV6SWuvJqJ0YtN6pLeH9zA=
github.com/multiformats/go-multiaddr-dns v0.0.3/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= github.com/multiformats/go-multiaddr-dns v0.2.0/go.mod h1:TJ5pr5bBO7Y1B18djPuRsVkduhQH2YqYSbxWJzYGdK0=
github.com/multiformats/go-multiaddr-fmt v0.0.1 h1:5YjeOIzbX8OTKVaN72aOzGIYW7PnrZrnkDyOfAWRSMA= github.com/multiformats/go-multiaddr-fmt v0.0.1 h1:5YjeOIzbX8OTKVaN72aOzGIYW7PnrZrnkDyOfAWRSMA=
github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q= github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q=
github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E=
github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo=
github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g= github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g=
github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU=
github.com/multiformats/go-multiaddr-net v0.1.0 h1:ZepO8Ezwovd+7b5XPPDhQhayk1yt0AJpzQBpq9fejx4=
github.com/multiformats/go-multiaddr-net v0.1.0/go.mod h1:5JNbcfBOP4dnhoZOv10JJVkJO0pCCEf8mTnipAo2UZQ=
github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA=
github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs=
github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U=
github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po=
github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew=
github.com/multiformats/go-multihash v0.0.9 h1:aoijQXYYl7Xtb2pUUP68R+ys1TlnlR3eX6wmozr0Hp4= github.com/multiformats/go-multihash v0.0.9 h1:aoijQXYYl7Xtb2pUUP68R+ys1TlnlR3eX6wmozr0Hp4=
github.com/multiformats/go-multihash v0.0.9/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.0.9/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew=
github.com/multiformats/go-multistream v0.0.1/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= github.com/multiformats/go-multistream v0.0.1/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg=
@ -540,6 +569,7 @@ github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJy
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
@ -581,8 +611,8 @@ github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7V
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= go.opencensus.io v0.22.1 h1:8dP3SGL7MPB94crU3bEPplMPe83FI4EouesJUeFHv50=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA=
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/dig v1.7.0 h1:E5/L92iQTNJTjfgJF2KgU+/JpMaiuvK2DHLBj0+kSZk= go.uber.org/dig v1.7.0 h1:E5/L92iQTNJTjfgJF2KgU+/JpMaiuvK2DHLBj0+kSZk=
@ -611,8 +641,8 @@ golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 h1:Gv7RPwsi3eZ2Fgewe3CBsuOebPwO27PoXzRpJPsvSSM= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@ -632,13 +662,11 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -668,9 +696,8 @@ golang.org/x/sys v0.0.0-20190526052359-791d8a0f4d09/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456 h1:ng0gs1AKnRRuEMZoTLLlbOd+C17zUDepwGQBb/n+JVg=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69 h1:rOhMmluY6kLMhdnrivzec6lLgaVbMHMn2ISQXJeJ5EM=
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
@ -681,6 +708,7 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181130052023-1c3d964395ce/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181130052023-1c3d964395ce/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@ -691,6 +719,8 @@ golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBn
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
google.golang.org/api v0.3.2/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.3.2/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
@ -710,6 +740,7 @@ google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@ -724,6 +755,7 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD
gopkg.in/urfave/cli.v2 v2.0.0-20180128182452-d3ae77c26ac8 h1:Ggy3mWN4l3PUFPfSG0YB3n5fVYggzysUmiUQ89SnX6Y= gopkg.in/urfave/cli.v2 v2.0.0-20180128182452-d3ae77c26ac8 h1:Ggy3mWN4l3PUFPfSG0YB3n5fVYggzysUmiUQ89SnX6Y=
gopkg.in/urfave/cli.v2 v2.0.0-20180128182452-d3ae77c26ac8/go.mod h1:cKXr3E0k4aosgycml1b5z33BVV6hai1Kh7uDgFOkbcs= gopkg.in/urfave/cli.v2 v2.0.0-20180128182452-d3ae77c26ac8/go.mod h1:cKXr3E0k4aosgycml1b5z33BVV6hai1Kh7uDgFOkbcs=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@ -4,7 +4,7 @@ import (
"io" "io"
"math/bits" "math/bits"
sectorbuilder "github.com/filecoin-project/go-sectorbuilder" sectorbuilder "github.com/filecoin-project/filecoin-ffi"
) )
func PaddedSize(size uint64) uint64 { func PaddedSize(size uint64) uint64 {

View File

@ -1,8 +1,9 @@
package padreader package padreader
import ( import (
"gotest.tools/assert"
"testing" "testing"
"gotest.tools/assert"
) )
func TestComputePaddedSize(t *testing.T) { func TestComputePaddedSize(t *testing.T) {

View File

@ -17,8 +17,6 @@ func TempSectorbuilder(sectorSize uint64, ds dtypes.MetadataDS) (*SectorBuilder,
sb, err := TempSectorbuilderDir(dir, sectorSize, ds) sb, err := TempSectorbuilderDir(dir, sectorSize, ds)
return sb, func() { return sb, func() {
sb.Destroy()
if err := os.RemoveAll(dir); err != nil { if err := os.RemoveAll(dir); err != nil {
log.Warn("failed to clean up temp sectorbuilder: ", err) log.Warn("failed to clean up temp sectorbuilder: ", err)
} }

View File

@ -0,0 +1 @@
package sectorbuilder

View File

@ -7,13 +7,13 @@ import (
"strconv" "strconv"
"sync" "sync"
"sync/atomic" "sync/atomic"
"unsafe"
sectorbuilder "github.com/filecoin-project/go-sectorbuilder" sectorbuilder "github.com/filecoin-project/filecoin-ffi"
"github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore"
logging "github.com/ipfs/go-log" logging "github.com/ipfs/go-log"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/node/modules/dtypes"
) )
@ -21,17 +21,12 @@ import (
const PoStReservedWorkers = 1 const PoStReservedWorkers = 1
const PoRepProofPartitions = 2 const PoRepProofPartitions = 2
var lastSectorIdKey = datastore.NewKey("/sectorbuilder/last") var LastSectorIdKey = datastore.NewKey("/sectorbuilder/last")
var log = logging.Logger("sectorbuilder") var log = logging.Logger("sectorbuilder")
type SectorSealingStatus = sectorbuilder.SectorSealingStatus type SortedPublicSectorInfo = sectorbuilder.SortedPublicSectorInfo
type SortedPrivateSectorInfo = sectorbuilder.SortedPrivateSectorInfo
type StagedSectorMetadata = sectorbuilder.StagedSectorMetadata
type SortedSectorInfo = sectorbuilder.SortedSectorInfo
type SectorInfo = sectorbuilder.SectorInfo
type SealTicket = sectorbuilder.SealTicket type SealTicket = sectorbuilder.SealTicket
@ -45,14 +40,16 @@ type PublicPieceInfo = sectorbuilder.PublicPieceInfo
type RawSealPreCommitOutput sectorbuilder.RawSealPreCommitOutput type RawSealPreCommitOutput sectorbuilder.RawSealPreCommitOutput
type EPostCandidate = sectorbuilder.Candidate
const CommLen = sectorbuilder.CommitmentBytesLen const CommLen = sectorbuilder.CommitmentBytesLen
type SectorBuilder struct { type SectorBuilder struct {
handle unsafe.Pointer ds dtypes.MetadataDS
ds dtypes.MetadataDS idLk sync.Mutex
idLk sync.Mutex
ssize uint64 ssize uint64
lastID uint64
Miner address.Address Miner address.Address
@ -130,8 +127,6 @@ func New(cfg *Config, ds dtypes.MetadataDS) (*SectorBuilder, error) {
return nil, xerrors.Errorf("minimum worker threads is %d, specified %d", PoStReservedWorkers, cfg.WorkerThreads) return nil, xerrors.Errorf("minimum worker threads is %d, specified %d", PoStReservedWorkers, cfg.WorkerThreads)
} }
proverId := addressToProverID(cfg.Miner)
for _, dir := range []string{cfg.StagedDir, cfg.SealedDir, cfg.CacheDir, cfg.MetadataDir} { for _, dir := range []string{cfg.StagedDir, cfg.SealedDir, cfg.CacheDir, cfg.MetadataDir} {
if err := os.Mkdir(dir, 0755); err != nil { if err := os.Mkdir(dir, 0755); err != nil {
if os.IsExist(err) { if os.IsExist(err) {
@ -142,7 +137,7 @@ func New(cfg *Config, ds dtypes.MetadataDS) (*SectorBuilder, error) {
} }
var lastUsedID uint64 var lastUsedID uint64
b, err := ds.Get(lastSectorIdKey) b, err := ds.Get(LastSectorIdKey)
switch err { switch err {
case nil: case nil:
i, err := strconv.ParseInt(string(b), 10, 64) i, err := strconv.ParseInt(string(b), 10, 64)
@ -155,11 +150,6 @@ func New(cfg *Config, ds dtypes.MetadataDS) (*SectorBuilder, error) {
return nil, err return nil, err
} }
sbp, err := sectorbuilder.InitSectorBuilder(cfg.SectorSize, PoRepProofPartitions, lastUsedID, cfg.MetadataDir, proverId, cfg.SealedDir, cfg.StagedDir, cfg.CacheDir, 16, cfg.WorkerThreads)
if err != nil {
return nil, err
}
rlimit := cfg.WorkerThreads - PoStReservedWorkers rlimit := cfg.WorkerThreads - PoStReservedWorkers
sealLocal := rlimit > 0 sealLocal := rlimit > 0
@ -169,10 +159,10 @@ func New(cfg *Config, ds dtypes.MetadataDS) (*SectorBuilder, error) {
} }
sb := &SectorBuilder{ sb := &SectorBuilder{
handle: sbp, ds: ds,
ds: ds,
ssize: cfg.SectorSize, ssize: cfg.SectorSize,
lastID: lastUsedID,
stagedDir: cfg.StagedDir, stagedDir: cfg.StagedDir,
sealedDir: cfg.SealedDir, sealedDir: cfg.SealedDir,
@ -205,9 +195,10 @@ func NewStandalone(cfg *Config) (*SectorBuilder, error) {
} }
return &SectorBuilder{ return &SectorBuilder{
handle: nil,
ds: nil, ds: nil,
ssize: cfg.SectorSize, ssize: cfg.SectorSize,
Miner: cfg.Miner, Miner: cfg.Miner,
stagedDir: cfg.StagedDir, stagedDir: cfg.StagedDir,
sealedDir: cfg.SealedDir, sealedDir: cfg.SealedDir,
@ -272,19 +263,14 @@ func addressToProverID(a address.Address) [32]byte {
return proverId return proverId
} }
func (sb *SectorBuilder) Destroy() {
sectorbuilder.DestroySectorBuilder(sb.handle)
}
func (sb *SectorBuilder) AcquireSectorId() (uint64, error) { func (sb *SectorBuilder) AcquireSectorId() (uint64, error) {
sb.idLk.Lock() sb.idLk.Lock()
defer sb.idLk.Unlock() defer sb.idLk.Unlock()
id, err := sectorbuilder.AcquireSectorId(sb.handle) sb.lastID++
if err != nil { id := sb.lastID
return 0, err
} err := sb.ds.Put(LastSectorIdKey, []byte(fmt.Sprint(id)))
err = sb.ds.Put(lastSectorIdKey, []byte(fmt.Sprint(id)))
if err != nil { if err != nil {
return 0, err return 0, err
} }
@ -305,7 +291,7 @@ func (sb *SectorBuilder) AddPiece(pieceSize uint64, sectorId uint64, file io.Rea
return PublicPieceInfo{}, err return PublicPieceInfo{}, err
} }
_, _, commP, err := sectorbuilder.StandaloneWriteWithAlignment(f, pieceSize, stagedFile, existingPieceSizes) _, _, commP, err := sectorbuilder.WriteWithAlignment(f, pieceSize, stagedFile, existingPieceSizes)
if err != nil { if err != nil {
return PublicPieceInfo{}, err return PublicPieceInfo{}, err
} }
@ -329,7 +315,8 @@ func (sb *SectorBuilder) ReadPieceFromSealedSector(pieceKey string) ([]byte, err
ret := sb.RateLimit() ret := sb.RateLimit()
defer ret() defer ret()
return sectorbuilder.ReadPieceFromSealedSector(sb.handle, pieceKey) panic("fixme")
//return sectorbuilder.Unseal(sb.handle, pieceKey)
} }
func (sb *SectorBuilder) sealPreCommitRemote(call workerCall) (RawSealPreCommitOutput, error) { func (sb *SectorBuilder) sealPreCommitRemote(call workerCall) (RawSealPreCommitOutput, error) {
@ -394,7 +381,7 @@ func (sb *SectorBuilder) SealPreCommit(sectorID uint64, ticket SealTicket, piece
stagedPath := sb.StagedSectorPath(sectorID) stagedPath := sb.StagedSectorPath(sectorID)
rspco, err := sectorbuilder.StandaloneSealPreCommit( rspco, err := sectorbuilder.SealPreCommit(
sb.ssize, sb.ssize,
PoRepProofPartitions, PoRepProofPartitions,
cacheDir, cacheDir,
@ -431,7 +418,7 @@ func (sb *SectorBuilder) sealCommitLocal(sectorID uint64, ticket SealTicket, see
return nil, err return nil, err
} }
proof, err = sectorbuilder.StandaloneSealCommit( proof, err = sectorbuilder.SealCommit(
sb.ssize, sb.ssize,
PoRepProofPartitions, PoRepProofPartitions,
cacheDir, cacheDir,
@ -452,7 +439,7 @@ func (sb *SectorBuilder) sealCommitLocal(sectorID uint64, ticket SealTicket, see
return proof, nil return proof, nil
} }
func (sb *SectorBuilder) SealCommit(sectorID uint64, ticket SealTicket, seed SealSeed, pieces []PublicPieceInfo, pieceKeys []string, rspco RawSealPreCommitOutput) (proof []byte, err error) { func (sb *SectorBuilder) SealCommit(sectorID uint64, ticket SealTicket, seed SealSeed, pieces []PublicPieceInfo, rspco RawSealPreCommitOutput) (proof []byte, err error) {
call := workerCall{ call := workerCall{
task: WorkerTask{ task: WorkerTask{
Type: WorkerCommit, Type: WorkerCommit,
@ -484,49 +471,91 @@ func (sb *SectorBuilder) SealCommit(sectorID uint64, ticket SealTicket, seed Sea
return nil, xerrors.Errorf("commit: %w", err) return nil, xerrors.Errorf("commit: %w", err)
} }
if pieceKeys == nil {
return
}
pmeta := make([]sectorbuilder.PieceMetadata, len(pieces))
for i, piece := range pieces {
pmeta[i] = sectorbuilder.PieceMetadata{
Key: pieceKeys[i],
Size: piece.Size,
CommP: piece.CommP,
}
}
sealedPath, err := sb.SealedSectorPath(sectorID)
if err != nil {
return nil, err
}
cacheDir, err := sb.sectorCacheDir(sectorID)
if err != nil {
return nil, err
}
err = sectorbuilder.ImportSealedSector(
sb.handle,
sectorID,
cacheDir,
sealedPath,
ticket,
seed,
rspco.CommR,
rspco.CommD,
rspco.CommC,
rspco.CommRLast,
proof,
pmeta,
)
if err != nil {
return nil, xerrors.Errorf("ImportSealedSector: %w", err)
}
return proof, nil return proof, nil
} }
func (sb *SectorBuilder) ComputeElectionPoSt(sectorInfo SortedPublicSectorInfo, challengeSeed []byte, winners []EPostCandidate) ([]byte, error) {
if len(challengeSeed) != CommLen {
return nil, xerrors.Errorf("given challenge seed was the wrong length: %d != %d", len(challengeSeed), CommLen)
}
var cseed [CommLen]byte
copy(cseed[:], challengeSeed)
privsects, err := sb.pubSectorToPriv(sectorInfo)
if err != nil {
return nil, err
}
proverID := addressToProverID(sb.Miner)
return sectorbuilder.GeneratePoSt(sb.ssize, proverID, privsects, cseed, winners)
}
func (sb *SectorBuilder) GenerateEPostCandidates(sectorInfo SortedPublicSectorInfo, challengeSeed [CommLen]byte, faults []uint64) ([]EPostCandidate, error) {
privsectors, err := sb.pubSectorToPriv(sectorInfo)
if err != nil {
return nil, err
}
challengeCount := electionPostChallengeCount(uint64(len(sectorInfo.Values())))
proverID := addressToProverID(sb.Miner)
return sectorbuilder.GenerateCandidates(sb.ssize, proverID, challengeSeed, challengeCount, privsectors)
}
func (sb *SectorBuilder) pubSectorToPriv(sectorInfo SortedPublicSectorInfo) (SortedPrivateSectorInfo, error) {
var out []sectorbuilder.PrivateSectorInfo
for _, s := range sectorInfo.Values() {
cachePath, err := sb.sectorCacheDir(s.SectorID)
if err != nil {
return SortedPrivateSectorInfo{}, xerrors.Errorf("getting cache path for sector %d: %w", s.SectorID, err)
}
sealedPath, err := sb.SealedSectorPath(s.SectorID)
if err != nil {
return SortedPrivateSectorInfo{}, xerrors.Errorf("getting sealed path for sector %d: %w", s.SectorID, err)
}
out = append(out, sectorbuilder.PrivateSectorInfo{
SectorID: s.SectorID,
CommR: s.CommR,
CacheDirPath: cachePath,
SealedSectorPath: sealedPath,
})
}
return NewSortedPrivateSectorInfo(out), nil
}
func (sb *SectorBuilder) GenerateFallbackPoSt(sectorInfo SortedPublicSectorInfo, challengeSeed [CommLen]byte, faults []uint64) ([]EPostCandidate, []byte, error) {
privsectors, err := sb.pubSectorToPriv(sectorInfo)
if err != nil {
return nil, nil, err
}
challengeCount := fallbackPostChallengeCount(uint64(len(sectorInfo.Values())))
proverID := addressToProverID(sb.Miner)
candidates, err := sectorbuilder.GenerateCandidates(sb.ssize, proverID, challengeSeed, challengeCount, privsectors)
if err != nil {
return nil, nil, err
}
proof, err := sectorbuilder.GeneratePoSt(sb.ssize, proverID, privsectors, challengeSeed, candidates)
return candidates, proof, err
}
func (sb *SectorBuilder) Stop() { func (sb *SectorBuilder) Stop() {
close(sb.stopping) close(sb.stopping)
} }
func electionPostChallengeCount(sectors uint64) uint64 {
// ceil(sectors / build.SectorChallengeRatioDiv)
return (sectors + build.SectorChallengeRatioDiv - 1) / build.SectorChallengeRatioDiv
}
func fallbackPostChallengeCount(sectors uint64) uint64 {
challengeCount := electionPostChallengeCount(sectors)
if challengeCount > build.MaxFallbackPostChallengeCount {
return build.MaxFallbackPostChallengeCount
}
return challengeCount
}

View File

@ -2,6 +2,7 @@ package sectorbuilder_test
import ( import (
"context" "context"
"fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"math/rand" "math/rand"
@ -15,6 +16,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
ffi "github.com/filecoin-project/filecoin-ffi"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/lib/sectorbuilder" "github.com/filecoin-project/lotus/lib/sectorbuilder"
) )
@ -59,7 +61,7 @@ func (s *seal) commit(t *testing.T, sb *sectorbuilder.SectorBuilder, done func()
TicketBytes: [32]byte{0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 9, 8, 7, 6, 45, 3, 2, 1, 0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 9}, TicketBytes: [32]byte{0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 9, 8, 7, 6, 45, 3, 2, 1, 0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 9},
} }
proof, err := sb.SealCommit(s.sid, s.ticket, seed, []sectorbuilder.PublicPieceInfo{s.ppi}, []string{"foo"}, s.pco) proof, err := sb.SealCommit(s.sid, s.ticket, seed, []sectorbuilder.PublicPieceInfo{s.ppi}, s.pco)
if err != nil { if err != nil {
t.Fatalf("%+v", err) t.Fatalf("%+v", err)
} }
@ -76,26 +78,44 @@ func (s *seal) commit(t *testing.T, sb *sectorbuilder.SectorBuilder, done func()
done() done()
} }
func (s *seal) post(t *testing.T, sb *sectorbuilder.SectorBuilder) { func post(t *testing.T, sb *sectorbuilder.SectorBuilder, seals ...seal) time.Time {
cSeed := [32]byte{0, 9, 2, 7, 6, 5, 4, 3, 2, 1, 0, 9, 8, 7, 6, 45, 3, 2, 1, 0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 9} cSeed := [32]byte{0, 9, 2, 7, 6, 5, 4, 3, 2, 1, 0, 9, 8, 7, 6, 45, 3, 2, 1, 0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 9}
ssi := sectorbuilder.NewSortedSectorInfo([]sectorbuilder.SectorInfo{{ ppi := make([]ffi.PublicSectorInfo, len(seals))
SectorID: s.sid, for i, s := range seals {
CommR: s.pco.CommR, ppi[i] = ffi.PublicSectorInfo{
}}) SectorID: s.sid,
CommR: s.pco.CommR,
}
}
postProof, err := sb.GeneratePoSt(ssi, cSeed, []uint64{}) ssi := sectorbuilder.NewSortedPublicSectorInfo(ppi)
candndates, err := sb.GenerateEPostCandidates(ssi, cSeed, []uint64{})
if err != nil { if err != nil {
t.Fatalf("%+v", err) t.Fatalf("%+v", err)
} }
ok, err := sectorbuilder.VerifyPost(context.TODO(), sb.SectorSize(), ssi, cSeed, postProof, []uint64{}) genCandidates := time.Now()
if len(candndates) != 1 {
t.Fatal("expected 1 candidate")
}
postProof, err := sb.ComputeElectionPoSt(ssi, cSeed[:], candndates)
if err != nil {
t.Fatalf("%+v", err)
}
ok, err := sectorbuilder.VerifyElectionPost(context.TODO(), sb.SectorSize(), ssi, cSeed[:], postProof, candndates, sb.Miner)
if err != nil { if err != nil {
t.Fatalf("%+v", err) t.Fatalf("%+v", err)
} }
if !ok { if !ok {
t.Fatal("bad post") t.Fatal("bad post")
} }
return genCandidates
} }
func TestSealAndVerify(t *testing.T) { func TestSealAndVerify(t *testing.T) {
@ -123,7 +143,10 @@ func TestSealAndVerify(t *testing.T) {
t.Fatalf("%+v", err) t.Fatalf("%+v", err)
} }
cleanup := func() { cleanup := func() {
sb.Destroy() if t.Failed() {
fmt.Printf("not removing %s\n", dir)
return
}
if err := os.RemoveAll(dir); err != nil { if err := os.RemoveAll(dir); err != nil {
t.Error(err) t.Error(err)
} }
@ -137,20 +160,95 @@ func TestSealAndVerify(t *testing.T) {
s := seal{sid: si} s := seal{sid: si}
start := time.Now()
s.precommit(t, sb, 1, func() {}) s.precommit(t, sb, 1, func() {})
precommit := time.Now()
s.commit(t, sb, func() {}) s.commit(t, sb, func() {})
s.post(t, sb) commit := time.Now()
genCandidiates := post(t, sb, s)
epost := time.Now()
// Restart sectorbuilder, re-run post // Restart sectorbuilder, re-run post
sb.Destroy()
sb, err = sectorbuilder.TempSectorbuilderDir(dir, sectorSize, ds) sb, err = sectorbuilder.TempSectorbuilderDir(dir, sectorSize, ds)
if err != nil { if err != nil {
t.Fatalf("%+v", err) t.Fatalf("%+v", err)
} }
s.post(t, sb) post(t, sb, s)
fmt.Printf("PreCommit: %s\n", precommit.Sub(start).String())
fmt.Printf("Commit: %s\n", commit.Sub(precommit).String())
fmt.Printf("GenCandidates: %s\n", genCandidiates.Sub(commit).String())
fmt.Printf("EPoSt: %s\n", epost.Sub(genCandidiates).String())
}
func TestSealPoStNoCommit(t *testing.T) {
if runtime.NumCPU() < 10 && os.Getenv("CI") == "" { // don't bother on slow hardware
t.Skip("this is slow")
}
os.Setenv("BELLMAN_NO_GPU", "1")
os.Setenv("RUST_LOG", "info")
build.SectorSizes = []uint64{sectorSize}
if err := build.GetParams(true, true); err != nil {
t.Fatalf("%+v", err)
}
ds := datastore.NewMapDatastore()
dir, err := ioutil.TempDir("", "sbtest")
if err != nil {
t.Fatal(err)
}
sb, err := sectorbuilder.TempSectorbuilderDir(dir, sectorSize, ds)
if err != nil {
t.Fatalf("%+v", err)
}
cleanup := func() {
if t.Failed() {
fmt.Printf("not removing %s\n", dir)
return
}
if err := os.RemoveAll(dir); err != nil {
t.Error(err)
}
}
defer cleanup()
si, err := sb.AcquireSectorId()
if err != nil {
t.Fatalf("%+v", err)
}
s := seal{sid: si}
start := time.Now()
s.precommit(t, sb, 1, func() {})
precommit := time.Now()
// Restart sectorbuilder, re-run post
sb, err = sectorbuilder.TempSectorbuilderDir(dir, sectorSize, ds)
if err != nil {
t.Fatalf("%+v", err)
}
genCandidiates := post(t, sb, s)
epost := time.Now()
fmt.Printf("PreCommit: %s\n", precommit.Sub(start).String())
fmt.Printf("GenCandidates: %s\n", genCandidiates.Sub(precommit).String())
fmt.Printf("EPoSt: %s\n", epost.Sub(genCandidiates).String())
} }
func TestSealAndVerify2(t *testing.T) { func TestSealAndVerify2(t *testing.T) {
@ -178,7 +276,6 @@ func TestSealAndVerify2(t *testing.T) {
t.Fatalf("%+v", err) t.Fatalf("%+v", err)
} }
cleanup := func() { cleanup := func() {
sb.Destroy()
if err := os.RemoveAll(dir); err != nil { if err := os.RemoveAll(dir); err != nil {
t.Error(err) t.Error(err)
} }
@ -210,6 +307,8 @@ func TestSealAndVerify2(t *testing.T) {
go s1.commit(t, sb, wg.Done) go s1.commit(t, sb, wg.Done)
go s2.commit(t, sb, wg.Done) go s2.commit(t, sb, wg.Done)
wg.Wait() wg.Wait()
post(t, sb, s1, s2)
} }
func TestAcquireID(t *testing.T) { func TestAcquireID(t *testing.T) {
@ -235,8 +334,6 @@ func TestAcquireID(t *testing.T) {
assertAcquire(2) assertAcquire(2)
assertAcquire(3) assertAcquire(3)
sb.Destroy()
sb, err = sectorbuilder.TempSectorbuilderDir(dir, sectorSize, ds) sb, err = sectorbuilder.TempSectorbuilderDir(dir, sectorSize, ds)
if err != nil { if err != nil {
t.Fatalf("%+v", err) t.Fatalf("%+v", err)
@ -246,7 +343,6 @@ func TestAcquireID(t *testing.T) {
assertAcquire(5) assertAcquire(5)
assertAcquire(6) assertAcquire(6)
sb.Destroy()
if err := os.RemoveAll(dir); err != nil { if err := os.RemoveAll(dir); err != nil {
t.Error(err) t.Error(err)
} }

View File

@ -4,18 +4,12 @@ import (
"context" "context"
"io" "io"
sectorbuilder "github.com/filecoin-project/go-sectorbuilder" sectorbuilder "github.com/filecoin-project/filecoin-ffi"
"go.opencensus.io/trace" "go.opencensus.io/trace"
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/address"
) )
func (sb *SectorBuilder) GeneratePoSt(sectorInfo SortedSectorInfo, challengeSeed [CommLen]byte, faults []uint64) ([]byte, error) {
// Wait, this is a blocking method with no way of interrupting it?
// does it checkpoint itself?
return sectorbuilder.GeneratePoSt(sb.handle, sectorInfo, challengeSeed, faults)
}
func (sb *SectorBuilder) SectorSize() uint64 { func (sb *SectorBuilder) SectorSize() uint64 {
return sb.ssize return sb.ssize
} }
@ -33,14 +27,37 @@ func VerifySeal(sectorSize uint64, commR, commD []byte, proverID address.Address
return sectorbuilder.VerifySeal(sectorSize, commRa, commDa, proverIDa, ticketa, seeda, sectorID, proof) return sectorbuilder.VerifySeal(sectorSize, commRa, commDa, proverIDa, ticketa, seeda, sectorID, proof)
} }
func NewSortedSectorInfo(sectors []SectorInfo) SortedSectorInfo { func NewSortedPrivateSectorInfo(sectors []sectorbuilder.PrivateSectorInfo) SortedPrivateSectorInfo {
return sectorbuilder.NewSortedSectorInfo(sectors...) return sectorbuilder.NewSortedPrivateSectorInfo(sectors...)
} }
func VerifyPost(ctx context.Context, sectorSize uint64, sectorInfo SortedSectorInfo, challengeSeed [CommLen]byte, proof []byte, faults []uint64) (bool, error) { func NewSortedPublicSectorInfo(sectors []sectorbuilder.PublicSectorInfo) SortedPublicSectorInfo {
return sectorbuilder.NewSortedPublicSectorInfo(sectors...)
}
func VerifyElectionPost(ctx context.Context, sectorSize uint64, sectorInfo SortedPublicSectorInfo, challengeSeed []byte, proof []byte, candidates []EPostCandidate, proverID address.Address) (bool, error) {
challengeCount := electionPostChallengeCount(uint64(len(sectorInfo.Values())))
return verifyPost(ctx, sectorSize, sectorInfo, challengeCount, challengeSeed, proof, candidates, proverID)
}
func VerifyFallbackPost(ctx context.Context, sectorSize uint64, sectorInfo SortedPublicSectorInfo, challengeSeed []byte, proof []byte, candidates []EPostCandidate, proverID address.Address) (bool, error) {
challengeCount := fallbackPostChallengeCount(uint64(len(sectorInfo.Values())))
return verifyPost(ctx, sectorSize, sectorInfo, challengeCount, challengeSeed, proof, candidates, proverID)
}
func verifyPost(ctx context.Context, sectorSize uint64, sectorInfo SortedPublicSectorInfo, challengeCount uint64, challengeSeed []byte, proof []byte, candidates []EPostCandidate, proverID address.Address) (bool, error) {
if challengeCount != uint64(len(candidates)) {
log.Warnf("verifyPost with wrong candidate count: expected %d, got %d", challengeCount, len(candidates))
return false, nil // user input, dont't error
}
var challengeSeeda [CommLen]byte
copy(challengeSeeda[:], challengeSeed)
_, span := trace.StartSpan(ctx, "VerifyPoSt") _, span := trace.StartSpan(ctx, "VerifyPoSt")
defer span.End() defer span.End()
return sectorbuilder.VerifyPoSt(sectorSize, sectorInfo, challengeSeed, proof, faults) prover := addressToProverID(proverID)
return sectorbuilder.VerifyPoSt(sectorSize, sectorInfo, challengeSeeda, challengeCount, proof, candidates, prover)
} }
func GeneratePieceCommitment(piece io.Reader, pieceSize uint64) (commP [CommLen]byte, err error) { func GeneratePieceCommitment(piece io.Reader, pieceSize uint64) (commP [CommLen]byte, err error) {
@ -57,6 +74,6 @@ func GeneratePieceCommitment(piece io.Reader, pieceSize uint64) (commP [CommLen]
return commP, werr() return commP, werr()
} }
func GenerateDataCommitment(ssize uint64, pieces []PublicPieceInfo) ([CommLen]byte, error) { func GenerateDataCommitment(ssize uint64, pieces []sectorbuilder.PublicPieceInfo) ([CommLen]byte, error) {
return sectorbuilder.GenerateDataCommitment(ssize, pieces) return sectorbuilder.GenerateDataCommitment(ssize, pieces)
} }

View File

@ -2,14 +2,15 @@ package main
import ( import (
"crypto/rand" "crypto/rand"
"github.com/filecoin-project/lotus/lib/jsonrpc"
"github.com/filecoin-project/lotus/node/repo"
"io" "io"
"io/ioutil" "io/ioutil"
"os" "os"
"sync" "sync"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/lotus/lib/jsonrpc"
"github.com/filecoin-project/lotus/node/repo"
) )
type NodeState int type NodeState int

View File

@ -45,8 +45,6 @@ class FullNode extends React.Component {
return this.props.client.call('Filecoin.PaychVoucherList', [paych]) return this.props.client.call('Filecoin.PaychVoucherList', [paych])
})) }))
let minerList = await this.props.client.call('Filecoin.MinerAddresses', [])
let mpoolPending = (await this.props.client.call('Filecoin.MpoolPending', [tipset])).length let mpoolPending = (await this.props.client.call('Filecoin.MpoolPending', [tipset])).length
this.setState(() => ({ this.setState(() => ({
@ -62,8 +60,6 @@ class FullNode extends React.Component {
vouchers: vouchers, vouchers: vouchers,
defaultAddr: defaultAddr, defaultAddr: defaultAddr,
minerList: minerList,
})) }))
} }
@ -110,11 +106,6 @@ class FullNode extends React.Component {
) )
} }
let miners = <span/>
if(this.state.minerList.length > 0) {
miners = this.state.minerList.map((a, k) => <div key={k}><Address miner={true} client={this.props.client} addr={a} mountWindow={this.props.mountWindow}/></div>)
}
let storageMine = <a href="#" onClick={this.startStorageMiner} hidden={!this.props.spawnStorageNode}>[Spawn Storage Miner]</a> let storageMine = <a href="#" onClick={this.startStorageMiner} hidden={!this.props.spawnStorageNode}>[Spawn Storage Miner]</a>
let addresses = this.state.addrs.map((addr) => { let addresses = this.state.addrs.map((addr) => {
@ -153,7 +144,6 @@ class FullNode extends React.Component {
<div> <div>
<div>Balances: [New <a href="#" onClick={this.newSecpAddr}>[Secp256k1]</a> <a href="#" onClick={this.newBLSAddr}>[BLS]</a>]</div> <div>Balances: [New <a href="#" onClick={this.newSecpAddr}>[Secp256k1]</a> <a href="#" onClick={this.newBLSAddr}>[BLS]</a>]</div>
<div>{addresses}</div> <div>{addresses}</div>
<div>{miners}</div>
<div>{paychannels}</div> <div>{paychannels}</div>
</div> </div>

View File

@ -181,7 +181,7 @@ class MinerState extends React.Component {
<div>Worker: <Address addr={this.state.worker} client={this.props.client} mountWindow={this.props.mountWindow}/></div> <div>Worker: <Address addr={this.state.worker} client={this.props.client} mountWindow={this.props.mountWindow}/></div>
<div>Sector Size: <b>{this.state.sectorSize/1024}</b> KiB</div> <div>Sector Size: <b>{this.state.sectorSize/1024}</b> KiB</div>
<div>Power: <b>{state.Power}</b> (<b>{state.Power/this.state.networkPower*100}</b>%)</div> <div>Power: <b>{state.Power}</b> (<b>{state.Power/this.state.networkPower*100}</b>%)</div>
<div>Proving Period End: <b>{state.ProvingPeriodEnd}</b></div> <div>Election Period Start: <b>{state.ElectionPeriodStart}</b></div>
<div>Slashed: <b>{state.SlashedAt === 0 ? "NO" : state.SlashedAt}</b></div> <div>Slashed: <b>{state.SlashedAt === 0 ? "NO" : state.SlashedAt}</b></div>
<div> <div>
<div>----</div> <div>----</div>

View File

@ -120,7 +120,7 @@ class StorageNode extends React.Component {
</div> </div>
<div> <div>
<Address client={this.props.fullConn} addr={this.state.actor} mountWindow={this.props.mountWindow}/> <Address client={this.props.fullConn} addr={this.state.actor} mountWindow={this.props.mountWindow}/>
<span>&nbsp;<abbr title="Proving period end">PPE:</abbr> <b>{this.state.actorState.State.ProvingPeriodEnd}</b></span> <span>&nbsp;<abbr title="Proving period end">EPS:</abbr> <b>{this.state.actorState.State.ElectionPeriodStart}</b></span>
</div> </div>
<div>{this.state.statusCounts.map((c, i) => <span key={i}>{sealCodes[i]}: {c} | </span>)}</div> <div>{this.state.statusCounts.map((c, i) => <span key={i}>{sealCodes[i]}: {c} | </span>)}</div>
<div> <div>

View File

@ -3,12 +3,13 @@ package main
import ( import (
"bufio" "bufio"
"fmt" "fmt"
"github.com/gorilla/websocket"
"github.com/opentracing/opentracing-go/log"
"io" "io"
"net/http" "net/http"
"strings" "strings"
"sync" "sync"
"github.com/gorilla/websocket"
"github.com/opentracing/opentracing-go/log"
) )
type outmux struct { type outmux struct {

View File

@ -11,6 +11,10 @@ import (
"time" "time"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/cmd/lotus-seed/seed"
) )
func (api *api) Spawn() (nodeInfo, error) { func (api *api) Spawn() (nodeInfo, error) {
@ -19,9 +23,29 @@ func (api *api) Spawn() (nodeInfo, error) {
return nodeInfo{}, err return nodeInfo{}, err
} }
params := []string{"daemon", "--bootstrap=false"}
genParam := "--genesis=" + api.genesis genParam := "--genesis=" + api.genesis
id := atomic.AddInt32(&api.cmds, 1) id := atomic.AddInt32(&api.cmds, 1)
if id == 1 { if id == 1 {
// preseal
genMiner, err := address.NewIDAddress(101)
if err != nil {
return nodeInfo{}, err
}
sbroot := filepath.Join(dir, "preseal")
genm, err := seed.PreSeal(genMiner, build.SectorSizes[0], 1, sbroot, []byte("8"))
if err != nil {
return nodeInfo{}, xerrors.Errorf("preseal failed: %w", err)
}
if err := seed.WriteGenesisMiner(genMiner, sbroot, genm); err != nil {
return nodeInfo{}, xerrors.Errorf("failed to write genminer info: %w", err)
}
params = append(params, "--genesis-presealed-sectors="+filepath.Join(dir, "preseal", "pre-seal-t0101.json"))
// make genesis // make genesis
genf, err := ioutil.TempFile(os.TempDir(), "lotus-genesis-") genf, err := ioutil.TempFile(os.TempDir(), "lotus-genesis-")
if err != nil { if err != nil {
@ -54,7 +78,7 @@ func (api *api) Spawn() (nodeInfo, error) {
return nodeInfo{}, err return nodeInfo{}, err
} }
cmd := exec.Command("./lotus", "daemon", "--bootstrap=false", genParam) cmd := exec.Command("./lotus", append(params, genParam)...)
cmd.Stderr = io.MultiWriter(os.Stderr, errlogfile, mux.errpw) cmd.Stderr = io.MultiWriter(os.Stderr, errlogfile, mux.errpw)
cmd.Stdout = io.MultiWriter(os.Stdout, logfile, mux.outpw) cmd.Stdout = io.MultiWriter(os.Stdout, logfile, mux.outpw)
@ -114,7 +138,7 @@ func (api *api) SpawnStorage(fullNodeRepo string) (nodeInfo, error) {
initArgs := []string{"init"} initArgs := []string{"init"}
if fullNodeRepo == api.running[1].meta.Repo { if fullNodeRepo == api.running[1].meta.Repo {
initArgs = []string{"init", "--actor=t0101", "--genesis-miner"} initArgs = []string{"init", "--actor=t0101", "--genesis-miner", "--pre-sealed-sectors=" + filepath.Join(fullNodeRepo, "preseal")}
} }
id := atomic.AddInt32(&api.cmds, 1) id := atomic.AddInt32(&api.cmds, 1)

View File

@ -5,17 +5,15 @@ import (
"sync" "sync"
"time" "time"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/gen"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/node/impl/full"
logging "github.com/ipfs/go-log" logging "github.com/ipfs/go-log"
"github.com/pkg/errors"
"go.opencensus.io/trace" "go.opencensus.io/trace"
"go.uber.org/fx"
"golang.org/x/xerrors" "golang.org/x/xerrors"
) )
@ -23,19 +21,10 @@ var log = logging.Logger("miner")
type waitFunc func(ctx context.Context) error type waitFunc func(ctx context.Context) error
type api struct { func NewMiner(api api.FullNode, epp gen.ElectionPoStProver) *Miner {
fx.In
full.ChainAPI
full.SyncAPI
full.MpoolAPI
full.WalletAPI
full.StateAPI
}
func NewMiner(api api) *Miner {
return &Miner{ return &Miner{
api: api, api: api,
epp: epp,
waitFunc: func(ctx context.Context) error { waitFunc: func(ctx context.Context) error {
// Wait around for half the block time in case other parents come in // Wait around for half the block time in case other parents come in
time.Sleep(build.BlockDelay * time.Second / 2) time.Sleep(build.BlockDelay * time.Second / 2)
@ -45,7 +34,9 @@ func NewMiner(api api) *Miner {
} }
type Miner struct { type Miner struct {
api api api api.FullNode
epp gen.ElectionPoStProver
lk sync.Mutex lk sync.Mutex
addresses []address.Address addresses []address.Address
@ -161,8 +152,8 @@ eventLoop:
log.Errorf("failed to get best mining candidate: %s", err) log.Errorf("failed to get best mining candidate: %s", err)
continue continue
} }
if base.ts.Equals(lastBase.ts) && len(lastBase.tickets) == len(base.tickets) { if base.ts.Equals(lastBase.ts) && lastBase.nullRounds == base.nullRounds {
log.Errorf("BestMiningCandidate from the previous round: %s (tkts:%d)", lastBase.ts.Cids(), len(lastBase.tickets)) log.Errorf("BestMiningCandidate from the previous round: %s (nulls:%d)", lastBase.ts.Cids(), lastBase.nullRounds)
time.Sleep(build.BlockDelay * time.Second) time.Sleep(build.BlockDelay * time.Second)
continue continue
} }
@ -173,7 +164,7 @@ eventLoop:
for _, addr := range addrs { for _, addr := range addrs {
b, err := m.mineOne(ctx, addr, base) b, err := m.mineOne(ctx, addr, base)
if err != nil { if err != nil {
log.Errorf("mining block failed: %s", err) log.Errorf("mining block failed: %+v", err)
continue continue
} }
if b != nil { if b != nil {
@ -205,15 +196,15 @@ eventLoop:
} }
} }
} else { } else {
nextRound := time.Unix(int64(base.ts.MinTimestamp()+uint64(build.BlockDelay*len(base.tickets))), 0) nextRound := time.Unix(int64(base.ts.MinTimestamp()+uint64(build.BlockDelay*base.nullRounds)), 0)
time.Sleep(time.Until(nextRound)) time.Sleep(time.Until(nextRound))
} }
} }
} }
type MiningBase struct { type MiningBase struct {
ts *types.TipSet ts *types.TipSet
tickets []*types.Ticket nullRounds uint64
} }
func (m *Miner) GetBestMiningCandidate(ctx context.Context) (*MiningBase, error) { func (m *Miner) GetBestMiningCandidate(ctx context.Context) (*MiningBase, error) {
@ -246,35 +237,54 @@ func (m *Miner) GetBestMiningCandidate(ctx context.Context) (*MiningBase, error)
}, nil }, nil
} }
func (m *Miner) mineOne(ctx context.Context, addr address.Address, base *MiningBase) (*types.BlockMsg, error) { func (m *Miner) isSlashed(ctx context.Context, addr address.Address, ts *types.TipSet) (bool, error) {
log.Debugw("attempting to mine a block", "tipset", types.LogCids(base.ts.Cids())) power, err := m.api.StateMinerPower(ctx, addr, ts)
ticket, err := m.scratchTicket(ctx, addr, base)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "scratching ticket failed") return false, err
} }
win, proof, err := gen.IsRoundWinner(ctx, base.ts, append(base.tickets, ticket), addr, &m.api) return power.MinerPower.Equals(types.NewInt(0)), nil
}
func (m *Miner) mineOne(ctx context.Context, addr address.Address, base *MiningBase) (*types.BlockMsg, error) {
log.Debugw("attempting to mine a block", "tipset", types.LogCids(base.ts.Cids()))
start := time.Now()
slashed, err := m.isSlashed(ctx, addr, base.ts)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed to check if we win next round") return nil, xerrors.Errorf("checking if miner is slashed: %w", err)
}
if slashed {
log.Warnf("Slashed at epoch %d, not attempting to mine a block", base.ts.Height()+base.nullRounds)
base.nullRounds++
return nil, nil
}
ticket, err := m.computeTicket(ctx, addr, base)
if err != nil {
return nil, xerrors.Errorf("scratching ticket failed: %w", err)
}
win, proof, err := gen.IsRoundWinner(ctx, base.ts, int64(base.ts.Height()+base.nullRounds+1), addr, m.epp, m.api)
if err != nil {
return nil, xerrors.Errorf("failed to check if we win next round: %w", err)
} }
if !win { if !win {
m.submitNullTicket(base, ticket) base.nullRounds++
return nil, nil return nil, nil
} }
b, err := m.createBlock(base, addr, ticket, proof) b, err := m.createBlock(base, addr, ticket, proof)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed to create block") return nil, xerrors.Errorf("failed to create block: %w", err)
} }
log.Infow("mined new block", "cid", b.Cid()) log.Infow("mined new block", "cid", b.Cid())
return b, nil dur := time.Now().Sub(start)
} log.Infof("Creating block took %s", dur)
func (m *Miner) submitNullTicket(base *MiningBase, ticket *types.Ticket) { return b, nil
base.tickets = append(base.tickets, ticket)
m.lastWork = base
} }
func (m *Miner) computeVRF(ctx context.Context, addr address.Address, input []byte) ([]byte, error) { func (m *Miner) computeVRF(ctx context.Context, addr address.Address, input []byte) ([]byte, error) {
@ -283,7 +293,7 @@ func (m *Miner) computeVRF(ctx context.Context, addr address.Address, input []by
return nil, err return nil, err
} }
return gen.ComputeVRF(ctx, m.api.WalletSign, w, input) return gen.ComputeVRF(ctx, m.api.WalletSign, w, addr, gen.DSepTicket, input)
} }
func (m *Miner) getMinerWorker(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) { func (m *Miner) getMinerWorker(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) {
@ -308,15 +318,11 @@ func (m *Miner) getMinerWorker(ctx context.Context, addr address.Address, ts *ty
return w, nil return w, nil
} }
func (m *Miner) scratchTicket(ctx context.Context, addr address.Address, base *MiningBase) (*types.Ticket, error) { func (m *Miner) computeTicket(ctx context.Context, addr address.Address, base *MiningBase) (*types.Ticket, error) {
var lastTicket *types.Ticket
if len(base.tickets) > 0 {
lastTicket = base.tickets[len(base.tickets)-1]
} else {
lastTicket = base.ts.MinTicket()
}
vrfOut, err := m.computeVRF(ctx, addr, lastTicket.VRFProof) vrfBase := base.ts.MinTicket().VRFProof
vrfOut, err := m.computeVRF(ctx, addr, vrfBase)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -326,11 +332,11 @@ func (m *Miner) scratchTicket(ctx context.Context, addr address.Address, base *M
}, nil }, nil
} }
func (m *Miner) createBlock(base *MiningBase, addr address.Address, ticket *types.Ticket, proof types.ElectionProof) (*types.BlockMsg, error) { func (m *Miner) createBlock(base *MiningBase, addr address.Address, ticket *types.Ticket, proof *types.EPostProof) (*types.BlockMsg, error) {
pending, err := m.api.MpoolPending(context.TODO(), base.ts) pending, err := m.api.MpoolPending(context.TODO(), base.ts)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "failed to get pending messages") return nil, xerrors.Errorf("failed to get pending messages: %w", err)
} }
msgs, err := selectMessages(context.TODO(), m.api.StateGetActor, base, pending) msgs, err := selectMessages(context.TODO(), m.api.StateGetActor, base, pending)
@ -338,10 +344,12 @@ func (m *Miner) createBlock(base *MiningBase, addr address.Address, ticket *type
return nil, xerrors.Errorf("message filtering failed: %w", err) return nil, xerrors.Errorf("message filtering failed: %w", err)
} }
uts := base.ts.MinTimestamp() + uint64(build.BlockDelay*(len(base.tickets)+1)) uts := base.ts.MinTimestamp() + uint64(build.BlockDelay*(base.nullRounds+1))
nheight := base.ts.Height() + base.nullRounds + 1
// why even return this? that api call could just submit it for us // why even return this? that api call could just submit it for us
return m.api.MinerCreateBlock(context.TODO(), addr, base.ts, append(base.tickets, ticket), proof, msgs, uint64(uts)) return m.api.MinerCreateBlock(context.TODO(), addr, base.ts, ticket, proof, msgs, nheight, uint64(uts))
} }
type actorLookup func(context.Context, address.Address, *types.TipSet) (*types.Actor, error) type actorLookup func(context.Context, address.Address, *types.TipSet) (*types.Actor, error)
@ -378,7 +386,7 @@ func selectMessages(ctx context.Context, al actorLookup, base *MiningBase, msgs
} }
if msg.Message.Nonce < inclNonces[from] { if msg.Message.Nonce < inclNonces[from] {
log.Warnf("message in mempool has already used nonce (%d < %d) %s", msg.Message.Nonce, inclNonces[from], msg.Cid()) log.Warnf("message in mempool has already used nonce (%d < %d), from %s, to %s, %s", msg.Message.Nonce, inclNonces[from], msg.Message.From, msg.Message.To, msg.Cid())
continue continue
} }

View File

@ -2,10 +2,12 @@ package miner
import ( import (
"context" "context"
"github.com/filecoin-project/lotus/api"
) )
func NewTestMiner(nextCh <-chan struct{}) func(api api) *Miner { func NewTestMiner(nextCh <-chan struct{}) func(api api.FullNode) *Miner {
return func(api api) *Miner { return func(api api.FullNode) *Miner {
return &Miner{ return &Miner{
api: api, api: api,
waitFunc: chanWaiter(nextCh), waitFunc: chanWaiter(nextCh),

View File

@ -22,6 +22,7 @@ import (
"github.com/filecoin-project/lotus/chain" "github.com/filecoin-project/lotus/chain"
"github.com/filecoin-project/lotus/chain/blocksync" "github.com/filecoin-project/lotus/chain/blocksync"
"github.com/filecoin-project/lotus/chain/deals" "github.com/filecoin-project/lotus/chain/deals"
"github.com/filecoin-project/lotus/chain/gen"
"github.com/filecoin-project/lotus/chain/market" "github.com/filecoin-project/lotus/chain/market"
"github.com/filecoin-project/lotus/chain/metrics" "github.com/filecoin-project/lotus/chain/metrics"
"github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/stmgr"
@ -92,7 +93,6 @@ const (
HandleDealsKey HandleDealsKey
HandleRetrievalKey HandleRetrievalKey
RunSectorServiceKey RunSectorServiceKey
RegisterMinerKey
RegisterProviderValidatorKey RegisterProviderValidatorKey
// daemon // daemon
@ -231,8 +231,6 @@ func Online() Option {
Override(new(*paych.Store), paych.NewStore), Override(new(*paych.Store), paych.NewStore),
Override(new(*paych.Manager), paych.NewManager), Override(new(*paych.Manager), paych.NewManager),
Override(new(*market.FundMgr), market.NewFundMgr), Override(new(*market.FundMgr), market.NewFundMgr),
Override(new(*miner.Miner), miner.NewMiner),
), ),
// Storage miner // Storage miner
@ -252,7 +250,8 @@ func Online() Option {
Override(RegisterProviderValidatorKey, modules.RegisterProviderValidator), Override(RegisterProviderValidatorKey, modules.RegisterProviderValidator),
Override(HandleRetrievalKey, modules.HandleRetrieval), Override(HandleRetrievalKey, modules.HandleRetrieval),
Override(HandleDealsKey, modules.HandleDeals), Override(HandleDealsKey, modules.HandleDeals),
Override(RegisterMinerKey, modules.RegisterMiner), Override(new(gen.ElectionPoStProver), storage.NewElectionPoStProver),
Override(new(*miner.Miner), modules.SetupBlockProducer),
), ),
) )
} }
@ -312,6 +311,9 @@ func ConfigFullNode(c interface{}) Option {
return Options( return Options(
ConfigCommon(&cfg.Common), ConfigCommon(&cfg.Common),
Override(HeadMetricsKey, metrics.SendHeadNotifs(cfg.Metrics.Nickname)), Override(HeadMetricsKey, metrics.SendHeadNotifs(cfg.Metrics.Nickname)),
If(cfg.Metrics.PubsubTracing,
Override(new(*pubsub.PubSub), lp2p.GossipSub(lp2p.PubsubTracer())),
),
) )
} }

View File

@ -41,7 +41,8 @@ type Libp2p struct {
// // Full Node // // Full Node
type Metrics struct { type Metrics struct {
Nickname string Nickname string
PubsubTracing bool
} }
// // Storage Miner // // Storage Miner

View File

@ -1,8 +1,6 @@
package impl package impl
import ( import (
"context"
logging "github.com/ipfs/go-log" logging "github.com/ipfs/go-log"
"github.com/filecoin-project/lotus/node/impl/client" "github.com/filecoin-project/lotus/node/impl/client"
@ -10,8 +8,6 @@ import (
"github.com/filecoin-project/lotus/node/impl/paych" "github.com/filecoin-project/lotus/node/impl/paych"
"github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/miner"
"github.com/filecoin-project/lotus/node/impl/full" "github.com/filecoin-project/lotus/node/impl/full"
) )
@ -27,20 +23,6 @@ type FullNodeAPI struct {
full.StateAPI full.StateAPI
full.WalletAPI full.WalletAPI
full.SyncAPI full.SyncAPI
Miner *miner.Miner
}
func (a *FullNodeAPI) MinerAddresses(context.Context) ([]address.Address, error) {
return a.Miner.Addresses()
}
func (a *FullNodeAPI) MinerRegister(ctx context.Context, addr address.Address) error {
return a.Miner.Register(addr)
}
func (a *FullNodeAPI) MinerUnregister(ctx context.Context, addr address.Address) error {
return a.Miner.Unregister(ctx, addr)
} }
var _ api.FullNode = &FullNodeAPI{} var _ api.FullNode = &FullNodeAPI{}

View File

@ -28,8 +28,8 @@ func (a *ChainAPI) ChainHead(context.Context) (*types.TipSet, error) {
return a.Chain.GetHeaviestTipSet(), nil return a.Chain.GetHeaviestTipSet(), nil
} }
func (a *ChainAPI) ChainGetRandomness(ctx context.Context, pts types.TipSetKey, tickets []*types.Ticket, lb int) ([]byte, error) { func (a *ChainAPI) ChainGetRandomness(ctx context.Context, pts types.TipSetKey, round int64) ([]byte, error) {
return a.Chain.GetRandomness(ctx, pts.Cids(), tickets, int64(lb)) return a.Chain.GetRandomness(ctx, pts.Cids(), round)
} }
func (a *ChainAPI) ChainGetBlock(ctx context.Context, msg cid.Cid) (*types.BlockHeader, error) { func (a *ChainAPI) ChainGetBlock(ctx context.Context, msg cid.Cid) (*types.BlockHeader, error) {

View File

@ -76,8 +76,8 @@ func (a *StateAPI) StateMinerPeerID(ctx context.Context, m address.Address, ts *
return stmgr.GetMinerPeerID(ctx, a.StateManager, ts, m) return stmgr.GetMinerPeerID(ctx, a.StateManager, ts, m)
} }
func (a *StateAPI) StateMinerProvingPeriodEnd(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error) { func (a *StateAPI) StateMinerElectionPeriodStart(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error) {
return stmgr.GetMinerProvingPeriodEnd(ctx, a.StateManager, ts, actor) return stmgr.GetMinerElectionPeriodStart(ctx, a.StateManager, ts, actor)
} }
func (a *StateAPI) StateMinerSectorSize(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error) { func (a *StateAPI) StateMinerSectorSize(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error) {
@ -186,8 +186,8 @@ func (a *StateAPI) StateReadState(ctx context.Context, act *types.Actor, ts *typ
} }
// This is on StateAPI because miner.Miner requires this, and MinerAPI requires miner.Miner // This is on StateAPI because miner.Miner requires this, and MinerAPI requires miner.Miner
func (a *StateAPI) MinerCreateBlock(ctx context.Context, addr address.Address, parents *types.TipSet, tickets []*types.Ticket, proof types.ElectionProof, msgs []*types.SignedMessage, ts uint64) (*types.BlockMsg, error) { func (a *StateAPI) MinerCreateBlock(ctx context.Context, addr address.Address, parents *types.TipSet, ticket *types.Ticket, proof *types.EPostProof, msgs []*types.SignedMessage, height, ts uint64) (*types.BlockMsg, error) {
fblk, err := gen.MinerCreateBlock(ctx, a.StateManager, a.Wallet, addr, parents, tickets, proof, msgs, ts) fblk, err := gen.MinerCreateBlock(ctx, a.StateManager, a.Wallet, addr, parents, ticket, proof, msgs, height, ts)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -11,6 +11,7 @@ import (
"github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/address" "github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/lib/sectorbuilder" "github.com/filecoin-project/lotus/lib/sectorbuilder"
"github.com/filecoin-project/lotus/miner"
"github.com/filecoin-project/lotus/storage" "github.com/filecoin-project/lotus/storage"
"github.com/filecoin-project/lotus/storage/sectorblocks" "github.com/filecoin-project/lotus/storage/sectorblocks"
) )
@ -22,8 +23,9 @@ type StorageMinerAPI struct {
SectorBuilder *sectorbuilder.SectorBuilder SectorBuilder *sectorbuilder.SectorBuilder
SectorBlocks *sectorblocks.SectorBlocks SectorBlocks *sectorblocks.SectorBlocks
Miner *storage.Miner Miner *storage.Miner
Full api.FullNode BlockMiner *miner.Miner
Full api.FullNode
} }
func (sm *StorageMinerAPI) ServeRemote(w http.ResponseWriter, r *http.Request) { func (sm *StorageMinerAPI) ServeRemote(w http.ResponseWriter, r *http.Request) {

View File

@ -41,14 +41,17 @@ func ChainExchange(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host, rt
return exch return exch
} }
func MessagePool(lc fx.Lifecycle, sm *stmgr.StateManager, ps *pubsub.PubSub) *chain.MessagePool { func MessagePool(lc fx.Lifecycle, sm *stmgr.StateManager, ps *pubsub.PubSub, ds dtypes.MetadataDS) (*chain.MessagePool, error) {
mp := chain.NewMessagePool(sm, ps) mp, err := chain.NewMessagePool(sm, ps, ds)
if err != nil {
return nil, xerrors.Errorf("constructing mpool: %w", err)
}
lc.Append(fx.Hook{ lc.Append(fx.Hook{
OnStop: func(_ context.Context) error { OnStop: func(_ context.Context) error {
return mp.Close() return mp.Close()
}, },
}) })
return mp return mp, nil
} }
func ChainBlockstore(r repo.LockedRepo) (dtypes.ChainBlockstore, error) { func ChainBlockstore(r repo.LockedRepo) (dtypes.ChainBlockstore, error) {

View File

@ -3,6 +3,9 @@ package modules
import ( import (
"context" "context"
"crypto/rand" "crypto/rand"
"io"
"io/ioutil"
"github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
@ -14,8 +17,6 @@ import (
"github.com/libp2p/go-libp2p-core/peerstore" "github.com/libp2p/go-libp2p-core/peerstore"
record "github.com/libp2p/go-libp2p-record" record "github.com/libp2p/go-libp2p-record"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"io"
"io/ioutil"
) )
var log = logging.Logger("modules") var log = logging.Logger("modules")

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