Merge branch 'feat/election-post' into feat/remote-workers
This commit is contained in:
commit
8767d8c16b
@ -46,6 +46,15 @@ jobs:
|
||||
- go/mod-download
|
||||
- go/mod-tidy-check
|
||||
|
||||
build-all:
|
||||
executor: golang
|
||||
steps:
|
||||
- install-deps
|
||||
- prepare
|
||||
- go/mod-download
|
||||
- run:
|
||||
command: make buildall
|
||||
|
||||
test:
|
||||
description: |
|
||||
Run tests with gotestsum.
|
||||
@ -166,3 +175,4 @@ workflows:
|
||||
- test:
|
||||
codecov-upload: true
|
||||
- mod-tidy-check
|
||||
- build-all
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,9 +1,13 @@
|
||||
/lotus
|
||||
/lotus-storage-miner
|
||||
/lotus-seal-worker
|
||||
/lotus-seed
|
||||
/pond
|
||||
/townhall
|
||||
/fountain
|
||||
/stats
|
||||
/bench
|
||||
/bench.json
|
||||
/lotuspond/front/node_modules
|
||||
/lotuspond/front/build
|
||||
/cmd/lotus-townhall/townhall/node_modules
|
||||
|
10
.gitmodules
vendored
10
.gitmodules
vendored
@ -1,6 +1,4 @@
|
||||
[submodule "extern/go-bls-sigs"]
|
||||
path = extern/go-bls-sigs
|
||||
url = https://github.com/filecoin-project/go-bls-sigs.git
|
||||
[submodule "extern/go-sectorbuilder"]
|
||||
path = extern/go-sectorbuilder
|
||||
url = https://github.com/filecoin-project/go-sectorbuilder
|
||||
[submodule "extern/filecoin-ffi"]
|
||||
path = extern/filecoin-ffi
|
||||
url = https://github.com/filecoin-project/filecoin-ffi.git
|
||||
branch = master
|
||||
|
83
Makefile
83
Makefile
@ -12,37 +12,21 @@ MODULES:=
|
||||
|
||||
CLEAN:=
|
||||
|
||||
## BLS
|
||||
## FFI
|
||||
|
||||
BLS_PATH:=extern/go-bls-sigs/
|
||||
BLS_DEPS:=libbls_signatures.a libbls_signatures.pc libbls_signatures.h
|
||||
BLS_DEPS:=$(addprefix $(BLS_PATH),$(BLS_DEPS))
|
||||
FFI_PATH:=extern/filecoin-ffi/
|
||||
FFI_DEPS:=libfilecoin.a filecoin.pc filecoin.h
|
||||
FFI_DEPS:=$(addprefix $(FFI_PATH),$(FFI_DEPS))
|
||||
|
||||
$(BLS_DEPS): build/.bls-install ;
|
||||
$(FFI_DEPS): build/.filecoin-install ;
|
||||
|
||||
build/.bls-install: $(BLS_PATH)
|
||||
$(MAKE) -C $(BLS_PATH) $(BLS_DEPS:$(BLS_PATH)%=%)
|
||||
build/.filecoin-install: $(FFI_PATH)
|
||||
$(MAKE) -C $(FFI_PATH) $(FFI_DEPS:$(FFI_PATH)%=%)
|
||||
@touch $@
|
||||
|
||||
MODULES+=$(BLS_PATH)
|
||||
BUILD_DEPS+=build/.bls-install
|
||||
CLEAN+=build/.bls-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+=$(FFI_PATH)
|
||||
BUILD_DEPS+=build/.filecoin-install
|
||||
CLEAN+=build/.filecoin-install
|
||||
|
||||
$(MODULES): build/.update-modules ;
|
||||
|
||||
@ -53,43 +37,55 @@ build/.update-modules:
|
||||
|
||||
# end git modules
|
||||
|
||||
## PROOFS
|
||||
## MAIN BINARIES
|
||||
|
||||
CLEAN+=build/.update-modules
|
||||
|
||||
deps: $(BUILD_DEPS)
|
||||
.PHONY: deps
|
||||
|
||||
debug: GOFLAGS=-tags=debug
|
||||
debug: lotus lotus-storage-miner
|
||||
|
||||
lotus: $(BUILD_DEPS)
|
||||
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
|
||||
|
||||
.PHONY: lotus
|
||||
CLEAN+=lotus
|
||||
BINS+=lotus
|
||||
|
||||
lotus-storage-miner: $(BUILD_DEPS)
|
||||
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
|
||||
.PHONY: lotus-storage-miner
|
||||
BINS+=lotus-storage-miner
|
||||
|
||||
lotus-seal-worker: $(BUILD_DEPS)
|
||||
rm -f 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
|
||||
.PHONY: lotus-seal-worker
|
||||
|
||||
CLEAN+=lotus-storage-miner
|
||||
BINS+=lotus-seal-worker
|
||||
|
||||
build: lotus lotus-storage-miner
|
||||
|
||||
.PHONY: build
|
||||
|
||||
install:
|
||||
install -C ./lotus /usr/local/bin/lotus
|
||||
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:
|
||||
go run github.com/whyrusleeping/bencher ./... > bench.json
|
||||
@echo Submitting results
|
||||
@ -100,6 +96,7 @@ pond: build
|
||||
go build -o pond ./lotuspond
|
||||
(cd lotuspond/front && npm i && npm run build)
|
||||
.PHONY: pond
|
||||
BINS+=pond
|
||||
|
||||
townhall:
|
||||
rm -f townhall
|
||||
@ -107,28 +104,42 @@ townhall:
|
||||
(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
|
||||
.PHONY: townhall
|
||||
BINS+=townhall
|
||||
|
||||
fountain:
|
||||
rm -f fountain
|
||||
go build -o fountain ./cmd/lotus-fountain
|
||||
go run github.com/GeertJohan/go.rice/rice append --exec fountain -i ./cmd/lotus-fountain
|
||||
.PHONY: fountain
|
||||
BINS+=fountain
|
||||
|
||||
chainwatch:
|
||||
rm -f chainwatch
|
||||
go build -o chainwatch ./cmd/lotus-chainwatch
|
||||
go run github.com/GeertJohan/go.rice/rice append --exec chainwatch -i ./cmd/lotus-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:
|
||||
rm -f stats
|
||||
go build -o stats ./tools/stats
|
||||
.PHONY: stats
|
||||
BINS+=stats
|
||||
|
||||
# MISC
|
||||
|
||||
buildall: $(BINS)
|
||||
|
||||
clean:
|
||||
rm -rf $(CLEAN)
|
||||
-$(MAKE) -C $(BLS_PATH) clean
|
||||
-$(MAKE) -C $(SECTOR_BUILDER_PATH) clean
|
||||
rm -rf $(CLEAN) $(BINS)
|
||||
-$(MAKE) -C $(FFI_PATH) clean
|
||||
.PHONY: clean
|
||||
|
||||
dist-clean:
|
||||
|
@ -23,7 +23,7 @@ type FullNode interface {
|
||||
// First message is guaranteed to be of len == 1, and type == 'current'
|
||||
ChainNotify(context.Context) (<-chan []*store.HeadChange, 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)
|
||||
ChainGetTipSet(context.Context, types.TipSetKey) (*types.TipSet, error)
|
||||
ChainGetBlockMessages(context.Context, cid.Cid) (*BlockMessages, error)
|
||||
@ -51,10 +51,7 @@ type FullNode interface {
|
||||
|
||||
// miner
|
||||
|
||||
MinerRegister(context.Context, address.Address) 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)
|
||||
MinerCreateBlock(context.Context, address.Address, *types.TipSet, *types.Ticket, *types.EPostProof, []*types.SignedMessage, uint64, uint64) (*types.BlockMsg, error)
|
||||
|
||||
// // UX ?
|
||||
|
||||
@ -102,7 +99,7 @@ type FullNode interface {
|
||||
StateMinerPower(context.Context, address.Address, *types.TipSet) (MinerPower, error)
|
||||
StateMinerWorker(context.Context, address.Address, *types.TipSet) (address.Address, 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)
|
||||
StatePledgeCollateral(context.Context, *types.TipSet) (types.BigInt, error)
|
||||
StateWaitMsg(context.Context, cid.Cid) (*MsgWait, error)
|
||||
|
@ -38,19 +38,19 @@ type FullNodeStruct struct {
|
||||
CommonStruct
|
||||
|
||||
Internal struct {
|
||||
ChainNotify func(context.Context) (<-chan []*store.HeadChange, 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"`
|
||||
ChainGetBlock func(context.Context, cid.Cid) (*types.BlockHeader, error) `perm:"read"`
|
||||
ChainGetTipSet func(context.Context, types.TipSetKey) (*types.TipSet, error) `perm:"read"`
|
||||
ChainGetBlockMessages func(context.Context, cid.Cid) (*BlockMessages, error) `perm:"read"`
|
||||
ChainGetParentReceipts func(context.Context, cid.Cid) ([]*types.MessageReceipt, 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"`
|
||||
ChainReadObj func(context.Context, cid.Cid) ([]byte, error) `perm:"read"`
|
||||
ChainSetHead func(context.Context, *types.TipSet) error `perm:"admin"`
|
||||
ChainGetGenesis func(context.Context) (*types.TipSet, error) `perm:"read"`
|
||||
ChainTipSetWeight func(context.Context, *types.TipSet) (types.BigInt, error) `perm:"read"`
|
||||
ChainNotify func(context.Context) (<-chan []*store.HeadChange, error) `perm:"read"`
|
||||
ChainHead func(context.Context) (*types.TipSet, 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"`
|
||||
ChainGetTipSet func(context.Context, types.TipSetKey) (*types.TipSet, error) `perm:"read"`
|
||||
ChainGetBlockMessages func(context.Context, cid.Cid) (*BlockMessages, error) `perm:"read"`
|
||||
ChainGetParentReceipts func(context.Context, cid.Cid) ([]*types.MessageReceipt, 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"`
|
||||
ChainReadObj func(context.Context, cid.Cid) ([]byte, error) `perm:"read"`
|
||||
ChainSetHead func(context.Context, *types.TipSet) error `perm:"admin"`
|
||||
ChainGetGenesis func(context.Context) (*types.TipSet, error) `perm:"read"`
|
||||
ChainTipSetWeight func(context.Context, *types.TipSet) (types.BigInt, error) `perm:"read"`
|
||||
|
||||
SyncState func(context.Context) (*SyncState, error) `perm:"read"`
|
||||
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"`
|
||||
MpoolSub func(context.Context) (<-chan MpoolUpdate, error) `perm:"read"`
|
||||
|
||||
MinerRegister func(context.Context, address.Address) error `perm:"admin"`
|
||||
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"`
|
||||
MinerCreateBlock func(context.Context, address.Address, *types.TipSet, *types.Ticket, *types.EPostProof, []*types.SignedMessage, uint64, uint64) (*types.BlockMsg, error) `perm:"write"`
|
||||
|
||||
WalletNew func(context.Context, string) (address.Address, 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"`
|
||||
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"`
|
||||
StateMinerProvingSet func(context.Context, address.Address, *types.TipSet) ([]*ChainSectorInfo, 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"`
|
||||
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"`
|
||||
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"`
|
||||
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"`
|
||||
StateReadState func(context.Context, *types.Actor, *types.TipSet) (*ActorState, error) `perm:"read"`
|
||||
StatePledgeCollateral func(context.Context, *types.TipSet) (types.BigInt, error) `perm:"read"`
|
||||
StateWaitMsg func(context.Context, cid.Cid) (*MsgWait, 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"`
|
||||
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"`
|
||||
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"`
|
||||
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"`
|
||||
StateGetReceipt func(context.Context, cid.Cid, *types.TipSet) (*types.MessageReceipt, 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"`
|
||||
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"`
|
||||
StateMinerPeerID func(ctx context.Context, m address.Address, ts *types.TipSet) (peer.ID, 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"`
|
||||
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"`
|
||||
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"`
|
||||
StatePledgeCollateral func(context.Context, *types.TipSet) (types.BigInt, error) `perm:"read"`
|
||||
StateWaitMsg func(context.Context, cid.Cid) (*MsgWait, 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"`
|
||||
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"`
|
||||
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"`
|
||||
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"`
|
||||
StateGetReceipt func(context.Context, cid.Cid, *types.TipSet) (*types.MessageReceipt, error) `perm:"read"`
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MinerRegister(ctx context.Context, addr address.Address) error {
|
||||
return c.Internal.MinerRegister(ctx, addr)
|
||||
}
|
||||
|
||||
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) 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.MinerCreateBlock(ctx, addr, base, ticket, eproof, msgs, height, ts)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) ChainHead(ctx context.Context) (*types.TipSet, error) {
|
||||
return c.Internal.ChainHead(ctx)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) ChainGetRandomness(ctx context.Context, pts types.TipSetKey, ticks []*types.Ticket, lb int) ([]byte, error) {
|
||||
return c.Internal.ChainGetRandomness(ctx, pts, ticks, lb)
|
||||
func (c *FullNodeStruct) ChainGetRandomness(ctx context.Context, pts types.TipSetKey, round int64) ([]byte, error) {
|
||||
return c.Internal.ChainGetRandomness(ctx, pts, round)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateMinerProvingPeriodEnd(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error) {
|
||||
return c.Internal.StateMinerProvingPeriodEnd(ctx, actor, ts)
|
||||
func (c *FullNodeStruct) StateMinerElectionPeriodStart(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error) {
|
||||
return c.Internal.StateMinerElectionPeriodStart(ctx, actor, ts)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateMinerSectorSize(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error) {
|
||||
|
@ -42,7 +42,7 @@ func TestDealFlow(t *testing.T, b APIBuilder) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
maddr, err := address.NewFromString("t0101")
|
||||
maddr, err := address.NewFromString("t0102")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -2,10 +2,11 @@ package build
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/filecoin-project/lotus/lib/addrutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/filecoin-project/lotus/lib/addrutil"
|
||||
|
||||
rice "github.com/GeertJohan/go.rice"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
)
|
||||
|
@ -1 +0,0 @@
|
||||
/ip4/147.75.80.17/tcp/1347/p2p/12D3KooWFCkQdiJEMBVA6RrWq22ZXVFfM41YX8soQ5QVvNFjMJT8
|
@ -1 +0,0 @@
|
||||
/ip4/147.75.80.29/tcp/1347/p2p/12D3KooWSw9h3e6YrYZfRWDcir8qMV7ctZG9VmtXwSaP2ntsKXYf
|
@ -156,6 +156,8 @@ func doFetch(out string, info paramFile) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Infof("GET %s", url)
|
||||
|
||||
req := http.Request{
|
||||
Method: "GET",
|
||||
URL: url,
|
||||
|
27
build/params_debug.go
Normal file
27
build/params_debug.go
Normal 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
21
build/params_devnet.go
Normal 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
|
@ -13,6 +13,7 @@ const UnixfsChunkSize uint64 = 1 << 20
|
||||
const UnixfsLinksPerLevel = 1024
|
||||
|
||||
var SectorSizes = []uint64{
|
||||
1 << 10,
|
||||
16 << 20,
|
||||
256 << 20,
|
||||
1 << 30,
|
||||
@ -30,25 +31,22 @@ func SupportedSectorSize(ssize uint64) bool {
|
||||
// /////
|
||||
// Payments
|
||||
|
||||
// Blocks
|
||||
// Epochs
|
||||
const PaymentChannelClosingDelay = 6 * 60 * 2 // six hours
|
||||
|
||||
// /////
|
||||
// Consensus / Network
|
||||
|
||||
// Seconds
|
||||
const BlockDelay = 2
|
||||
|
||||
// Seconds
|
||||
const AllowableClockDrift = BlockDelay * 2
|
||||
|
||||
// Blocks
|
||||
// Epochs
|
||||
const ForkLengthThreshold = Finality
|
||||
|
||||
// Blocks (e)
|
||||
const BlocksPerEpoch = 5
|
||||
|
||||
// Blocks
|
||||
// Epochs
|
||||
const Finality = 500
|
||||
|
||||
// constants for Weight calculation
|
||||
@ -59,39 +57,27 @@ const WRatioDen = 2
|
||||
// /////
|
||||
// Proofs
|
||||
|
||||
// Blocks
|
||||
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
|
||||
// Epochs
|
||||
const SealRandomnessLookback = Finality
|
||||
|
||||
// Blocks
|
||||
// Epochs
|
||||
const SealRandomnessLookbackLimit = SealRandomnessLookback + 2000
|
||||
|
||||
// 1 / n
|
||||
const SectorChallengeRatioDiv = 25
|
||||
|
||||
const MaxFallbackPostChallengeCount = 10
|
||||
|
||||
// /////
|
||||
// Mining
|
||||
|
||||
// Blocks
|
||||
// Epochs
|
||||
const EcRandomnessLookback = 300
|
||||
|
||||
const PowerCollateralProportion = 5
|
||||
const PerCapitaCollateralProportion = 1
|
||||
const CollateralPrecision = 1000
|
||||
|
||||
// Blocks
|
||||
const InteractivePoRepDelay = 10
|
||||
|
||||
// /////
|
||||
// Devnet settings
|
||||
|
||||
@ -105,8 +91,8 @@ var InitialReward *big.Int
|
||||
const FilecoinPrecision = 1_000_000_000_000_000_000
|
||||
|
||||
// six years
|
||||
// Blocks
|
||||
const HalvingPeriodBlocks = 6 * 365 * 24 * 60 * 2
|
||||
// Epochs
|
||||
const HalvingPeriodEpochs = 6 * 365 * 24 * 60 * 2
|
||||
|
||||
// TODO: Move other important consts here
|
||||
|
||||
@ -124,6 +110,6 @@ func init() {
|
||||
// Sync
|
||||
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.
|
||||
const BlsSignatureCacheSize = 40000
|
@ -1,82 +1,82 @@
|
||||
{
|
||||
"v15-proof-of-spacetime-rational-535d1050e3adca2a0dfe6c3c0c4fa12097c9a7835fb969042f82a507b13310e0.params": {
|
||||
"cid": "QmT22f1Np1GpW29NXD7Zrv3Ae4poMYhmkDjyscqL8QrJXY",
|
||||
"digest": "989fd8d989e0f7f1fe21bb010cf1b231",
|
||||
"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",
|
||||
"v19-proof-of-spacetime-election-09ae025de08399327e14f0cb6b4c907b6fe1e8b77046e31de8921bde588de900.params": {
|
||||
"cid": "QmZEKhzKbC7SPngjL85ghyuxabPmiEuUh4fpkC7CDK1J5q",
|
||||
"digest": "1c81338b8afeaae514fd5d6c08c9c6e5",
|
||||
"sector_size": 268435456
|
||||
},
|
||||
"v15-proof-of-spacetime-rational-c2ae2b440e693ee69fd6da9e85c4294c5c70c1a46d5785ca5f2a676d6cd4c8de.vk": {
|
||||
"cid": "QmdWENZBAbuUty1vVNn9vmvj1XbJ5UC8qzpcVD35s5AJxG",
|
||||
"digest": "1b755c74b9d6823c014f6a7ef76249f2",
|
||||
"v19-proof-of-spacetime-election-09ae025de08399327e14f0cb6b4c907b6fe1e8b77046e31de8921bde588de900.vk": {
|
||||
"cid": "Qmf5XQuM58jNmxudXeZMuZtGGiNzcd56Fiyn9h76wpX5dN",
|
||||
"digest": "bb0f07b6071cd28e9348223c6a9c46d1",
|
||||
"sector_size": 268435456
|
||||
},
|
||||
"v15-stacked-proof-of-replication-0c0b444c6f31d11c8e98003cc99a3b938db26b77a296d4253cda8945c234266d.params": {
|
||||
"cid": "QmZDVpWTw5Eti5pE7N5z1Cmqsw8hPXhUcvG3cQuceK56LH",
|
||||
"digest": "6aa80306018ea1328f2d6faf8c080734",
|
||||
"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",
|
||||
"v19-proof-of-spacetime-election-4a2342062706429612fac099694f77294e355c6c9265b80feaff12a0268b0a92.params": {
|
||||
"cid": "QmaHs5CHcSD6QhaGAp4ysJP4HTZaxPxybCGmUVDk3TNocA",
|
||||
"digest": "727fb2896a5668d04ba6e0ce71eb50d7",
|
||||
"sector_size": 1024
|
||||
},
|
||||
"v15-stacked-proof-of-replication-f464b92d805d03de6e2c20e2530135b2c8ec96045ec58f342d6feb90282bff8a.vk": {
|
||||
"cid": "QmTMC8hdZ2TkZ9BFuzHzRLM9SuR2PQdUrSAwABeCuHyV2f",
|
||||
"digest": "f27f08ce1246ee6612c250bb12803ef1",
|
||||
"v19-proof-of-spacetime-election-4a2342062706429612fac099694f77294e355c6c9265b80feaff12a0268b0a92.vk": {
|
||||
"cid": "QmVg8mUXMb6MiZQseAyCmHzEgNkPbV72xQoRmdFr1yJA4w",
|
||||
"digest": "3fdf4e65a7baf1a2bab5b8a717f3379a",
|
||||
"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
3
build/testing_flags.go
Normal file
@ -0,0 +1,3 @@
|
||||
package build
|
||||
|
||||
var InsecurePoStValidation = false
|
@ -40,7 +40,6 @@ func init() {
|
||||
type InitActor struct{}
|
||||
|
||||
type InitActorState struct {
|
||||
// TODO: this needs to be a HAMT, its a dumb map for now
|
||||
AddressMap cid.Cid
|
||||
|
||||
NextID uint64
|
||||
|
@ -6,6 +6,8 @@ import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
|
||||
ffi "github.com/filecoin-project/filecoin-ffi"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
@ -29,12 +31,16 @@ type StorageMinerActorState struct {
|
||||
PreCommittedSectors map[string]*PreCommittedSector
|
||||
|
||||
// All sectors this miner has committed.
|
||||
//
|
||||
// AMT[sectorID]ffi.PublicSectorInfo
|
||||
Sectors cid.Cid
|
||||
|
||||
// TODO: Spec says 'StagedCommittedSectors', which one is it?
|
||||
|
||||
// Sectors this miner is currently mining. It is only updated
|
||||
// when a PoSt is submitted (not as each new sector commitment is added).
|
||||
//
|
||||
// AMT[sectorID]ffi.PublicSectorInfo
|
||||
ProvingSet cid.Cid
|
||||
|
||||
// TODO: these:
|
||||
@ -54,12 +60,6 @@ type StorageMinerActorState struct {
|
||||
// These become the currentFaultSet when a PoSt is submitted.
|
||||
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.
|
||||
Power types.BigInt
|
||||
|
||||
@ -69,7 +69,7 @@ type StorageMinerActorState struct {
|
||||
// The height at which this miner was slashed at.
|
||||
SlashedAt uint64
|
||||
|
||||
ProvingPeriodEnd uint64
|
||||
ElectionPeriodStart uint64
|
||||
}
|
||||
|
||||
type MinerInfo struct {
|
||||
@ -117,7 +117,7 @@ type maMethods struct {
|
||||
Constructor uint64
|
||||
PreCommitSector uint64
|
||||
ProveCommitSector uint64
|
||||
SubmitPoSt uint64
|
||||
SubmitFallbackPoSt uint64
|
||||
SlashStorageFault uint64
|
||||
GetCurrentProvingSet uint64
|
||||
ArbitrateDeal uint64
|
||||
@ -133,16 +133,17 @@ type maMethods struct {
|
||||
CheckMiner uint64
|
||||
DeclareFaults 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{} {
|
||||
return []interface{}{
|
||||
1: sma.StorageMinerConstructor,
|
||||
2: sma.PreCommitSector,
|
||||
3: sma.ProveCommitSector,
|
||||
4: sma.SubmitPoSt,
|
||||
4: sma.SubmitFallbackPoSt,
|
||||
//5: sma.SlashStorageFault,
|
||||
//6: sma.GetCurrentProvingSet,
|
||||
//7: sma.ArbitrateDeal,
|
||||
@ -158,6 +159,7 @@ func (sma StorageMinerActor) Exports() []interface{} {
|
||||
17: sma.CheckMiner,
|
||||
18: sma.DeclareFaults,
|
||||
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
|
||||
// sector ID. The `faults`, `recovered`, and `done` parameters of the
|
||||
// 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 {
|
||||
return nil, err
|
||||
}
|
||||
@ -366,7 +368,9 @@ func (sma StorageMinerActor) ProveCommitSector(act *types.Actor, vmctx types.VMC
|
||||
|
||||
if pss.Count == 0 {
|
||||
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)
|
||||
@ -388,23 +392,12 @@ func (sma StorageMinerActor) ProveCommitSector(act *types.Actor, vmctx types.VMC
|
||||
return nil, err
|
||||
}
|
||||
|
||||
type SubmitPoStParams struct {
|
||||
Proof []byte
|
||||
DoneSet types.BitField
|
||||
// TODO: once the spec changes finish, we have more work to do here...
|
||||
type SubmitFallbackPoStParams struct {
|
||||
Proof []byte
|
||||
Candidates []types.EPostTicket
|
||||
}
|
||||
|
||||
func ProvingPeriodEnd(setPeriodEnd, height uint64) (uint64, uint64) {
|
||||
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) {
|
||||
func (sma StorageMinerActor) SubmitFallbackPoSt(act *types.Actor, vmctx types.VMContext, params *SubmitFallbackPoStParams) ([]byte, ActorError) {
|
||||
oldstate, self, err := loadState(vmctx)
|
||||
if err != nil {
|
||||
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")
|
||||
}
|
||||
|
||||
currentProvingPeriodEnd, _ := ProvingPeriodEnd(self.ProvingPeriodEnd, vmctx.BlockHeight())
|
||||
|
||||
feesRequired := types.NewInt(0)
|
||||
|
||||
if currentProvingPeriodEnd > self.ProvingPeriodEnd {
|
||||
//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")
|
||||
/*
|
||||
// TODO: handle 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")
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
var seed [sectorbuilder.CommLen]byte
|
||||
{
|
||||
randHeight := currentProvingPeriodEnd - build.PoStChallangeTime - build.PoStRandomnessLookback
|
||||
randHeight := self.ElectionPeriodStart + build.FallbackPoStDelay
|
||||
if vmctx.BlockHeight() <= randHeight {
|
||||
// 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)
|
||||
@ -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")
|
||||
}
|
||||
|
||||
var sectorInfos []sectorbuilder.SectorInfo
|
||||
var sectorInfos []ffi.PublicSectorInfo
|
||||
if err := pss.ForEach(func(id uint64, v *cbg.Deferred) error {
|
||||
var comms [][]byte
|
||||
if err := cbor.DecodeInto(v.Raw, &comms); err != nil {
|
||||
return xerrors.New("could not decode comms")
|
||||
}
|
||||
si := sectorbuilder.SectorInfo{
|
||||
si := ffi.PublicSectorInfo{
|
||||
SectorID: id,
|
||||
}
|
||||
commR := comms[0]
|
||||
@ -491,10 +476,23 @@ func (sma StorageMinerActor) SubmitPoSt(act *types.Actor, vmctx types.VMContext,
|
||||
}
|
||||
|
||||
faults := self.CurrentFaultSet.All()
|
||||
_ = faults
|
||||
|
||||
if ok, lerr := sectorbuilder.VerifyPost(vmctx.Context(), mi.SectorSize,
|
||||
sectorbuilder.NewSortedSectorInfo(sectorInfos), seed, params.Proof,
|
||||
faults); !ok || lerr != nil {
|
||||
proverID := vmctx.Message().To // TODO: normalize to ID address
|
||||
|
||||
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 {
|
||||
// TODO: study PoST errors
|
||||
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")
|
||||
}
|
||||
}
|
||||
self.CurrentFaultSet = self.NextFaultSet
|
||||
self.NextFaultSet = types.NewBitField()
|
||||
|
||||
ss, lerr := amt.LoadAMT(types.WrapStorage(vmctx.Storage()), self.ProvingSet)
|
||||
if lerr != 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 {
|
||||
// Post submission is successful!
|
||||
if err := onSuccessfulPoSt(self, vmctx); err != nil {
|
||||
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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -586,8 +536,8 @@ func SectorIsUnique(ctx context.Context, s types.Storage, sroot cid.Cid, sid uin
|
||||
return !found, nil
|
||||
}
|
||||
|
||||
func AddToSectorSet(ctx context.Context, s types.Storage, ss cid.Cid, sectorID uint64, commR, commD []byte) (cid.Cid, ActorError) {
|
||||
ssr, err := amt.LoadAMT(types.WrapStorage(s), ss)
|
||||
func AddToSectorSet(ctx context.Context, blks amt.Blocks, ss cid.Cid, sectorID uint64, commR, commD []byte) (cid.Cid, ActorError) {
|
||||
ssr, err := amt.LoadAMT(blks, ss)
|
||||
if err != nil {
|
||||
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 {
|
||||
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) {
|
||||
@ -817,32 +767,34 @@ type DeclareFaultsParams struct {
|
||||
}
|
||||
|
||||
func (sma StorageMinerActor) DeclareFaults(act *types.Actor, vmctx types.VMContext, params *DeclareFaultsParams) ([]byte, ActorError) {
|
||||
oldstate, self, aerr := loadState(vmctx)
|
||||
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)
|
||||
/*
|
||||
oldstate, self, aerr := loadState(vmctx)
|
||||
if aerr != nil {
|
||||
return nil, aerr
|
||||
}
|
||||
} else {
|
||||
for _, v := range params.Faults.All() {
|
||||
self.NextFaultSet.Set(v)
|
||||
|
||||
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() {
|
||||
self.NextFaultSet.Set(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nstate, err := vmctx.Storage().Put(self)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := vmctx.Storage().Commit(oldstate, nstate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nstate, err := vmctx.Storage().Put(self)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := vmctx.Storage().Commit(oldstate, nstate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
*/
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@ -892,6 +844,88 @@ func (sma StorageMinerActor) SlashConsensusFault(act *types.Actor, vmctx types.V
|
||||
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 {
|
||||
// [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}
|
||||
|
@ -3,16 +3,17 @@ package actors
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-amt-ipld"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/ipfs/go-hamt-ipld"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/lib/cborutil"
|
||||
"github.com/filecoin-project/lotus/lib/sectorbuilder"
|
||||
)
|
||||
|
||||
@ -110,6 +111,15 @@ func (sdp *StorageDealProposal) Sign(ctx context.Context, sign SignFunc) error {
|
||||
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 {
|
||||
unsigned := *sdp
|
||||
unsigned.ProposerSignature = nil
|
||||
@ -538,9 +548,7 @@ func (sma StorageMarketActor) ProcessStorageDealsPayment(act *types.Actor, vmctx
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// todo: check math (written on a plane, also tired)
|
||||
// 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))
|
||||
toPay := types.BigMul(dealInfo.Deal.Proposal.StoragePricePerEpoch, types.NewInt(build.SlashablePowerDelay))
|
||||
|
||||
b, bnd, aerr := GetMarketBalances(vmctx.Context(), vmctx.Ipld(), self.Balances, dealInfo.Deal.Proposal.Client, providerWorker)
|
||||
if aerr != nil {
|
||||
|
@ -289,8 +289,8 @@ func (spa StoragePowerActor) UpdateStorage(act *types.Actor, vmctx types.VMConte
|
||||
|
||||
self.TotalStorage = types.BigAdd(self.TotalStorage, params.Delta)
|
||||
|
||||
previousBucket := params.PreviousProvingPeriodEnd % build.ProvingPeriodDuration
|
||||
nextBucket := params.NextProvingPeriodEnd % build.ProvingPeriodDuration
|
||||
previousBucket := params.PreviousProvingPeriodEnd % build.SlashablePowerDelay
|
||||
nextBucket := params.NextProvingPeriodEnd % build.SlashablePowerDelay
|
||||
|
||||
if previousBucket == nextBucket && params.PreviousProvingPeriodEnd != 0 {
|
||||
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 {
|
||||
bucketID := height % build.ProvingPeriodDuration
|
||||
bucketID := height % build.SlashablePowerDelay
|
||||
|
||||
buckets, eerr := amt.LoadAMT(types.WrapStorage(vmctx.Storage()), self.ProvingBuckets)
|
||||
if eerr != nil {
|
||||
|
@ -170,5 +170,5 @@ func signBlock(t *testing.T, w *wallet.Wallet, worker address.Address, blk *type
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
blk.BlockSig = *sig
|
||||
blk.BlockSig = sig
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ func (t *StorageMinerActorState) MarshalCBOR(w io.Writer) error {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write([]byte{139}); err != nil {
|
||||
if _, err := w.Write([]byte{138}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -258,11 +258,6 @@ func (t *StorageMinerActorState) MarshalCBOR(w io.Writer) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.t.NextDoneSet (types.BitField) (struct)
|
||||
if err := t.NextDoneSet.MarshalCBOR(w); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.t.Power (types.BigInt) (struct)
|
||||
if err := t.Power.MarshalCBOR(w); err != nil {
|
||||
return err
|
||||
@ -278,8 +273,8 @@ func (t *StorageMinerActorState) MarshalCBOR(w io.Writer) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.t.ProvingPeriodEnd (uint64) (uint64)
|
||||
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.ProvingPeriodEnd))); err != nil {
|
||||
// t.t.ElectionPeriodStart (uint64) (uint64)
|
||||
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.ElectionPeriodStart))); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@ -296,7 +291,7 @@ func (t *StorageMinerActorState) UnmarshalCBOR(r io.Reader) error {
|
||||
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")
|
||||
}
|
||||
|
||||
@ -406,15 +401,6 @@ func (t *StorageMinerActorState) UnmarshalCBOR(r io.Reader) error {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
// t.t.NextDoneSet (types.BitField) (struct)
|
||||
|
||||
{
|
||||
|
||||
if err := t.NextDoneSet.UnmarshalCBOR(br); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
// 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")
|
||||
}
|
||||
t.SlashedAt = uint64(extra)
|
||||
// t.t.ProvingPeriodEnd (uint64) (uint64)
|
||||
// t.t.ElectionPeriodStart (uint64) (uint64)
|
||||
|
||||
maj, extra, err = cbg.CborReadHeader(br)
|
||||
if err != nil {
|
||||
@ -461,7 +447,7 @@ func (t *StorageMinerActorState) UnmarshalCBOR(r io.Reader) error {
|
||||
if maj != cbg.MajUnsignedInt {
|
||||
return fmt.Errorf("wrong type for uint64 field")
|
||||
}
|
||||
t.ProvingPeriodEnd = uint64(extra)
|
||||
t.ElectionPeriodStart = uint64(extra)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -827,7 +813,7 @@ func (t *MinerInfo) UnmarshalCBOR(r io.Reader) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *SubmitPoStParams) MarshalCBOR(w io.Writer) error {
|
||||
func (t *SubmitFallbackPoStParams) MarshalCBOR(w io.Writer) error {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
@ -844,14 +830,19 @@ func (t *SubmitPoStParams) MarshalCBOR(w io.Writer) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.t.DoneSet (types.BitField) (struct)
|
||||
if err := t.DoneSet.MarshalCBOR(w); err != nil {
|
||||
// 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 *SubmitPoStParams) UnmarshalCBOR(r io.Reader) error {
|
||||
func (t *SubmitFallbackPoStParams) UnmarshalCBOR(r io.Reader) error {
|
||||
br := cbg.GetPeeker(r)
|
||||
|
||||
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 {
|
||||
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
|
||||
}
|
||||
|
||||
t.Candidates[i] = v
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
"io"
|
||||
"strconv"
|
||||
|
||||
"github.com/filecoin-project/go-bls-sigs"
|
||||
bls "github.com/filecoin-project/filecoin-ffi"
|
||||
"github.com/filecoin-project/go-leb128"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
"github.com/minio/blake2b-simd"
|
||||
@ -389,3 +389,11 @@ func (a *Address) UnmarshalCBOR(br io.Reader) error {
|
||||
|
||||
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
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/go-bls-sigs"
|
||||
ffi "github.com/filecoin-project/filecoin-ffi"
|
||||
"github.com/filecoin-project/go-leb128"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@ -285,7 +285,7 @@ func TestVectorActorAddress(t *testing.T) {
|
||||
func TestRandomBLSAddress(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
pk := bls.PrivateKeyPublicKey(bls.PrivateKeyGenerate())
|
||||
pk := ffi.PrivateKeyPublicKey(ffi.PrivateKeyGenerate())
|
||||
|
||||
addr, err := NewBLSAddress(pk[:])
|
||||
assert.NoError(err)
|
||||
@ -410,8 +410,8 @@ func TestInvalidByteAddresses(t *testing.T) {
|
||||
{append([]byte{2}, make([]byte, PayloadHashLength+1)...), ErrInvalidPayload},
|
||||
|
||||
// BLS Protocol
|
||||
{append([]byte{3}, make([]byte, bls.PublicKeyBytes-1)...), ErrInvalidPayload},
|
||||
{append([]byte{3}, make([]byte, bls.PrivateKeyBytes+1)...), ErrInvalidPayload},
|
||||
{append([]byte{3}, make([]byte, ffi.PublicKeyBytes-1)...), ErrInvalidPayload},
|
||||
{append([]byte{3}, make([]byte, ffi.PrivateKeyBytes+1)...), ErrInvalidPayload},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
|
@ -2,9 +2,9 @@ package address
|
||||
|
||||
import (
|
||||
"encoding/base32"
|
||||
"errors"
|
||||
|
||||
"github.com/minio/blake2b-simd"
|
||||
errors "github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"io"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
xerrors "golang.org/x/xerrors"
|
||||
)
|
||||
|
@ -24,6 +24,8 @@ import (
|
||||
"github.com/filecoin-project/lotus/storage/sectorblocks"
|
||||
)
|
||||
|
||||
var ProviderDsPrefix = "/deals/provider"
|
||||
|
||||
type MinerDeal struct {
|
||||
Client peer.ID
|
||||
Proposal actors.StorageDealProposal
|
||||
@ -110,7 +112,7 @@ func NewProvider(ds dtypes.MetadataDS, sminer *storage.Miner, secb *sectorblocks
|
||||
|
||||
actor: minerAddress,
|
||||
|
||||
deals: statestore.New(namespace.Wrap(ds, datastore.NewKey("/deals/client"))),
|
||||
deals: statestore.New(namespace.Wrap(ds, datastore.NewKey(ProviderDsPrefix))),
|
||||
ds: ds,
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,9 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
@ -302,9 +304,10 @@ func (e *calledEvents) Called(check CheckFunc, hnd CalledHandler, rev RevertHand
|
||||
e.lk.Lock()
|
||||
defer e.lk.Unlock()
|
||||
|
||||
done, more, err := check(e.tsc.best())
|
||||
ts := e.tsc.best()
|
||||
done, more, err := check(ts)
|
||||
if err != nil {
|
||||
return err
|
||||
return xerrors.Errorf("called check error (h: %d): %w", ts.Height(), err)
|
||||
}
|
||||
if done {
|
||||
timeout = NoTimeout
|
||||
@ -335,6 +338,6 @@ func (e *calledEvents) Called(check CheckFunc, hnd CalledHandler, rev RevertHand
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *calledEvents) CalledMsg(ctx context.Context, hnd CalledHandler, rev RevertHandler, confidence int, timeout uint64, msg *types.Message) error {
|
||||
return e.Called(e.CheckMsg(ctx, msg, hnd), hnd, rev, confidence, timeout, e.MatchMsg(msg))
|
||||
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.VMMessage()))
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ func (e *heightEvents) headChangeAt(rev, app []*types.TipSet) error {
|
||||
span.End()
|
||||
|
||||
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
|
||||
|
@ -60,26 +60,26 @@ func makeTs(t *testing.T, h uint64, msgcid cid.Cid) *types.TipSet {
|
||||
Height: h,
|
||||
Miner: a,
|
||||
|
||||
Tickets: []*types.Ticket{{[]byte{byte(h % 2)}}},
|
||||
Ticket: &types.Ticket{[]byte{byte(h % 2)}},
|
||||
|
||||
ParentStateRoot: dummyCid,
|
||||
Messages: msgcid,
|
||||
ParentMessageReceipts: dummyCid,
|
||||
|
||||
BlockSig: types.Signature{Type: types.KTBLS},
|
||||
BlockSig: &types.Signature{Type: types.KTBLS},
|
||||
BLSAggregate: types.Signature{Type: types.KTBLS},
|
||||
},
|
||||
{
|
||||
Height: h,
|
||||
Miner: b,
|
||||
|
||||
Tickets: []*types.Ticket{{[]byte{byte((h + 1) % 2)}}},
|
||||
Ticket: &types.Ticket{[]byte{byte((h + 1) % 2)}},
|
||||
|
||||
ParentStateRoot: dummyCid,
|
||||
Messages: msgcid,
|
||||
ParentMessageReceipts: dummyCid,
|
||||
|
||||
BlockSig: types.Signature{Type: types.KTBLS},
|
||||
BlockSig: &types.Signature{Type: types.KTBLS},
|
||||
BLSAggregate: types.Signature{Type: types.KTBLS},
|
||||
},
|
||||
})
|
||||
|
@ -27,7 +27,7 @@ func TestTsCache(t *testing.T) {
|
||||
ParentStateRoot: dummyCid,
|
||||
Messages: dummyCid,
|
||||
ParentMessageReceipts: dummyCid,
|
||||
BlockSig: types.Signature{Type: types.KTBLS},
|
||||
BlockSig: &types.Signature{Type: types.KTBLS},
|
||||
BLSAggregate: types.Signature{Type: types.KTBLS},
|
||||
}})
|
||||
if err != nil {
|
||||
@ -69,7 +69,7 @@ func TestTsCacheNulls(t *testing.T) {
|
||||
ParentStateRoot: dummyCid,
|
||||
Messages: dummyCid,
|
||||
ParentMessageReceipts: dummyCid,
|
||||
BlockSig: types.Signature{Type: types.KTBLS},
|
||||
BlockSig: &types.Signature{Type: types.KTBLS},
|
||||
BLSAggregate: types.Signature{Type: types.KTBLS},
|
||||
}})
|
||||
if err != nil {
|
||||
|
@ -5,28 +5,32 @@ import (
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"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) {
|
||||
fa, err := e.cs.StateGetActor(ctx, msg.From, ts)
|
||||
if err != nil {
|
||||
return false, true, err
|
||||
}
|
||||
|
||||
// TODO: probably want to look at the chain to make sure it's
|
||||
// the right message, but this is probably good enough for now
|
||||
done = fa.Nonce >= msg.Nonce
|
||||
// >= because actor nonce is actually the next nonce that is expected to appear on chain
|
||||
if msg.Nonce >= fa.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 {
|
||||
return false, true, err
|
||||
return false, true, xerrors.Errorf("getting receipt in CheckMsg: %w", err)
|
||||
}
|
||||
|
||||
more, err = hnd(msg, rec, ts, ts.Height())
|
||||
|
||||
return done, more, err
|
||||
return true, more, err
|
||||
}
|
||||
}
|
||||
|
||||
|
299
chain/gen/gen.go
299
chain/gen/gen.go
@ -3,14 +3,20 @@ package gen
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"sync/atomic"
|
||||
|
||||
ffi "github.com/filecoin-project/filecoin-ffi"
|
||||
|
||||
"github.com/ipfs/go-blockservice"
|
||||
"github.com/ipfs/go-car"
|
||||
offline "github.com/ipfs/go-ipfs-exchange-offline"
|
||||
"github.com/ipfs/go-merkledag"
|
||||
peer "github.com/libp2p/go-libp2p-peer"
|
||||
"go.opencensus.io/trace"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
@ -20,6 +26,9 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"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"
|
||||
|
||||
block "github.com/ipfs/go-block-format"
|
||||
@ -46,10 +55,11 @@ type ChainGen struct {
|
||||
genesis *types.BlockHeader
|
||||
CurTipset *store.FullTipSet
|
||||
|
||||
Timestamper func(*types.TipSet, int) uint64
|
||||
Timestamper func(*types.TipSet, uint64) uint64
|
||||
|
||||
w *wallet.Wallet
|
||||
|
||||
eppProvs map[address.Address]ElectionPoStProver
|
||||
Miners []address.Address
|
||||
mworkers []address.Address
|
||||
receivers []address.Address
|
||||
@ -102,16 +112,6 @@ func NewGenerator() (*ChainGen, error) {
|
||||
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)
|
||||
if err != nil {
|
||||
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{
|
||||
Workers: []address.Address{worker1, worker2},
|
||||
Owners: []address.Address{worker1, worker2},
|
||||
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{
|
||||
worker1: types.FromFil(40000),
|
||||
worker2: types.FromFil(40000),
|
||||
banker: types.FromFil(50000),
|
||||
mk1: types.FromFil(40000),
|
||||
mk2: types.FromFil(40000),
|
||||
banker: types.FromFil(50000),
|
||||
}, minercfg, 100000)
|
||||
if err != nil {
|
||||
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")
|
||||
}
|
||||
|
||||
mgen := make(map[address.Address]ElectionPoStProver)
|
||||
for _, m := range minercfg.MinerAddrs {
|
||||
mgen[m] = &eppProvider{}
|
||||
}
|
||||
|
||||
sm := stmgr.NewStateManager(cs)
|
||||
|
||||
gen := &ChainGen{
|
||||
@ -163,8 +212,9 @@ func NewGenerator() (*ChainGen, error) {
|
||||
genesis: genb.Genesis,
|
||||
w: w,
|
||||
|
||||
Miners: minercfg.MinerAddrs,
|
||||
mworkers: minercfg.Workers,
|
||||
Miners: minercfg.MinerAddrs,
|
||||
eppProvs: mgen,
|
||||
//mworkers: minercfg.Workers,
|
||||
banker: banker,
|
||||
receivers: receievers,
|
||||
|
||||
@ -189,20 +239,15 @@ func (cg *ChainGen) GenesisCar() ([]byte, error) {
|
||||
out := new(bytes.Buffer)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
if len(ticks) == 0 {
|
||||
lastTicket = pts.MinTicket()
|
||||
} else {
|
||||
lastTicket = ticks[len(ticks)-1]
|
||||
}
|
||||
lastTicket := pts.MinTicket()
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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 {
|
||||
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,
|
||||
}
|
||||
|
||||
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 {
|
||||
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) {
|
||||
var blks []*types.FullBlock
|
||||
ticketSets := make([][]*types.Ticket, len(miners))
|
||||
|
||||
msgs, err := cg.getRandomMessages()
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("get random messages: %w", err)
|
||||
}
|
||||
|
||||
for len(blks) == 0 {
|
||||
for i, m := range miners {
|
||||
proof, t, err := cg.nextBlockProof(context.TODO(), base, m, ticketSets[i])
|
||||
for round := int64(base.Height() + 1); len(blks) == 0; round++ {
|
||||
for _, m := range miners {
|
||||
proof, t, err := cg.nextBlockProof(context.TODO(), base, m, round)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("next block proof: %w", err)
|
||||
}
|
||||
|
||||
ticketSets[i] = append(ticketSets[i], t)
|
||||
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 {
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
if cg.Timestamper != nil {
|
||||
ts = cg.Timestamper(parents, len(tickets))
|
||||
ts = cg.Timestamper(parents, height-parents.Height())
|
||||
} 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 {
|
||||
return nil, err
|
||||
}
|
||||
@ -354,12 +399,16 @@ func (cg *ChainGen) YieldRepo() (repo.Repo, error) {
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
@ -368,8 +417,8 @@ type mca struct {
|
||||
sm *stmgr.StateManager
|
||||
}
|
||||
|
||||
func (mca mca) ChainGetRandomness(ctx context.Context, pts types.TipSetKey, ticks []*types.Ticket, lb int) ([]byte, error) {
|
||||
return mca.sm.ChainStore().GetRandomness(ctx, pts.Cids(), ticks, int64(lb))
|
||||
func (mca mca) ChainGetRandomness(ctx context.Context, pts types.TipSetKey, lb int64) ([]byte, error) {
|
||||
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) {
|
||||
@ -388,12 +437,45 @@ func (mca mca) StateMinerWorker(ctx context.Context, maddr address.Address, ts *
|
||||
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) {
|
||||
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) {
|
||||
r, err := a.ChainGetRandomness(ctx, ts.Key(), ticks, build.EcRandomnessLookback)
|
||||
type ElectionPoStProver interface {
|
||||
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 {
|
||||
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)
|
||||
}
|
||||
|
||||
vrfout, err := ComputeVRF(ctx, a.WalletSign, mworker, r)
|
||||
vrfout, err := ComputeVRF(ctx, a.WalletSign, mworker, miner, DSepElectionPost, r)
|
||||
if err != nil {
|
||||
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)
|
||||
if err != nil {
|
||||
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)
|
||||
|
||||
func ComputeVRF(ctx context.Context, sign SignFunc, w address.Address, input []byte) ([]byte, error) {
|
||||
sig, err := sign(ctx, w, input)
|
||||
const (
|
||||
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 {
|
||||
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 {
|
||||
return nil, fmt.Errorf("miner worker address was not a BLS key")
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
@ -12,18 +12,12 @@ func testGeneration(t testing.TB, n int, msgs int) {
|
||||
|
||||
g.msgsPerBlock = msgs
|
||||
|
||||
var height int
|
||||
for i := 0; i < n; i++ {
|
||||
mts, err := g.NextTipSet()
|
||||
if err != nil {
|
||||
t.Fatalf("error at H:%d, %s", i, err)
|
||||
}
|
||||
|
||||
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)
|
||||
_ = mts
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,8 @@ package gen
|
||||
import (
|
||||
"context"
|
||||
|
||||
bls "github.com/filecoin-project/filecoin-ffi"
|
||||
amt "github.com/filecoin-project/go-amt-ipld"
|
||||
bls "github.com/filecoin-project/go-bls-sigs"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
hamt "github.com/ipfs/go-hamt-ipld"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
@ -18,14 +18,12 @@ import (
|
||||
"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)
|
||||
if err != nil {
|
||||
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)
|
||||
if err != nil {
|
||||
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{
|
||||
Miner: miner,
|
||||
Parents: parents.Cids(),
|
||||
Tickets: tickets,
|
||||
Ticket: ticket,
|
||||
Height: height,
|
||||
Timestamp: timestamp,
|
||||
ElectionProof: proof,
|
||||
EPostProof: *proof,
|
||||
ParentStateRoot: st,
|
||||
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)
|
||||
}
|
||||
|
||||
next.BlockSig = *sig
|
||||
next.BlockSig = sig
|
||||
|
||||
fullBlock := &types.FullBlock{
|
||||
Header: next,
|
||||
|
@ -1,6 +1,7 @@
|
||||
package gen
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
@ -8,6 +9,7 @@ import (
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/ipfs/go-datastore"
|
||||
hamt "github.com/ipfs/go-hamt-ipld"
|
||||
blockstore "github.com/ipfs/go-ipfs-blockstore"
|
||||
bstore "github.com/ipfs/go-ipfs-blockstore"
|
||||
peer "github.com/libp2p/go-libp2p-peer"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
@ -20,8 +22,17 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"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 {
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
for _, amt := range actmap {
|
||||
netAmt = types.BigSub(netAmt, amt)
|
||||
@ -177,46 +179,61 @@ func SetupStoragePowerActor(bs bstore.Blockstore) (*types.Actor, error) {
|
||||
}, 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)
|
||||
nd := hamt.NewNode(cst)
|
||||
emptyHAMT, err := cst.Put(context.TODO(), nd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
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 {
|
||||
return nil, xerrors.Errorf("amt build failed: %w", err)
|
||||
return cid.Undef, xerrors.Errorf("amt build failed: %w", err)
|
||||
}
|
||||
|
||||
sms := &actors.StorageMarketState{
|
||||
Balances: emptyHAMT,
|
||||
Deals: emptyAMT,
|
||||
Deals: dealAmt,
|
||||
NextDealID: 0,
|
||||
}
|
||||
|
||||
stcid, err := cst.Put(context.TODO(), sms)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
return &types.Actor{
|
||||
act := &types.Actor{
|
||||
Code: actors.StorageMarketCodeCid,
|
||||
Head: stcid,
|
||||
Nonce: 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 {
|
||||
Owners []address.Address
|
||||
Workers []address.Address
|
||||
|
||||
// not quite generating real sectors yet, but this will be necessary
|
||||
//SectorDir string
|
||||
PreSeals map[string]genesis.GenesisMiner
|
||||
|
||||
// The addresses of the created miner, this is set by the genesis setup
|
||||
MinerAddrs []address.Address
|
||||
@ -232,78 +249,250 @@ func mustEnc(i cbg.CBORMarshaler) []byte {
|
||||
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())
|
||||
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++ {
|
||||
owner := gmcfg.Owners[i]
|
||||
worker := gmcfg.Workers[i]
|
||||
pid := gmcfg.PeerIDs[i]
|
||||
if len(gmcfg.MinerAddrs) != len(gmcfg.PreSeals) {
|
||||
return cid.Undef, nil, xerrors.Errorf("miner address list, and preseal count doesn't match (%d != %d)", len(gmcfg.MinerAddrs), len(gmcfg.PreSeals))
|
||||
}
|
||||
|
||||
params := mustEnc(&actors.CreateStorageMinerParams{
|
||||
Owner: owner,
|
||||
Worker: worker,
|
||||
SectorSize: build.SectorSizes[0],
|
||||
PeerID: pid,
|
||||
})
|
||||
var deals []actors.StorageDeal
|
||||
|
||||
// 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
|
||||
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 {
|
||||
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 {
|
||||
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)
|
||||
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
|
||||
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()
|
||||
mact, err := st.GetActor(maddr)
|
||||
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
|
||||
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)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
return cid.Undef, nil, err
|
||||
}
|
||||
|
||||
mact.Head = nstate
|
||||
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) {
|
||||
@ -352,11 +541,21 @@ func MakeGenesisBlock(bs bstore.Blockstore, balances map[address.Address]types.B
|
||||
|
||||
// temp chainstore
|
||||
cs := store.NewChainStore(bs, datastore.NewMapDatastore())
|
||||
stateroot, err = SetupStorageMiners(ctx, cs, stateroot, gmcfg)
|
||||
stateroot, deals, err := SetupStorageMiners(ctx, cs, stateroot, gmcfg)
|
||||
if err != nil {
|
||||
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)
|
||||
|
||||
emptyroot, err := amt.FromArray(blks, nil)
|
||||
@ -383,9 +582,12 @@ func MakeGenesisBlock(bs bstore.Blockstore, balances map[address.Address]types.B
|
||||
}
|
||||
|
||||
b := &types.BlockHeader{
|
||||
Miner: actors.InitAddress,
|
||||
Tickets: []*types.Ticket{genesisticket},
|
||||
ElectionProof: []byte("the Genesis block"),
|
||||
Miner: actors.InitAddress,
|
||||
Ticket: genesisticket,
|
||||
EPostProof: types.EPostProof{
|
||||
Proof: []byte("not a real proof"),
|
||||
PostRand: []byte("i guess this is kinda random"),
|
||||
},
|
||||
Parents: []cid.Cid{},
|
||||
Height: 0,
|
||||
ParentWeight: types.NewInt(0),
|
||||
@ -393,7 +595,7 @@ func MakeGenesisBlock(bs bstore.Blockstore, balances map[address.Address]types.B
|
||||
Messages: mmb.Cid(),
|
||||
ParentMessageReceipts: emptyroot,
|
||||
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,
|
||||
}
|
||||
|
||||
@ -410,3 +612,37 @@ func MakeGenesisBlock(bs bstore.Blockstore, balances map[address.Address]types.B
|
||||
Genesis: b,
|
||||
}, 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()
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package chain
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"sort"
|
||||
@ -8,6 +9,9 @@ import (
|
||||
"time"
|
||||
|
||||
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"
|
||||
lps "github.com/whyrusleeping/pubsub"
|
||||
"go.uber.org/multierr"
|
||||
@ -18,6 +22,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -35,6 +40,8 @@ var (
|
||||
const (
|
||||
msgTopic = "/fil/messages"
|
||||
|
||||
localMsgsDs = "/mpool/local"
|
||||
|
||||
localUpdates = "update"
|
||||
)
|
||||
|
||||
@ -60,6 +67,8 @@ type MessagePool struct {
|
||||
blsSigCache *lru.TwoQueueCache
|
||||
|
||||
changes *lps.PubSub
|
||||
|
||||
localMsgs datastore.Datastore
|
||||
}
|
||||
|
||||
type msgSet struct {
|
||||
@ -89,7 +98,7 @@ func (ms *msgSet) add(m *types.SignedMessage) error {
|
||||
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)
|
||||
mp := &MessagePool{
|
||||
closer: make(chan struct{}),
|
||||
@ -99,10 +108,18 @@ func NewMessagePool(sm *stmgr.StateManager, ps *pubsub.PubSub) *MessagePool {
|
||||
sm: sm,
|
||||
ps: ps,
|
||||
minGasPrice: types.NewInt(0),
|
||||
maxTxPoolSize: 100000,
|
||||
maxTxPoolSize: 5000,
|
||||
blsSigCache: cache,
|
||||
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 {
|
||||
err := mp.HeadChange(rev, app)
|
||||
if err != nil {
|
||||
@ -111,7 +128,7 @@ func NewMessagePool(sm *stmgr.StateManager, ps *pubsub.PubSub) *MessagePool {
|
||||
return err
|
||||
})
|
||||
|
||||
return mp
|
||||
return mp, nil
|
||||
}
|
||||
|
||||
func (mp *MessagePool) Close() error {
|
||||
@ -134,13 +151,13 @@ func (mp *MessagePool) repubLocal() {
|
||||
for _, msg := range msgs {
|
||||
msgb, err := msg.Serialize()
|
||||
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
|
||||
}
|
||||
|
||||
err = mp.ps.Publish(msgTopic, msgb)
|
||||
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
|
||||
}
|
||||
}
|
||||
@ -156,8 +173,14 @@ func (mp *MessagePool) repubLocal() {
|
||||
|
||||
}
|
||||
|
||||
func (mp *MessagePool) addLocal(a address.Address) {
|
||||
mp.localAddrs[a] = struct{}{}
|
||||
func (mp *MessagePool) addLocal(m *types.SignedMessage, msgb []byte) error {
|
||||
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 {
|
||||
@ -171,7 +194,10 @@ func (mp *MessagePool) Push(m *types.SignedMessage) error {
|
||||
}
|
||||
|
||||
mp.lk.Lock()
|
||||
mp.addLocal(m.Message.From)
|
||||
if err := mp.addLocal(m, msgb); err != nil {
|
||||
mp.lk.Unlock()
|
||||
return err
|
||||
}
|
||||
mp.lk.Unlock()
|
||||
|
||||
return mp.ps.Publish(msgTopic, msgb)
|
||||
@ -231,13 +257,20 @@ func (mp *MessagePool) addLocked(m *types.SignedMessage) error {
|
||||
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]
|
||||
if !ok {
|
||||
mset = newMsgSet()
|
||||
mp.pending[m.Message.From] = mset
|
||||
}
|
||||
|
||||
mset.add(m)
|
||||
if err := mset.add(m); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
mp.changes.Pub(api.MpoolUpdate{
|
||||
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) {
|
||||
stateNonce, err := mp.getStateNonce(addr) // sanity check
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
mset, ok := mp.pending[addr]
|
||||
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 mp.getStateNonce(addr)
|
||||
return stateNonce, nil
|
||||
}
|
||||
|
||||
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 {
|
||||
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)
|
||||
}
|
||||
@ -328,8 +374,7 @@ func (mp *MessagePool) Remove(from address.Address, nonce uint64) {
|
||||
delete(mset.msgs, nonce)
|
||||
|
||||
if len(mset.msgs) == 0 {
|
||||
// FIXME: This is racy
|
||||
//delete(mp.pending, from)
|
||||
delete(mp.pending, from)
|
||||
} else {
|
||||
var max uint64
|
||||
for nonce := range mset.msgs {
|
||||
@ -337,6 +382,10 @@ func (mp *MessagePool) Remove(from address.Address, nonce uint64) {
|
||||
max = nonce
|
||||
}
|
||||
}
|
||||
if max < nonce {
|
||||
max = nonce // we could have not seen the removed message before
|
||||
}
|
||||
|
||||
mset.nextNonce = max + 1
|
||||
}
|
||||
}
|
||||
@ -380,7 +429,7 @@ func (mp *MessagePool) HeadChange(revert []*types.TipSet, apply []*types.TipSet)
|
||||
}
|
||||
for _, msg := range smsgs {
|
||||
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)
|
||||
if smsg != nil {
|
||||
if err := mp.Add(smsg); err != nil {
|
||||
return err
|
||||
log.Error(err) // TODO: probably lots of spam in multi-block tsets
|
||||
}
|
||||
} else {
|
||||
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)
|
||||
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
|
||||
}
|
||||
|
||||
@ -456,3 +505,31 @@ func (mp *MessagePool) Updates(ctx context.Context) (<-chan api.MpoolUpdate, err
|
||||
|
||||
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
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types.
|
||||
|
||||
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())
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ import (
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
bls "github.com/filecoin-project/go-bls-sigs"
|
||||
bls "github.com/filecoin-project/filecoin-ffi"
|
||||
"github.com/ipfs/go-cid"
|
||||
hamt "github.com/ipfs/go-hamt-ipld"
|
||||
logging "github.com/ipfs/go-log"
|
||||
@ -102,7 +102,7 @@ func (sm *StateManager) computeTipSetState(ctx context.Context, blks []*types.Bl
|
||||
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())
|
||||
if err != nil {
|
||||
@ -113,9 +113,14 @@ func (sm *StateManager) computeTipSetState(ctx context.Context, blks []*types.Bl
|
||||
if err != nil {
|
||||
return cid.Undef, cid.Undef, xerrors.Errorf("failed to get network actor: %w", err)
|
||||
}
|
||||
|
||||
reward := vm.MiningReward(netact.Balance)
|
||||
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)
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
|
||||
// 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
|
||||
@ -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) {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@ -331,11 +358,6 @@ func (sm *StateManager) GetReceipt(ctx context.Context, msg cid.Cid, ts *types.T
|
||||
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)
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
|
||||
r, err := sm.tipsetExecutedMessage(head[0].Val, mcid)
|
||||
r, err := sm.tipsetExecutedMessage(head[0].Val, mcid, msg.VMMessage())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@ -403,7 +425,7 @@ func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid) (*type
|
||||
case store.HCRevert:
|
||||
continue
|
||||
case store.HCApply:
|
||||
r, err := sm.tipsetExecutedMessage(val.Val, mcid)
|
||||
r, err := sm.tipsetExecutedMessage(val.Val, mcid, msg.VMMessage())
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
|
||||
r, err := sm.tipsetExecutedMessage(ts, m.Cid())
|
||||
r, err := sm.tipsetExecutedMessage(ts, m.Cid(), m.VMMessage())
|
||||
if err != nil {
|
||||
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
|
||||
if ts.Height() == 0 {
|
||||
return nil, nil
|
||||
@ -483,9 +505,24 @@ func (sm *StateManager) tipsetExecutedMessage(ts *types.TipSet, msg cid.Cid) (*t
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i, m := range cm {
|
||||
if m.Cid() == msg {
|
||||
return sm.cs.GetParentReceipt(ts.Blocks()[0], i)
|
||||
for ii := range cm {
|
||||
// iterate in reverse because we going backwards through the chain
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,10 +3,13 @@ package stmgr
|
||||
import (
|
||||
"context"
|
||||
|
||||
ffi "github.com/filecoin-project/filecoin-ffi"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"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/lib/sectorbuilder"
|
||||
|
||||
amt "github.com/filecoin-project/go-amt-ipld"
|
||||
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)
|
||||
}
|
||||
|
||||
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
|
||||
_, err := sm.LoadActorState(ctx, maddr, &mas, ts)
|
||||
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) {
|
||||
var mas actors.StorageMinerActorState
|
||||
_, err := sm.LoadActorState(ctx, maddr, &mas, ts)
|
||||
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)
|
||||
@ -171,17 +174,37 @@ func GetMinerSectorSet(ctx context.Context, sm *StateManager, ts *types.TipSet,
|
||||
var mas actors.StorageMinerActorState
|
||||
_, err := sm.LoadActorState(ctx, maddr, &mas, ts)
|
||||
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)
|
||||
}
|
||||
|
||||
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) {
|
||||
var mas actors.StorageMinerActorState
|
||||
_, err := sm.LoadActorState(ctx, maddr, &mas, ts)
|
||||
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())
|
||||
@ -197,7 +220,7 @@ func GetMinerSlashed(ctx context.Context, sm *StateManager, ts *types.TipSet, ma
|
||||
var mas actors.StorageMinerActorState
|
||||
_, err := sm.LoadActorState(ctx, maddr, &mas, ts)
|
||||
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
|
||||
|
@ -3,8 +3,8 @@ package store
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
@ -12,7 +12,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/vm"
|
||||
"go.opencensus.io/trace"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/multierr"
|
||||
|
||||
amt "github.com/filecoin-project/go-amt-ipld"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@ -24,7 +24,6 @@ import (
|
||||
hamt "github.com/ipfs/go-hamt-ipld"
|
||||
bstore "github.com/ipfs/go-ipfs-blockstore"
|
||||
logging "github.com/ipfs/go-log"
|
||||
"github.com/pkg/errors"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
pubsub "github.com/whyrusleeping/pubsub"
|
||||
"golang.org/x/xerrors"
|
||||
@ -100,12 +99,12 @@ func (cs *ChainStore) Load() error {
|
||||
return 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
|
||||
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)
|
||||
@ -121,11 +120,11 @@ func (cs *ChainStore) Load() error {
|
||||
func (cs *ChainStore) writeHead(ts *types.TipSet) error {
|
||||
data, err := json.Marshal(ts.Cids())
|
||||
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 {
|
||||
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
|
||||
@ -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())
|
||||
|
||||
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
|
||||
}
|
||||
@ -429,17 +428,32 @@ func (cs *ChainStore) AddToTipSetTracker(b *types.BlockHeader) error {
|
||||
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))
|
||||
|
||||
for i, header := range b {
|
||||
var err error
|
||||
sbs[i], err = header.ToStorageBlock()
|
||||
if err != nil {
|
||||
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 {
|
||||
@ -507,7 +521,7 @@ func (cs *ChainStore) AddBlock(ctx context.Context, b *types.BlockHeader) error
|
||||
}
|
||||
|
||||
if err := cs.MaybeTakeHeavierTipSet(ctx, ts); err != nil {
|
||||
return errors.Wrap(err, "MaybeTakeHeavierTipSet failed")
|
||||
return xerrors.Errorf("MaybeTakeHeavierTipSet failed: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -537,6 +551,9 @@ func (cs *ChainStore) GetCMessage(c cid.Cid) (ChainMsg, error) {
|
||||
if err == nil {
|
||||
return m, nil
|
||||
}
|
||||
if err != bstore.ErrNotFound {
|
||||
log.Warn("GetCMessage: unexpected error getting unsigned message: %s", err)
|
||||
}
|
||||
|
||||
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)
|
||||
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)
|
||||
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{
|
||||
@ -691,12 +708,12 @@ func (cs *ChainStore) MessagesForBlock(b *types.BlockHeader) ([]*types.Message,
|
||||
|
||||
blsmsgs, err := cs.LoadMessagesFromCids(blscids)
|
||||
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)
|
||||
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
|
||||
@ -706,7 +723,7 @@ func (cs *ChainStore) GetParentReceipt(b *types.BlockHeader, i int) (*types.Mess
|
||||
bs := amt.WrapBlockstore(cs.bs)
|
||||
a, err := amt.LoadAMT(bs, b.ParentMessageReceipts)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "amt load")
|
||||
return nil, xerrors.Errorf("amt load: %w", err)
|
||||
}
|
||||
|
||||
var r types.MessageReceipt
|
||||
@ -722,7 +739,7 @@ func (cs *ChainStore) LoadMessagesFromCids(cids []cid.Cid) ([]*types.Message, er
|
||||
for i, c := range cids {
|
||||
m, err := cs.GetMessage(c)
|
||||
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)
|
||||
@ -736,7 +753,7 @@ func (cs *ChainStore) LoadSignedMessagesFromCids(cids []cid.Cid) ([]*types.Signe
|
||||
for i, c := range cids {
|
||||
m, err := cs.GetSignedMessage(c)
|
||||
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)
|
||||
@ -771,24 +788,21 @@ func (cs *ChainStore) TryFillTipSet(ts *types.TipSet) (*FullTipSet, error) {
|
||||
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")
|
||||
defer span.End()
|
||||
span.AddAttributes(trace.Int64Attribute("lb", lb))
|
||||
|
||||
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
|
||||
span.AddAttributes(trace.Int64Attribute("round", round))
|
||||
|
||||
for {
|
||||
nts, err := cs.LoadTipSet(blks)
|
||||
@ -797,26 +811,21 @@ func (cs *ChainStore) GetRandomness(ctx context.Context, blks []cid.Cid, tickets
|
||||
}
|
||||
|
||||
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
|
||||
// TODO(spec): this is not in the spec, need to sync that
|
||||
if mtb.Height == 0 {
|
||||
|
||||
t := mtb.Tickets[0]
|
||||
// round is negative
|
||||
thash := drawRandomness(mtb.Ticket, round*-1)
|
||||
|
||||
rval := t.VRFProof
|
||||
for i := int64(0); i < nv; i++ {
|
||||
h := sha256.Sum256(rval)
|
||||
rval = h[:]
|
||||
}
|
||||
return rval, nil
|
||||
// for negative lookbacks, just use the hash of the positive tickethash value
|
||||
h := sha256.Sum256(thash)
|
||||
return h[:], nil
|
||||
}
|
||||
|
||||
blks = mtb.Parents
|
||||
@ -837,36 +846,33 @@ func (cs *ChainStore) GetTipsetByHeight(ctx context.Context, h uint64, ts *types
|
||||
}
|
||||
|
||||
for {
|
||||
mtb := ts.MinTicketBlock()
|
||||
if h >= ts.Height()-uint64(len(mtb.Tickets)) {
|
||||
return ts, nil
|
||||
}
|
||||
|
||||
pts, err := cs.LoadTipSet(ts.Parents())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if h > pts.Height() {
|
||||
return ts, nil
|
||||
}
|
||||
|
||||
ts = pts
|
||||
}
|
||||
}
|
||||
|
||||
type chainRand struct {
|
||||
cs *ChainStore
|
||||
blks []cid.Cid
|
||||
bh uint64
|
||||
tickets []*types.Ticket
|
||||
cs *ChainStore
|
||||
blks []cid.Cid
|
||||
bh uint64
|
||||
}
|
||||
|
||||
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{
|
||||
cs: cs,
|
||||
blks: blks,
|
||||
bh: bheight,
|
||||
tickets: tickets,
|
||||
cs: cs,
|
||||
blks: blks,
|
||||
bh: bheight,
|
||||
}
|
||||
}
|
||||
|
||||
func (cr *chainRand) GetRandomness(ctx context.Context, h int64) ([]byte, error) {
|
||||
lb := (int64(cr.bh) + int64(len(cr.tickets))) - h
|
||||
return cr.cs.GetRandomness(ctx, cr.blks, cr.tickets, lb)
|
||||
func (cr *chainRand) GetRandomness(ctx context.Context, round int64) ([]byte, error) {
|
||||
return cr.cs.GetRandomness(ctx, cr.blks, round)
|
||||
}
|
||||
|
@ -2,12 +2,13 @@ package store
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/big"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/vm"
|
||||
"golang.org/x/xerrors"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
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)
|
||||
} else {
|
||||
// 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!")
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
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)
|
||||
if err != nil {
|
||||
|
137
chain/sync.go
137
chain/sync.go
@ -3,14 +3,15 @@ package chain
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/Gurpartap/async"
|
||||
bls "github.com/filecoin-project/filecoin-ffi"
|
||||
amt "github.com/filecoin-project/go-amt-ipld"
|
||||
"github.com/filecoin-project/go-bls-sigs"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/ipfs/go-cid"
|
||||
dstore "github.com/ipfs/go-datastore"
|
||||
@ -28,10 +29,12 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"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/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/lib/sectorbuilder"
|
||||
)
|
||||
|
||||
var log = logging.Logger("chain")
|
||||
@ -506,33 +509,8 @@ func (syncer *Syncer) minerIsValid(ctx context.Context, maddr address.Address, b
|
||||
return nil
|
||||
}
|
||||
|
||||
func (syncer *Syncer) validateTickets(ctx context.Context, mworker address.Address, tickets []*types.Ticket, base *types.TipSet) error {
|
||||
ctx, span := trace.StartSpan(ctx, "validateTickets")
|
||||
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
|
||||
func (syncer *Syncer) validateTicket(ctx context.Context, maddr, mworker address.Address, ticket *types.Ticket, base *types.TipSet) error {
|
||||
return gen.VerifyVRF(ctx, mworker, maddr, gen.DSepTicket, base.MinTicket().VRFProof, ticket.VRFProof)
|
||||
}
|
||||
|
||||
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 {
|
||||
ctx, span := trace.StartSpan(ctx, "validateBlock")
|
||||
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
|
||||
|
||||
@ -550,23 +531,34 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
|
||||
}
|
||||
|
||||
// fast checks first
|
||||
if h.BlockSig == nil {
|
||||
return xerrors.Errorf("block had nil signature")
|
||||
}
|
||||
|
||||
if h.Timestamp > uint64(time.Now().Unix()+build.AllowableClockDrift) {
|
||||
return xerrors.Errorf("block was from the future")
|
||||
}
|
||||
|
||||
if h.Timestamp < baseTs.MinTimestamp()+uint64(build.BlockDelay*len(h.Tickets)) {
|
||||
log.Warn("timestamp funtimes: ", h.Timestamp, baseTs.MinTimestamp(), len(h.Tickets))
|
||||
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))
|
||||
if h.Timestamp < baseTs.MinTimestamp()+(build.BlockDelay*(h.Height-baseTs.Height())) {
|
||||
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 * deltaH:%d)", h.Timestamp, baseTs.MinTimestamp(), build.BlockDelay, h.Height-baseTs.Height())
|
||||
}
|
||||
|
||||
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 {
|
||||
return xerrors.Errorf("failed getting power: %w", err)
|
||||
}
|
||||
|
||||
if !types.PowerCmp(h.ElectionProof, mpow, tpow) {
|
||||
return xerrors.Errorf("miner created a block but was not a winner")
|
||||
ssize, err := stmgr.GetMinerSectorSize(ctx, syncer.sm, baseTs, h.Miner)
|
||||
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
|
||||
})
|
||||
@ -623,20 +615,20 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
|
||||
})
|
||||
|
||||
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 nil
|
||||
})
|
||||
|
||||
eproofCheck := async.Err(func() error {
|
||||
rand, err := syncer.sm.ChainStore().GetRandomness(ctx, baseTs.Cids(), h.Tickets, build.EcRandomnessLookback)
|
||||
if err != nil {
|
||||
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)
|
||||
if err := syncer.VerifyElectionPoStProof(ctx, h, baseTs, waddr); err != nil {
|
||||
return xerrors.Errorf("invalid election post: %w", err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
@ -660,6 +652,56 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
|
||||
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 {
|
||||
nonces := make(map[address.Address]uint64)
|
||||
balances := make(map[address.Address]types.BigInt)
|
||||
@ -1103,14 +1145,9 @@ func (syncer *Syncer) collectChain(ctx context.Context, ts *types.TipSet) error
|
||||
return nil
|
||||
}
|
||||
|
||||
func VerifyElectionProof(ctx context.Context, eproof []byte, rand []byte, worker address.Address) error {
|
||||
sig := types.Signature{
|
||||
Data: eproof,
|
||||
Type: types.KTBLS,
|
||||
}
|
||||
|
||||
if err := sig.Verify(worker, rand); err != nil {
|
||||
return xerrors.Errorf("failed to verify election proof signature: %w", err)
|
||||
func VerifyElectionPoStVRF(ctx context.Context, evrf []byte, rand []byte, worker, miner address.Address) error {
|
||||
if err := gen.VerifyVRF(ctx, worker, miner, gen.DSepElectionPost, rand, evrf); err != nil {
|
||||
return xerrors.Errorf("failed to verify post_randomness vrf: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -23,6 +23,10 @@ import (
|
||||
"github.com/filecoin-project/lotus/node/repo"
|
||||
)
|
||||
|
||||
func init() {
|
||||
build.InsecurePoStValidation = true
|
||||
}
|
||||
|
||||
const source = 0
|
||||
|
||||
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) {
|
||||
H := 50
|
||||
H := 2
|
||||
tu := prepSyncTest(t, H)
|
||||
|
||||
client := tu.addClientNode()
|
||||
@ -390,7 +394,7 @@ func TestSyncBadTimestamp(t *testing.T) {
|
||||
tu.waitUntilSync(0, client)
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -20,14 +20,24 @@ type Ticket struct {
|
||||
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 {
|
||||
Miner address.Address
|
||||
|
||||
Tickets []*Ticket
|
||||
Ticket *Ticket
|
||||
|
||||
ElectionProof []byte
|
||||
EPostProof EPostProof
|
||||
|
||||
Parents []cid.Cid
|
||||
|
||||
@ -45,7 +55,7 @@ type BlockHeader struct {
|
||||
|
||||
Timestamp uint64
|
||||
|
||||
BlockSig Signature
|
||||
BlockSig *Signature
|
||||
}
|
||||
|
||||
func (b *BlockHeader) ToStorageBlock() (block.Block, error) {
|
||||
@ -91,12 +101,12 @@ func (blk *BlockHeader) Serialize() ([]byte, error) {
|
||||
}
|
||||
|
||||
func (blk *BlockHeader) LastTicket() *Ticket {
|
||||
return blk.Tickets[len(blk.Tickets)-1]
|
||||
return blk.Ticket
|
||||
}
|
||||
|
||||
func (blk *BlockHeader) SigningBytes() ([]byte, error) {
|
||||
blkcopy := *blk
|
||||
blkcopy.BlockSig = Signature{}
|
||||
blkcopy.BlockSig = nil
|
||||
|
||||
return blkcopy.Serialize()
|
||||
}
|
||||
@ -162,29 +172,31 @@ func CidArrsEqual(a, b []cid.Cid) bool {
|
||||
|
||||
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
|
||||
(h(vrfout) + 1) / (max(h) + 1) <= e * minerPower / totalPower
|
||||
(h(vrfout) + 1) / (max(h) + 1) <= e * sectorSize / totalPower
|
||||
max(h) == 2^256-1
|
||||
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:
|
||||
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 = lhs.Mul(lhs, totpow.Int)
|
||||
lhs = lhs.Mul(lhs, big.NewInt(sampleRate))
|
||||
|
||||
// rhs = minerPower * 2^256
|
||||
// rhs = minerPower << 256
|
||||
rhs := new(big.Int).Lsh(mpow.Int, 256)
|
||||
// rhs = sectorSize * 2^256
|
||||
// rhs = sectorSize << 256
|
||||
rhs := new(big.Int).Lsh(ssize.Int, 256)
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
@ -23,12 +24,13 @@ func testBlockHeader(t testing.TB) *BlockHeader {
|
||||
}
|
||||
|
||||
return &BlockHeader{
|
||||
Miner: addr,
|
||||
ElectionProof: []byte("cats won the election"),
|
||||
Tickets: []*Ticket{
|
||||
&Ticket{
|
||||
VRFProof: []byte("vrf proof0000000vrf proof0000000"),
|
||||
},
|
||||
Miner: addr,
|
||||
EPostProof: EPostProof{
|
||||
Proof: []byte("pruuf"),
|
||||
PostRand: []byte("random"),
|
||||
},
|
||||
Ticket: &Ticket{
|
||||
VRFProof: []byte("vrf proof0000000vrf proof0000000"),
|
||||
},
|
||||
Parents: []cid.Cid{c, c},
|
||||
ParentMessageReceipts: c,
|
||||
@ -37,7 +39,7 @@ func testBlockHeader(t testing.TB) *BlockHeader {
|
||||
Messages: c,
|
||||
Height: 85919298723,
|
||||
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) {
|
||||
fmt.Printf("%#v\n", &out)
|
||||
fmt.Printf("%#v\n", bh)
|
||||
t.Fatal("not equal")
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"io"
|
||||
"math"
|
||||
|
||||
cid "github.com/ipfs/go-cid"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
xerrors "golang.org/x/xerrors"
|
||||
)
|
||||
@ -28,21 +28,13 @@ func (t *BlockHeader) MarshalCBOR(w io.Writer) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.t.Tickets ([]*types.Ticket) (slice)
|
||||
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Tickets)))); err != nil {
|
||||
// t.t.Ticket (types.Ticket) (struct)
|
||||
if err := t.Ticket.MarshalCBOR(w); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, v := range t.Tickets {
|
||||
if err := v.MarshalCBOR(w); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// t.t.ElectionProof ([]uint8) (slice)
|
||||
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.ElectionProof)))); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write(t.ElectionProof); err != nil {
|
||||
// t.t.EPostProof (types.EPostProof) (struct)
|
||||
if err := t.EPostProof.MarshalCBOR(w); err != nil {
|
||||
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 {
|
||||
return fmt.Errorf("expected cbor array")
|
||||
}
|
||||
if extra > 0 {
|
||||
t.Tickets = make([]*Ticket, extra)
|
||||
}
|
||||
for i := 0; i < int(extra); i++ {
|
||||
pb, err := br.PeekByte()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if pb == cbg.CborNull[0] {
|
||||
var nbuf [1]byte
|
||||
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
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
@ -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
|
||||
}
|
||||
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
|
||||
@ -333,6 +324,205 @@ func (t *Ticket) UnmarshalCBOR(r io.Reader) error {
|
||||
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 {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
|
@ -34,12 +34,12 @@ func MkBlock(parents *types.TipSet, weightInc uint64, ticketNonce uint64) *types
|
||||
}
|
||||
|
||||
return &types.BlockHeader{
|
||||
Miner: addr,
|
||||
ElectionProof: []byte("cats won the election"),
|
||||
Tickets: []*types.Ticket{
|
||||
{
|
||||
VRFProof: []byte(fmt.Sprintf("====%d=====", ticketNonce)),
|
||||
},
|
||||
Miner: addr,
|
||||
EPostProof: types.EPostProof{
|
||||
Proof: []byte("election post proof proof"),
|
||||
},
|
||||
Ticket: &types.Ticket{
|
||||
VRFProof: []byte(fmt.Sprintf("====%d=====", ticketNonce)),
|
||||
},
|
||||
Parents: pcids,
|
||||
ParentMessageReceipts: c,
|
||||
@ -48,7 +48,7 @@ func MkBlock(parents *types.TipSet, weightInc uint64, ticketNonce uint64) *types
|
||||
Messages: c,
|
||||
Height: height,
|
||||
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")},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ package types
|
||||
import (
|
||||
"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/lib/crypto"
|
||||
"github.com/minio/blake2b-simd"
|
||||
|
@ -165,8 +165,7 @@ func (t *Ticket) Less(o *Ticket) bool {
|
||||
}
|
||||
|
||||
func (ts *TipSet) MinTicket() *Ticket {
|
||||
b := ts.MinTicketBlock()
|
||||
return b.Tickets[len(b.Tickets)-1]
|
||||
return ts.MinTicketBlock().Ticket
|
||||
}
|
||||
|
||||
func (ts *TipSet) MinTimestamp() uint64 {
|
||||
|
@ -3,7 +3,7 @@ package types
|
||||
import (
|
||||
"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/address"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
@ -48,8 +48,8 @@ type storageWrapper struct {
|
||||
s Storage
|
||||
}
|
||||
|
||||
func (sw *storageWrapper) Put(i interface{}) (cid.Cid, error) {
|
||||
c, err := sw.s.Put(i.(cbg.CBORMarshaler))
|
||||
func (sw *storageWrapper) Put(i cbg.CBORMarshaler) (cid.Cid, error) {
|
||||
c, err := sw.s.Put(i)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
}
|
||||
@ -57,8 +57,8 @@ func (sw *storageWrapper) Put(i interface{}) (cid.Cid, error) {
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (sw *storageWrapper) Get(c cid.Cid, out interface{}) error {
|
||||
if err := sw.s.Get(c, out.(cbg.CBORUnmarshaler)); err != nil {
|
||||
func (sw *storageWrapper) Get(c cid.Cid, out cbg.CBORUnmarshaler) error {
|
||||
if err := sw.s.Get(c, out); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -3,11 +3,10 @@ package validation
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"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/state"
|
||||
@ -43,7 +42,7 @@ func (mf *MessageFactory) MakeMessage(from, to state.Address, method chain.Metho
|
||||
}
|
||||
|
||||
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]
|
||||
msg := &types.Message{
|
||||
|
@ -5,11 +5,10 @@ import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/gen"
|
||||
"github.com/filecoin-project/lotus/chain/vm"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"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.
|
||||
_, err = tree.RegisterNewAddress(addrInt, &actr.Actor)
|
||||
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)
|
||||
}
|
||||
@ -131,17 +130,24 @@ func (s *StateWrapper) SetSingletonActor(addr vstate.SingletonActorID, balance v
|
||||
return nil, nil, err
|
||||
}
|
||||
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)
|
||||
case actors.StorageMarketAddress:
|
||||
smact, err := gen.SetupStorageMarketActor(s.bs)
|
||||
nsroot, err := gen.SetupStorageMarketActor(s.bs, s.stateRoot, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := tree.SetActor(actors.StorageMarketAddress, smact); err != nil {
|
||||
return nil, nil, errors.Wrapf(err, "set network storage market actor")
|
||||
s.stateRoot = nsroot
|
||||
|
||||
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)
|
||||
case actors.StoragePowerAddress:
|
||||
@ -150,7 +156,7 @@ func (s *StateWrapper) SetSingletonActor(addr vstate.SingletonActorID, balance v
|
||||
return nil, nil, err
|
||||
}
|
||||
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)
|
||||
case actors.NetworkAddress:
|
||||
@ -160,7 +166,7 @@ func (s *StateWrapper) SetSingletonActor(addr vstate.SingletonActorID, balance v
|
||||
Head: vm.EmptyObjectCid,
|
||||
}
|
||||
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)
|
||||
case actors.BurntFundsAddress:
|
||||
@ -170,11 +176,11 @@ func (s *StateWrapper) SetSingletonActor(addr vstate.SingletonActorID, balance v
|
||||
Head: vm.EmptyObjectCid,
|
||||
}
|
||||
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)
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,9 +42,13 @@ func newInvoker() *invoker {
|
||||
|
||||
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]
|
||||
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))
|
||||
}
|
||||
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]
|
||||
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)
|
||||
|
@ -12,7 +12,7 @@ import (
|
||||
func TestBlockReward(t *testing.T) {
|
||||
coffer := types.FromFil(build.MiningRewardTotal).Int
|
||||
sum := new(big.Int)
|
||||
N := build.HalvingPeriodBlocks
|
||||
N := build.HalvingPeriodEpochs
|
||||
for i := 0; i < N; i++ {
|
||||
a := MiningReward(types.BigInt{coffer})
|
||||
sum = sum.Add(sum, a.Int)
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/filecoin-project/go-bls-sigs"
|
||||
bls "github.com/filecoin-project/filecoin-ffi"
|
||||
|
||||
logging "github.com/ipfs/go-log"
|
||||
"github.com/minio/blake2b-simd"
|
||||
@ -41,6 +41,17 @@ func NewWallet(keystore types.KeyStore) (*Wallet, error) {
|
||||
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) {
|
||||
ki, err := w.findKey(addr)
|
||||
if err != nil {
|
||||
@ -85,6 +96,11 @@ func (w *Wallet) findKey(addr address.Address) (*Key, error) {
|
||||
if ok {
|
||||
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())
|
||||
if err != nil {
|
||||
if xerrors.Is(err, types.ErrKeyInfoNotFound) {
|
||||
|
@ -143,7 +143,6 @@ var Commands = []*cli.Command{
|
||||
sendCmd,
|
||||
stateCmd,
|
||||
syncCmd,
|
||||
unregisterMinerCmd,
|
||||
versionCmd,
|
||||
walletCmd,
|
||||
}
|
||||
|
32
cli/miner.go
32
cli/miner.go
@ -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)
|
||||
},
|
||||
}
|
77
cli/mpool.go
77
cli/mpool.go
@ -4,7 +4,11 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
var mpoolCmd = &cli.Command{
|
||||
@ -13,6 +17,7 @@ var mpoolCmd = &cli.Command{
|
||||
Subcommands: []*cli.Command{
|
||||
mpoolPending,
|
||||
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
264
cmd/lotus-bench/main.go
Normal 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 := §orbuilder.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
|
||||
}
|
||||
}
|
@ -252,7 +252,7 @@ func (st *storage) storeMiners(miners map[minerKey]*minerInfo) error {
|
||||
i.info.SectorSize,
|
||||
i.state.Power.String(),
|
||||
i.state.Active,
|
||||
i.state.ProvingPeriodEnd,
|
||||
i.state.ElectionPeriodStart,
|
||||
i.state.SlashedAt,
|
||||
); err != nil {
|
||||
return err
|
||||
|
@ -4,9 +4,10 @@ import (
|
||||
"bytes"
|
||||
"container/list"
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
actors2 "github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"sync"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
|
89
cmd/lotus-seed/main.go
Normal file
89
cmd/lotus-seed/main.go
Normal 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
167
cmd/lotus-seed/seed/seed.go
Normal 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 := §orbuilder.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
|
||||
}
|
@ -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("\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 {
|
||||
return err
|
||||
}
|
||||
|
@ -3,22 +3,36 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
||||
"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/peer"
|
||||
"github.com/mitchellh/go-homedir"
|
||||
"golang.org/x/xerrors"
|
||||
"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/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/lotus/chain/deals"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
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/storage"
|
||||
)
|
||||
|
||||
var initCmd = &cli.Command{
|
||||
@ -53,6 +67,10 @@ var initCmd = &cli.Command{
|
||||
Usage: "specify sector size to use",
|
||||
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 {
|
||||
log.Info("Initializing lotus storage miner")
|
||||
@ -104,6 +122,25 @@ var initCmd = &cli.Command{
|
||||
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 {
|
||||
log.Errorf("Failed to initialize lotus-storage-miner: %+v", err)
|
||||
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)
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
|
||||
mds, err := lr.Datastore("/metadata")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var addr address.Address
|
||||
if act := cctx.String("actor"); 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)
|
||||
}
|
||||
|
||||
if err := configureStorageMiner(ctx, api, a, peerid, cctx.Bool("genesis-miner")); err != nil {
|
||||
return xerrors.Errorf("failed to configure storage miner: %w", err)
|
||||
if cctx.Bool("genesis-miner") {
|
||||
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
|
||||
@ -165,12 +404,7 @@ func storageMinerInit(ctx context.Context, cctx *cli.Context, api api.FullNode,
|
||||
}
|
||||
|
||||
log.Infof("Created new storage miner: %s", addr)
|
||||
|
||||
ds, err := lr.Datastore("/metadata")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ds.Put(datastore.NewKey("miner-address"), addr.Bytes()); err != nil {
|
||||
if err := mds.Put(datastore.NewKey("miner-address"), addr.Bytes()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -203,22 +437,7 @@ func makeHostKey(lr repo.LockedRepo) (crypto.PrivKey, error) {
|
||||
return pk, nil
|
||||
}
|
||||
|
||||
func configureStorageMiner(ctx context.Context, api api.FullNode, addr address.Address, peerid peer.ID, genmine bool) 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)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func configureStorageMiner(ctx context.Context, api lapi.FullNode, addr address.Address, peerid peer.ID) error {
|
||||
// This really just needs to be an api call at this point...
|
||||
recp, err := api.StateCall(ctx, &types.Message{
|
||||
To: addr,
|
||||
@ -271,7 +490,7 @@ func configureStorageMiner(ctx context.Context, api api.FullNode, addr address.A
|
||||
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")
|
||||
|
||||
var owner address.Address
|
||||
|
@ -70,7 +70,7 @@ func main() {
|
||||
}
|
||||
|
||||
if err := app.Run(os.Args); err != nil {
|
||||
log.Warn(err)
|
||||
log.Warnf("%+v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ var runCmd = &cli.Command{
|
||||
&cli.BoolFlag{
|
||||
Name: "enable-gpu-proving",
|
||||
Usage: "Enable use of GPU for mining operations",
|
||||
Value: true,
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
|
@ -21,7 +21,8 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
makeGenFlag = "lotus-make-random-genesis"
|
||||
makeGenFlag = "lotus-make-random-genesis"
|
||||
preSealedSectorsFlag = "genesis-presealed-sectors"
|
||||
)
|
||||
|
||||
// DaemonCmd is the `go-lotus daemon` command
|
||||
@ -38,6 +39,10 @@ var DaemonCmd = &cli.Command{
|
||||
Value: "",
|
||||
Hidden: true,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: preSealedSectorsFlag,
|
||||
Hidden: true,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "genesis",
|
||||
Usage: "genesis file to use for first node run",
|
||||
@ -51,11 +56,11 @@ var DaemonCmd = &cli.Command{
|
||||
ctx := context.Background()
|
||||
r, err := repo.NewFS(cctx.String("repo"))
|
||||
if err != nil {
|
||||
return err
|
||||
return xerrors.Errorf("opening fs repo: %w", err)
|
||||
}
|
||||
|
||||
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 {
|
||||
@ -67,9 +72,8 @@ var DaemonCmd = &cli.Command{
|
||||
if cctx.String("genesis") != "" {
|
||||
genBytes, err = ioutil.ReadFile(cctx.String("genesis"))
|
||||
if err != nil {
|
||||
return err
|
||||
return xerrors.Errorf("reading genesis: %w", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
genesis := node.Options()
|
||||
@ -77,7 +81,10 @@ var DaemonCmd = &cli.Command{
|
||||
genesis = node.Override(new(modules.Genesis), modules.LoadGenesis(genBytes))
|
||||
}
|
||||
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
|
||||
@ -105,12 +112,12 @@ var DaemonCmd = &cli.Command{
|
||||
),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
return xerrors.Errorf("initializing node: %w", err)
|
||||
}
|
||||
|
||||
endpoint, err := r.APIEndpoint()
|
||||
if err != nil {
|
||||
return err
|
||||
return xerrors.Errorf("getting api endpoint: %w", err)
|
||||
}
|
||||
|
||||
// TODO: properly parse api endpoint (or make it a URL)
|
||||
|
@ -69,7 +69,7 @@ func main() {
|
||||
Code: trace.StatusCodeFailedPrecondition,
|
||||
Message: err.Error(),
|
||||
})
|
||||
log.Warn(err)
|
||||
log.Warnf("%+v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
return
|
||||
|
1
extern/filecoin-ffi
vendored
Submodule
1
extern/filecoin-ffi
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 0e71b164cf4b2e1c0f53ca25145e3ea57cc53e90
|
1
extern/go-bls-sigs
vendored
1
extern/go-bls-sigs
vendored
@ -1 +0,0 @@
|
||||
Subproject commit 98479d3c79620f18783da0c2c6a15f8b8eb4fa2e
|
1
extern/go-sectorbuilder
vendored
1
extern/go-sectorbuilder
vendored
@ -1 +0,0 @@
|
||||
Subproject commit 40278d4a6623e4c81003e20444871c9362bedd61
|
@ -20,6 +20,8 @@ func main() {
|
||||
err := gen.WriteTupleEncodersToFile("./chain/types/cbor_gen.go", "types",
|
||||
types.BlockHeader{},
|
||||
types.Ticket{},
|
||||
types.EPostProof{},
|
||||
types.EPostTicket{},
|
||||
types.Message{},
|
||||
types.SignedMessage{},
|
||||
types.MsgMeta{},
|
||||
@ -91,7 +93,7 @@ func main() {
|
||||
actors.SectorPreCommitInfo{},
|
||||
actors.PreCommittedSector{},
|
||||
actors.MinerInfo{},
|
||||
actors.SubmitPoStParams{},
|
||||
actors.SubmitFallbackPoStParams{},
|
||||
actors.PaymentVerifyParams{},
|
||||
actors.UpdatePeerIDParams{},
|
||||
actors.MultiSigActorState{},
|
||||
|
25
genesis/types.go
Normal file
25
genesis/types.go
Normal 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
37
go.mod
@ -8,19 +8,17 @@ require (
|
||||
github.com/GeertJohan/go.rice v1.0.0
|
||||
github.com/Gurpartap/async v0.0.0-20180927173644-4f7f499dd9ee
|
||||
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/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/go-bls-sigs v0.0.0-20190718224239-4bc4b8a7bbf8
|
||||
github.com/filecoin-project/filecoin-ffi v0.0.0-00010101000000-000000000000
|
||||
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-sectorbuilder v0.0.0-00010101000000-000000000000
|
||||
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1
|
||||
github.com/go-ole/go-ole v1.2.4 // indirect
|
||||
github.com/google/go-cmp v0.3.1 // indirect
|
||||
github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f // indirect
|
||||
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/golang-lru v0.5.3
|
||||
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-ipld-cbor v0.0.3
|
||||
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-unixfs v0.2.2-0.20190827150610-868af2e9e5cb
|
||||
github.com/ipld/go-ipld-prime v0.0.2-0.20191025154717-8dff1cbec43b
|
||||
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-circuit v0.1.1
|
||||
github.com/libp2p/go-libp2p-connmgr v0.1.0
|
||||
github.com/libp2p/go-libp2p-core v0.2.2
|
||||
github.com/libp2p/go-libp2p-discovery v0.1.0
|
||||
github.com/libp2p/go-libp2p-core v0.2.4
|
||||
github.com/libp2p/go-libp2p-discovery v0.2.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-mplex v0.2.1
|
||||
@ -62,31 +59,30 @@ require (
|
||||
github.com/libp2p/go-libp2p-peerstore v0.1.3
|
||||
github.com/libp2p/go-libp2p-pnet 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-record v0.1.1
|
||||
github.com/libp2p/go-libp2p-routing-helpers v0.1.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-yamux v0.2.1
|
||||
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-runewidth v0.0.4 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.12.0
|
||||
github.com/miekg/dns v1.1.16 // indirect
|
||||
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/multiformats/go-base32 v0.0.3
|
||||
github.com/multiformats/go-multiaddr v0.0.4
|
||||
github.com/multiformats/go-multiaddr-dns v0.0.3
|
||||
github.com/multiformats/go-multiaddr-net v0.0.1
|
||||
github.com/multiformats/go-multiaddr v0.1.1
|
||||
github.com/multiformats/go-multiaddr-dns v0.2.0
|
||||
github.com/multiformats/go-multiaddr-net v0.1.0
|
||||
github.com/multiformats/go-multihash v0.0.9
|
||||
github.com/onsi/ginkgo v1.9.0 // indirect
|
||||
github.com/onsi/gomega v1.6.0 // indirect
|
||||
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/smartystreets/assertions v1.0.1 // 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/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7
|
||||
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/fx v1.9.0
|
||||
go.uber.org/goleak v0.10.0 // indirect
|
||||
go.uber.org/multierr v1.1.0
|
||||
go.uber.org/zap v1.10.0
|
||||
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/xerrors v0.0.0-20190717185122-a985d3407aa7
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898
|
||||
google.golang.org/api v0.9.0 // indirect
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.28
|
||||
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/filecoin-project/go-bls-sigs => ./extern/go-bls-sigs
|
||||
|
||||
replace github.com/filecoin-project/go-sectorbuilder => ./extern/go-sectorbuilder
|
||||
replace github.com/filecoin-project/filecoin-ffi => ./extern/filecoin-ffi
|
||||
|
78
go.sum
78
go.sum
@ -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-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-20190807005414-4063feeff79a h1:We35J+0yvVFrEXbtViYUW8H/wNOhqjIF3PsrW4yYmGw=
|
||||
github.com/btcsuite/btcd v0.0.0-20190807005414-4063feeff79a/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
|
||||
github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3 h1:A/EVblehb75cUgXA5njHPn0kLAsykn6mJGz7rnmW5W0=
|
||||
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/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=
|
||||
@ -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/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/go-amt-ipld v0.0.0-20190919045431-3650716fff16 h1:NzojcJU1VbS6zdLG13JMYis/cQy/MrN3rxmZRq56jKA=
|
||||
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 h1:lKSMm8Go6qI7+Dk3rWCNIh57wBOqVNJ21re/p7D58gc=
|
||||
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/go.mod h1:mjrHv1cDGJWDlGmC0eDc1E5VJr8DmL9XMUcaFwiuKg8=
|
||||
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.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
|
||||
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/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.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk=
|
||||
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/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.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/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=
|
||||
@ -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/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.2-0.20190920042044-a609c1ae5144 h1:5WM8S1nwquWQ3zEuNhK82NE5Di6Pd41qz9JxxvxTAIA=
|
||||
github.com/ipfs/go-log v0.0.2-0.20190920042044-a609c1ae5144/go.mod h1:azGN5dH7ailfREknDDNYB0Eq4qZ/4I4Y3gO0ivjJNyM=
|
||||
github.com/ipfs/go-log v1.0.0 h1:BW3LQIiZzpNyolt84yvKNCd3FU+AK4VDw1hnHR+1aiI=
|
||||
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.2.3/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB3ClKnBAlk=
|
||||
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/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.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/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=
|
||||
@ -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.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.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.1 h1:eopfG9fAg6rEHWQO1TSrLosXDgYbbbu/RTva/tBANus=
|
||||
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.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.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.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-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.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.1.0 h1:OZwENiFm6JOK3YR5PZJxkXlJE8a5u8g4YvAUrEV2MjM=
|
||||
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.1.0 h1:HdqhEyhg0ToCaxgMhnOmUO8snQtt/kQlcjVk3UoJU3c=
|
||||
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.1.0/go.mod h1:ZwlKzRSe1eGvSIdU5bD7+8RZN/Uzw0t1Bp9R1znpR/Q=
|
||||
github.com/libp2p/go-libp2p-pubsub v0.2.3 h1:qJRnRnM7Z4xnHb4i6EBb3DKQXRPgtFWlKP4AmfJudLQ=
|
||||
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/go.mod h1:wqG/jzhF3Pu2NrhJEvE+IE0NTHNXslOPn9JQzyCAxzU=
|
||||
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-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.1 h1:9A8oQqPIZvbaRyrjViHeDYS7fE7fNtP7BRWdJrBHbe8=
|
||||
github.com/libp2p/go-libp2p-swarm v0.2.1/go.mod h1:x07b4zkMFo2EvgPV2bMTlNmdQc8i+74Jjio7xGvsTgU=
|
||||
github.com/libp2p/go-libp2p-swarm v0.2.2 h1:T4hUpgEs2r371PweU3DuH7EOmBIdTBCwWs+FLcgx3bQ=
|
||||
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.3/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-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.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/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA=
|
||||
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-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.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-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.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.3 h1:xX8A36vpXb59frIzWFdEgptLMsOANMFq2K7fPRlunYI=
|
||||
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/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.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
|
||||
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.5/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.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 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/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
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.4 h1:WgMSI84/eRLdbptXMkMWDXPjPq7SPLIgGUVm2eroyU4=
|
||||
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.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.0.3/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q=
|
||||
github.com/multiformats/go-multiaddr-dns v0.2.0 h1:YWJoIDwLePniH7OU5hBnDZV6SWuvJqJ0YtN6pLeH9zA=
|
||||
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/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/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/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.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/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew=
|
||||
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/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/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/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
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=
|
||||
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.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.1 h1:8dP3SGL7MPB94crU3bEPplMPe83FI4EouesJUeFHv50=
|
||||
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/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
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-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-20190829043050-9756ffdc2472 h1:Gv7RPwsi3eZ2Fgewe3CBsuOebPwO27PoXzRpJPsvSSM=
|
||||
golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
|
||||
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/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=
|
||||
@ -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-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-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-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-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-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-20190226205417-e64efc72b421/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-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-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-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.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
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-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-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-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
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-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-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.2/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
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=
|
||||
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 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-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
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/go.mod h1:cKXr3E0k4aosgycml1b5z33BVV6hai1Kh7uDgFOkbcs=
|
||||
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.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"io"
|
||||
"math/bits"
|
||||
|
||||
sectorbuilder "github.com/filecoin-project/go-sectorbuilder"
|
||||
sectorbuilder "github.com/filecoin-project/filecoin-ffi"
|
||||
)
|
||||
|
||||
func PaddedSize(size uint64) uint64 {
|
||||
|
@ -1,8 +1,9 @@
|
||||
package padreader
|
||||
|
||||
import (
|
||||
"gotest.tools/assert"
|
||||
"testing"
|
||||
|
||||
"gotest.tools/assert"
|
||||
)
|
||||
|
||||
func TestComputePaddedSize(t *testing.T) {
|
||||
|
@ -17,8 +17,6 @@ func TempSectorbuilder(sectorSize uint64, ds dtypes.MetadataDS) (*SectorBuilder,
|
||||
|
||||
sb, err := TempSectorbuilderDir(dir, sectorSize, ds)
|
||||
return sb, func() {
|
||||
sb.Destroy()
|
||||
|
||||
if err := os.RemoveAll(dir); err != nil {
|
||||
log.Warn("failed to clean up temp sectorbuilder: ", err)
|
||||
}
|
||||
|
1
lib/sectorbuilder/post.go
Normal file
1
lib/sectorbuilder/post.go
Normal file
@ -0,0 +1 @@
|
||||
package sectorbuilder
|
@ -7,13 +7,13 @@ import (
|
||||
"strconv"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"unsafe"
|
||||
|
||||
sectorbuilder "github.com/filecoin-project/go-sectorbuilder"
|
||||
sectorbuilder "github.com/filecoin-project/filecoin-ffi"
|
||||
"github.com/ipfs/go-datastore"
|
||||
logging "github.com/ipfs/go-log"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
)
|
||||
@ -21,17 +21,12 @@ import (
|
||||
const PoStReservedWorkers = 1
|
||||
const PoRepProofPartitions = 2
|
||||
|
||||
var lastSectorIdKey = datastore.NewKey("/sectorbuilder/last")
|
||||
var LastSectorIdKey = datastore.NewKey("/sectorbuilder/last")
|
||||
|
||||
var log = logging.Logger("sectorbuilder")
|
||||
|
||||
type SectorSealingStatus = sectorbuilder.SectorSealingStatus
|
||||
|
||||
type StagedSectorMetadata = sectorbuilder.StagedSectorMetadata
|
||||
|
||||
type SortedSectorInfo = sectorbuilder.SortedSectorInfo
|
||||
|
||||
type SectorInfo = sectorbuilder.SectorInfo
|
||||
type SortedPublicSectorInfo = sectorbuilder.SortedPublicSectorInfo
|
||||
type SortedPrivateSectorInfo = sectorbuilder.SortedPrivateSectorInfo
|
||||
|
||||
type SealTicket = sectorbuilder.SealTicket
|
||||
|
||||
@ -45,14 +40,16 @@ type PublicPieceInfo = sectorbuilder.PublicPieceInfo
|
||||
|
||||
type RawSealPreCommitOutput sectorbuilder.RawSealPreCommitOutput
|
||||
|
||||
type EPostCandidate = sectorbuilder.Candidate
|
||||
|
||||
const CommLen = sectorbuilder.CommitmentBytesLen
|
||||
|
||||
type SectorBuilder struct {
|
||||
handle unsafe.Pointer
|
||||
ds dtypes.MetadataDS
|
||||
idLk sync.Mutex
|
||||
ds dtypes.MetadataDS
|
||||
idLk sync.Mutex
|
||||
|
||||
ssize uint64
|
||||
ssize uint64
|
||||
lastID uint64
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
proverId := addressToProverID(cfg.Miner)
|
||||
|
||||
for _, dir := range []string{cfg.StagedDir, cfg.SealedDir, cfg.CacheDir, cfg.MetadataDir} {
|
||||
if err := os.Mkdir(dir, 0755); err != nil {
|
||||
if os.IsExist(err) {
|
||||
@ -142,7 +137,7 @@ func New(cfg *Config, ds dtypes.MetadataDS) (*SectorBuilder, error) {
|
||||
}
|
||||
|
||||
var lastUsedID uint64
|
||||
b, err := ds.Get(lastSectorIdKey)
|
||||
b, err := ds.Get(LastSectorIdKey)
|
||||
switch err {
|
||||
case nil:
|
||||
i, err := strconv.ParseInt(string(b), 10, 64)
|
||||
@ -155,11 +150,6 @@ func New(cfg *Config, ds dtypes.MetadataDS) (*SectorBuilder, error) {
|
||||
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
|
||||
|
||||
sealLocal := rlimit > 0
|
||||
@ -169,10 +159,10 @@ func New(cfg *Config, ds dtypes.MetadataDS) (*SectorBuilder, error) {
|
||||
}
|
||||
|
||||
sb := &SectorBuilder{
|
||||
handle: sbp,
|
||||
ds: ds,
|
||||
ds: ds,
|
||||
|
||||
ssize: cfg.SectorSize,
|
||||
ssize: cfg.SectorSize,
|
||||
lastID: lastUsedID,
|
||||
|
||||
stagedDir: cfg.StagedDir,
|
||||
sealedDir: cfg.SealedDir,
|
||||
@ -205,9 +195,10 @@ func NewStandalone(cfg *Config) (*SectorBuilder, error) {
|
||||
}
|
||||
|
||||
return &SectorBuilder{
|
||||
handle: nil,
|
||||
ds: nil,
|
||||
|
||||
ssize: cfg.SectorSize,
|
||||
|
||||
Miner: cfg.Miner,
|
||||
stagedDir: cfg.StagedDir,
|
||||
sealedDir: cfg.SealedDir,
|
||||
@ -272,19 +263,14 @@ func addressToProverID(a address.Address) [32]byte {
|
||||
return proverId
|
||||
}
|
||||
|
||||
func (sb *SectorBuilder) Destroy() {
|
||||
sectorbuilder.DestroySectorBuilder(sb.handle)
|
||||
}
|
||||
|
||||
func (sb *SectorBuilder) AcquireSectorId() (uint64, error) {
|
||||
sb.idLk.Lock()
|
||||
defer sb.idLk.Unlock()
|
||||
|
||||
id, err := sectorbuilder.AcquireSectorId(sb.handle)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
err = sb.ds.Put(lastSectorIdKey, []byte(fmt.Sprint(id)))
|
||||
sb.lastID++
|
||||
id := sb.lastID
|
||||
|
||||
err := sb.ds.Put(LastSectorIdKey, []byte(fmt.Sprint(id)))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -305,7 +291,7 @@ func (sb *SectorBuilder) AddPiece(pieceSize uint64, sectorId uint64, file io.Rea
|
||||
return PublicPieceInfo{}, err
|
||||
}
|
||||
|
||||
_, _, commP, err := sectorbuilder.StandaloneWriteWithAlignment(f, pieceSize, stagedFile, existingPieceSizes)
|
||||
_, _, commP, err := sectorbuilder.WriteWithAlignment(f, pieceSize, stagedFile, existingPieceSizes)
|
||||
if err != nil {
|
||||
return PublicPieceInfo{}, err
|
||||
}
|
||||
@ -329,7 +315,8 @@ func (sb *SectorBuilder) ReadPieceFromSealedSector(pieceKey string) ([]byte, err
|
||||
ret := sb.RateLimit()
|
||||
defer ret()
|
||||
|
||||
return sectorbuilder.ReadPieceFromSealedSector(sb.handle, pieceKey)
|
||||
panic("fixme")
|
||||
//return sectorbuilder.Unseal(sb.handle, pieceKey)
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
rspco, err := sectorbuilder.StandaloneSealPreCommit(
|
||||
rspco, err := sectorbuilder.SealPreCommit(
|
||||
sb.ssize,
|
||||
PoRepProofPartitions,
|
||||
cacheDir,
|
||||
@ -431,7 +418,7 @@ func (sb *SectorBuilder) sealCommitLocal(sectorID uint64, ticket SealTicket, see
|
||||
return nil, err
|
||||
}
|
||||
|
||||
proof, err = sectorbuilder.StandaloneSealCommit(
|
||||
proof, err = sectorbuilder.SealCommit(
|
||||
sb.ssize,
|
||||
PoRepProofPartitions,
|
||||
cacheDir,
|
||||
@ -452,7 +439,7 @@ func (sb *SectorBuilder) sealCommitLocal(sectorID uint64, ticket SealTicket, see
|
||||
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{
|
||||
task: WorkerTask{
|
||||
Type: WorkerCommit,
|
||||
@ -484,49 +471,91 @@ func (sb *SectorBuilder) SealCommit(sectorID uint64, ticket SealTicket, seed Sea
|
||||
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
|
||||
}
|
||||
|
||||
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() {
|
||||
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
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package sectorbuilder_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
@ -15,6 +16,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
ffi "github.com/filecoin-project/filecoin-ffi"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"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},
|
||||
}
|
||||
|
||||
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 {
|
||||
t.Fatalf("%+v", err)
|
||||
}
|
||||
@ -76,26 +78,44 @@ func (s *seal) commit(t *testing.T, sb *sectorbuilder.SectorBuilder, done func()
|
||||
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}
|
||||
|
||||
ssi := sectorbuilder.NewSortedSectorInfo([]sectorbuilder.SectorInfo{{
|
||||
SectorID: s.sid,
|
||||
CommR: s.pco.CommR,
|
||||
}})
|
||||
ppi := make([]ffi.PublicSectorInfo, len(seals))
|
||||
for i, s := range seals {
|
||||
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 {
|
||||
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 {
|
||||
t.Fatalf("%+v", err)
|
||||
}
|
||||
if !ok {
|
||||
t.Fatal("bad post")
|
||||
}
|
||||
|
||||
return genCandidates
|
||||
}
|
||||
|
||||
func TestSealAndVerify(t *testing.T) {
|
||||
@ -123,7 +143,10 @@ func TestSealAndVerify(t *testing.T) {
|
||||
t.Fatalf("%+v", err)
|
||||
}
|
||||
cleanup := func() {
|
||||
sb.Destroy()
|
||||
if t.Failed() {
|
||||
fmt.Printf("not removing %s\n", dir)
|
||||
return
|
||||
}
|
||||
if err := os.RemoveAll(dir); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@ -137,20 +160,95 @@ func TestSealAndVerify(t *testing.T) {
|
||||
|
||||
s := seal{sid: si}
|
||||
|
||||
start := time.Now()
|
||||
|
||||
s.precommit(t, sb, 1, func() {})
|
||||
|
||||
precommit := time.Now()
|
||||
|
||||
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
|
||||
sb.Destroy()
|
||||
sb, err = sectorbuilder.TempSectorbuilderDir(dir, sectorSize, ds)
|
||||
if err != nil {
|
||||
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) {
|
||||
@ -178,7 +276,6 @@ func TestSealAndVerify2(t *testing.T) {
|
||||
t.Fatalf("%+v", err)
|
||||
}
|
||||
cleanup := func() {
|
||||
sb.Destroy()
|
||||
if err := os.RemoveAll(dir); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@ -210,6 +307,8 @@ func TestSealAndVerify2(t *testing.T) {
|
||||
go s1.commit(t, sb, wg.Done)
|
||||
go s2.commit(t, sb, wg.Done)
|
||||
wg.Wait()
|
||||
|
||||
post(t, sb, s1, s2)
|
||||
}
|
||||
|
||||
func TestAcquireID(t *testing.T) {
|
||||
@ -235,8 +334,6 @@ func TestAcquireID(t *testing.T) {
|
||||
assertAcquire(2)
|
||||
assertAcquire(3)
|
||||
|
||||
sb.Destroy()
|
||||
|
||||
sb, err = sectorbuilder.TempSectorbuilderDir(dir, sectorSize, ds)
|
||||
if err != nil {
|
||||
t.Fatalf("%+v", err)
|
||||
@ -246,7 +343,6 @@ func TestAcquireID(t *testing.T) {
|
||||
assertAcquire(5)
|
||||
assertAcquire(6)
|
||||
|
||||
sb.Destroy()
|
||||
if err := os.RemoveAll(dir); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
@ -4,18 +4,12 @@ import (
|
||||
"context"
|
||||
"io"
|
||||
|
||||
sectorbuilder "github.com/filecoin-project/go-sectorbuilder"
|
||||
sectorbuilder "github.com/filecoin-project/filecoin-ffi"
|
||||
"go.opencensus.io/trace"
|
||||
|
||||
"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 {
|
||||
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)
|
||||
}
|
||||
|
||||
func NewSortedSectorInfo(sectors []SectorInfo) SortedSectorInfo {
|
||||
return sectorbuilder.NewSortedSectorInfo(sectors...)
|
||||
func NewSortedPrivateSectorInfo(sectors []sectorbuilder.PrivateSectorInfo) SortedPrivateSectorInfo {
|
||||
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")
|
||||
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) {
|
||||
@ -57,6 +74,6 @@ func GeneratePieceCommitment(piece io.Reader, pieceSize uint64) (commP [CommLen]
|
||||
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)
|
||||
}
|
||||
}
|
@ -2,14 +2,15 @@ package main
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"github.com/filecoin-project/lotus/lib/jsonrpc"
|
||||
"github.com/filecoin-project/lotus/node/repo"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/lotus/lib/jsonrpc"
|
||||
"github.com/filecoin-project/lotus/node/repo"
|
||||
)
|
||||
|
||||
type NodeState int
|
||||
|
@ -45,8 +45,6 @@ class FullNode extends React.Component {
|
||||
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
|
||||
|
||||
this.setState(() => ({
|
||||
@ -62,8 +60,6 @@ class FullNode extends React.Component {
|
||||
vouchers: vouchers,
|
||||
|
||||
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 addresses = this.state.addrs.map((addr) => {
|
||||
@ -153,7 +144,6 @@ class FullNode extends React.Component {
|
||||
<div>
|
||||
<div>Balances: [New <a href="#" onClick={this.newSecpAddr}>[Secp256k1]</a> <a href="#" onClick={this.newBLSAddr}>[BLS]</a>]</div>
|
||||
<div>{addresses}</div>
|
||||
<div>{miners}</div>
|
||||
<div>{paychannels}</div>
|
||||
</div>
|
||||
|
||||
|
@ -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>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>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>
|
||||
<div>----</div>
|
||||
|
@ -120,7 +120,7 @@ class StorageNode extends React.Component {
|
||||
</div>
|
||||
<div>
|
||||
<Address client={this.props.fullConn} addr={this.state.actor} mountWindow={this.props.mountWindow}/>
|
||||
<span> <abbr title="Proving period end">PPE:</abbr> <b>{this.state.actorState.State.ProvingPeriodEnd}</b></span>
|
||||
<span> <abbr title="Proving period end">EPS:</abbr> <b>{this.state.actorState.State.ElectionPeriodStart}</b></span>
|
||||
</div>
|
||||
<div>{this.state.statusCounts.map((c, i) => <span key={i}>{sealCodes[i]}: {c} | </span>)}</div>
|
||||
<div>
|
||||
|
@ -3,12 +3,13 @@ package main
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/opentracing/opentracing-go/log"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/opentracing/opentracing-go/log"
|
||||
)
|
||||
|
||||
type outmux struct {
|
||||
|
@ -11,6 +11,10 @@ import (
|
||||
"time"
|
||||
|
||||
"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) {
|
||||
@ -19,9 +23,29 @@ func (api *api) Spawn() (nodeInfo, error) {
|
||||
return nodeInfo{}, err
|
||||
}
|
||||
|
||||
params := []string{"daemon", "--bootstrap=false"}
|
||||
genParam := "--genesis=" + api.genesis
|
||||
|
||||
id := atomic.AddInt32(&api.cmds, 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
|
||||
genf, err := ioutil.TempFile(os.TempDir(), "lotus-genesis-")
|
||||
if err != nil {
|
||||
@ -54,7 +78,7 @@ func (api *api) Spawn() (nodeInfo, error) {
|
||||
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.Stdout = io.MultiWriter(os.Stdout, logfile, mux.outpw)
|
||||
@ -114,7 +138,7 @@ func (api *api) SpawnStorage(fullNodeRepo string) (nodeInfo, error) {
|
||||
|
||||
initArgs := []string{"init"}
|
||||
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)
|
||||
|
104
miner/miner.go
104
miner/miner.go
@ -5,17 +5,15 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"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/gen"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/node/impl/full"
|
||||
|
||||
logging "github.com/ipfs/go-log"
|
||||
"github.com/pkg/errors"
|
||||
"go.opencensus.io/trace"
|
||||
"go.uber.org/fx"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
@ -23,19 +21,10 @@ var log = logging.Logger("miner")
|
||||
|
||||
type waitFunc func(ctx context.Context) error
|
||||
|
||||
type api struct {
|
||||
fx.In
|
||||
|
||||
full.ChainAPI
|
||||
full.SyncAPI
|
||||
full.MpoolAPI
|
||||
full.WalletAPI
|
||||
full.StateAPI
|
||||
}
|
||||
|
||||
func NewMiner(api api) *Miner {
|
||||
func NewMiner(api api.FullNode, epp gen.ElectionPoStProver) *Miner {
|
||||
return &Miner{
|
||||
api: api,
|
||||
epp: epp,
|
||||
waitFunc: func(ctx context.Context) error {
|
||||
// Wait around for half the block time in case other parents come in
|
||||
time.Sleep(build.BlockDelay * time.Second / 2)
|
||||
@ -45,7 +34,9 @@ func NewMiner(api api) *Miner {
|
||||
}
|
||||
|
||||
type Miner struct {
|
||||
api api
|
||||
api api.FullNode
|
||||
|
||||
epp gen.ElectionPoStProver
|
||||
|
||||
lk sync.Mutex
|
||||
addresses []address.Address
|
||||
@ -161,8 +152,8 @@ eventLoop:
|
||||
log.Errorf("failed to get best mining candidate: %s", err)
|
||||
continue
|
||||
}
|
||||
if base.ts.Equals(lastBase.ts) && len(lastBase.tickets) == len(base.tickets) {
|
||||
log.Errorf("BestMiningCandidate from the previous round: %s (tkts:%d)", lastBase.ts.Cids(), len(lastBase.tickets))
|
||||
if base.ts.Equals(lastBase.ts) && lastBase.nullRounds == base.nullRounds {
|
||||
log.Errorf("BestMiningCandidate from the previous round: %s (nulls:%d)", lastBase.ts.Cids(), lastBase.nullRounds)
|
||||
time.Sleep(build.BlockDelay * time.Second)
|
||||
continue
|
||||
}
|
||||
@ -173,7 +164,7 @@ eventLoop:
|
||||
for _, addr := range addrs {
|
||||
b, err := m.mineOne(ctx, addr, base)
|
||||
if err != nil {
|
||||
log.Errorf("mining block failed: %s", err)
|
||||
log.Errorf("mining block failed: %+v", err)
|
||||
continue
|
||||
}
|
||||
if b != nil {
|
||||
@ -205,15 +196,15 @@ eventLoop:
|
||||
}
|
||||
}
|
||||
} 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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type MiningBase struct {
|
||||
ts *types.TipSet
|
||||
tickets []*types.Ticket
|
||||
ts *types.TipSet
|
||||
nullRounds uint64
|
||||
}
|
||||
|
||||
func (m *Miner) GetBestMiningCandidate(ctx context.Context) (*MiningBase, error) {
|
||||
@ -246,35 +237,54 @@ func (m *Miner) GetBestMiningCandidate(ctx context.Context) (*MiningBase, error)
|
||||
}, 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()))
|
||||
ticket, err := m.scratchTicket(ctx, addr, base)
|
||||
func (m *Miner) isSlashed(ctx context.Context, addr address.Address, ts *types.TipSet) (bool, error) {
|
||||
power, err := m.api.StateMinerPower(ctx, addr, ts)
|
||||
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 {
|
||||
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 {
|
||||
m.submitNullTicket(base, ticket)
|
||||
base.nullRounds++
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
b, err := m.createBlock(base, addr, ticket, proof)
|
||||
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())
|
||||
|
||||
return b, nil
|
||||
}
|
||||
dur := time.Now().Sub(start)
|
||||
log.Infof("Creating block took %s", dur)
|
||||
|
||||
func (m *Miner) submitNullTicket(base *MiningBase, ticket *types.Ticket) {
|
||||
base.tickets = append(base.tickets, ticket)
|
||||
m.lastWork = base
|
||||
return b, nil
|
||||
}
|
||||
|
||||
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 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) {
|
||||
@ -308,15 +318,11 @@ func (m *Miner) getMinerWorker(ctx context.Context, addr address.Address, ts *ty
|
||||
return w, nil
|
||||
}
|
||||
|
||||
func (m *Miner) scratchTicket(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()
|
||||
}
|
||||
func (m *Miner) computeTicket(ctx context.Context, addr address.Address, base *MiningBase) (*types.Ticket, error) {
|
||||
|
||||
vrfOut, err := m.computeVRF(ctx, addr, lastTicket.VRFProof)
|
||||
vrfBase := base.ts.MinTicket().VRFProof
|
||||
|
||||
vrfOut, err := m.computeVRF(ctx, addr, vrfBase)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -326,11 +332,11 @@ func (m *Miner) scratchTicket(ctx context.Context, addr address.Address, base *M
|
||||
}, 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)
|
||||
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)
|
||||
@ -338,10 +344,12 @@ func (m *Miner) createBlock(base *MiningBase, addr address.Address, ticket *type
|
||||
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
|
||||
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)
|
||||
@ -378,7 +386,7 @@ func selectMessages(ctx context.Context, al actorLookup, base *MiningBase, msgs
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -2,10 +2,12 @@ package miner
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
)
|
||||
|
||||
func NewTestMiner(nextCh <-chan struct{}) func(api api) *Miner {
|
||||
return func(api api) *Miner {
|
||||
func NewTestMiner(nextCh <-chan struct{}) func(api api.FullNode) *Miner {
|
||||
return func(api api.FullNode) *Miner {
|
||||
return &Miner{
|
||||
api: api,
|
||||
waitFunc: chanWaiter(nextCh),
|
||||
|
@ -22,6 +22,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain"
|
||||
"github.com/filecoin-project/lotus/chain/blocksync"
|
||||
"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/metrics"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
@ -92,7 +93,6 @@ const (
|
||||
HandleDealsKey
|
||||
HandleRetrievalKey
|
||||
RunSectorServiceKey
|
||||
RegisterMinerKey
|
||||
RegisterProviderValidatorKey
|
||||
|
||||
// daemon
|
||||
@ -231,8 +231,6 @@ func Online() Option {
|
||||
Override(new(*paych.Store), paych.NewStore),
|
||||
Override(new(*paych.Manager), paych.NewManager),
|
||||
Override(new(*market.FundMgr), market.NewFundMgr),
|
||||
|
||||
Override(new(*miner.Miner), miner.NewMiner),
|
||||
),
|
||||
|
||||
// Storage miner
|
||||
@ -252,7 +250,8 @@ func Online() Option {
|
||||
Override(RegisterProviderValidatorKey, modules.RegisterProviderValidator),
|
||||
Override(HandleRetrievalKey, modules.HandleRetrieval),
|
||||
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(
|
||||
ConfigCommon(&cfg.Common),
|
||||
Override(HeadMetricsKey, metrics.SendHeadNotifs(cfg.Metrics.Nickname)),
|
||||
If(cfg.Metrics.PubsubTracing,
|
||||
Override(new(*pubsub.PubSub), lp2p.GossipSub(lp2p.PubsubTracer())),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,8 @@ type Libp2p struct {
|
||||
// // Full Node
|
||||
|
||||
type Metrics struct {
|
||||
Nickname string
|
||||
Nickname string
|
||||
PubsubTracing bool
|
||||
}
|
||||
|
||||
// // Storage Miner
|
||||
|
@ -1,8 +1,6 @@
|
||||
package impl
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
logging "github.com/ipfs/go-log"
|
||||
|
||||
"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/api"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"github.com/filecoin-project/lotus/miner"
|
||||
"github.com/filecoin-project/lotus/node/impl/full"
|
||||
)
|
||||
|
||||
@ -27,20 +23,6 @@ type FullNodeAPI struct {
|
||||
full.StateAPI
|
||||
full.WalletAPI
|
||||
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{}
|
||||
|
@ -28,8 +28,8 @@ func (a *ChainAPI) ChainHead(context.Context) (*types.TipSet, error) {
|
||||
return a.Chain.GetHeaviestTipSet(), nil
|
||||
}
|
||||
|
||||
func (a *ChainAPI) ChainGetRandomness(ctx context.Context, pts types.TipSetKey, tickets []*types.Ticket, lb int) ([]byte, error) {
|
||||
return a.Chain.GetRandomness(ctx, pts.Cids(), tickets, int64(lb))
|
||||
func (a *ChainAPI) ChainGetRandomness(ctx context.Context, pts types.TipSetKey, round int64) ([]byte, error) {
|
||||
return a.Chain.GetRandomness(ctx, pts.Cids(), round)
|
||||
}
|
||||
|
||||
func (a *ChainAPI) ChainGetBlock(ctx context.Context, msg cid.Cid) (*types.BlockHeader, error) {
|
||||
|
@ -76,8 +76,8 @@ func (a *StateAPI) StateMinerPeerID(ctx context.Context, m address.Address, ts *
|
||||
return stmgr.GetMinerPeerID(ctx, a.StateManager, ts, m)
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateMinerProvingPeriodEnd(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error) {
|
||||
return stmgr.GetMinerProvingPeriodEnd(ctx, a.StateManager, ts, actor)
|
||||
func (a *StateAPI) StateMinerElectionPeriodStart(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error) {
|
||||
return stmgr.GetMinerElectionPeriodStart(ctx, a.StateManager, ts, actor)
|
||||
}
|
||||
|
||||
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
|
||||
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) {
|
||||
fblk, err := gen.MinerCreateBlock(ctx, a.StateManager, a.Wallet, addr, parents, tickets, proof, msgs, ts)
|
||||
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, ticket, proof, msgs, height, ts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain/address"
|
||||
"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/sectorblocks"
|
||||
)
|
||||
@ -22,8 +23,9 @@ type StorageMinerAPI struct {
|
||||
SectorBuilder *sectorbuilder.SectorBuilder
|
||||
SectorBlocks *sectorblocks.SectorBlocks
|
||||
|
||||
Miner *storage.Miner
|
||||
Full api.FullNode
|
||||
Miner *storage.Miner
|
||||
BlockMiner *miner.Miner
|
||||
Full api.FullNode
|
||||
}
|
||||
|
||||
func (sm *StorageMinerAPI) ServeRemote(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -41,14 +41,17 @@ func ChainExchange(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host, rt
|
||||
return exch
|
||||
}
|
||||
|
||||
func MessagePool(lc fx.Lifecycle, sm *stmgr.StateManager, ps *pubsub.PubSub) *chain.MessagePool {
|
||||
mp := chain.NewMessagePool(sm, ps)
|
||||
func MessagePool(lc fx.Lifecycle, sm *stmgr.StateManager, ps *pubsub.PubSub, ds dtypes.MetadataDS) (*chain.MessagePool, error) {
|
||||
mp, err := chain.NewMessagePool(sm, ps, ds)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("constructing mpool: %w", err)
|
||||
}
|
||||
lc.Append(fx.Hook{
|
||||
OnStop: func(_ context.Context) error {
|
||||
return mp.Close()
|
||||
},
|
||||
})
|
||||
return mp
|
||||
return mp, nil
|
||||
}
|
||||
|
||||
func ChainBlockstore(r repo.LockedRepo) (dtypes.ChainBlockstore, error) {
|
||||
|
@ -3,6 +3,9 @@ package modules
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@ -14,8 +17,6 @@ import (
|
||||
"github.com/libp2p/go-libp2p-core/peerstore"
|
||||
record "github.com/libp2p/go-libp2p-record"
|
||||
"golang.org/x/xerrors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
var log = logging.Logger("modules")
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user