More progress on fixing storing garbage data

This commit is contained in:
Łukasz Magiera 2019-11-02 00:43:54 +01:00
parent 1dcebece71
commit 3bc4a5dddf
9 changed files with 266 additions and 36 deletions

View File

@ -37,7 +37,7 @@ const PaymentChannelClosingDelay = 6 * 60 * 2 // six hours
// Consensus / Network
// Seconds
const BlockDelay = 10
const BlockDelay = 2
// Seconds
const AllowableClockDrift = BlockDelay * 2

View File

@ -227,11 +227,11 @@ func (sma StorageMinerActor) PreCommitSector(act *types.Actor, vmctx types.VMCon
return nil, err
}
if params.Epoch >= vmctx.BlockHeight() {
return nil, aerrors.Newf(1, "sector commitment must be based off past randomness (%d >= %d)", params.Epoch, vmctx.BlockHeight())
if params.Epoch >= vmctx.BlockHeight()+build.SealRandomnessLookback {
return nil, aerrors.Newf(1, "sector commitment must be based off past randomness (%d >= %d)", params.Epoch, vmctx.BlockHeight()+build.SealRandomnessLookback)
}
if vmctx.BlockHeight()-params.Epoch > 1000 {
if vmctx.BlockHeight()-params.Epoch+build.SealRandomnessLookback > 1000 {
return nil, aerrors.New(2, "sector commitment must be recent enough")
}
@ -318,7 +318,7 @@ func (sma StorageMinerActor) ProveCommitSector(act *types.Actor, vmctx types.VMC
// TODO: ensure normalization to ID address
maddr := vmctx.Message().To
ticket, err := vmctx.GetRandomness(us.TicketEpoch)
ticket, err := vmctx.GetRandomness(us.TicketEpoch - build.SealRandomnessLookback)
if err != nil {
return nil, aerrors.Wrap(err, "failed to get ticket randomness")
}

View File

@ -3771,3 +3771,112 @@ func (t *ComputeDataCommitmentParams) UnmarshalCBOR(r io.Reader) error {
t.SectorSize = extra
return nil
}
func (t *SectorProveCommitInfo) 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)
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.SectorID (uint64)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.SectorID)); err != nil {
return err
}
// t.t.DealIDs ([]uint64)
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.DealIDs)))); err != nil {
return err
}
for _, v := range t.DealIDs {
if err := cbg.CborWriteHeader(w, cbg.MajUnsignedInt, v); err != nil {
return err
}
}
return nil
}
func (t *SectorProveCommitInfo) 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)
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.SectorID (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 = extra
// t.t.DealIDs ([]uint64)
maj, extra, err = cbg.CborReadHeader(br)
if err != nil {
return err
}
if extra > 8192 {
return fmt.Errorf("t.DealIDs: array too large (%d)", extra)
}
if maj != cbg.MajArray {
return fmt.Errorf("expected cbor array")
}
if extra > 0 {
t.DealIDs = make([]uint64, extra)
}
for i := 0; i < int(extra); i++ {
maj, val, err := cbg.CborReadHeader(br)
if err != nil {
return xerrors.Errorf("failed to read uint64 for t.DealIDs slice: %w", err)
}
if maj != cbg.MajUnsignedInt {
return xerrors.Errorf("value read for array t.DealIDs was not a uint, instead got %d", maj)
}
t.DealIDs[i] = val
}
return nil
}

View File

@ -91,6 +91,7 @@ func main() {
actors.ProcessStorageDealsPaymentParams{},
actors.OnChainDeal{},
actors.ComputeDataCommitmentParams{},
actors.SectorProveCommitInfo{},
)
if err != nil {
fmt.Println(err)

View File

@ -2,9 +2,6 @@ package impl
import (
"context"
"fmt"
"io"
"math/rand"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/address"
@ -12,8 +9,6 @@ import (
"github.com/filecoin-project/lotus/storage"
"github.com/filecoin-project/lotus/storage/sector"
"github.com/filecoin-project/lotus/storage/sectorblocks"
"golang.org/x/xerrors"
)
type StorageMinerAPI struct {
@ -25,6 +20,7 @@ type StorageMinerAPI struct {
SectorBlocks *sectorblocks.SectorBlocks
Miner *storage.Miner
Full api.FullNode
}
func (sm *StorageMinerAPI) ActorAddress(context.Context) (address.Address, error) {
@ -32,28 +28,7 @@ func (sm *StorageMinerAPI) ActorAddress(context.Context) (address.Address, error
}
func (sm *StorageMinerAPI) StoreGarbageData(ctx context.Context) error {
ssize, err := sm.Miner.SectorSize(ctx)
if err != nil {
return xerrors.Errorf("failed to get miner sector size: %w", err)
}
go func() {
size := sectorbuilder.UserBytesForSectorSize(ssize)
// TODO: create a deal
name := fmt.Sprintf("fake-file-%d", rand.Intn(100000000))
sectorId, err := sm.Sectors.AddPiece(name, size, io.LimitReader(rand.New(rand.NewSource(42)), int64(size)))
if err != nil {
log.Error(err)
return
}
if err := sm.Miner.SealSector(context.TODO(), sectorId); err != nil {
log.Error(err)
return
}
}()
return err
return sm.Miner.StoreGarbageData(ctx)
}
func (sm *StorageMinerAPI) SectorsStatus(ctx context.Context, sid uint64) (sectorbuilder.SectorSealingStatus, error) {

View File

@ -184,7 +184,7 @@ func SealTicketGen(api api.FullNode) sector.TicketFn {
}
return &sectorbuilder.SealTicket{
BlockHeight: ts.Height() - build.SealRandomnessLookback,
BlockHeight: ts.Height(),
TicketBytes: tkt,
}, nil
}

140
storage/garbage.go Normal file
View File

@ -0,0 +1,140 @@
package storage
import (
"bytes"
"context"
"fmt"
"io"
"math"
"math/rand"
"golang.org/x/xerrors"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/sectorbuilder"
)
func (m *Miner) StoreGarbageData(_ context.Context) error {
ctx := context.TODO()
ssize, err := m.SectorSize(ctx)
if err != nil {
return xerrors.Errorf("failed to get miner sector size: %w", err)
}
go func() {
size := sectorbuilder.UserBytesForSectorSize(ssize)
/*// Add market funds
smsg, err := m.api.MpoolPushMessage(ctx, &types.Message{
To: actors.StorageMarketAddress,
From: m.worker,
Value: types.NewInt(size),
GasPrice: types.NewInt(0),
GasLimit: types.NewInt(1000000),
Method: actors.SMAMethods.AddBalance,
})
if err != nil {
log.Error(err)
return
}
r, err := m.api.StateWaitMsg(ctx, smsg.Cid())
if err != nil {
log.Error(err)
return
}
if r.Receipt.ExitCode != 0 {
log.Error(xerrors.Errorf("adding funds to storage miner market actor failed: exit %d", r.Receipt.ExitCode))
return
}*/
// Publish a deal
// TODO: Maybe cache
commP, err := sectorbuilder.GeneratePieceCommitment(io.LimitReader(rand.New(rand.NewSource(42)), int64(size)), size)
if err != nil {
log.Error(err)
return
}
sdp := actors.StorageDealProposal{
PieceRef: commP[:],
PieceSize: size,
PieceSerialization: actors.SerializationUnixFSv0,
Client: m.worker,
Provider: m.worker,
ProposalExpiration: math.MaxUint64,
Duration: math.MaxUint64 / 2, // /2 because overflows
StoragePricePerEpoch: types.NewInt(0),
StorageCollateral: types.NewInt(0),
ProposerSignature: nil,
}
if err := api.SignWith(ctx, m.api.WalletSign, m.worker, &sdp); err != nil {
log.Error(xerrors.Errorf("signing storage deal failed: ", err))
return
}
storageDeal := actors.StorageDeal{
Proposal: sdp,
}
if err := api.SignWith(ctx, m.api.WalletSign, m.worker, &storageDeal); err != nil {
log.Error(xerrors.Errorf("signing storage deal failed: ", err))
return
}
params, err := actors.SerializeParams(&actors.PublishStorageDealsParams{
Deals: []actors.StorageDeal{storageDeal},
})
if err != nil {
log.Error(xerrors.Errorf("serializing PublishStorageDeals params failed: ", err))
}
// TODO: We may want this to happen after fetching data
smsg, err := m.api.MpoolPushMessage(ctx, &types.Message{
To: actors.StorageMarketAddress,
From: m.worker,
Value: types.NewInt(0),
GasPrice: types.NewInt(0),
GasLimit: types.NewInt(1000000),
Method: actors.SMAMethods.PublishStorageDeals,
Params: params,
})
if err != nil {
log.Error(err)
return
}
r, err := m.api.StateWaitMsg(ctx, smsg.Cid())
if err != nil {
log.Error(err)
return
}
if r.Receipt.ExitCode != 0 {
log.Error(xerrors.Errorf("publishing deal failed: exit %d", r.Receipt.ExitCode))
}
var resp actors.PublishStorageDealResponse
if err := resp.UnmarshalCBOR(bytes.NewReader(r.Receipt.Return)); err != nil {
log.Error(err)
return
}
if len(resp.DealIDs) != 1 {
log.Error("got unexpected number of DealIDs from")
return
}
name := fmt.Sprintf("fake-file-%d", rand.Intn(100000000))
sectorId, err := m.secst.AddPiece(name, size, io.LimitReader(rand.New(rand.NewSource(42)), int64(size)), resp.DealIDs[0])
if err != nil {
log.Error(err)
return
}
if err := m.SealSector(context.TODO(), sectorId); err != nil {
log.Error(err)
return
}
}()
return err
}

View File

@ -67,6 +67,7 @@ type storageMinerApi interface {
ChainGetTipSetByHeight(context.Context, uint64, *types.TipSet) (*types.TipSet, error)
ChainGetBlockMessages(context.Context, cid.Cid) (*api.BlockMessages, error)
WalletSign(context.Context, address.Address, []byte) (*types.Signature, error)
WalletBalance(context.Context, address.Address) (types.BigInt, error)
WalletHas(context.Context, address.Address) (bool, error)
}

View File

@ -135,14 +135,18 @@ func (m *Miner) committing(ctx context.Context, sector SectorInfo) (func(*Sector
return nil, xerrors.Errorf("computing seal proof failed: %w", err)
}
deals, err := m.secst.DealsForCommit(sector.SectorID)
if err != nil {
return nil, err
}
params := &actors.SectorProveCommitInfo{
Proof: proof,
SectorID: sector.SectorID,
//DealIDs: deals,
DealIDs: deals,
}
_ = params
enc, aerr := actors.SerializeParams(nil)
enc, aerr := actors.SerializeParams(params)
if aerr != nil {
return nil, xerrors.Errorf("could not serialize commit sector parameters: %w", aerr)
}