Mostly functional mock sectorbuilder

This commit is contained in:
Łukasz Magiera 2020-01-13 21:47:27 +01:00
parent 85f0f0bf81
commit a2bcc1fec2
33 changed files with 390 additions and 95 deletions

View File

@ -64,7 +64,7 @@ func TestDealFlow(t *testing.T, b APIBuilder) {
go func() { go func() {
defer close(done) defer close(done)
for mine { for mine {
time.Sleep(time.Second) time.Sleep(100 * time.Millisecond)
fmt.Println("mining a block now") fmt.Println("mining a block now")
if err := sn[0].MineOne(ctx); err != nil { if err := sn[0].MineOne(ctx); err != nil {
t.Error(err) t.Error(err)

View File

@ -19,7 +19,6 @@ import (
cbor "github.com/ipfs/go-ipld-cbor" cbor "github.com/ipfs/go-ipld-cbor"
"github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/peer"
cbg "github.com/whyrusleeping/cbor-gen" cbg "github.com/whyrusleeping/cbor-gen"
"go.opencensus.io/trace"
"golang.org/x/xerrors" "golang.org/x/xerrors"
) )
@ -526,7 +525,7 @@ func (sma StorageMinerActor) SubmitFallbackPoSt(act *types.Actor, vmctx types.VM
}) })
} }
if ok, lerr := sectorbuilder.VerifyFallbackPost(vmctx.Context(), mi.SectorSize, if ok, lerr := vmctx.Sys().VerifyFallbackPost(vmctx.Context(), mi.SectorSize,
sectorbuilder.NewSortedPublicSectorInfo(sectorInfos), seed[:], params.Proof, candidates, proverID, activeFaults); !ok || lerr != nil { sectorbuilder.NewSortedPublicSectorInfo(sectorInfos), seed[:], params.Proof, candidates, proverID, activeFaults); !ok || lerr != nil {
if lerr != nil { if lerr != nil {
// TODO: study PoST errors // TODO: study PoST errors
@ -641,17 +640,6 @@ func RemoveFromSectorSet(ctx context.Context, s types.Storage, ss cid.Cid, ids [
return ncid, nil return ncid, nil
} }
func ValidatePoRep(ctx context.Context, maddr address.Address, ssize uint64, commD, commR, ticket, proof, seed []byte, sectorID uint64) (bool, ActorError) {
_, span := trace.StartSpan(ctx, "ValidatePoRep")
defer span.End()
ok, err := sectorbuilder.VerifySeal(ssize, commR, commD, maddr, ticket, seed, sectorID, proof)
if err != nil {
return false, aerrors.Absorb(err, 25, "verify seal failed")
}
return ok, nil
}
func CollateralForPower(power types.BigInt) types.BigInt { func CollateralForPower(power types.BigInt) types.BigInt {
return types.BigMul(power, types.NewInt(10)) return types.BigMul(power, types.NewInt(10))
/* TODO: this /* TODO: this

View File

@ -254,7 +254,7 @@ func getMinerSectorSet(ctx context.Context, st types.StateTree, bs blockstore.Bl
func (h *Harness) makeFakeDeal(t *testing.T, miner, worker, client address.Address, size uint64) *actors.StorageDealProposal { func (h *Harness) makeFakeDeal(t *testing.T, miner, worker, client address.Address, size uint64) *actors.StorageDealProposal {
data := make([]byte, size) data := make([]byte, size)
rand.Read(data) rand.Read(data)
commP, err := sectorbuilder.GeneratePieceCommitment(bytes.NewReader(data), size) commP, err := (&sectorbuilder.SectorBuilder{}).GeneratePieceCommitment(bytes.NewReader(data), size)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -262,7 +262,6 @@ func (h *Harness) makeFakeDeal(t *testing.T, miner, worker, client address.Addre
prop := actors.StorageDealProposal{ prop := actors.StorageDealProposal{
PieceRef: commP[:], PieceRef: commP[:],
PieceSize: size, PieceSize: size,
//PieceSerialization SerializationMode // Needs to be here as it tells how data in the sector maps to PieceRef cid
Client: client, Client: client,
Provider: miner, Provider: miner,

View File

@ -649,7 +649,7 @@ func (sma StorageMarketActor) ComputeDataCommitment(act *types.Actor, vmctx type
}) })
} }
commd, err := sectorbuilder.GenerateDataCommitment(params.SectorSize, pieces) commd, err := vmctx.Sys().GenerateDataCommitment(params.SectorSize, pieces)
if err != nil { if err != nil {
return nil, aerrors.Absorb(err, 6, "failed to generate data commitment from pieces") return nil, aerrors.Absorb(err, 6, "failed to generate data commitment from pieces")
} }

View File

@ -50,10 +50,10 @@ func setupVMTestEnv(t *testing.T) (*vm.VM, []address.Address, bstore.Blockstore)
t.Fatal(err) t.Fatal(err)
} }
cs := store.NewChainStore(bs, nil) cs := store.NewChainStore(bs, nil, nil)
// TODO: should probabaly mock out the randomness bit, nil works for now // TODO: should probabaly mock out the randomness bit, nil works for now
vm, err := vm.NewVM(stateroot, 1, nil, maddr, cs.Blockstore()) vm, err := vm.NewVM(stateroot, 1, nil, maddr, cs.Blockstore(), cs.VMSys())
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -3,6 +3,7 @@ package actors_test
import ( import (
"bytes" "bytes"
"context" "context"
"github.com/filecoin-project/go-sectorbuilder"
"math/rand" "math/rand"
"testing" "testing"
@ -194,8 +195,8 @@ func NewHarness(t *testing.T, options ...HarnessOpt) *Harness {
t.Fatal(err) t.Fatal(err)
} }
h.cs = store.NewChainStore(h.bs, nil) h.cs = store.NewChainStore(h.bs, nil, vm.Syscalls(sectorbuilder.ProofVerifier))
h.vm, err = vm.NewVM(stateroot, 1, h.Rand, h.HI.Miner, h.cs.Blockstore()) h.vm, err = vm.NewVM(stateroot, 1, h.Rand, h.HI.Miner, h.cs.Blockstore(), h.cs.VMSys())
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -6,6 +6,7 @@ import (
"crypto/sha256" "crypto/sha256"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"github.com/filecoin-project/lotus/chain/vm"
"io/ioutil" "io/ioutil"
"sync/atomic" "sync/atomic"
@ -170,7 +171,9 @@ func NewGenerator() (*ChainGen, error) {
MinerAddrs: []address.Address{maddr1, maddr2}, MinerAddrs: []address.Address{maddr1, maddr2},
} }
genb, err := MakeGenesisBlock(bs, map[address.Address]types.BigInt{ sys := vm.Syscalls(sectorbuilder.ProofVerifier)
genb, err := MakeGenesisBlock(bs, sys, map[address.Address]types.BigInt{
mk1: types.FromFil(40000), mk1: types.FromFil(40000),
mk2: types.FromFil(40000), mk2: types.FromFil(40000),
banker: types.FromFil(50000), banker: types.FromFil(50000),
@ -179,7 +182,7 @@ func NewGenerator() (*ChainGen, error) {
return nil, xerrors.Errorf("make genesis block failed: %w", err) return nil, xerrors.Errorf("make genesis block failed: %w", err)
} }
cs := store.NewChainStore(bs, ds) cs := store.NewChainStore(bs, ds, sys)
genfb := &types.FullBlock{Header: genb.Genesis} genfb := &types.FullBlock{Header: genb.Genesis}
gents := store.NewFullTipSet([]*types.FullBlock{genfb}) gents := store.NewFullTipSet([]*types.FullBlock{genfb})

View File

@ -275,7 +275,7 @@ func mustEnc(i cbg.CBORMarshaler) []byte {
} }
func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid, gmcfg *GenMinerCfg) (cid.Cid, []actors.StorageDealProposal, error) { func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid, gmcfg *GenMinerCfg) (cid.Cid, []actors.StorageDealProposal, error) {
vm, err := vm.NewVM(sroot, 0, nil, actors.NetworkAddress, cs.Blockstore()) vm, err := vm.NewVM(sroot, 0, nil, actors.NetworkAddress, cs.Blockstore(), cs.VMSys())
if err != nil { if err != nil {
return cid.Undef, nil, xerrors.Errorf("failed to create NewVM: %w", err) return cid.Undef, nil, xerrors.Errorf("failed to create NewVM: %w", err)
} }
@ -555,7 +555,7 @@ func doExecValue(ctx context.Context, vm *vm.VM, to, from address.Address, value
return ret.Return, nil return ret.Return, nil
} }
func MakeGenesisBlock(bs bstore.Blockstore, balances map[address.Address]types.BigInt, gmcfg *GenMinerCfg, ts uint64) (*GenesisBootstrap, error) { func MakeGenesisBlock(bs bstore.Blockstore, sys *types.VMSyscalls, balances map[address.Address]types.BigInt, gmcfg *GenMinerCfg, ts uint64) (*GenesisBootstrap, error) {
ctx := context.Background() ctx := context.Background()
state, err := MakeInitialStateTree(bs, balances) state, err := MakeInitialStateTree(bs, balances)
@ -569,7 +569,7 @@ func MakeGenesisBlock(bs bstore.Blockstore, balances map[address.Address]types.B
} }
// temp chainstore // temp chainstore
cs := store.NewChainStore(bs, datastore.NewMapDatastore()) cs := store.NewChainStore(bs, datastore.NewMapDatastore(), sys)
stateroot, deals, err := SetupStorageMiners(ctx, cs, stateroot, gmcfg) stateroot, deals, err := SetupStorageMiners(ctx, cs, stateroot, gmcfg)
if err != nil { if err != nil {
return nil, xerrors.Errorf("setup storage miners failed: %w", err) return nil, xerrors.Errorf("setup storage miners failed: %w", err)

View File

@ -18,7 +18,7 @@ func (sm *StateManager) CallRaw(ctx context.Context, msg *types.Message, bstate
ctx, span := trace.StartSpan(ctx, "statemanager.CallRaw") ctx, span := trace.StartSpan(ctx, "statemanager.CallRaw")
defer span.End() defer span.End()
vmi, err := vm.NewVM(bstate, bheight, r, actors.NetworkAddress, sm.cs.Blockstore()) vmi, err := vm.NewVM(bstate, bheight, r, actors.NetworkAddress, sm.cs.Blockstore(), sm.cs.VMSys())
if err != nil { if err != nil {
return nil, xerrors.Errorf("failed to set up vm: %w", err) return nil, xerrors.Errorf("failed to set up vm: %w", err)
} }

View File

@ -139,7 +139,7 @@ func (sm *StateManager) computeTipSetState(ctx context.Context, blks []*types.Bl
r := store.NewChainRand(sm.cs, cids, blks[0].Height) r := store.NewChainRand(sm.cs, cids, blks[0].Height)
vmi, err := vm.NewVM(pstate, blks[0].Height, r, address.Undef, sm.cs.Blockstore()) vmi, err := vm.NewVM(pstate, blks[0].Height, r, address.Undef, sm.cs.Blockstore(), sm.cs.VMSys())
if err != nil { if err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("instantiating VM failed: %w", err) return cid.Undef, cid.Undef, xerrors.Errorf("instantiating VM failed: %w", err)
} }

View File

@ -51,9 +51,11 @@ type ChainStore struct {
mmCache *lru.ARCCache mmCache *lru.ARCCache
tsCache *lru.ARCCache tsCache *lru.ARCCache
vmcalls *types.VMSyscalls
} }
func NewChainStore(bs bstore.Blockstore, ds dstore.Batching) *ChainStore { func NewChainStore(bs bstore.Blockstore, ds dstore.Batching, vmcalls *types.VMSyscalls) *ChainStore {
c, _ := lru.NewARC(2048) c, _ := lru.NewARC(2048)
tsc, _ := lru.NewARC(4096) tsc, _ := lru.NewARC(4096)
cs := &ChainStore{ cs := &ChainStore{
@ -63,6 +65,7 @@ func NewChainStore(bs bstore.Blockstore, ds dstore.Batching) *ChainStore {
tipsets: make(map[uint64][]cid.Cid), tipsets: make(map[uint64][]cid.Cid),
mmCache: c, mmCache: c,
tsCache: tsc, tsCache: tsc,
vmcalls: vmcalls,
} }
cs.reorgCh = cs.reorgWorker(context.TODO()) cs.reorgCh = cs.reorgWorker(context.TODO())
@ -793,6 +796,11 @@ func (cs *ChainStore) Blockstore() bstore.Blockstore {
return cs.bs return cs.bs
} }
func (cs *ChainStore) VMSys() *types.VMSyscalls {
return cs.vmcalls
}
func (cs *ChainStore) TryFillTipSet(ts *types.TipSet) (*FullTipSet, error) { func (cs *ChainStore) TryFillTipSet(ts *types.TipSet) (*FullTipSet, error) {
var out []*types.FullBlock var out []*types.FullBlock

View File

@ -55,7 +55,7 @@ func BenchmarkGetRandomness(b *testing.B) {
bs := blockstore.NewBlockstore(bds) bs := blockstore.NewBlockstore(bds)
cs := store.NewChainStore(bs, mds) cs := store.NewChainStore(bs, mds, nil)
b.ResetTimer() b.ResetTimer()

View File

@ -60,7 +60,7 @@ func (cs *ChainStore) call(ctx context.Context, msg *types.Message, ts *types.Ti
r := NewChainRand(cs, ts.Cids(), ts.Height()) r := NewChainRand(cs, ts.Cids(), ts.Height())
vmi, err := vm.NewVM(bstate, ts.Height(), r, actors.NetworkAddress, cs.bs) vmi, err := vm.NewVM(bstate, ts.Height(), r, actors.NetworkAddress, cs.bs, cs.vmcalls)
if err != nil { if err != nil {
return nil, xerrors.Errorf("failed to set up vm: %w", err) return nil, xerrors.Errorf("failed to set up vm: %w", err)
} }

View File

@ -690,7 +690,7 @@ func (syncer *Syncer) VerifyElectionPoStProof(ctx context.Context, h *types.Bloc
} }
hvrf := sha256.Sum256(h.EPostProof.PostRand) hvrf := sha256.Sum256(h.EPostProof.PostRand)
ok, err := sectorbuilder.VerifyElectionPost(ctx, ssize, *sectorInfo, hvrf[:], h.EPostProof.Proof, winners, h.Miner) ok, err := sectorbuilder.ProofVerifier.VerifyElectionPost(ctx, ssize, *sectorInfo, hvrf[:], h.EPostProof.Proof, winners, h.Miner)
if err != nil { if err != nil {
return xerrors.Errorf("failed to verify election post: %w", err) return xerrors.Errorf("failed to verify election post: %w", err)
} }

View File

@ -2,6 +2,7 @@ package types
import ( import (
"context" "context"
"github.com/filecoin-project/go-sectorbuilder"
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-amt-ipld" "github.com/filecoin-project/go-amt-ipld"
@ -46,7 +47,17 @@ type VMContext interface {
} }
type VMSyscalls struct { type VMSyscalls struct {
ValidatePoRep func(context.Context, address.Address, uint64, []byte, []byte, []byte, []byte, []byte, uint64) (bool, aerrors.ActorError) ValidatePoRep func(context.Context, address.Address, uint64, []byte, []byte, []byte, []byte, []byte, uint64) (bool, aerrors.ActorError)
VerifyFallbackPost func(ctx context.Context,
sectorSize uint64,
sectorInfo sectorbuilder.SortedPublicSectorInfo,
challengeSeed []byte,
proof []byte,
candidates []sectorbuilder.EPostCandidate,
proverID address.Address,
faults uint64) (bool, error)
GenerateDataCommitment func(ssize uint64, pieces []sectorbuilder.PublicPieceInfo) ([sectorbuilder.CommLen]byte, error)
} }
type storageWrapper struct { type storageWrapper struct {

View File

@ -2,6 +2,7 @@ package validation
import ( import (
"context" "context"
"github.com/filecoin-project/go-sectorbuilder"
vchain "github.com/filecoin-project/chain-validation/pkg/chain" vchain "github.com/filecoin-project/chain-validation/pkg/chain"
vstate "github.com/filecoin-project/chain-validation/pkg/state" vstate "github.com/filecoin-project/chain-validation/pkg/state"
@ -32,7 +33,7 @@ func (a *Applier) ApplyMessage(eCtx *vchain.ExecutionContext, state vstate.Wrapp
if err != nil { if err != nil {
return vchain.MessageReceipt{}, err return vchain.MessageReceipt{}, err
} }
lotusVM, err := vm.NewVM(base, eCtx.Epoch, randSrc, minerAddr, st.bs) lotusVM, err := vm.NewVM(base, eCtx.Epoch, randSrc, minerAddr, st.bs, vm.Syscalls(sectorbuilder.ProofVerifier))
if err != nil { if err != nil {
return vchain.MessageReceipt{}, err return vchain.MessageReceipt{}, err
} }

View File

@ -1,14 +1,30 @@
package vm package vm
import ( import (
"context"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-sectorbuilder"
"github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/actors/aerrors"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"go.opencensus.io/trace"
) )
// Actual type is defined in chain/types/vmcontext.go because the VMContext interface is there // Actual type is defined in chain/types/vmcontext.go because the VMContext interface is there
func DefaultSyscalls() *types.VMSyscalls { func Syscalls(verifier sectorbuilder.Verifier) *types.VMSyscalls {
return &types.VMSyscalls{ return &types.VMSyscalls{
ValidatePoRep: actors.ValidatePoRep, ValidatePoRep: func(ctx context.Context, maddr address.Address, ssize uint64, commD, commR, ticket, proof, seed []byte, sectorID uint64) (bool, actors.ActorError) {
_, span := trace.StartSpan(ctx, "ValidatePoRep")
defer span.End()
ok, err := verifier.VerifySeal(ssize, commR, commD, maddr, ticket, seed, sectorID, proof)
if err != nil {
return false, aerrors.Absorb(err, 25, "verify seal failed")
}
return ok, nil
},
VerifyFallbackPost: verifier.VerifyFallbackPost,
GenerateDataCommitment: verifier.GenerateDataCommitment,
} }
} }

View File

@ -312,7 +312,7 @@ type VM struct {
Syscalls *types.VMSyscalls Syscalls *types.VMSyscalls
} }
func NewVM(base cid.Cid, height uint64, r Rand, maddr address.Address, cbs blockstore.Blockstore) (*VM, error) { func NewVM(base cid.Cid, height uint64, r Rand, maddr address.Address, cbs blockstore.Blockstore, syscalls *types.VMSyscalls) (*VM, error) {
buf := bufbstore.NewBufferedBstore(cbs) buf := bufbstore.NewBufferedBstore(cbs)
cst := hamt.CSTFromBstore(buf) cst := hamt.CSTFromBstore(buf)
state, err := state.LoadStateTree(cst, base) state, err := state.LoadStateTree(cst, base)
@ -328,8 +328,8 @@ func NewVM(base cid.Cid, height uint64, r Rand, maddr address.Address, cbs block
blockHeight: height, blockHeight: height,
blockMiner: maddr, blockMiner: maddr,
inv: newInvoker(), inv: newInvoker(),
rand: r, rand: r, // TODO: Probably should be a syscall
Syscalls: DefaultSyscalls(), Syscalls: syscalls,
}, nil }, nil
} }

View File

@ -213,7 +213,7 @@ func main() {
sealcommit := time.Now() sealcommit := time.Now()
commD := pi.CommP commD := pi.CommP
ok, err := sectorbuilder.VerifySeal(sectorSize, pco.CommR[:], commD[:], maddr, ticket.TicketBytes[:], seed.TicketBytes[:], i, proof) ok, err := sectorbuilder.ProofVerifier.VerifySeal(sectorSize, pco.CommR[:], commD[:], maddr, ticket.TicketBytes[:], seed.TicketBytes[:], i, proof)
if err != nil { if err != nil {
return err return err
} }
@ -307,7 +307,7 @@ func main() {
log.Warn("separate epost calls returned different proof values (this might be bad)") 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) ok, err := sectorbuilder.ProofVerifier.VerifyElectionPost(context.TODO(), sectorSize, sinfos, challenge[:], proof1, candidates[:1], maddr)
if err != nil { if err != nil {
return err return err
} }
@ -317,7 +317,7 @@ func main() {
verifypost1 := time.Now() verifypost1 := time.Now()
ok, err = sectorbuilder.VerifyElectionPost(context.TODO(), sectorSize, sinfos, challenge[:], proof2, candidates[:1], maddr) ok, err = sectorbuilder.ProofVerifier.VerifyElectionPost(context.TODO(), sectorSize, sinfos, challenge[:], proof2, candidates[:1], maddr)
if err != nil { if err != nil {
return err return err
} }

4
go.mod
View File

@ -109,3 +109,7 @@ require (
replace github.com/golangci/golangci-lint => github.com/golangci/golangci-lint v1.18.0 replace github.com/golangci/golangci-lint => github.com/golangci/golangci-lint v1.18.0
replace github.com/filecoin-project/filecoin-ffi => ./extern/filecoin-ffi replace github.com/filecoin-project/filecoin-ffi => ./extern/filecoin-ffi
replace github.com/filecoin-project/go-sectorbuilder => /home/magik6k/gohack/github.com/filecoin-project/go-sectorbuilder
replace github.com/filecoin-project/go-fil-markets => /home/magik6k/gohack/github.com/filecoin-project/go-fil-markets

View File

@ -23,6 +23,7 @@ import (
"github.com/filecoin-project/go-fil-markets/retrievalmarket/discovery" "github.com/filecoin-project/go-fil-markets/retrievalmarket/discovery"
"github.com/filecoin-project/go-fil-markets/storagemarket" "github.com/filecoin-project/go-fil-markets/storagemarket"
deals "github.com/filecoin-project/go-fil-markets/storagemarket/impl" deals "github.com/filecoin-project/go-fil-markets/storagemarket/impl"
"github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain" "github.com/filecoin-project/lotus/chain"
"github.com/filecoin-project/lotus/chain/blocksync" "github.com/filecoin-project/lotus/chain/blocksync"
@ -33,6 +34,7 @@ import (
"github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm"
"github.com/filecoin-project/lotus/chain/wallet" "github.com/filecoin-project/lotus/chain/wallet"
"github.com/filecoin-project/lotus/markets/storageadapter" "github.com/filecoin-project/lotus/markets/storageadapter"
"github.com/filecoin-project/lotus/miner" "github.com/filecoin-project/lotus/miner"
@ -193,6 +195,8 @@ func Online() Option {
Override(HandleIncomingMessagesKey, modules.HandleIncomingMessages), Override(HandleIncomingMessagesKey, modules.HandleIncomingMessages),
Override(new(sectorbuilder.Verifier), sectorbuilder.ProofVerifier),
Override(new(*types.VMSyscalls), vm.Syscalls),
Override(new(*store.ChainStore), modules.ChainStore), Override(new(*store.ChainStore), modules.ChainStore),
Override(new(*stmgr.StateManager), stmgr.NewStateManager), Override(new(*stmgr.StateManager), stmgr.NewStateManager),
Override(new(*wallet.Wallet), wallet.NewWallet), Override(new(*wallet.Wallet), wallet.NewWallet),
@ -239,7 +243,7 @@ func Online() Option {
// Storage miner // Storage miner
ApplyIf(func(s *Settings) bool { return s.nodeType == repo.StorageMiner }, ApplyIf(func(s *Settings) bool { return s.nodeType == repo.StorageMiner },
Override(new(storage.SectorBuilder), modules.SectorBuilder), Override(new(sectorbuilder.Interface), modules.SectorBuilder),
Override(new(*sectorblocks.SectorBlocks), sectorblocks.NewSectorBlocks), Override(new(*sectorblocks.SectorBlocks), sectorblocks.NewSectorBlocks),
Override(new(storage.TicketFn), modules.SealTicketGen), Override(new(storage.TicketFn), modules.SealTicketGen),
Override(new(*storage.Miner), modules.StorageMiner), Override(new(*storage.Miner), modules.StorageMiner),

View File

@ -26,7 +26,7 @@ type StorageMinerAPI struct {
CommonAPI CommonAPI
SectorBuilderConfig *sectorbuilder.Config SectorBuilderConfig *sectorbuilder.Config
SectorBuilder storage.SectorBuilder SectorBuilder sectorbuilder.Interface
SectorBlocks *sectorblocks.SectorBlocks SectorBlocks *sectorblocks.SectorBlocks
Miner *storage.Miner Miner *storage.Miner

View File

@ -73,8 +73,8 @@ func ChainBlockservice(bs dtypes.ChainBlockstore, rem dtypes.ChainExchange) dtyp
return blockservice.New(bs, rem) return blockservice.New(bs, rem)
} }
func ChainStore(lc fx.Lifecycle, bs dtypes.ChainBlockstore, ds dtypes.MetadataDS) *store.ChainStore { func ChainStore(lc fx.Lifecycle, bs dtypes.ChainBlockstore, ds dtypes.MetadataDS, syscalls *types.VMSyscalls) *store.ChainStore {
chain := store.NewChainStore(bs, ds) chain := store.NewChainStore(bs, ds, syscalls)
if err := chain.Load(); err != nil { if err := chain.Load(); err != nil {
log.Warnf("loading chain state from disk: %s", err) log.Warnf("loading chain state from disk: %s", err)

View File

@ -98,7 +98,7 @@ func SectorBuilderConfig(storagePath string, threads uint, noprecommit, nocommit
} }
} }
func StorageMiner(mctx helpers.MetricsCtx, lc fx.Lifecycle, api api.FullNode, h host.Host, ds dtypes.MetadataDS, sb storage.SectorBuilder, tktFn storage.TicketFn) (*storage.Miner, error) { func StorageMiner(mctx helpers.MetricsCtx, lc fx.Lifecycle, api api.FullNode, h host.Host, ds dtypes.MetadataDS, sb sectorbuilder.Interface, tktFn storage.TicketFn) (*storage.Miner, error) {
maddr, err := minerAddrFromDS(ds) maddr, err := minerAddrFromDS(ds)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -30,8 +30,8 @@ import (
var glog = logging.Logger("genesis") var glog = logging.Logger("genesis")
func MakeGenesisMem(out io.Writer, gmc *gen.GenMinerCfg) func(bs dtypes.ChainBlockstore, w *wallet.Wallet) modules.Genesis { func MakeGenesisMem(out io.Writer, gmc *gen.GenMinerCfg) func(bs dtypes.ChainBlockstore, w *wallet.Wallet, syscalls *types.VMSyscalls) modules.Genesis {
return func(bs dtypes.ChainBlockstore, w *wallet.Wallet) modules.Genesis { return func(bs dtypes.ChainBlockstore, w *wallet.Wallet, syscalls *types.VMSyscalls) modules.Genesis {
return func() (*types.BlockHeader, error) { return func() (*types.BlockHeader, error) {
glog.Warn("Generating new random genesis block, note that this SHOULD NOT happen unless you are setting up new network") glog.Warn("Generating new random genesis block, note that this SHOULD NOT happen unless you are setting up new network")
defk, err := w.GenerateKey(types.KTBLS) defk, err := w.GenerateKey(types.KTBLS)
@ -51,7 +51,7 @@ func MakeGenesisMem(out io.Writer, gmc *gen.GenMinerCfg) func(bs dtypes.ChainBlo
alloc[waddr] = types.FromFil(10000) alloc[waddr] = types.FromFil(10000)
} }
b, err := gen.MakeGenesisBlock(bs, alloc, gmc, 100000) b, err := gen.MakeGenesisBlock(bs, syscalls, alloc, gmc, 100000)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -68,8 +68,8 @@ func MakeGenesisMem(out io.Writer, gmc *gen.GenMinerCfg) func(bs dtypes.ChainBlo
} }
} }
func MakeGenesis(outFile, presealInfo, timestamp string) func(bs dtypes.ChainBlockstore, w *wallet.Wallet) modules.Genesis { func MakeGenesis(outFile, presealInfo, timestamp string) func(bs dtypes.ChainBlockstore, w *wallet.Wallet, syscalls *types.VMSyscalls) modules.Genesis {
return func(bs dtypes.ChainBlockstore, w *wallet.Wallet) modules.Genesis { return func(bs dtypes.ChainBlockstore, w *wallet.Wallet, syscalls *types.VMSyscalls) modules.Genesis {
return func() (*types.BlockHeader, error) { return func() (*types.BlockHeader, error) {
glog.Warn("Generating new random genesis block, note that this SHOULD NOT happen unless you are setting up new network") glog.Warn("Generating new random genesis block, note that this SHOULD NOT happen unless you are setting up new network")
presealInfo, err := homedir.Expand(presealInfo) presealInfo, err := homedir.Expand(presealInfo)
@ -130,7 +130,7 @@ func MakeGenesis(outFile, presealInfo, timestamp string) func(bs dtypes.ChainBlo
ts = uint64(t.Unix()) ts = uint64(t.Unix())
} }
b, err := gen.MakeGenesisBlock(bs, addrs, gmc, ts) b, err := gen.MakeGenesisBlock(bs, syscalls, addrs, gmc, ts)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -36,6 +36,7 @@ import (
"github.com/filecoin-project/lotus/node/modules" "github.com/filecoin-project/lotus/node/modules"
modtest "github.com/filecoin-project/lotus/node/modules/testing" modtest "github.com/filecoin-project/lotus/node/modules/testing"
"github.com/filecoin-project/lotus/node/repo" "github.com/filecoin-project/lotus/node/repo"
"github.com/filecoin-project/lotus/storage/sbmock"
) )
func init() { func init() {
@ -102,6 +103,7 @@ func testStorageNode(ctx context.Context, t *testing.T, waddr address.Address, a
node.Test(), node.Test(),
node.MockHost(mn), node.MockHost(mn),
node.Override(new(sectorbuilder.Interface), sbmock.NewMockSectorBuilder(5, build.SectorSizes[0])),
node.Override(new(api.FullNode), tnd), node.Override(new(api.FullNode), tnd),
node.Override(new(*miner.Miner), miner.NewTestMiner(mineBlock, act)), node.Override(new(*miner.Miner), miner.NewTestMiner(mineBlock, act)),
@ -247,6 +249,110 @@ func builder(t *testing.T, nFull int, storage []int) ([]test.TestNode, []test.Te
return fulls, storers return fulls, storers
} }
func mockSbBuilder(t *testing.T, nFull int, storage []int) ([]test.TestNode, []test.TestStorageNode) {
ctx := context.Background()
mn := mocknet.New(ctx)
fulls := make([]test.TestNode, nFull)
storers := make([]test.TestStorageNode, len(storage))
pk, _, err := crypto.GenerateEd25519Key(rand.Reader)
require.NoError(t, err)
minerPid, err := peer.IDFromPrivateKey(pk)
require.NoError(t, err)
var genbuf bytes.Buffer
if len(storage) > 1 {
panic("need more peer IDs")
}
// PRESEAL SECTION, TRY TO REPLACE WITH BETTER IN THE FUTURE
// TODO: would be great if there was a better way to fake the preseals
gmc := &gen.GenMinerCfg{
PeerIDs: []peer.ID{minerPid}, // TODO: if we have more miners, need more peer IDs
PreSeals: map[string]genesis.GenesisMiner{},
}
var presealDirs []string
for i := 0; i < len(storage); i++ {
maddr, err := address.NewIDAddress(300 + uint64(i))
if err != nil {
t.Fatal(err)
}
tdir, err := ioutil.TempDir("", "preseal-memgen")
if err != nil {
t.Fatal(err)
}
genm, err := sbmock.PreSeal(1024, maddr, 1)
if err != nil {
t.Fatal(err)
}
presealDirs = append(presealDirs, tdir)
gmc.MinerAddrs = append(gmc.MinerAddrs, maddr)
gmc.PreSeals[maddr.String()] = *genm
}
// END PRESEAL SECTION
for i := 0; i < nFull; i++ {
var genesis node.Option
if i == 0 {
genesis = node.Override(new(modules.Genesis), modtest.MakeGenesisMem(&genbuf, gmc))
} else {
genesis = node.Override(new(modules.Genesis), modules.LoadGenesis(genbuf.Bytes()))
}
var err error
// TODO: Don't ignore stop
_, err = node.New(ctx,
node.FullAPI(&fulls[i].FullNode),
node.Online(),
node.Repo(repo.NewMemory(nil)),
node.MockHost(mn),
node.Test(),
node.Override(new(sectorbuilder.Verifier), sbmock.MockVerifier),
genesis,
)
if err != nil {
t.Fatal(err)
}
}
for i, full := range storage {
// TODO: support non-bootstrap miners
if i != 0 {
t.Fatal("only one storage node supported")
}
if full != 0 {
t.Fatal("storage nodes only supported on the first full node")
}
f := fulls[full]
genMiner := gmc.MinerAddrs[i]
wa := gmc.PreSeals[genMiner.String()].Worker
storers[i] = testStorageNode(ctx, t, wa, genMiner, pk, f, mn)
/*if err := sma.SectorBuilder.ImportFrom(osb, false); err != nil {
t.Fatal(err)
}*/
}
if err := mn.LinkAll(); err != nil {
t.Fatal(err)
}
return fulls, storers
}
func TestAPI(t *testing.T) { func TestAPI(t *testing.T) {
test.TestApis(t, builder) test.TestApis(t, builder)
} }
@ -292,5 +398,5 @@ func TestAPIDealFlow(t *testing.T) {
if testing.Short() { if testing.Short() {
t.Skip("skipping test in short mode") t.Skip("skipping test in short mode")
} }
test.TestDealFlow(t, builder) test.TestDealFlow(t, mockSbBuilder)
} }

View File

@ -8,6 +8,8 @@ import (
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-sectorbuilder"
"github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
@ -19,7 +21,7 @@ const StartConfidence = 4 // TODO: config
type fpostScheduler struct { type fpostScheduler struct {
api storageMinerApi api storageMinerApi
sb SectorBuilder sb sectorbuilder.Interface
actor address.Address actor address.Address
worker address.Address worker address.Address

View File

@ -22,7 +22,7 @@ func (m *Miner) pledgeSector(ctx context.Context, sectorID uint64, existingPiece
deals := make([]actors.StorageDealProposal, len(sizes)) deals := make([]actors.StorageDealProposal, len(sizes))
for i, size := range sizes { for i, size := range sizes {
release := m.sb.RateLimit() release := m.sb.RateLimit()
commP, err := sectorbuilder.GeneratePieceCommitment(io.LimitReader(rand.New(rand.NewSource(42)), int64(size)), size) commP, err := m.sb.GeneratePieceCommitment(io.LimitReader(rand.New(rand.NewSource(42)), int64(size)), size)
release() release()
if err != nil { if err != nil {

View File

@ -3,7 +3,6 @@ package storage
import ( import (
"context" "context"
"errors" "errors"
"io"
"time" "time"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
@ -37,7 +36,7 @@ type Miner struct {
worker address.Address worker address.Address
// Sealing // Sealing
sb SectorBuilder sb sectorbuilder.Interface
sectors *statestore.StateStore sectors *statestore.StateStore
tktFn TicketFn tktFn TicketFn
@ -72,24 +71,7 @@ type storageMinerApi interface {
WalletHas(context.Context, address.Address) (bool, error) WalletHas(context.Context, address.Address) (bool, error)
} }
type SectorBuilder interface { func NewMiner(api storageMinerApi, addr address.Address, h host.Host, ds datastore.Batching, sb sectorbuilder.Interface, tktFn TicketFn) (*Miner, error) {
RateLimit() func()
AddPiece(uint64, uint64, io.Reader, []uint64) (sectorbuilder.PublicPieceInfo, error)
SectorSize() uint64
AcquireSectorId() (uint64, error)
Scrub(sectorbuilder.SortedPublicSectorInfo) []*sectorbuilder.Fault
GenerateFallbackPoSt(sectorbuilder.SortedPublicSectorInfo, [sectorbuilder.CommLen]byte, []uint64) ([]sectorbuilder.EPostCandidate, []byte, error)
SealPreCommit(context.Context, uint64, sectorbuilder.SealTicket, []sectorbuilder.PublicPieceInfo) (sectorbuilder.RawSealPreCommitOutput, error)
SealCommit(context.Context, uint64, sectorbuilder.SealTicket, sectorbuilder.SealSeed, []sectorbuilder.PublicPieceInfo, sectorbuilder.RawSealPreCommitOutput) ([]byte, error)
// Not so sure about these being on the interface
GetPath(string, string) (string, error)
WorkerStats() sectorbuilder.WorkerStats
AddWorker(context.Context, sectorbuilder.WorkerCfg) (<-chan sectorbuilder.WorkerTask, error)
TaskDone(context.Context, uint64, sectorbuilder.SealRes) error
}
func NewMiner(api storageMinerApi, addr address.Address, h host.Host, ds datastore.Batching, sb SectorBuilder, tktFn TicketFn) (*Miner, error) {
return &Miner{ return &Miner{
api: api, api: api,
@ -162,11 +144,11 @@ func (m *Miner) runPreflightChecks(ctx context.Context) error {
} }
type SectorBuilderEpp struct { type SectorBuilderEpp struct {
sb *sectorbuilder.SectorBuilder sb sectorbuilder.Interface
} }
func NewElectionPoStProver(sb SectorBuilder) *SectorBuilderEpp { func NewElectionPoStProver(sb sectorbuilder.Interface) *SectorBuilderEpp {
return &SectorBuilderEpp{sb.(*sectorbuilder.SectorBuilder)} return &SectorBuilderEpp{sb}
} }
var _ gen.ElectionPoStProver = (*SectorBuilderEpp)(nil) var _ gen.ElectionPoStProver = (*SectorBuilderEpp)(nil)

52
storage/sbmock/preseal.go Normal file
View File

@ -0,0 +1,52 @@
package sbmock
import (
"math"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-sectorbuilder"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/wallet"
"github.com/filecoin-project/lotus/genesis"
)
func PreSeal(ssize uint64, maddr address.Address, sectors int) (*genesis.GenesisMiner, error) {
k, err := wallet.GenerateKey(types.KTBLS)
if err != nil {
return nil, err
}
genm := &genesis.GenesisMiner{
Owner: k.Address,
Worker: k.Address,
SectorSize: ssize,
Sectors: make([]*genesis.PreSeal, sectors),
Key: k.KeyInfo,
}
for i := range genm.Sectors {
preseal := &genesis.PreSeal{}
sdata := randB(sectorbuilder.UserBytesForSectorSize(ssize))
preseal.CommD = commD(sdata)
preseal.CommR = commDR(preseal.CommD[:])
preseal.SectorID = uint64(i + 1)
preseal.Deal = actors.StorageDealProposal{
PieceRef: preseal.CommD[:],
PieceSize: sectorbuilder.UserBytesForSectorSize(ssize),
Client: maddr,
Provider: maddr,
ProposalExpiration: math.MaxUint64,
Duration: math.MaxUint64,
StoragePricePerEpoch: types.NewInt(0),
StorageCollateral: types.NewInt(0),
ProposerSignature: nil,
}
genm.Sectors[i] = preseal
}
return genm, nil
}

View File

@ -6,19 +6,16 @@ import (
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"math/big"
"math/rand" "math/rand"
"sync" "sync"
ffi "github.com/filecoin-project/filecoin-ffi"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-sectorbuilder" "github.com/filecoin-project/go-sectorbuilder"
"golang.org/x/xerrors" "golang.org/x/xerrors"
) )
func randComm() [sectorbuilder.CommLen]byte {
var out [sectorbuilder.CommLen]byte
rand.Read(out[:])
return out
}
type SBMock struct { type SBMock struct {
sectors map[uint64]*sectorState sectors map[uint64]*sectorState
sectorSize uint64 sectorSize uint64
@ -28,11 +25,13 @@ type SBMock struct {
lk sync.Mutex lk sync.Mutex
} }
type mockVerif struct {}
func NewMockSectorBuilder(threads int, ssize uint64) *SBMock { func NewMockSectorBuilder(threads int, ssize uint64) *SBMock {
return &SBMock{ return &SBMock{
sectors: make(map[uint64]*sectorState), sectors: make(map[uint64]*sectorState),
sectorSize: ssize, sectorSize: ssize,
nextSectorID: 0, nextSectorID: 5,
rateLimit: make(chan struct{}, threads), rateLimit: make(chan struct{}, threads),
} }
} }
@ -82,7 +81,7 @@ func (sb *SBMock) AddPiece(size uint64, sectorId uint64, r io.Reader, existingPi
ss.pieces = append(ss.pieces, b) ss.pieces = append(ss.pieces, b)
return sectorbuilder.PublicPieceInfo{ return sectorbuilder.PublicPieceInfo{
Size: size, Size: size,
// TODO: should we compute a commP? maybe do it when we need it CommP: commD(b),
}, nil }, nil
} }
@ -158,9 +157,22 @@ func (sb *SBMock) SealPreCommit(ctx context.Context, sid uint64, ticket sectorbu
ss.state = statePreCommit ss.state = statePreCommit
pis := make([]ffi.PublicPieceInfo, len(ss.pieces))
for i, piece := range ss.pieces {
pis[i] = ffi.PublicPieceInfo{
Size: uint64(len(piece)),
CommP: commD(piece),
}
}
commd, err := MockVerifier.GenerateDataCommitment(sb.sectorSize, pis)
if err != nil {
return sectorbuilder.RawSealPreCommitOutput{}, err
}
return sectorbuilder.RawSealPreCommitOutput{ return sectorbuilder.RawSealPreCommitOutput{
CommD: randComm(), CommD: commd,
CommR: randComm(), CommR: commDR(commd[:]),
}, nil }, nil
} }
@ -184,9 +196,11 @@ func (sb *SBMock) SealCommit(ctx context.Context, sid uint64, ticket sectorbuild
opFinishWait(ctx) opFinishWait(ctx)
buf := make([]byte, 32) var out [32]byte
rand.Read(buf) for i := range out {
return buf, nil out[i] = precommit.CommD[i] + precommit.CommR[31 - i] - ticket.TicketBytes[i] * seed.TicketBytes[i]
}
return out[:], nil
} }
func (sb *SBMock) GetPath(string, string) (string, error) { func (sb *SBMock) GetPath(string, string) (string, error) {
@ -235,6 +249,45 @@ func AddOpFinish(ctx context.Context) (context.Context, func()) {
} }
} }
func (sb *SBMock) ComputeElectionPoSt(sectorInfo sectorbuilder.SortedPublicSectorInfo, challengeSeed []byte, winners []sectorbuilder.EPostCandidate) ([]byte, error) {
panic("implement me")
}
func (sb *SBMock) GenerateEPostCandidates(sectorInfo sectorbuilder.SortedPublicSectorInfo, challengeSeed [sectorbuilder.CommLen]byte, faults []uint64) ([]sectorbuilder.EPostCandidate, error) {
if len(faults) > 0 {
panic("todo")
}
n := sectorbuilder.ElectionPostChallengeCount(uint64(len(sectorInfo.Values())), uint64(len(faults)))
if n > uint64(len(sectorInfo.Values())) {
n = uint64(len(sectorInfo.Values()))
}
out := make([]sectorbuilder.EPostCandidate, len(sectorInfo.Values()))
seed := big.NewInt(0).SetBytes(challengeSeed[:])
start := seed.Mod(seed, big.NewInt(int64(len(sectorInfo.Values())))).Int64()
for i := 0; uint64(i) < n; i++ {
out[i] = sectorbuilder.EPostCandidate{
SectorID: uint64((int(start) + i) % len(sectorInfo.Values())),
PartialTicket: challengeSeed,
Ticket: commDR(challengeSeed[:]),
SectorChallengeIndex: 0,
}
}
return out, nil
}
func (sb *SBMock) GeneratePieceCommitment(piece io.Reader, pieceSize uint64) (commP [sectorbuilder.CommLen]byte, err error) {
panic("implement me")
}
func (sb *SBMock) ReadPieceFromSealedSector(sectorID uint64, offset uint64, size uint64, ticket []byte, commD []byte) (io.ReadCloser, error) {
panic("implement me")
}
func (sb *SBMock) StageFakeData() (uint64, []sectorbuilder.PublicPieceInfo, error) { func (sb *SBMock) StageFakeData() (uint64, []sectorbuilder.PublicPieceInfo, error) {
usize := sectorbuilder.UserBytesForSectorSize(sb.sectorSize) usize := sectorbuilder.UserBytesForSectorSize(sb.sectorSize)
sid, err := sb.AcquireSectorId() sid, err := sb.AcquireSectorId()
@ -252,3 +305,40 @@ func (sb *SBMock) StageFakeData() (uint64, []sectorbuilder.PublicPieceInfo, erro
return sid, []sectorbuilder.PublicPieceInfo{pi}, nil return sid, []sectorbuilder.PublicPieceInfo{pi}, nil
} }
func (m mockVerif) VerifyElectionPost(ctx context.Context, sectorSize uint64, sectorInfo sectorbuilder.SortedPublicSectorInfo, challengeSeed []byte, proof []byte, candidates []sectorbuilder.EPostCandidate, proverID address.Address) (bool, error) {
panic("implement me")
}
func (m mockVerif) VerifyFallbackPost(ctx context.Context, sectorSize uint64, sectorInfo sectorbuilder.SortedPublicSectorInfo, challengeSeed []byte, proof []byte, candidates []sectorbuilder.EPostCandidate, proverID address.Address, faults uint64) (bool, error) {
panic("implement me")
}
func (m mockVerif) VerifySeal(sectorSize uint64, commR, commD []byte, proverID address.Address, ticket []byte, seed []byte, sectorID uint64, proof []byte) (bool, error) {
if len(proof) != 32 { // Real ones are longer, but this should be fine
return false, nil
}
for i, b := range proof {
if b != commD[i] + commR[31 - i] - ticket[i] * seed[i] {
return false, nil
}
}
return true, nil
}
func (m mockVerif) GenerateDataCommitment(ssize uint64, pieces []ffi.PublicPieceInfo) ([sectorbuilder.CommLen]byte, error) {
if len(pieces) != 1 {
panic("todo")
}
if pieces[0].Size != sectorbuilder.UserBytesForSectorSize(ssize) {
panic("todo")
}
return pieces[0].CommP, nil
}
var MockVerifier = mockVerif{}
var _ sectorbuilder.Verifier = MockVerifier
var _ sectorbuilder.Interface = &SBMock{}

28
storage/sbmock/util.go Normal file
View File

@ -0,0 +1,28 @@
package sbmock
import (
"crypto/rand"
"crypto/sha256"
"io"
"io/ioutil"
)
func randB(n uint64) []byte {
b, err := ioutil.ReadAll(io.LimitReader(rand.Reader, int64(n)))
if err != nil {
panic(err)
}
return b
}
func commDR(in []byte) (out [32]byte) {
for i, b := range in {
out[i] = ^b
}
return out
}
func commD(b []byte) [32]byte {
return sha256.Sum256(b)
}

View File

@ -39,7 +39,7 @@ var ErrNotFound = errors.New("not found")
type SectorBlocks struct { type SectorBlocks struct {
*storage.Miner *storage.Miner
sb *sectorbuilder.SectorBuilder sb sectorbuilder.Interface
intermediate blockstore.Blockstore // holds intermediate nodes TODO: consider combining with the staging blockstore intermediate blockstore.Blockstore // holds intermediate nodes TODO: consider combining with the staging blockstore
@ -47,10 +47,10 @@ type SectorBlocks struct {
keyLk sync.Mutex keyLk sync.Mutex
} }
func NewSectorBlocks(miner *storage.Miner, ds dtypes.MetadataDS, sb storage.SectorBuilder) *SectorBlocks { func NewSectorBlocks(miner *storage.Miner, ds dtypes.MetadataDS, sb sectorbuilder.Interface) *SectorBlocks {
sbc := &SectorBlocks{ sbc := &SectorBlocks{
Miner: miner, Miner: miner,
sb: sb.(*sectorbuilder.SectorBuilder), sb: sb,
intermediate: blockstore.NewBlockstore(namespace.Wrap(ds, imBlocksPrefix)), intermediate: blockstore.NewBlockstore(namespace.Wrap(ds, imBlocksPrefix)),