From 7d2b3f05db38cee481c4b91e628b53bb460bdadc Mon Sep 17 00:00:00 2001 From: zenground0 Date: Wed, 10 Nov 2021 13:53:00 -0500 Subject: [PATCH] WIP sector storage and integration test --- api/api_storage.go | 25 +-- api/api_worker.go | 3 + api/proxy_gen.go | 78 +++++++++ build/openrpc/full.json.gz | Bin 25465 -> 25466 bytes build/openrpc/miner.json.gz | Bin 10467 -> 10672 bytes build/openrpc/worker.json.gz | Bin 2713 -> 2940 bytes documentation/en/api-v0-methods-miner.md | 85 +++++++++ documentation/en/api-v0-methods-worker.md | 118 +++++++++++++ extern/filecoin-ffi | 2 +- .../sector-storage/ffiwrapper/sealer_cgo.go | 83 +++++++++ .../sector-storage/ffiwrapper/verifier_cgo.go | 3 +- extern/sector-storage/manager.go | 161 ++++++++++++++++++ extern/sector-storage/manager_calltracker.go | 1 - extern/sector-storage/manager_test.go | 139 ++++++++++++++- extern/sector-storage/mock/mock.go | 32 ++++ extern/sector-storage/sched_test.go | 12 ++ extern/sector-storage/sealtasks/task.go | 27 ++- extern/sector-storage/storiface/filetype.go | 42 +++-- extern/sector-storage/storiface/worker.go | 6 + extern/sector-storage/teststorage_test.go | 16 ++ extern/sector-storage/testworker_test.go | 28 +++ extern/sector-storage/worker_local.go | 85 ++++++--- extern/sector-storage/worker_tracked.go | 19 ++- go.mod | 4 +- go.sum | 10 +- 25 files changed, 911 insertions(+), 68 deletions(-) diff --git a/api/api_storage.go b/api/api_storage.go index 8cca2aa5b..bf7520d09 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -118,17 +118,20 @@ type StorageMiner interface { WorkerJobs(context.Context) (map[uuid.UUID][]storiface.WorkerJob, error) //perm:admin //storiface.WorkerReturn - ReturnAddPiece(ctx context.Context, callID storiface.CallID, pi abi.PieceInfo, err *storiface.CallError) error //perm:admin retry:true - ReturnSealPreCommit1(ctx context.Context, callID storiface.CallID, p1o storage.PreCommit1Out, err *storiface.CallError) error //perm:admin retry:true - ReturnSealPreCommit2(ctx context.Context, callID storiface.CallID, sealed storage.SectorCids, err *storiface.CallError) error //perm:admin retry:true - ReturnSealCommit1(ctx context.Context, callID storiface.CallID, out storage.Commit1Out, err *storiface.CallError) error //perm:admin retry:true - ReturnSealCommit2(ctx context.Context, callID storiface.CallID, proof storage.Proof, err *storiface.CallError) error //perm:admin retry:true - ReturnFinalizeSector(ctx context.Context, callID storiface.CallID, err *storiface.CallError) error //perm:admin retry:true - ReturnReleaseUnsealed(ctx context.Context, callID storiface.CallID, err *storiface.CallError) error //perm:admin retry:true - ReturnMoveStorage(ctx context.Context, callID storiface.CallID, err *storiface.CallError) error //perm:admin retry:true - ReturnUnsealPiece(ctx context.Context, callID storiface.CallID, err *storiface.CallError) error //perm:admin retry:true - ReturnReadPiece(ctx context.Context, callID storiface.CallID, ok bool, err *storiface.CallError) error //perm:admin retry:true - ReturnFetch(ctx context.Context, callID storiface.CallID, err *storiface.CallError) error //perm:admin retry:true + ReturnAddPiece(ctx context.Context, callID storiface.CallID, pi abi.PieceInfo, err *storiface.CallError) error //perm:admin retry:true + ReturnSealPreCommit1(ctx context.Context, callID storiface.CallID, p1o storage.PreCommit1Out, err *storiface.CallError) error //perm:admin retry:true + ReturnSealPreCommit2(ctx context.Context, callID storiface.CallID, sealed storage.SectorCids, err *storiface.CallError) error //perm:admin retry:true + ReturnSealCommit1(ctx context.Context, callID storiface.CallID, out storage.Commit1Out, err *storiface.CallError) error //perm:admin retry:true + ReturnSealCommit2(ctx context.Context, callID storiface.CallID, proof storage.Proof, err *storiface.CallError) error //perm:admin retry:true + ReturnFinalizeSector(ctx context.Context, callID storiface.CallID, err *storiface.CallError) error //perm:admin retry:true + ReturnReplicaUpdate(ctx context.Context, callID storiface.CallID, out storage.ReplicaUpdateOut, err *storiface.CallError) error //perm:admin retry:true + ReturnProveReplicaUpdate1(ctx context.Context, callID storiface.CallID, vanillaProofs storage.ReplicaVanillaProofs, err *storiface.CallError) error //perm:admin retry:true + ReturnProveReplicaUpdate2(ctx context.Context, callID storiface.CallID, proof storage.ReplicaUpdateProof, err *storiface.CallError) error //perm:admin retry:true + ReturnReleaseUnsealed(ctx context.Context, callID storiface.CallID, err *storiface.CallError) error //perm:admin retry:true + ReturnMoveStorage(ctx context.Context, callID storiface.CallID, err *storiface.CallError) error //perm:admin retry:true + ReturnUnsealPiece(ctx context.Context, callID storiface.CallID, err *storiface.CallError) error //perm:admin retry:true + ReturnReadPiece(ctx context.Context, callID storiface.CallID, ok bool, err *storiface.CallError) error //perm:admin retry:true + ReturnFetch(ctx context.Context, callID storiface.CallID, err *storiface.CallError) error //perm:admin retry:true // SealingSchedDiag dumps internal sealing scheduler state SealingSchedDiag(ctx context.Context, doSched bool) (interface{}, error) //perm:admin diff --git a/api/api_worker.go b/api/api_worker.go index 4553c30e0..5e0b4f8c6 100644 --- a/api/api_worker.go +++ b/api/api_worker.go @@ -39,6 +39,9 @@ type Worker interface { SealCommit1(ctx context.Context, sector storage.SectorRef, ticket abi.SealRandomness, seed abi.InteractiveSealRandomness, pieces []abi.PieceInfo, cids storage.SectorCids) (storiface.CallID, error) //perm:admin SealCommit2(ctx context.Context, sector storage.SectorRef, c1o storage.Commit1Out) (storiface.CallID, error) //perm:admin FinalizeSector(ctx context.Context, sector storage.SectorRef, keepUnsealed []storage.Range) (storiface.CallID, error) //perm:admin + ReplicaUpdate(ctx context.Context, sector storage.SectorRef, pieces []abi.PieceInfo) (storiface.CallID, error) //perm:admin + ProveReplicaUpdate1(ctx context.Context, sector storage.SectorRef, sectorKey, newSealed, newUnsealed cid.Cid) (storiface.CallID, error) //perm:admin + ProveReplicaUpdate2(ctx context.Context, sector storage.SectorRef, sectorKey, newSealed, newUnsealed cid.Cid, vanillaProofs storage.ReplicaVanillaProofs) (storiface.CallID, error) //perm:admin ReleaseUnsealed(ctx context.Context, sector storage.SectorRef, safeToFree []storage.Range) (storiface.CallID, error) //perm:admin MoveStorage(ctx context.Context, sector storage.SectorRef, types storiface.SectorFileType) (storiface.CallID, error) //perm:admin UnsealPiece(context.Context, storage.SectorRef, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) (storiface.CallID, error) //perm:admin diff --git a/api/proxy_gen.go b/api/proxy_gen.go index b36f19a7e..b78b40959 100644 --- a/api/proxy_gen.go +++ b/api/proxy_gen.go @@ -709,10 +709,16 @@ type StorageMinerStruct struct { ReturnMoveStorage func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"` + ReturnProveReplicaUpdate1 func(p0 context.Context, p1 storiface.CallID, p2 storage.ReplicaVanillaProofs, p3 *storiface.CallError) error `perm:"admin"` + + ReturnProveReplicaUpdate2 func(p0 context.Context, p1 storiface.CallID, p2 storage.ReplicaUpdateProof, p3 *storiface.CallError) error `perm:"admin"` + ReturnReadPiece func(p0 context.Context, p1 storiface.CallID, p2 bool, p3 *storiface.CallError) error `perm:"admin"` ReturnReleaseUnsealed func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"` + ReturnReplicaUpdate func(p0 context.Context, p1 storiface.CallID, p2 storage.ReplicaUpdateOut, p3 *storiface.CallError) error `perm:"admin"` + ReturnSealCommit1 func(p0 context.Context, p1 storiface.CallID, p2 storage.Commit1Out, p3 *storiface.CallError) error `perm:"admin"` ReturnSealCommit2 func(p0 context.Context, p1 storiface.CallID, p2 storage.Proof, p3 *storiface.CallError) error `perm:"admin"` @@ -852,10 +858,16 @@ type WorkerStruct struct { ProcessSession func(p0 context.Context) (uuid.UUID, error) `perm:"admin"` + ProveReplicaUpdate1 func(p0 context.Context, p1 storage.SectorRef, p2 cid.Cid, p3 cid.Cid, p4 cid.Cid) (storiface.CallID, error) `perm:"admin"` + + ProveReplicaUpdate2 func(p0 context.Context, p1 storage.SectorRef, p2 cid.Cid, p3 cid.Cid, p4 cid.Cid, p5 storage.ReplicaVanillaProofs) (storiface.CallID, error) `perm:"admin"` + ReleaseUnsealed func(p0 context.Context, p1 storage.SectorRef, p2 []storage.Range) (storiface.CallID, error) `perm:"admin"` Remove func(p0 context.Context, p1 abi.SectorID) error `perm:"admin"` + ReplicaUpdate func(p0 context.Context, p1 storage.SectorRef, p2 []abi.PieceInfo) (storiface.CallID, error) `perm:"admin"` + SealCommit1 func(p0 context.Context, p1 storage.SectorRef, p2 abi.SealRandomness, p3 abi.InteractiveSealRandomness, p4 []abi.PieceInfo, p5 storage.SectorCids) (storiface.CallID, error) `perm:"admin"` SealCommit2 func(p0 context.Context, p1 storage.SectorRef, p2 storage.Commit1Out) (storiface.CallID, error) `perm:"admin"` @@ -4165,6 +4177,28 @@ func (s *StorageMinerStub) ReturnMoveStorage(p0 context.Context, p1 storiface.Ca return ErrNotSupported } +func (s *StorageMinerStruct) ReturnProveReplicaUpdate1(p0 context.Context, p1 storiface.CallID, p2 storage.ReplicaVanillaProofs, p3 *storiface.CallError) error { + if s.Internal.ReturnProveReplicaUpdate1 == nil { + return ErrNotSupported + } + return s.Internal.ReturnProveReplicaUpdate1(p0, p1, p2, p3) +} + +func (s *StorageMinerStub) ReturnProveReplicaUpdate1(p0 context.Context, p1 storiface.CallID, p2 storage.ReplicaVanillaProofs, p3 *storiface.CallError) error { + return ErrNotSupported +} + +func (s *StorageMinerStruct) ReturnProveReplicaUpdate2(p0 context.Context, p1 storiface.CallID, p2 storage.ReplicaUpdateProof, p3 *storiface.CallError) error { + if s.Internal.ReturnProveReplicaUpdate2 == nil { + return ErrNotSupported + } + return s.Internal.ReturnProveReplicaUpdate2(p0, p1, p2, p3) +} + +func (s *StorageMinerStub) ReturnProveReplicaUpdate2(p0 context.Context, p1 storiface.CallID, p2 storage.ReplicaUpdateProof, p3 *storiface.CallError) error { + return ErrNotSupported +} + func (s *StorageMinerStruct) ReturnReadPiece(p0 context.Context, p1 storiface.CallID, p2 bool, p3 *storiface.CallError) error { if s.Internal.ReturnReadPiece == nil { return ErrNotSupported @@ -4187,6 +4221,17 @@ func (s *StorageMinerStub) ReturnReleaseUnsealed(p0 context.Context, p1 storifac return ErrNotSupported } +func (s *StorageMinerStruct) ReturnReplicaUpdate(p0 context.Context, p1 storiface.CallID, p2 storage.ReplicaUpdateOut, p3 *storiface.CallError) error { + if s.Internal.ReturnReplicaUpdate == nil { + return ErrNotSupported + } + return s.Internal.ReturnReplicaUpdate(p0, p1, p2, p3) +} + +func (s *StorageMinerStub) ReturnReplicaUpdate(p0 context.Context, p1 storiface.CallID, p2 storage.ReplicaUpdateOut, p3 *storiface.CallError) error { + return ErrNotSupported +} + func (s *StorageMinerStruct) ReturnSealCommit1(p0 context.Context, p1 storiface.CallID, p2 storage.Commit1Out, p3 *storiface.CallError) error { if s.Internal.ReturnSealCommit1 == nil { return ErrNotSupported @@ -4858,6 +4903,28 @@ func (s *WorkerStub) ProcessSession(p0 context.Context) (uuid.UUID, error) { return *new(uuid.UUID), ErrNotSupported } +func (s *WorkerStruct) ProveReplicaUpdate1(p0 context.Context, p1 storage.SectorRef, p2 cid.Cid, p3 cid.Cid, p4 cid.Cid) (storiface.CallID, error) { + if s.Internal.ProveReplicaUpdate1 == nil { + return *new(storiface.CallID), ErrNotSupported + } + return s.Internal.ProveReplicaUpdate1(p0, p1, p2, p3, p4) +} + +func (s *WorkerStub) ProveReplicaUpdate1(p0 context.Context, p1 storage.SectorRef, p2 cid.Cid, p3 cid.Cid, p4 cid.Cid) (storiface.CallID, error) { + return *new(storiface.CallID), ErrNotSupported +} + +func (s *WorkerStruct) ProveReplicaUpdate2(p0 context.Context, p1 storage.SectorRef, p2 cid.Cid, p3 cid.Cid, p4 cid.Cid, p5 storage.ReplicaVanillaProofs) (storiface.CallID, error) { + if s.Internal.ProveReplicaUpdate2 == nil { + return *new(storiface.CallID), ErrNotSupported + } + return s.Internal.ProveReplicaUpdate2(p0, p1, p2, p3, p4, p5) +} + +func (s *WorkerStub) ProveReplicaUpdate2(p0 context.Context, p1 storage.SectorRef, p2 cid.Cid, p3 cid.Cid, p4 cid.Cid, p5 storage.ReplicaVanillaProofs) (storiface.CallID, error) { + return *new(storiface.CallID), ErrNotSupported +} + func (s *WorkerStruct) ReleaseUnsealed(p0 context.Context, p1 storage.SectorRef, p2 []storage.Range) (storiface.CallID, error) { if s.Internal.ReleaseUnsealed == nil { return *new(storiface.CallID), ErrNotSupported @@ -4880,6 +4947,17 @@ func (s *WorkerStub) Remove(p0 context.Context, p1 abi.SectorID) error { return ErrNotSupported } +func (s *WorkerStruct) ReplicaUpdate(p0 context.Context, p1 storage.SectorRef, p2 []abi.PieceInfo) (storiface.CallID, error) { + if s.Internal.ReplicaUpdate == nil { + return *new(storiface.CallID), ErrNotSupported + } + return s.Internal.ReplicaUpdate(p0, p1, p2) +} + +func (s *WorkerStub) ReplicaUpdate(p0 context.Context, p1 storage.SectorRef, p2 []abi.PieceInfo) (storiface.CallID, error) { + return *new(storiface.CallID), ErrNotSupported +} + func (s *WorkerStruct) SealCommit1(p0 context.Context, p1 storage.SectorRef, p2 abi.SealRandomness, p3 abi.InteractiveSealRandomness, p4 []abi.PieceInfo, p5 storage.SectorCids) (storiface.CallID, error) { if s.Internal.SealCommit1 == nil { return *new(storiface.CallID), ErrNotSupported diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 8719b71713e8587d8e7ec8ea03f23b0d6486fd6c..a5816ef4f3d57f10df36cc9e5a911257fb47e0e6 100644 GIT binary patch delta 25088 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 WJUo1P`2PU_0RR7TD+|HU^Z@`4(25@b delta 10388 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 literal 2713 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", t) } @@ -104,9 +116,11 @@ func (t SectorFileType) All() [FileTypes]bool { type SectorPaths struct { ID abi.SectorID - Unsealed string - Sealed string - Cache string + Unsealed string + Sealed string + Cache string + Update string + UpdateCache string } func ParseSectorID(baseName string) (abi.SectorID, error) { @@ -139,6 +153,10 @@ func PathByType(sps SectorPaths, fileType SectorFileType) string { return sps.Sealed case FTCache: return sps.Cache + case FTUpdate: + return sps.Update + case FTUpdateCache: + return sps.UpdateCache } panic("requested unknown path type") @@ -152,5 +170,9 @@ func SetPathByType(sps *SectorPaths, fileType SectorFileType, p string) { sps.Sealed = p case FTCache: sps.Cache = p + case FTUpdate: + sps.Update = p + case FTUpdateCache: + sps.UpdateCache = p } } diff --git a/extern/sector-storage/storiface/worker.go b/extern/sector-storage/storiface/worker.go index e3374d6cf..970e0ec33 100644 --- a/extern/sector-storage/storiface/worker.go +++ b/extern/sector-storage/storiface/worker.go @@ -92,6 +92,9 @@ type WorkerCalls interface { SealCommit2(ctx context.Context, sector storage.SectorRef, c1o storage.Commit1Out) (CallID, error) FinalizeSector(ctx context.Context, sector storage.SectorRef, keepUnsealed []storage.Range) (CallID, error) ReleaseUnsealed(ctx context.Context, sector storage.SectorRef, safeToFree []storage.Range) (CallID, error) + ReplicaUpdate(ctx context.Context, sector storage.SectorRef, pieces []abi.PieceInfo) (CallID, error) + ProveReplicaUpdate1(ctx context.Context, sector storage.SectorRef, sectorKey, newSealed, newUnsealed cid.Cid) (CallID, error) + ProveReplicaUpdate2(ctx context.Context, sector storage.SectorRef, sectorKey, newSealed, newUnsealed cid.Cid, vanillaProofs storage.ReplicaVanillaProofs) (CallID, error) MoveStorage(ctx context.Context, sector storage.SectorRef, types SectorFileType) (CallID, error) UnsealPiece(context.Context, storage.SectorRef, UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) (CallID, error) Fetch(context.Context, storage.SectorRef, SectorFileType, PathType, AcquireMode) (CallID, error) @@ -145,6 +148,9 @@ type WorkerReturn interface { ReturnSealCommit2(ctx context.Context, callID CallID, proof storage.Proof, err *CallError) error ReturnFinalizeSector(ctx context.Context, callID CallID, err *CallError) error ReturnReleaseUnsealed(ctx context.Context, callID CallID, err *CallError) error + ReturnReplicaUpdate(ctx context.Context, callID CallID, out storage.ReplicaUpdateOut, err *CallError) error + ReturnProveReplicaUpdate1(ctx context.Context, callID CallID, proofs storage.ReplicaVanillaProofs, err *CallError) error + ReturnProveReplicaUpdate2(ctx context.Context, callID CallID, proof storage.ReplicaUpdateProof, err *CallError) error ReturnMoveStorage(ctx context.Context, callID CallID, err *CallError) error ReturnUnsealPiece(ctx context.Context, callID CallID, err *CallError) error ReturnReadPiece(ctx context.Context, callID CallID, ok bool, err *CallError) error diff --git a/extern/sector-storage/teststorage_test.go b/extern/sector-storage/teststorage_test.go index 72b27b154..4061b48d9 100644 --- a/extern/sector-storage/teststorage_test.go +++ b/extern/sector-storage/teststorage_test.go @@ -55,10 +55,26 @@ func (t *testExec) ReleaseUnsealed(ctx context.Context, sector storage.SectorRef panic("implement me") } +func (t *testExec) ReleaseSealed(ctx context.Context, sector storage.SectorRef) error { + panic("implement me") +} + func (t *testExec) Remove(ctx context.Context, sector storage.SectorRef) error { panic("implement me") } +func (t *testExec) ReplicaUpdate(ctx context.Context, sector storage.SectorRef, pieces []abi.PieceInfo) (storage.ReplicaUpdateOut, error) { + panic("implement me") +} + +func (t *testExec) ProveReplicaUpdate1(ctx context.Context, sector storage.SectorRef, sectorKey, newSealed, newUnsealed cid.Cid) (storage.ReplicaVanillaProofs, error) { + panic("implement me") +} + +func (t *testExec) ProveReplicaUpdate2(ctx context.Context, sector storage.SectorRef, sectorKey, newSealed, newUnsealed cid.Cid, vanillaProofs storage.ReplicaVanillaProofs) (storage.ReplicaUpdateProof, error) { + panic("implement me") +} + func (t *testExec) NewSector(ctx context.Context, sector storage.SectorRef) error { panic("implement me") } diff --git a/extern/sector-storage/testworker_test.go b/extern/sector-storage/testworker_test.go index 2fe99f3d4..a5c678415 100644 --- a/extern/sector-storage/testworker_test.go +++ b/extern/sector-storage/testworker_test.go @@ -7,6 +7,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/specs-storage/storage" "github.com/google/uuid" + cid "github.com/ipfs/go-cid" "github.com/filecoin-project/lotus/extern/sector-storage/mock" "github.com/filecoin-project/lotus/extern/sector-storage/sealtasks" @@ -67,6 +68,33 @@ func (t *testWorker) AddPiece(ctx context.Context, sector storage.SectorRef, pie }) } +func (t *testWorker) ReplicaUpdate(ctx context.Context, sector storage.SectorRef, pieces []abi.PieceInfo) (storiface.CallID, error) { + return t.asyncCall(sector, func(ci storiface.CallID) { + out, err := t.mockSeal.ReplicaUpdate(ctx, sector, pieces) + if err := t.ret.ReturnReplicaUpdate(ctx, ci, out, toCallError(err)); err != nil { + log.Error(err) + } + }) +} + +func (t *testWorker) ProveReplicaUpdate1(ctx context.Context, sector storage.SectorRef, sectorKey, newSealed, newUnsealed cid.Cid) (storiface.CallID, error) { + return t.asyncCall(sector, func(ci storiface.CallID) { + vanillaProofs, err := t.mockSeal.ProveReplicaUpdate1(ctx, sector, sectorKey, newSealed, newUnsealed) + if err := t.ret.ReturnProveReplicaUpdate1(ctx, ci, vanillaProofs, toCallError(err)); err != nil { + log.Error(err) + } + }) +} + +func (t *testWorker) ProveReplicaUpdate2(ctx context.Context, sector storage.SectorRef, sectorKey, newSealed, newUnsealed cid.Cid, vanillaProofs storage.ReplicaVanillaProofs) (storiface.CallID, error) { + return t.asyncCall(sector, func(ci storiface.CallID) { + proof, err := t.mockSeal.ProveReplicaUpdate2(ctx, sector, sectorKey, newSealed, newUnsealed, vanillaProofs) + if err := t.ret.ReturnProveReplicaUpdate2(ctx, ci, proof, toCallError(err)); err != nil { + log.Error(err) + } + }) +} + func (t *testWorker) SealPreCommit1(ctx context.Context, sector storage.SectorRef, ticket abi.SealRandomness, pieces []abi.PieceInfo) (storiface.CallID, error) { return t.asyncCall(sector, func(ci storiface.CallID) { t.pc1s++ diff --git a/extern/sector-storage/worker_local.go b/extern/sector-storage/worker_local.go index d45d140f8..cc41e916e 100644 --- a/extern/sector-storage/worker_local.go +++ b/extern/sector-storage/worker_local.go @@ -28,7 +28,7 @@ import ( "github.com/filecoin-project/lotus/extern/sector-storage/storiface" ) -var pathTypes = []storiface.SectorFileType{storiface.FTUnsealed, storiface.FTSealed, storiface.FTCache} +var pathTypes = []storiface.SectorFileType{storiface.FTUnsealed, storiface.FTSealed, storiface.FTCache, storiface.FTUpdate, storiface.FTUpdateCache} type WorkerConfig struct { TaskTypes []sealtasks.TaskType @@ -145,7 +145,6 @@ func (l *localWorkerPathProvider) AcquireSector(ctx context.Context, sector stor } sid := storiface.PathByType(storageIDs, fileType) - if err := l.w.sindex.StorageDeclareSector(ctx, stores.ID(sid), sector.ID, fileType, l.op == storiface.AcquireMove); err != nil { log.Errorf("declare sector error: %+v", err) } @@ -160,16 +159,19 @@ func (l *LocalWorker) ffiExec() (ffiwrapper.Storage, error) { type ReturnType string const ( - AddPiece ReturnType = "AddPiece" - SealPreCommit1 ReturnType = "SealPreCommit1" - SealPreCommit2 ReturnType = "SealPreCommit2" - SealCommit1 ReturnType = "SealCommit1" - SealCommit2 ReturnType = "SealCommit2" - FinalizeSector ReturnType = "FinalizeSector" - ReleaseUnsealed ReturnType = "ReleaseUnsealed" - MoveStorage ReturnType = "MoveStorage" - UnsealPiece ReturnType = "UnsealPiece" - Fetch ReturnType = "Fetch" + AddPiece ReturnType = "AddPiece" + SealPreCommit1 ReturnType = "SealPreCommit1" + SealPreCommit2 ReturnType = "SealPreCommit2" + SealCommit1 ReturnType = "SealCommit1" + SealCommit2 ReturnType = "SealCommit2" + FinalizeSector ReturnType = "FinalizeSector" + ReplicaUpdate ReturnType = "ReplicaUpdate" + ProveReplicaUpdate1 ReturnType = "ProveReplicaUpdate1" + ProveReplicaUpdate2 ReturnType = "ProveReplicaUpdate2" + ReleaseUnsealed ReturnType = "ReleaseUnsealed" + MoveStorage ReturnType = "MoveStorage" + UnsealPiece ReturnType = "UnsealPiece" + Fetch ReturnType = "Fetch" ) // in: func(WorkerReturn, context.Context, CallID, err string) @@ -207,16 +209,19 @@ func rfunc(in interface{}) func(context.Context, storiface.CallID, storiface.Wor } var returnFunc = map[ReturnType]func(context.Context, storiface.CallID, storiface.WorkerReturn, interface{}, *storiface.CallError) error{ - AddPiece: rfunc(storiface.WorkerReturn.ReturnAddPiece), - SealPreCommit1: rfunc(storiface.WorkerReturn.ReturnSealPreCommit1), - SealPreCommit2: rfunc(storiface.WorkerReturn.ReturnSealPreCommit2), - SealCommit1: rfunc(storiface.WorkerReturn.ReturnSealCommit1), - SealCommit2: rfunc(storiface.WorkerReturn.ReturnSealCommit2), - FinalizeSector: rfunc(storiface.WorkerReturn.ReturnFinalizeSector), - ReleaseUnsealed: rfunc(storiface.WorkerReturn.ReturnReleaseUnsealed), - MoveStorage: rfunc(storiface.WorkerReturn.ReturnMoveStorage), - UnsealPiece: rfunc(storiface.WorkerReturn.ReturnUnsealPiece), - Fetch: rfunc(storiface.WorkerReturn.ReturnFetch), + AddPiece: rfunc(storiface.WorkerReturn.ReturnAddPiece), + SealPreCommit1: rfunc(storiface.WorkerReturn.ReturnSealPreCommit1), + SealPreCommit2: rfunc(storiface.WorkerReturn.ReturnSealPreCommit2), + SealCommit1: rfunc(storiface.WorkerReturn.ReturnSealCommit1), + SealCommit2: rfunc(storiface.WorkerReturn.ReturnSealCommit2), + FinalizeSector: rfunc(storiface.WorkerReturn.ReturnFinalizeSector), + ReleaseUnsealed: rfunc(storiface.WorkerReturn.ReturnReleaseUnsealed), + ReplicaUpdate: rfunc(storiface.WorkerReturn.ReturnReplicaUpdate), + ProveReplicaUpdate1: rfunc(storiface.WorkerReturn.ReturnProveReplicaUpdate1), + ProveReplicaUpdate2: rfunc(storiface.WorkerReturn.ReturnProveReplicaUpdate2), + MoveStorage: rfunc(storiface.WorkerReturn.ReturnMoveStorage), + UnsealPiece: rfunc(storiface.WorkerReturn.ReturnUnsealPiece), + Fetch: rfunc(storiface.WorkerReturn.ReturnFetch), } func (l *LocalWorker) asyncCall(ctx context.Context, sector storage.SectorRef, rt ReturnType, work func(ctx context.Context, ci storiface.CallID) (interface{}, error)) (storiface.CallID, error) { @@ -240,7 +245,6 @@ func (l *LocalWorker) asyncCall(ctx context.Context, sector storage.SectorRef, r } res, err := work(ctx, ci) - if err != nil { rb, err := json.Marshal(res) if err != nil { @@ -258,7 +262,6 @@ func (l *LocalWorker) asyncCall(ctx context.Context, sector storage.SectorRef, r } } }() - return ci, nil } @@ -382,6 +385,40 @@ func (l *LocalWorker) SealCommit2(ctx context.Context, sector storage.SectorRef, }) } +func (l *LocalWorker) ReplicaUpdate(ctx context.Context, sector storage.SectorRef, pieces []abi.PieceInfo) (storiface.CallID, error) { + sb, err := l.executor() + if err != nil { + return storiface.UndefCall, err + } + + return l.asyncCall(ctx, sector, ReplicaUpdate, func(ctx context.Context, ci storiface.CallID) (interface{}, error) { + sealerOut, err := sb.ReplicaUpdate(ctx, sector, pieces) + return sealerOut, err + }) +} + +func (l *LocalWorker) ProveReplicaUpdate1(ctx context.Context, sector storage.SectorRef, sectorKey, newSealed, newUnsealed cid.Cid) (storiface.CallID, error) { + sb, err := l.executor() + if err != nil { + return storiface.UndefCall, err + } + + return l.asyncCall(ctx, sector, ProveReplicaUpdate1, func(ctx context.Context, ci storiface.CallID) (interface{}, error) { + return sb.ProveReplicaUpdate1(ctx, sector, sectorKey, newSealed, newUnsealed) + }) +} + +func (l *LocalWorker) ProveReplicaUpdate2(ctx context.Context, sector storage.SectorRef, sectorKey, newSealed, newUnsealed cid.Cid, vanillaProofs storage.ReplicaVanillaProofs) (storiface.CallID, error) { + sb, err := l.executor() + if err != nil { + return storiface.UndefCall, err + } + + return l.asyncCall(ctx, sector, ProveReplicaUpdate2, func(ctx context.Context, ci storiface.CallID) (interface{}, error) { + return sb.ProveReplicaUpdate2(ctx, sector, sectorKey, newSealed, newUnsealed, vanillaProofs) + }) +} + func (l *LocalWorker) FinalizeSector(ctx context.Context, sector storage.SectorRef, keepUnsealed []storage.Range) (storiface.CallID, error) { sb, err := l.executor() if err != nil { diff --git a/extern/sector-storage/worker_tracked.go b/extern/sector-storage/worker_tracked.go index 5702426c3..b87abed06 100644 --- a/extern/sector-storage/worker_tracked.go +++ b/extern/sector-storage/worker_tracked.go @@ -98,7 +98,6 @@ func (wt *workTracker) track(ctx context.Context, ready chan struct{}, wid Worke wt.lk.Lock() delete(wt.prepared, prepID) } - callID, err := cb() if err != nil { return callID, err @@ -198,4 +197,22 @@ func (t *trackedWorker) UnsealPiece(ctx context.Context, id storage.SectorRef, i return t.tracker.track(ctx, t.execute, t.wid, t.workerInfo, id, sealtasks.TTUnseal, func() (storiface.CallID, error) { return t.Worker.UnsealPiece(ctx, id, index, size, randomness, cid) }) } +func (t *trackedWorker) ReplicaUpdate(ctx context.Context, sector storage.SectorRef, pieces []abi.PieceInfo) (storiface.CallID, error) { + return t.tracker.track(ctx, t.execute, t.wid, t.workerInfo, sector, sealtasks.TTReplicaUpdate, func() (storiface.CallID, error) { + return t.Worker.ReplicaUpdate(ctx, sector, pieces) + }) +} + +func (t *trackedWorker) ProveReplicaUpdate1(ctx context.Context, sector storage.SectorRef, sectorKey, newSealed, newUnsealed cid.Cid) (storiface.CallID, error) { + return t.tracker.track(ctx, t.execute, t.wid, t.workerInfo, sector, sealtasks.TTProveReplicaUpdate1, func() (storiface.CallID, error) { + return t.Worker.ProveReplicaUpdate1(ctx, sector, sectorKey, newSealed, newUnsealed) + }) +} + +func (t *trackedWorker) ProveReplicaUpdate2(ctx context.Context, sector storage.SectorRef, sectorKey, newSealed, newUnsealed cid.Cid, vanillaProofs storage.ReplicaVanillaProofs) (storiface.CallID, error) { + return t.tracker.track(ctx, t.execute, t.wid, t.workerInfo, sector, sealtasks.TTProveReplicaUpdate2, func() (storiface.CallID, error) { + return t.Worker.ProveReplicaUpdate2(ctx, sector, sectorKey, newSealed, newUnsealed, vanillaProofs) + }) +} + var _ Worker = &trackedWorker{} diff --git a/go.mod b/go.mod index ce52b7975..e0823094d 100644 --- a/go.mod +++ b/go.mod @@ -51,7 +51,7 @@ require ( github.com/filecoin-project/specs-actors/v5 v5.0.4 github.com/filecoin-project/specs-actors/v6 v6.0.1 github.com/filecoin-project/specs-actors/v7 v7.0.0-20211118013026-3dce48197cec - github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506 + github.com/filecoin-project/specs-storage v0.1.1-0.20211123153428-712cb8da07a3 github.com/filecoin-project/test-vectors/schema v0.0.5 github.com/gbrlsnchs/jwt/v3 v3.0.1 github.com/gdamore/tcell/v2 v2.2.0 @@ -156,7 +156,7 @@ require ( golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/sys v0.0.0-20210917161153-d61c044b1678 golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac - golang.org/x/tools v0.1.5 + golang.org/x/tools v0.1.7 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 gopkg.in/cheggaaa/pb.v1 v1.0.28 gotest.tools v2.2.0+incompatible diff --git a/go.sum b/go.sum index 06341ce01..e404ca72e 100644 --- a/go.sum +++ b/go.sum @@ -396,8 +396,8 @@ github.com/filecoin-project/specs-actors/v6 v6.0.1/go.mod h1:V1AYfi5GkHXipx1mnVi github.com/filecoin-project/specs-actors/v7 v7.0.0-20211117170924-fd07a4c7dff9/go.mod h1:p6LIOFezA1rgRLMewbvdi3Pp6SAu+q9FtJ9CAleSjrE= github.com/filecoin-project/specs-actors/v7 v7.0.0-20211118013026-3dce48197cec h1:KV9vE+Sl2Y3qKsrpba4HcE7wHwK7v6O5U/S0xHbje6A= github.com/filecoin-project/specs-actors/v7 v7.0.0-20211118013026-3dce48197cec/go.mod h1:p6LIOFezA1rgRLMewbvdi3Pp6SAu+q9FtJ9CAleSjrE= -github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506 h1:Ur/l2+6qN+lQiqjozWWc5p9UDaAMDZKTlDS98oRnlIw= -github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506/go.mod h1:nJRRM7Aa9XVvygr3W9k6xGF46RWzr2zxF/iGoAIfA/g= +github.com/filecoin-project/specs-storage v0.1.1-0.20211123153428-712cb8da07a3 h1:FLPxD2ksWwGc/sbnFLWep2p8ViP93VCAwFaVxrtVCyo= +github.com/filecoin-project/specs-storage v0.1.1-0.20211123153428-712cb8da07a3/go.mod h1:nJRRM7Aa9XVvygr3W9k6xGF46RWzr2zxF/iGoAIfA/g= github.com/filecoin-project/test-vectors/schema v0.0.5 h1:w3zHQhzM4pYxJDl21avXjOKBLF8egrvwUwjpT8TquDg= github.com/filecoin-project/test-vectors/schema v0.0.5/go.mod h1:iQ9QXLpYWL3m7warwvK1JC/pTri8mnfEmKygNDqqY6E= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= @@ -1872,6 +1872,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zondax/hid v0.9.0 h1:eiT3P6vNxAEVxXMw66eZUAAnU2zD33JBkfG/EnfAKl8= github.com/zondax/hid v0.9.0/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= github.com/zondax/ledger-go v0.12.1 h1:hYRcyznPRJp+5mzF2sazTLP2nGvGjYDD2VzhHhFomLU= @@ -2104,6 +2105,7 @@ golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210917221730-978cfadd31cf h1:R150MpwJIv1MpS0N/pc+NhTM8ajzvlmxlY5OYsrevXQ= golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -2227,6 +2229,7 @@ golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210917161153-d61c044b1678 h1:J27LZFQBFoihqXoegpscI10HpjZ7B5WQLLKL2FZXQKw= golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -2318,8 +2321,9 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1-0.20210225150353-54dc8c5edb56/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ= +golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=