From 03f31d74f18b61ea13292e7f81bdf5af2dd6e314 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 15 Jan 2020 21:49:11 +0100 Subject: [PATCH 001/126] Move miner sealing logic into a separate package --- cbor_gen.go | 1092 ++++++++++++++++++++++++++++++++++++++++++ garbage.go | 127 +++++ sector_fsm.go | 264 ++++++++++ sector_states.go | 254 ++++++++++ sector_types.go | 106 ++++ sector_utils.go | 57 +++ sector_utils_test.go | 46 ++ sectors.go | 136 ++++++ sectors_fsm_test.go | 79 +++ sectors_test.go | 56 +++ 10 files changed, 2217 insertions(+) create mode 100644 cbor_gen.go create mode 100644 garbage.go create mode 100644 sector_fsm.go create mode 100644 sector_states.go create mode 100644 sector_types.go create mode 100644 sector_utils.go create mode 100644 sector_utils_test.go create mode 100644 sectors.go create mode 100644 sectors_fsm_test.go create mode 100644 sectors_test.go diff --git a/cbor_gen.go b/cbor_gen.go new file mode 100644 index 000000000..62c6241dc --- /dev/null +++ b/cbor_gen.go @@ -0,0 +1,1092 @@ +package sealing + +import ( + "fmt" + "io" + + cbg "github.com/whyrusleeping/cbor-gen" + xerrors "golang.org/x/xerrors" +) + +// Code generated by github.com/whyrusleeping/cbor-gen. DO NOT EDIT. + +var _ = xerrors.Errorf + +func (t *SealTicket) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write([]byte{162}); err != nil { + return err + } + + // t.BlockHeight (uint64) (uint64) + if len("BlockHeight") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"BlockHeight\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("BlockHeight")))); err != nil { + return err + } + if _, err := w.Write([]byte("BlockHeight")); err != nil { + return err + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.BlockHeight))); err != nil { + return err + } + + // t.TicketBytes ([]uint8) (slice) + if len("TicketBytes") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"TicketBytes\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("TicketBytes")))); err != nil { + return err + } + if _, err := w.Write([]byte("TicketBytes")); err != nil { + return err + } + + if len(t.TicketBytes) > cbg.ByteArrayMaxLen { + return xerrors.Errorf("Byte array in field t.TicketBytes was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.TicketBytes)))); err != nil { + return err + } + if _, err := w.Write(t.TicketBytes); err != nil { + return err + } + return nil +} + +func (t *SealTicket) UnmarshalCBOR(r io.Reader) error { + br := cbg.GetPeeker(r) + + maj, extra, err := cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra != 2 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + var name string + + // t.BlockHeight (uint64) (uint64) + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + name = string(sval) + } + + if name != "BlockHeight" { + return fmt.Errorf("expected struct map entry %s to be BlockHeight", name) + } + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.BlockHeight = uint64(extra) + // t.TicketBytes ([]uint8) (slice) + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + name = string(sval) + } + + if name != "TicketBytes" { + return fmt.Errorf("expected struct map entry %s to be TicketBytes", name) + } + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + + if extra > cbg.ByteArrayMaxLen { + return fmt.Errorf("t.TicketBytes: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.TicketBytes = make([]byte, extra) + if _, err := io.ReadFull(br, t.TicketBytes); err != nil { + return err + } + return nil +} + +func (t *SealSeed) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write([]byte{162}); err != nil { + return err + } + + // t.BlockHeight (uint64) (uint64) + if len("BlockHeight") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"BlockHeight\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("BlockHeight")))); err != nil { + return err + } + if _, err := w.Write([]byte("BlockHeight")); err != nil { + return err + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.BlockHeight))); err != nil { + return err + } + + // t.TicketBytes ([]uint8) (slice) + if len("TicketBytes") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"TicketBytes\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("TicketBytes")))); err != nil { + return err + } + if _, err := w.Write([]byte("TicketBytes")); err != nil { + return err + } + + if len(t.TicketBytes) > cbg.ByteArrayMaxLen { + return xerrors.Errorf("Byte array in field t.TicketBytes was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.TicketBytes)))); err != nil { + return err + } + if _, err := w.Write(t.TicketBytes); err != nil { + return err + } + return nil +} + +func (t *SealSeed) UnmarshalCBOR(r io.Reader) error { + br := cbg.GetPeeker(r) + + maj, extra, err := cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra != 2 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + var name string + + // t.BlockHeight (uint64) (uint64) + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + name = string(sval) + } + + if name != "BlockHeight" { + return fmt.Errorf("expected struct map entry %s to be BlockHeight", name) + } + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.BlockHeight = uint64(extra) + // t.TicketBytes ([]uint8) (slice) + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + name = string(sval) + } + + if name != "TicketBytes" { + return fmt.Errorf("expected struct map entry %s to be TicketBytes", name) + } + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + + if extra > cbg.ByteArrayMaxLen { + return fmt.Errorf("t.TicketBytes: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.TicketBytes = make([]byte, extra) + if _, err := io.ReadFull(br, t.TicketBytes); err != nil { + return err + } + return nil +} + +func (t *Piece) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write([]byte{163}); err != nil { + return err + } + + // t.DealID (uint64) (uint64) + if len("DealID") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"DealID\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("DealID")))); err != nil { + return err + } + if _, err := w.Write([]byte("DealID")); err != nil { + return err + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.DealID))); err != nil { + return err + } + + // t.Size (uint64) (uint64) + if len("Size") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"Size\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Size")))); err != nil { + return err + } + if _, err := w.Write([]byte("Size")); err != nil { + return err + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Size))); err != nil { + return err + } + + // t.CommP ([]uint8) (slice) + if len("CommP") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"CommP\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("CommP")))); err != nil { + return err + } + if _, err := w.Write([]byte("CommP")); err != nil { + return err + } + + if len(t.CommP) > cbg.ByteArrayMaxLen { + return xerrors.Errorf("Byte array in field t.CommP was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.CommP)))); err != nil { + return err + } + if _, err := w.Write(t.CommP); err != nil { + return err + } + return nil +} + +func (t *Piece) UnmarshalCBOR(r io.Reader) error { + br := cbg.GetPeeker(r) + + maj, extra, err := cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra != 3 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + var name string + + // t.DealID (uint64) (uint64) + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + name = string(sval) + } + + if name != "DealID" { + return fmt.Errorf("expected struct map entry %s to be DealID", name) + } + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.DealID = uint64(extra) + // t.Size (uint64) (uint64) + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + name = string(sval) + } + + if name != "Size" { + return fmt.Errorf("expected struct map entry %s to be Size", name) + } + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Size = uint64(extra) + // t.CommP ([]uint8) (slice) + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + name = string(sval) + } + + if name != "CommP" { + return fmt.Errorf("expected struct map entry %s to be CommP", name) + } + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + + if extra > cbg.ByteArrayMaxLen { + return fmt.Errorf("t.CommP: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.CommP = make([]byte, extra) + if _, err := io.ReadFull(br, t.CommP); err != nil { + return err + } + return nil +} + +func (t *SectorInfo) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write([]byte{173}); err != nil { + return err + } + + // t.State (uint64) (uint64) + if len("State") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"State\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("State")))); err != nil { + return err + } + if _, err := w.Write([]byte("State")); err != nil { + return err + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.State))); err != nil { + return err + } + + // t.SectorID (uint64) (uint64) + if len("SectorID") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"SectorID\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("SectorID")))); err != nil { + return err + } + if _, err := w.Write([]byte("SectorID")); err != nil { + return err + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SectorID))); err != nil { + return err + } + + // t.Nonce (uint64) (uint64) + if len("Nonce") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"Nonce\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Nonce")))); err != nil { + return err + } + if _, err := w.Write([]byte("Nonce")); err != nil { + return err + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Nonce))); err != nil { + return err + } + + // t.Pieces ([]storage.Piece) (slice) + if len("Pieces") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"Pieces\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Pieces")))); err != nil { + return err + } + if _, err := w.Write([]byte("Pieces")); err != nil { + return err + } + + if len(t.Pieces) > cbg.MaxLength { + return xerrors.Errorf("Slice value in field t.Pieces was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Pieces)))); err != nil { + return err + } + for _, v := range t.Pieces { + if err := v.MarshalCBOR(w); err != nil { + return err + } + } + + // t.CommD ([]uint8) (slice) + if len("CommD") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"CommD\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("CommD")))); err != nil { + return err + } + if _, err := w.Write([]byte("CommD")); err != nil { + return err + } + + if len(t.CommD) > cbg.ByteArrayMaxLen { + return xerrors.Errorf("Byte array in field t.CommD was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.CommD)))); err != nil { + return err + } + if _, err := w.Write(t.CommD); err != nil { + return err + } + + // t.CommR ([]uint8) (slice) + if len("CommR") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"CommR\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("CommR")))); err != nil { + return err + } + if _, err := w.Write([]byte("CommR")); err != nil { + return err + } + + if len(t.CommR) > cbg.ByteArrayMaxLen { + return xerrors.Errorf("Byte array in field t.CommR was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.CommR)))); err != nil { + return err + } + if _, err := w.Write(t.CommR); err != nil { + return err + } + + // t.Proof ([]uint8) (slice) + if len("Proof") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"Proof\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Proof")))); err != nil { + return err + } + if _, err := w.Write([]byte("Proof")); err != nil { + return err + } + + if len(t.Proof) > cbg.ByteArrayMaxLen { + return xerrors.Errorf("Byte array in field t.Proof was too long") + } + + 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.Ticket (storage.SealTicket) (struct) + if len("Ticket") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"Ticket\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Ticket")))); err != nil { + return err + } + if _, err := w.Write([]byte("Ticket")); err != nil { + return err + } + + if err := t.Ticket.MarshalCBOR(w); err != nil { + return err + } + + // t.PreCommitMessage (cid.Cid) (struct) + if len("PreCommitMessage") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"PreCommitMessage\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("PreCommitMessage")))); err != nil { + return err + } + if _, err := w.Write([]byte("PreCommitMessage")); err != nil { + return err + } + + if t.PreCommitMessage == nil { + if _, err := w.Write(cbg.CborNull); err != nil { + return err + } + } else { + if err := cbg.WriteCid(w, *t.PreCommitMessage); err != nil { + return xerrors.Errorf("failed to write cid field t.PreCommitMessage: %w", err) + } + } + + // t.Seed (storage.SealSeed) (struct) + if len("Seed") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"Seed\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Seed")))); err != nil { + return err + } + if _, err := w.Write([]byte("Seed")); err != nil { + return err + } + + if err := t.Seed.MarshalCBOR(w); err != nil { + return err + } + + // t.CommitMessage (cid.Cid) (struct) + if len("CommitMessage") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"CommitMessage\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("CommitMessage")))); err != nil { + return err + } + if _, err := w.Write([]byte("CommitMessage")); err != nil { + return err + } + + if t.CommitMessage == nil { + if _, err := w.Write(cbg.CborNull); err != nil { + return err + } + } else { + if err := cbg.WriteCid(w, *t.CommitMessage); err != nil { + return xerrors.Errorf("failed to write cid field t.CommitMessage: %w", err) + } + } + + // t.FaultReportMsg (cid.Cid) (struct) + if len("FaultReportMsg") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"FaultReportMsg\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("FaultReportMsg")))); err != nil { + return err + } + if _, err := w.Write([]byte("FaultReportMsg")); err != nil { + return err + } + + if t.FaultReportMsg == nil { + if _, err := w.Write(cbg.CborNull); err != nil { + return err + } + } else { + if err := cbg.WriteCid(w, *t.FaultReportMsg); err != nil { + return xerrors.Errorf("failed to write cid field t.FaultReportMsg: %w", err) + } + } + + // t.LastErr (string) (string) + if len("LastErr") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"LastErr\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("LastErr")))); err != nil { + return err + } + if _, err := w.Write([]byte("LastErr")); err != nil { + return err + } + + if len(t.LastErr) > cbg.MaxLength { + return xerrors.Errorf("Value in field t.LastErr was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.LastErr)))); err != nil { + return err + } + if _, err := w.Write([]byte(t.LastErr)); err != nil { + return err + } + return nil +} + +func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { + br := cbg.GetPeeker(r) + + maj, extra, err := cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra != 13 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + var name string + + // t.State (uint64) (uint64) + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + name = string(sval) + } + + if name != "State" { + return fmt.Errorf("expected struct map entry %s to be State", name) + } + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.State = uint64(extra) + // t.SectorID (uint64) (uint64) + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + name = string(sval) + } + + if name != "SectorID" { + return fmt.Errorf("expected struct map entry %s to be SectorID", name) + } + + 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.Nonce (uint64) (uint64) + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + name = string(sval) + } + + if name != "Nonce" { + return fmt.Errorf("expected struct map entry %s to be Nonce", name) + } + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Nonce = uint64(extra) + // t.Pieces ([]storage.Piece) (slice) + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + name = string(sval) + } + + if name != "Pieces" { + return fmt.Errorf("expected struct map entry %s to be Pieces", name) + } + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + + if extra > cbg.MaxLength { + return fmt.Errorf("t.Pieces: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + if extra > 0 { + t.Pieces = make([]Piece, extra) + } + for i := 0; i < int(extra); i++ { + + var v Piece + if err := v.UnmarshalCBOR(br); err != nil { + return err + } + + t.Pieces[i] = v + } + + // t.CommD ([]uint8) (slice) + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + name = string(sval) + } + + if name != "CommD" { + return fmt.Errorf("expected struct map entry %s to be CommD", name) + } + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + + if extra > cbg.ByteArrayMaxLen { + return fmt.Errorf("t.CommD: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.CommD = make([]byte, extra) + if _, err := io.ReadFull(br, t.CommD); err != nil { + return err + } + // t.CommR ([]uint8) (slice) + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + name = string(sval) + } + + if name != "CommR" { + return fmt.Errorf("expected struct map entry %s to be CommR", name) + } + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + + if extra > cbg.ByteArrayMaxLen { + return fmt.Errorf("t.CommR: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.CommR = make([]byte, extra) + if _, err := io.ReadFull(br, t.CommR); err != nil { + return err + } + // t.Proof ([]uint8) (slice) + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + name = string(sval) + } + + if name != "Proof" { + return fmt.Errorf("expected struct map entry %s to be Proof", name) + } + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + + if extra > cbg.ByteArrayMaxLen { + return fmt.Errorf("t.Proof: byte 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.Ticket (storage.SealTicket) (struct) + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + name = string(sval) + } + + if name != "Ticket" { + return fmt.Errorf("expected struct map entry %s to be Ticket", name) + } + + { + + if err := t.Ticket.UnmarshalCBOR(br); err != nil { + return err + } + + } + // t.PreCommitMessage (cid.Cid) (struct) + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + name = string(sval) + } + + if name != "PreCommitMessage" { + return fmt.Errorf("expected struct map entry %s to be PreCommitMessage", name) + } + + { + + 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 { + + c, err := cbg.ReadCid(br) + if err != nil { + return xerrors.Errorf("failed to read cid field t.PreCommitMessage: %w", err) + } + + t.PreCommitMessage = &c + } + + } + // t.Seed (storage.SealSeed) (struct) + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + name = string(sval) + } + + if name != "Seed" { + return fmt.Errorf("expected struct map entry %s to be Seed", name) + } + + { + + if err := t.Seed.UnmarshalCBOR(br); err != nil { + return err + } + + } + // t.CommitMessage (cid.Cid) (struct) + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + name = string(sval) + } + + if name != "CommitMessage" { + return fmt.Errorf("expected struct map entry %s to be CommitMessage", name) + } + + { + + 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 { + + c, err := cbg.ReadCid(br) + if err != nil { + return xerrors.Errorf("failed to read cid field t.CommitMessage: %w", err) + } + + t.CommitMessage = &c + } + + } + // t.FaultReportMsg (cid.Cid) (struct) + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + name = string(sval) + } + + if name != "FaultReportMsg" { + return fmt.Errorf("expected struct map entry %s to be FaultReportMsg", name) + } + + { + + 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 { + + c, err := cbg.ReadCid(br) + if err != nil { + return xerrors.Errorf("failed to read cid field t.FaultReportMsg: %w", err) + } + + t.FaultReportMsg = &c + } + + } + // t.LastErr (string) (string) + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + name = string(sval) + } + + if name != "LastErr" { + return fmt.Errorf("expected struct map entry %s to be LastErr", name) + } + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + t.LastErr = string(sval) + } + return nil +} diff --git a/garbage.go b/garbage.go new file mode 100644 index 000000000..1c3925671 --- /dev/null +++ b/garbage.go @@ -0,0 +1,127 @@ +package sealing + +import ( + "bytes" + "context" + "io" + "math" + "math/rand" + + sectorbuilder "github.com/filecoin-project/go-sectorbuilder" + "golang.org/x/xerrors" + + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/types" +) + +func (m *Sealing) pledgeSector(ctx context.Context, sectorID uint64, existingPieceSizes []uint64, sizes ...uint64) ([]Piece, error) { + if len(sizes) == 0 { + return nil, nil + } + + deals := make([]actors.StorageDealProposal, len(sizes)) + for i, size := range sizes { + release := m.sb.RateLimit() + commP, err := sectorbuilder.GeneratePieceCommitment(io.LimitReader(rand.New(rand.NewSource(42)), int64(size)), size) + release() + + if err != nil { + return nil, err + } + + sdp := actors.StorageDealProposal{ + PieceRef: commP[:], + PieceSize: size, + Client: m.worker, + Provider: m.maddr, + ProposalExpiration: math.MaxUint64, + Duration: math.MaxUint64 / 2, // /2 because overflows + StoragePricePerEpoch: types.NewInt(0), + StorageCollateral: types.NewInt(0), + ProposerSignature: nil, // nil because self dealing + } + + deals[i] = sdp + } + + params, aerr := actors.SerializeParams(&actors.PublishStorageDealsParams{ + Deals: deals, + }) + if aerr != nil { + return nil, xerrors.Errorf("serializing PublishStorageDeals params failed: ", aerr) + } + + 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 { + return nil, err + } + r, err := m.api.StateWaitMsg(ctx, smsg.Cid()) + if err != nil { + return nil, err + } + 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 { + return nil, err + } + if len(resp.DealIDs) != len(sizes) { + return nil, xerrors.New("got unexpected number of DealIDs from PublishStorageDeals") + } + + out := make([]Piece, len(sizes)) + + for i, size := range sizes { + ppi, err := m.sb.AddPiece(size, sectorID, io.LimitReader(rand.New(rand.NewSource(42)), int64(size)), existingPieceSizes) + if err != nil { + return nil, err + } + + existingPieceSizes = append(existingPieceSizes, size) + + out[i] = Piece{ + DealID: resp.DealIDs[i], + Size: ppi.Size, + CommP: ppi.CommP[:], + } + } + + return out, nil +} + +func (m *Sealing) PledgeSector() error { + go func() { + ctx := context.TODO() // we can't use the context from command which invokes + // this, as we run everything here async, and it's cancelled when the + // command exits + + size := sectorbuilder.UserBytesForSectorSize(m.sb.SectorSize()) + + sid, err := m.sb.AcquireSectorId() + if err != nil { + log.Errorf("%+v", err) + return + } + + pieces, err := m.pledgeSector(ctx, sid, []uint64{}, size) + if err != nil { + log.Errorf("%+v", err) + return + } + + if err := m.newSector(context.TODO(), sid, pieces[0].DealID, pieces[0].ppi()); err != nil { + log.Errorf("%+v", err) + return + } + }() + return nil +} diff --git a/sector_fsm.go b/sector_fsm.go new file mode 100644 index 000000000..50b62844a --- /dev/null +++ b/sector_fsm.go @@ -0,0 +1,264 @@ +package sealing + +import ( + "context" + "fmt" + + "github.com/ipfs/go-cid" + "golang.org/x/xerrors" + + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/lib/statemachine" +) + +type SectorStart struct { + id uint64 + pieces []Piece +} +type SectorRestart struct{} + +type SectorFatalError struct{ error } + +type SectorPacked struct{ pieces []Piece } + +type SectorSealed struct { + commR []byte + commD []byte + ticket SealTicket +} +type SectorSealFailed struct{ error } + +type SectorPreCommitFailed struct{ error } +type SectorPreCommitted struct { + message cid.Cid +} + +type SectorSeedReady struct { + seed SealSeed +} + +type SectorSealCommitFailed struct{ error } +type SectorCommitFailed struct{ error } +type SectorCommitted struct { + message cid.Cid + proof []byte +} + +type SectorProving struct{} + +type SectorFaultReported struct{ reportMsg cid.Cid } +type SectorFaultedFinal struct{} + +type SectorForceState struct { + state api.SectorState +} + +func (m *Sealing) Plan(events []statemachine.Event, user interface{}) (interface{}, error) { + next, err := m.plan(events, user.(*SectorInfo)) + if err != nil || next == nil { + return nil, err + } + + return func(ctx statemachine.Context, si SectorInfo) error { + err := next(ctx, si) + if err != nil { + if err := ctx.Send(SectorFatalError{error: err}); err != nil { + return xerrors.Errorf("error while sending error: reporting %+v: %w", err, err) + } + } + + return nil + }, nil +} + +func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(statemachine.Context, SectorInfo) error, error) { + ///// + // First process all events + + for _, event := range events { + if err, ok := event.User.(error); ok { + state.LastErr = fmt.Sprintf("%+v", err) + } + + switch event := event.User.(type) { + case SectorStart: + // TODO: check if state is clean + state.SectorID = event.id + state.Pieces = event.pieces + state.State = api.Packing + + case SectorRestart: + // noop + case SectorFatalError: + log.Errorf("Fatal error on sector %d: %+v", state.SectorID, event.error) + // TODO: Do we want to mark the state as unrecoverable? + // I feel like this should be a softer error, where the user would + // be able to send a retry event of some kind + return nil, nil + + // // TODO: Incoming + // TODO: for those - look at dealIDs matching chain + + // // + // Packing + + case SectorPacked: + // TODO: assert state + state.Pieces = append(state.Pieces, event.pieces...) + state.State = api.Unsealed + + // // Unsealed + + case SectorSealFailed: + // TODO: try to find out the reason, maybe retry + state.State = api.SealFailed + + case SectorSealed: + state.CommD = event.commD + state.CommR = event.commR + state.Ticket = event.ticket + state.State = api.PreCommitting + + // // PreCommit + + case SectorPreCommitFailed: + // TODO: try to find out the reason, maybe retry + state.State = api.PreCommitFailed + case SectorPreCommitted: + state.PreCommitMessage = &event.message + state.State = api.PreCommitted + + case SectorSeedReady: + state.Seed = event.seed + state.State = api.Committing + + // // Commit + + case SectorSealCommitFailed: + // TODO: try to find out the reason, maybe retry + state.State = api.SealCommitFailed + case SectorCommitFailed: + // TODO: try to find out the reason, maybe retry + state.State = api.SealFailed + case SectorCommitted: + state.Proof = event.proof + state.CommitMessage = &event.message + state.State = api.CommitWait + case SectorProving: + state.State = api.Proving + + case SectorFaultReported: + state.FaultReportMsg = &event.reportMsg + state.State = api.FaultReported + case SectorFaultedFinal: + state.State = api.FaultedFinal + + // // Debug triggers + case SectorForceState: + state.State = event.state + } + } + + ///// + // Now decide what to do next + + /* + + * Empty + | | + | v + *<- Packing <- incoming + | | + | v + *<- Unsealed <--> SealFailed + | | + | v + * PreCommitting <--> PreCommitFailed + | | ^ + | v | + *<- PreCommitted ------/ + | ||| + | vvv v--> SealCommitFailed + *<- Committing + | | ^--> CommitFailed + | v ^ + *<- CommitWait ---/ + | | + | v + *<- Proving + | + v + FailedUnrecoverable + + UndefinedSectorState <- ¯\_(ツ)_/¯ + | ^ + *---------------------/ + + */ + + switch state.State { + // Happy path + case api.Packing: + return m.handlePacking, nil + case api.Unsealed: + return m.handleUnsealed, nil + case api.PreCommitting: + return m.handlePreCommitting, nil + case api.PreCommitted: + return m.handlePreCommitted, nil + case api.Committing: + return m.handleCommitting, nil + case api.CommitWait: + return m.handleCommitWait, nil + case api.Proving: + // TODO: track sector health / expiration + log.Infof("Proving sector %d", state.SectorID) + + // Handled failure modes + case api.SealFailed: + log.Warnf("sector %d entered unimplemented state 'SealFailed'", state.SectorID) + case api.PreCommitFailed: + log.Warnf("sector %d entered unimplemented state 'PreCommitFailed'", state.SectorID) + case api.SealCommitFailed: + log.Warnf("sector %d entered unimplemented state 'SealCommitFailed'", state.SectorID) + case api.CommitFailed: + log.Warnf("sector %d entered unimplemented state 'CommitFailed'", state.SectorID) + + // Faults + case api.Faulty: + return m.handleFaulty, nil + case api.FaultReported: + return m.handleFaultReported, nil + + // Fatal errors + case api.UndefinedSectorState: + log.Error("sector update with undefined state!") + case api.FailedUnrecoverable: + log.Errorf("sector %d failed unrecoverably", state.SectorID) + default: + log.Errorf("unexpected sector update state: %d", state.State) + } + + return nil, nil +} + +func (m *Sealing) restartSectors(ctx context.Context) error { + trackedSectors, err := m.ListSectors() + if err != nil { + log.Errorf("loading sector list: %+v", err) + } + + for _, sector := range trackedSectors { + if err := m.sectors.Send(sector.SectorID, SectorRestart{}); err != nil { + log.Errorf("restarting sector %d: %+v", sector.SectorID, err) + } + } + + // TODO: Grab on-chain sector set and diff with trackedSectors + + return nil +} + +func (m *Sealing) ForceSectorState(ctx context.Context, id uint64, state api.SectorState) error { + return m.sectors.Send(id, SectorForceState{state}) +} diff --git a/sector_states.go b/sector_states.go new file mode 100644 index 000000000..1dbc6e4d4 --- /dev/null +++ b/sector_states.go @@ -0,0 +1,254 @@ +package sealing + +import ( + "context" + + sectorbuilder "github.com/filecoin-project/go-sectorbuilder" + "golang.org/x/xerrors" + + "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/lib/statemachine" +) + +func (m *Sealing) handlePacking(ctx statemachine.Context, sector SectorInfo) error { + log.Infow("performing filling up rest of the sector...", "sector", sector.SectorID) + + var allocated uint64 + for _, piece := range sector.Pieces { + allocated += piece.Size + } + + ubytes := sectorbuilder.UserBytesForSectorSize(m.sb.SectorSize()) + + if allocated > ubytes { + return xerrors.Errorf("too much data in sector: %d > %d", allocated, ubytes) + } + + fillerSizes, err := fillersFromRem(ubytes - allocated) + if err != nil { + return err + } + + if len(fillerSizes) > 0 { + log.Warnf("Creating %d filler pieces for sector %d", len(fillerSizes), sector.SectorID) + } + + pieces, err := m.pledgeSector(ctx.Context(), sector.SectorID, sector.existingPieces(), fillerSizes...) + if err != nil { + return xerrors.Errorf("filling up the sector (%v): %w", fillerSizes, err) + } + + return ctx.Send(SectorPacked{pieces: pieces}) +} + +func (m *Sealing) handleUnsealed(ctx statemachine.Context, sector SectorInfo) error { + log.Infow("performing sector replication...", "sector", sector.SectorID) + ticket, err := m.tktFn(ctx.Context()) + if err != nil { + return err + } + + rspco, err := m.sb.SealPreCommit(ctx.Context(), sector.SectorID, *ticket, sector.pieceInfos()) + if err != nil { + return ctx.Send(SectorSealFailed{xerrors.Errorf("seal pre commit failed: %w", err)}) + } + + return ctx.Send(SectorSealed{ + commD: rspco.CommD[:], + commR: rspco.CommR[:], + ticket: SealTicket{ + BlockHeight: ticket.BlockHeight, + TicketBytes: ticket.TicketBytes[:], + }, + }) +} + +func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInfo) error { + params := &actors.SectorPreCommitInfo{ + SectorNumber: sector.SectorID, + + CommR: sector.CommR, + SealEpoch: sector.Ticket.BlockHeight, + DealIDs: sector.deals(), + } + enc, aerr := actors.SerializeParams(params) + if aerr != nil { + return ctx.Send(SectorPreCommitFailed{xerrors.Errorf("could not serialize commit sector parameters: %w", aerr)}) + } + + msg := &types.Message{ + To: m.maddr, + From: m.worker, + Method: actors.MAMethods.PreCommitSector, + Params: enc, + Value: types.NewInt(0), // TODO: need to ensure sufficient collateral + GasLimit: types.NewInt(1000000 /* i dont know help */), + GasPrice: types.NewInt(1), + } + + log.Info("submitting precommit for sector: ", sector.SectorID) + smsg, err := m.api.MpoolPushMessage(ctx.Context(), msg) + if err != nil { + return ctx.Send(SectorPreCommitFailed{xerrors.Errorf("pushing message to mpool: %w", err)}) + } + + return ctx.Send(SectorPreCommitted{message: smsg.Cid()}) +} + +func (m *Sealing) handlePreCommitted(ctx statemachine.Context, sector SectorInfo) error { + // would be ideal to just use the events.Called handler, but it wouldnt be able to handle individual message timeouts + log.Info("Sector precommitted: ", sector.SectorID) + mw, err := m.api.StateWaitMsg(ctx.Context(), *sector.PreCommitMessage) + if err != nil { + return ctx.Send(SectorPreCommitFailed{err}) + } + + if mw.Receipt.ExitCode != 0 { + log.Error("sector precommit failed: ", mw.Receipt.ExitCode) + err := xerrors.Errorf("sector precommit failed: %d", mw.Receipt.ExitCode) + return ctx.Send(SectorPreCommitFailed{err}) + } + log.Info("precommit message landed on chain: ", sector.SectorID) + + randHeight := mw.TipSet.Height() + build.InteractivePoRepDelay - 1 // -1 because of how the messages are applied + log.Infof("precommit for sector %d made it on chain, will start proof computation at height %d", sector.SectorID, randHeight) + + err = m.events.ChainAt(func(ectx context.Context, ts *types.TipSet, curH uint64) error { + rand, err := m.api.ChainGetRandomness(ectx, ts.Key(), int64(randHeight)) + if err != nil { + err = xerrors.Errorf("failed to get randomness for computing seal proof: %w", err) + + ctx.Send(SectorFatalError{error: err}) + return err + } + + ctx.Send(SectorSeedReady{seed: SealSeed{ + BlockHeight: randHeight, + TicketBytes: rand, + }}) + + return nil + }, func(ctx context.Context, ts *types.TipSet) error { + log.Warn("revert in interactive commit sector step") + // TODO: need to cancel running process and restart... + return nil + }, build.InteractivePoRepConfidence, mw.TipSet.Height()+build.InteractivePoRepDelay) + if err != nil { + log.Warn("waitForPreCommitMessage ChainAt errored: ", err) + } + + return nil +} + +func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) error { + log.Info("scheduling seal proof computation...") + + proof, err := m.sb.SealCommit(ctx.Context(), sector.SectorID, sector.Ticket.SB(), sector.Seed.SB(), sector.pieceInfos(), sector.rspco()) + if err != nil { + return ctx.Send(SectorSealCommitFailed{xerrors.Errorf("computing seal proof failed: %w", err)}) + } + + // TODO: Consider splitting states and persist proof for faster recovery + + params := &actors.SectorProveCommitInfo{ + Proof: proof, + SectorID: sector.SectorID, + DealIDs: sector.deals(), + } + + enc, aerr := actors.SerializeParams(params) + if aerr != nil { + return ctx.Send(SectorCommitFailed{xerrors.Errorf("could not serialize commit sector parameters: %w", aerr)}) + } + + msg := &types.Message{ + To: m.maddr, + From: m.worker, + Method: actors.MAMethods.ProveCommitSector, + Params: enc, + Value: types.NewInt(0), // TODO: need to ensure sufficient collateral + GasLimit: types.NewInt(1000000 /* i dont know help */), + GasPrice: types.NewInt(1), + } + + smsg, err := m.api.MpoolPushMessage(ctx.Context(), msg) + if err != nil { + return ctx.Send(SectorCommitFailed{xerrors.Errorf("pushing message to mpool: %w", err)}) + } + + return ctx.Send(SectorCommitted{ + proof: proof, + message: smsg.Cid(), + }) +} + +func (m *Sealing) handleCommitWait(ctx statemachine.Context, sector SectorInfo) error { + if sector.CommitMessage == nil { + log.Errorf("sector %d entered commit wait state without a message cid", sector.SectorID) + return ctx.Send(SectorCommitFailed{xerrors.Errorf("entered commit wait with no commit cid")}) + } + + mw, err := m.api.StateWaitMsg(ctx.Context(), *sector.CommitMessage) + if err != nil { + return ctx.Send(SectorCommitFailed{xerrors.Errorf("failed to wait for porep inclusion: %w", err)}) + } + + if mw.Receipt.ExitCode != 0 { + log.Errorf("UNHANDLED: submitting sector proof failed (exit=%d, msg=%s) (t:%x; s:%x(%d); p:%x)", mw.Receipt.ExitCode, sector.CommitMessage, sector.Ticket.TicketBytes, sector.Seed.TicketBytes, sector.Seed.BlockHeight, sector.Proof) + return xerrors.Errorf("UNHANDLED: submitting sector proof failed (exit: %d)", mw.Receipt.ExitCode) + } + + return ctx.Send(SectorProving{}) +} + +func (m *Sealing) handleFaulty(ctx statemachine.Context, sector SectorInfo) error { + // TODO: check if the fault has already been reported, and that this sector is even valid + + // TODO: coalesce faulty sector reporting + bf := types.NewBitField() + bf.Set(sector.SectorID) + + fp := &actors.DeclareFaultsParams{bf} + _ = fp + enc, aerr := actors.SerializeParams(nil) + if aerr != nil { + return xerrors.Errorf("failed to serialize declare fault params: %w", aerr) + } + + msg := &types.Message{ + To: m.maddr, + From: m.worker, + Method: actors.MAMethods.DeclareFaults, + Params: enc, + Value: types.NewInt(0), // TODO: need to ensure sufficient collateral + GasLimit: types.NewInt(1000000 /* i dont know help */), + GasPrice: types.NewInt(1), + } + + smsg, err := m.api.MpoolPushMessage(ctx.Context(), msg) + if err != nil { + return xerrors.Errorf("failed to push declare faults message to network: %w", err) + } + + return ctx.Send(SectorFaultReported{reportMsg: smsg.Cid()}) +} + +func (m *Sealing) handleFaultReported(ctx statemachine.Context, sector SectorInfo) error { + if sector.FaultReportMsg == nil { + return xerrors.Errorf("entered fault reported state without a FaultReportMsg cid") + } + + mw, err := m.api.StateWaitMsg(ctx.Context(), *sector.FaultReportMsg) + if err != nil { + return xerrors.Errorf("failed to wait for fault declaration: %w", err) + } + + if mw.Receipt.ExitCode != 0 { + log.Errorf("UNHANDLED: declaring sector fault failed (exit=%d, msg=%s) (id: %d)", mw.Receipt.ExitCode, *sector.FaultReportMsg, sector.SectorID) + return xerrors.Errorf("UNHANDLED: submitting fault declaration failed (exit %d)", mw.Receipt.ExitCode) + } + + return ctx.Send(SectorFaultedFinal{}) +} diff --git a/sector_types.go b/sector_types.go new file mode 100644 index 000000000..c2d6b3359 --- /dev/null +++ b/sector_types.go @@ -0,0 +1,106 @@ +package sealing + +import ( + sectorbuilder "github.com/filecoin-project/go-sectorbuilder" + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/api" +) + +type SealTicket struct { + BlockHeight uint64 + TicketBytes []byte +} + +func (t *SealTicket) SB() sectorbuilder.SealTicket { + out := sectorbuilder.SealTicket{BlockHeight: t.BlockHeight} + copy(out.TicketBytes[:], t.TicketBytes) + return out +} + +type SealSeed struct { + BlockHeight uint64 + TicketBytes []byte +} + +func (t *SealSeed) SB() sectorbuilder.SealSeed { + out := sectorbuilder.SealSeed{BlockHeight: t.BlockHeight} + copy(out.TicketBytes[:], t.TicketBytes) + return out +} + +type Piece struct { + DealID uint64 + + Size uint64 + CommP []byte +} + +func (p *Piece) ppi() (out sectorbuilder.PublicPieceInfo) { + out.Size = p.Size + copy(out.CommP[:], p.CommP) + return out +} + +type SectorInfo struct { + State api.SectorState + SectorID uint64 + Nonce uint64 + + // Packing + + Pieces []Piece + + // PreCommit + CommD []byte + CommR []byte + Proof []byte + Ticket SealTicket + + PreCommitMessage *cid.Cid + + // PreCommitted + Seed SealSeed + + // Committing + CommitMessage *cid.Cid + + // Faults + FaultReportMsg *cid.Cid + + // Debug + LastErr string +} + +func (t *SectorInfo) pieceInfos() []sectorbuilder.PublicPieceInfo { + out := make([]sectorbuilder.PublicPieceInfo, len(t.Pieces)) + for i, piece := range t.Pieces { + out[i] = piece.ppi() + } + return out +} + +func (t *SectorInfo) deals() []uint64 { + out := make([]uint64, len(t.Pieces)) + for i, piece := range t.Pieces { + out[i] = piece.DealID + } + return out +} + +func (t *SectorInfo) existingPieces() []uint64 { + out := make([]uint64, len(t.Pieces)) + for i, piece := range t.Pieces { + out[i] = piece.Size + } + return out +} + +func (t *SectorInfo) rspco() sectorbuilder.RawSealPreCommitOutput { + var out sectorbuilder.RawSealPreCommitOutput + + copy(out.CommD[:], t.CommD) + copy(out.CommR[:], t.CommR) + + return out +} diff --git a/sector_utils.go b/sector_utils.go new file mode 100644 index 000000000..8fa887d3c --- /dev/null +++ b/sector_utils.go @@ -0,0 +1,57 @@ +package sealing + +import ( + "math/bits" + + sectorbuilder "github.com/filecoin-project/go-sectorbuilder" +) + +func fillersFromRem(toFill uint64) ([]uint64, error) { + // Convert to in-sector bytes for easier math: + // + // Sector size to user bytes ratio is constant, e.g. for 1024B we have 1016B + // of user-usable data. + // + // (1024/1016 = 128/127) + // + // Given that we can get sector size by simply adding 1/127 of the user + // bytes + // + // (we convert to sector bytes as they are nice round binary numbers) + + toFill += toFill / 127 + + // We need to fill the sector with pieces that are powers of 2. Conveniently + // computers store numbers in binary, which means we can look at 1s to get + // all the piece sizes we need to fill the sector. It also means that number + // of pieces is the number of 1s in the number of remaining bytes to fill + out := make([]uint64, bits.OnesCount64(toFill)) + for i := range out { + // Extract the next lowest non-zero bit + next := bits.TrailingZeros64(toFill) + psize := uint64(1) << next + // e.g: if the number is 0b010100, psize will be 0b000100 + + // set that bit to 0 by XORing it, so the next iteration looks at the + // next bit + toFill ^= psize + + // Add the piece size to the list of pieces we need to create + out[i] = sectorbuilder.UserBytesForSectorSize(psize) + } + return out, nil +} + +func (m *Sealing) ListSectors() ([]SectorInfo, error) { + var sectors []SectorInfo + if err := m.sectors.List(§ors); err != nil { + return nil, err + } + return sectors, nil +} + +func (m *Sealing) GetSectorInfo(sid uint64) (SectorInfo, error) { + var out SectorInfo + err := m.sectors.Get(sid).Get(&out) + return out, err +} diff --git a/sector_utils_test.go b/sector_utils_test.go new file mode 100644 index 000000000..02746a3d8 --- /dev/null +++ b/sector_utils_test.go @@ -0,0 +1,46 @@ +package sealing + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + sectorbuilder "github.com/filecoin-project/go-sectorbuilder" +) + +func testFill(t *testing.T, n uint64, exp []uint64) { + f, err := fillersFromRem(n) + assert.NoError(t, err) + assert.Equal(t, exp, f) + + var sum uint64 + for _, u := range f { + sum += u + } + assert.Equal(t, n, sum) +} + +func TestFillersFromRem(t *testing.T) { + for i := 8; i < 32; i++ { + // single + ub := sectorbuilder.UserBytesForSectorSize(uint64(1) << i) + testFill(t, ub, []uint64{ub}) + + // 2 + ub = sectorbuilder.UserBytesForSectorSize(uint64(5) << i) + ub1 := sectorbuilder.UserBytesForSectorSize(uint64(1) << i) + ub3 := sectorbuilder.UserBytesForSectorSize(uint64(4) << i) + testFill(t, ub, []uint64{ub1, ub3}) + + // 4 + ub = sectorbuilder.UserBytesForSectorSize(uint64(15) << i) + ub2 := sectorbuilder.UserBytesForSectorSize(uint64(2) << i) + ub4 := sectorbuilder.UserBytesForSectorSize(uint64(8) << i) + testFill(t, ub, []uint64{ub1, ub2, ub3, ub4}) + + // different 2 + ub = sectorbuilder.UserBytesForSectorSize(uint64(9) << i) + testFill(t, ub, []uint64{ub1, ub4}) + } + +} diff --git a/sectors.go b/sectors.go new file mode 100644 index 000000000..c915c27f1 --- /dev/null +++ b/sectors.go @@ -0,0 +1,136 @@ +package sealing + +import ( + "context" + "github.com/ipfs/go-datastore" + "github.com/ipfs/go-datastore/namespace" + "io" + + "github.com/filecoin-project/lotus/lib/padreader" + logging "github.com/ipfs/go-log/v2" + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-sectorbuilder" + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/events" + "github.com/filecoin-project/lotus/chain/store" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/lib/statemachine" +) + +const SectorStorePrefix = "/sectors" + +var log = logging.Logger("sectors") + +type TicketFn func(context.Context) (*sectorbuilder.SealTicket, error) + +type sectorsApi interface { // TODO: trim down + // Call a read only method on actors (no interaction with the chain required) + StateCall(ctx context.Context, msg *types.Message, ts *types.TipSet) (*types.MessageReceipt, error) + StateMinerWorker(context.Context, address.Address, *types.TipSet) (address.Address, error) + StateMinerElectionPeriodStart(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error) + StateMinerSectors(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error) + StateMinerProvingSet(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error) + StateMinerSectorSize(context.Context, address.Address, *types.TipSet) (uint64, error) + StateWaitMsg(context.Context, cid.Cid) (*api.MsgWait, error) // TODO: removeme eventually + StateGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error) + StateGetReceipt(context.Context, cid.Cid, *types.TipSet) (*types.MessageReceipt, error) + + MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error) + + ChainHead(context.Context) (*types.TipSet, error) + ChainNotify(context.Context) (<-chan []*store.HeadChange, error) + ChainGetRandomness(context.Context, types.TipSetKey, int64) ([]byte, error) + 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) +} + +type Sealing struct { + api sectorsApi + events *events.Events + + maddr address.Address + worker address.Address + + sb sectorbuilder.Interface + sectors *statemachine.StateGroup + tktFn TicketFn +} + +func New(api sectorsApi, events *events.Events, maddr address.Address, worker address.Address, ds datastore.Batching, sb sectorbuilder.Interface, tktFn TicketFn) *Sealing { + s := &Sealing{ + api: api, + events: events, + + maddr: maddr, + worker: worker, + sb: sb, + tktFn: tktFn, + } + + s.sectors = statemachine.New(namespace.Wrap(ds, datastore.NewKey(SectorStorePrefix)), s, SectorInfo{}) + + return s +} + +func (m *Sealing) Run(ctx context.Context) error { + m.events = events.NewEvents(ctx, m.api) + + if err := m.restartSectors(ctx); err != nil { + log.Errorf("%+v", err) + return xerrors.Errorf("failed load sector states: %w", err) + } + + return nil +} + +func (m *Sealing) Stop(ctx context.Context) error { + return m.sectors.Stop(ctx) +} + +func (m *Sealing) AllocatePiece(size uint64) (sectorID uint64, offset uint64, err error) { + if padreader.PaddedSize(size) != size { + return 0, 0, xerrors.Errorf("cannot allocate unpadded piece") + } + + sid, err := m.sb.AcquireSectorId() // TODO: Put more than one thing in a sector + if err != nil { + return 0, 0, xerrors.Errorf("acquiring sector ID: %w", err) + } + + // offset hard-coded to 0 since we only put one thing in a sector for now + return sid, 0, nil +} + +func (m *Sealing) SealPiece(ctx context.Context, size uint64, r io.Reader, sectorID uint64, dealID uint64) error { + log.Infof("Seal piece for deal %d", dealID) + + ppi, err := m.sb.AddPiece(size, sectorID, r, []uint64{}) + if err != nil { + return xerrors.Errorf("adding piece to sector: %w", err) + } + + return m.newSector(ctx, sectorID, dealID, ppi) +} + +func (m *Sealing) newSector(ctx context.Context, sid uint64, dealID uint64, ppi sectorbuilder.PublicPieceInfo) error { + return m.sectors.Send(sid, SectorStart{ + id: sid, + pieces: []Piece{ + { + DealID: dealID, + + Size: ppi.Size, + CommP: ppi.CommP[:], + }, + }, + }) +} + diff --git a/sectors_fsm_test.go b/sectors_fsm_test.go new file mode 100644 index 000000000..3eda54860 --- /dev/null +++ b/sectors_fsm_test.go @@ -0,0 +1,79 @@ +package sealing + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/lib/statemachine" +) + +func (t *test) planSingle(evt interface{}) { + _, err := t.m.plan([]statemachine.Event{{evt}}, t.state) + require.NoError(t.t, err) +} + +type test struct { + m *Miner + t *testing.T + state *SectorInfo + + next func(statemachine.Context, SectorInfo) error +} + +func TestHappyPath(t *testing.T) { + m := test{ + m: &Miner{}, + t: t, + state: &SectorInfo{State: api.Packing}, + } + + m.planSingle(SectorPacked{}) + require.Equal(m.t, m.state.State, api.Unsealed) + + m.planSingle(SectorSealed{}) + require.Equal(m.t, m.state.State, api.PreCommitting) + + m.planSingle(SectorPreCommitted{}) + require.Equal(m.t, m.state.State, api.PreCommitted) + + m.planSingle(SectorSeedReady{}) + require.Equal(m.t, m.state.State, api.Committing) + + m.planSingle(SectorCommitted{}) + require.Equal(m.t, m.state.State, api.CommitWait) + + m.planSingle(SectorProving{}) + require.Equal(m.t, m.state.State, api.Proving) +} + +func TestSeedRevert(t *testing.T) { + m := test{ + m: &Miner{}, + t: t, + state: &SectorInfo{State: api.Packing}, + } + + m.planSingle(SectorPacked{}) + require.Equal(m.t, m.state.State, api.Unsealed) + + m.planSingle(SectorSealed{}) + require.Equal(m.t, m.state.State, api.PreCommitting) + + m.planSingle(SectorPreCommitted{}) + require.Equal(m.t, m.state.State, api.PreCommitted) + + m.planSingle(SectorSeedReady{}) + require.Equal(m.t, m.state.State, api.Committing) + + _, err := m.m.plan([]statemachine.Event{{SectorSeedReady{}}, {SectorCommitted{}}}, m.state) + require.NoError(t, err) + require.Equal(m.t, m.state.State, api.Committing) + + m.planSingle(SectorCommitted{}) + require.Equal(m.t, m.state.State, api.CommitWait) + + m.planSingle(SectorProving{}) + require.Equal(m.t, m.state.State, api.Proving) +} diff --git a/sectors_test.go b/sectors_test.go new file mode 100644 index 000000000..f14051a15 --- /dev/null +++ b/sectors_test.go @@ -0,0 +1,56 @@ +package sealing + +import ( + "bytes" + "testing" + + "gotest.tools/assert" + + "github.com/filecoin-project/go-cbor-util" +) + +func TestSectorInfoSelialization(t *testing.T) { + si := &SectorInfo{ + State: 123, + SectorID: 234, + Nonce: 345, + Pieces: []Piece{{ + DealID: 1234, + Size: 5, + CommP: []byte{3}, + }}, + CommD: []byte{32, 4}, + CommR: nil, + Proof: nil, + Ticket: SealTicket{ + BlockHeight: 345, + TicketBytes: []byte{87, 78, 7, 87}, + }, + PreCommitMessage: nil, + Seed: SealSeed{}, + CommitMessage: nil, + FaultReportMsg: nil, + LastErr: "hi", + } + + b, err := cborutil.Dump(si) + if err != nil { + t.Fatal(err) + } + + var si2 SectorInfo + if err := cborutil.ReadCborRPC(bytes.NewReader(b), &si); err != nil { + return + } + + assert.Equal(t, si.State, si2.State) + assert.Equal(t, si.Nonce, si2.Nonce) + assert.Equal(t, si.SectorID, si2.SectorID) + + assert.Equal(t, si.Pieces, si2.Pieces) + assert.Equal(t, si.CommD, si2.CommD) + assert.Equal(t, si.Ticket, si2.Ticket) + + assert.Equal(t, si, si2) + +} From 72ca563a1da60134e942239b24fd2b0bf8c730af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 15 Jan 2020 21:53:14 +0100 Subject: [PATCH 002/126] sealing: More cleanup --- sector_fsm.go => fsm.go | 43 ----------------------- fsm_events.go | 49 +++++++++++++++++++++++++++ sectors_fsm_test.go => fsm_test.go | 10 +++--- sectors.go => sealing.go | 6 ++-- sector_states.go => states.go | 0 sector_types.go => types.go | 0 sectors_test.go => types_test.go | 0 sector_utils.go => utils.go | 0 sector_utils_test.go => utils_test.go | 0 9 files changed, 57 insertions(+), 51 deletions(-) rename sector_fsm.go => fsm.go (87%) create mode 100644 fsm_events.go rename sectors_fsm_test.go => fsm_test.go (90%) rename sectors.go => sealing.go (97%) rename sector_states.go => states.go (100%) rename sector_types.go => types.go (100%) rename sectors_test.go => types_test.go (100%) rename sector_utils.go => utils.go (100%) rename sector_utils_test.go => utils_test.go (100%) diff --git a/sector_fsm.go b/fsm.go similarity index 87% rename from sector_fsm.go rename to fsm.go index 50b62844a..e984b883b 100644 --- a/sector_fsm.go +++ b/fsm.go @@ -4,55 +4,12 @@ import ( "context" "fmt" - "github.com/ipfs/go-cid" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/lib/statemachine" ) -type SectorStart struct { - id uint64 - pieces []Piece -} -type SectorRestart struct{} - -type SectorFatalError struct{ error } - -type SectorPacked struct{ pieces []Piece } - -type SectorSealed struct { - commR []byte - commD []byte - ticket SealTicket -} -type SectorSealFailed struct{ error } - -type SectorPreCommitFailed struct{ error } -type SectorPreCommitted struct { - message cid.Cid -} - -type SectorSeedReady struct { - seed SealSeed -} - -type SectorSealCommitFailed struct{ error } -type SectorCommitFailed struct{ error } -type SectorCommitted struct { - message cid.Cid - proof []byte -} - -type SectorProving struct{} - -type SectorFaultReported struct{ reportMsg cid.Cid } -type SectorFaultedFinal struct{} - -type SectorForceState struct { - state api.SectorState -} - func (m *Sealing) Plan(events []statemachine.Event, user interface{}) (interface{}, error) { next, err := m.plan(events, user.(*SectorInfo)) if err != nil || next == nil { diff --git a/fsm_events.go b/fsm_events.go new file mode 100644 index 000000000..39d0638d3 --- /dev/null +++ b/fsm_events.go @@ -0,0 +1,49 @@ +package sealing + +import ( + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/api" +) + +type SectorStart struct { + id uint64 + pieces []Piece +} +type SectorRestart struct{} + +type SectorFatalError struct{ error } + +type SectorPacked struct{ pieces []Piece } + +type SectorSealed struct { + commR []byte + commD []byte + ticket SealTicket +} +type SectorSealFailed struct{ error } + +type SectorPreCommitFailed struct{ error } +type SectorPreCommitted struct { + message cid.Cid +} + +type SectorSeedReady struct { + seed SealSeed +} + +type SectorSealCommitFailed struct{ error } +type SectorCommitFailed struct{ error } +type SectorCommitted struct { + message cid.Cid + proof []byte +} + +type SectorProving struct{} + +type SectorFaultReported struct{ reportMsg cid.Cid } +type SectorFaultedFinal struct{} + +type SectorForceState struct { + state api.SectorState +} diff --git a/sectors_fsm_test.go b/fsm_test.go similarity index 90% rename from sectors_fsm_test.go rename to fsm_test.go index 3eda54860..10b9723b9 100644 --- a/sectors_fsm_test.go +++ b/fsm_test.go @@ -10,12 +10,12 @@ import ( ) func (t *test) planSingle(evt interface{}) { - _, err := t.m.plan([]statemachine.Event{{evt}}, t.state) + _, err := t.s.plan([]statemachine.Event{{evt}}, t.state) require.NoError(t.t, err) } type test struct { - m *Miner + s *Sealing t *testing.T state *SectorInfo @@ -24,7 +24,7 @@ type test struct { func TestHappyPath(t *testing.T) { m := test{ - m: &Miner{}, + s: &Sealing{}, t: t, state: &SectorInfo{State: api.Packing}, } @@ -50,7 +50,7 @@ func TestHappyPath(t *testing.T) { func TestSeedRevert(t *testing.T) { m := test{ - m: &Miner{}, + s: &Sealing{}, t: t, state: &SectorInfo{State: api.Packing}, } @@ -67,7 +67,7 @@ func TestSeedRevert(t *testing.T) { m.planSingle(SectorSeedReady{}) require.Equal(m.t, m.state.State, api.Committing) - _, err := m.m.plan([]statemachine.Event{{SectorSeedReady{}}, {SectorCommitted{}}}, m.state) + _, err := m.s.plan([]statemachine.Event{{SectorSeedReady{}}, {SectorCommitted{}}}, m.state) require.NoError(t, err) require.Equal(m.t, m.state.State, api.Committing) diff --git a/sectors.go b/sealing.go similarity index 97% rename from sectors.go rename to sealing.go index c915c27f1..f0c2b3d50 100644 --- a/sectors.go +++ b/sealing.go @@ -27,7 +27,7 @@ var log = logging.Logger("sectors") type TicketFn func(context.Context) (*sectorbuilder.SealTicket, error) -type sectorsApi interface { // TODO: trim down +type sealingApi interface { // TODO: trim down // Call a read only method on actors (no interaction with the chain required) StateCall(ctx context.Context, msg *types.Message, ts *types.TipSet) (*types.MessageReceipt, error) StateMinerWorker(context.Context, address.Address, *types.TipSet) (address.Address, error) @@ -53,7 +53,7 @@ type sectorsApi interface { // TODO: trim down } type Sealing struct { - api sectorsApi + api sealingApi events *events.Events maddr address.Address @@ -64,7 +64,7 @@ type Sealing struct { tktFn TicketFn } -func New(api sectorsApi, events *events.Events, maddr address.Address, worker address.Address, ds datastore.Batching, sb sectorbuilder.Interface, tktFn TicketFn) *Sealing { +func New(api sealingApi, events *events.Events, maddr address.Address, worker address.Address, ds datastore.Batching, sb sectorbuilder.Interface, tktFn TicketFn) *Sealing { s := &Sealing{ api: api, events: events, diff --git a/sector_states.go b/states.go similarity index 100% rename from sector_states.go rename to states.go diff --git a/sector_types.go b/types.go similarity index 100% rename from sector_types.go rename to types.go diff --git a/sectors_test.go b/types_test.go similarity index 100% rename from sectors_test.go rename to types_test.go diff --git a/sector_utils.go b/utils.go similarity index 100% rename from sector_utils.go rename to utils.go diff --git a/sector_utils_test.go b/utils_test.go similarity index 100% rename from sector_utils_test.go rename to utils_test.go From e3b05e51b15c83592e41791eb7030c3f0ec928fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 16 Jan 2020 02:25:49 +0100 Subject: [PATCH 003/126] sealing: Handle seed changes more correctly --- fsm.go | 112 +++++++++++++++++++++++++++++++++++--------------- fsm_events.go | 30 ++++++++++++++ fsm_test.go | 10 ++++- types.go | 6 +++ 4 files changed, 122 insertions(+), 36 deletions(-) diff --git a/fsm.go b/fsm.go index e984b883b..56c7fa6b7 100644 --- a/fsm.go +++ b/fsm.go @@ -3,6 +3,7 @@ package sealing import ( "context" "fmt" + "reflect" "golang.org/x/xerrors" @@ -28,22 +29,37 @@ func (m *Sealing) Plan(events []statemachine.Event, user interface{}) (interface }, nil } +var fsmPlanners = []func(events []statemachine.Event, state *SectorInfo) error { + api.UndefinedSectorState: planOne(on(SectorStart{}, api.Packing)), + api.Packing: planOne(on(SectorPacked{}, api.Unsealed)), + api.Unsealed: planOne(on(SectorSealed{}, api.PreCommitting)), + api.PreCommitting: planOne(on(SectorPreCommitted{}, api.PreCommitted)), + api.PreCommitted: planOne(on(SectorSeedReady{}, api.Committing)), + api.Committing: planCommitting, + api.CommitWait: planOne(on(SectorProving{}, api.Proving)), + + api.Proving: final, +} + func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(statemachine.Context, SectorInfo) error, error) { ///// // First process all events + p := fsmPlanners[state.State] + if p == nil { + return nil, xerrors.Errorf("planner for state %d not found", state.State) + } + + if err := p(events, state); err != nil { + return nil, xerrors.Errorf("running planner for state %s failed: %w", api.SectorStates[state.State], err) + } + for _, event := range events { if err, ok := event.User.(error); ok { state.LastErr = fmt.Sprintf("%+v", err) } switch event := event.User.(type) { - case SectorStart: - // TODO: check if state is clean - state.SectorID = event.id - state.Pieces = event.pieces - state.State = api.Packing - case SectorRestart: // noop case SectorFatalError: @@ -56,38 +72,17 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta // // TODO: Incoming // TODO: for those - look at dealIDs matching chain - // // - // Packing - - case SectorPacked: - // TODO: assert state - state.Pieces = append(state.Pieces, event.pieces...) - state.State = api.Unsealed - // // Unsealed case SectorSealFailed: // TODO: try to find out the reason, maybe retry state.State = api.SealFailed - case SectorSealed: - state.CommD = event.commD - state.CommR = event.commR - state.Ticket = event.ticket - state.State = api.PreCommitting - // // PreCommit case SectorPreCommitFailed: // TODO: try to find out the reason, maybe retry state.State = api.PreCommitFailed - case SectorPreCommitted: - state.PreCommitMessage = &event.message - state.State = api.PreCommitted - - case SectorSeedReady: - state.Seed = event.seed - state.State = api.Committing // // Commit @@ -97,13 +92,6 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta case SectorCommitFailed: // TODO: try to find out the reason, maybe retry state.State = api.SealFailed - case SectorCommitted: - state.Proof = event.proof - state.CommitMessage = &event.message - state.State = api.CommitWait - case SectorProving: - state.State = api.Proving - case SectorFaultReported: state.FaultReportMsg = &event.reportMsg state.State = api.FaultReported @@ -199,6 +187,30 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta return nil, nil } +func planCommitting(events []statemachine.Event, state *SectorInfo) error { + for _, event := range events { + switch e := event.User.(type) { + case SectorRestart: + // noop + case SectorCommitted: // the normal case + e.apply(state) + state.State = api.CommitWait + case SectorSeedReady: // seed changed :/ + if e.seed.Equals(&state.Seed) { + log.Warnf("planCommitting: got SectorSeedReady, but the seed didn't change") + continue // or it didn't! + } + log.Warnf("planCommitting: commit Seed changed") + e.apply(state) + state.State = api.Committing + return nil + default: + return xerrors.Errorf("planCommitting got event of unknown type %T, events: %+v", event.User, events) + } + } + return nil +} + func (m *Sealing) restartSectors(ctx context.Context) error { trackedSectors, err := m.ListSectors() if err != nil { @@ -219,3 +231,35 @@ func (m *Sealing) restartSectors(ctx context.Context) error { func (m *Sealing) ForceSectorState(ctx context.Context, id uint64, state api.SectorState) error { return m.sectors.Send(id, SectorForceState{state}) } + +func final(events []statemachine.Event, state *SectorInfo) error { + return xerrors.Errorf("didn't expect any events in state %s, got %+v", api.SectorStates[state.State], events) +} + +func on(mut mutator, next api.SectorState) func() (mutator, api.SectorState) { + return func() (mutator, api.SectorState) { + return mut, next + } +} + +func planOne(ts ...func() (mut mutator, next api.SectorState)) func(events []statemachine.Event, state *SectorInfo) error { + return func(events []statemachine.Event, state *SectorInfo) error { + if len(events) != 1 { + return xerrors.Errorf("planner for state %s only has a plan for a single event only, got %+v", api.SectorStates[state.State], events) + } + + for _, t := range ts { + mut, next := t() + + if reflect.TypeOf(events[0].User) != reflect.TypeOf(mut) { + continue + } + + events[0].User.(mutator).apply(state) + state.State = next + return nil + } + + return xerrors.Errorf("planner for state %s received unexpected event %+v", events[0]) + } +} diff --git a/fsm_events.go b/fsm_events.go index 39d0638d3..3e230d02d 100644 --- a/fsm_events.go +++ b/fsm_events.go @@ -6,31 +6,56 @@ import ( "github.com/filecoin-project/lotus/api" ) +type mutator interface { + apply(state *SectorInfo) +} + type SectorStart struct { id uint64 pieces []Piece } +func (evt SectorStart) apply(state *SectorInfo) { + state.SectorID = evt.id + state.Pieces = evt.pieces +} + type SectorRestart struct{} type SectorFatalError struct{ error } type SectorPacked struct{ pieces []Piece } +func (evt SectorPacked) apply(state *SectorInfo) { + state.Pieces = append(state.Pieces, evt.pieces...) +} type SectorSealed struct { commR []byte commD []byte ticket SealTicket } +func (evt SectorSealed) apply(state *SectorInfo) { + state.CommD = evt.commD + state.CommR = evt.commR + state.Ticket = evt.ticket +} + type SectorSealFailed struct{ error } type SectorPreCommitFailed struct{ error } + type SectorPreCommitted struct { message cid.Cid } +func (evt SectorPreCommitted) apply(state *SectorInfo) { + state.PreCommitMessage = &evt.message +} type SectorSeedReady struct { seed SealSeed } +func (evt SectorSeedReady) apply(state *SectorInfo) { + state.Seed = evt.seed +} type SectorSealCommitFailed struct{ error } type SectorCommitFailed struct{ error } @@ -38,8 +63,13 @@ type SectorCommitted struct { message cid.Cid proof []byte } +func (evt SectorCommitted) apply(state *SectorInfo) { + state.Proof = evt.proof + state.CommitMessage = &evt.message +} type SectorProving struct{} +func (evt SectorProving) apply(*SectorInfo) {} type SectorFaultReported struct{ reportMsg cid.Cid } type SectorFaultedFinal struct{} diff --git a/fsm_test.go b/fsm_test.go index 10b9723b9..fb31f5192 100644 --- a/fsm_test.go +++ b/fsm_test.go @@ -3,12 +3,17 @@ package sealing import ( "testing" + logging "github.com/ipfs/go-log/v2" "github.com/stretchr/testify/require" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/lib/statemachine" ) +func init() { + _ = logging.SetLogLevel("*", "INFO") +} + func (t *test) planSingle(evt interface{}) { _, err := t.s.plan([]statemachine.Event{{evt}}, t.state) require.NoError(t.t, err) @@ -67,11 +72,12 @@ func TestSeedRevert(t *testing.T) { m.planSingle(SectorSeedReady{}) require.Equal(m.t, m.state.State, api.Committing) - _, err := m.s.plan([]statemachine.Event{{SectorSeedReady{}}, {SectorCommitted{}}}, m.state) + _, err := m.s.plan([]statemachine.Event{{SectorSeedReady{seed:SealSeed{BlockHeight: 5,}}}, {SectorCommitted{}}}, m.state) require.NoError(t, err) require.Equal(m.t, m.state.State, api.Committing) - m.planSingle(SectorCommitted{}) + // not changing the seed this time + _, err = m.s.plan([]statemachine.Event{{SectorSeedReady{seed:SealSeed{BlockHeight: 5,}}}, {SectorCommitted{}}}, m.state) require.Equal(m.t, m.state.State, api.CommitWait) m.planSingle(SectorProving{}) diff --git a/types.go b/types.go index c2d6b3359..6e248050e 100644 --- a/types.go +++ b/types.go @@ -29,6 +29,10 @@ func (t *SealSeed) SB() sectorbuilder.SealSeed { return out } +func (t *SealSeed) Equals(o *SealSeed) bool { + return string(t.TicketBytes) == string(o.TicketBytes) && t.BlockHeight == o.BlockHeight +} + type Piece struct { DealID uint64 @@ -70,6 +74,8 @@ type SectorInfo struct { // Debug LastErr string + + // TODO: Log []struct{ts, msg, trace string} } func (t *SectorInfo) pieceInfos() []sectorbuilder.PublicPieceInfo { From 6413108dc9cfdef99eaa53a8f9b307b8fc45adb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 16 Jan 2020 03:53:59 +0100 Subject: [PATCH 004/126] sealing: Handle events based on current state --- fsm.go | 92 ++++++++++++++++++++------------------------------- fsm_events.go | 51 ++++++++++++++++++++++------ states.go | 2 ++ 3 files changed, 78 insertions(+), 67 deletions(-) diff --git a/fsm.go b/fsm.go index 56c7fa6b7..163e0eccd 100644 --- a/fsm.go +++ b/fsm.go @@ -2,7 +2,6 @@ package sealing import ( "context" - "fmt" "reflect" "golang.org/x/xerrors" @@ -32,13 +31,30 @@ func (m *Sealing) Plan(events []statemachine.Event, user interface{}) (interface var fsmPlanners = []func(events []statemachine.Event, state *SectorInfo) error { api.UndefinedSectorState: planOne(on(SectorStart{}, api.Packing)), api.Packing: planOne(on(SectorPacked{}, api.Unsealed)), - api.Unsealed: planOne(on(SectorSealed{}, api.PreCommitting)), - api.PreCommitting: planOne(on(SectorPreCommitted{}, api.PreCommitted)), - api.PreCommitted: planOne(on(SectorSeedReady{}, api.Committing)), + api.Unsealed: planOne( + on(SectorSealed{}, api.PreCommitting), + on(SectorSealFailed{}, api.SealFailed), + ), + api.PreCommitting: planOne( + on(SectorPreCommitted{}, api.PreCommitted), + on(SectorPreCommitFailed{}, api.PreCommitFailed), + ), + api.PreCommitted: planOne( + on(SectorSeedReady{}, api.Committing), + on(SectorPreCommitFailed{}, api.PreCommitFailed), + ), api.Committing: planCommitting, api.CommitWait: planOne(on(SectorProving{}, api.Proving)), - api.Proving: final, + api.Proving: planOne( + on(SectorFaultReported{}, api.FaultReported), + on(SectorFaulty{}, api.Faulty), + ), + + api.Faulty: planOne( + on(SectorFaultReported{}, api.FaultReported), + ), + api.FaultedFinal: final, } func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(statemachine.Context, SectorInfo) error, error) { @@ -54,56 +70,6 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta return nil, xerrors.Errorf("running planner for state %s failed: %w", api.SectorStates[state.State], err) } - for _, event := range events { - if err, ok := event.User.(error); ok { - state.LastErr = fmt.Sprintf("%+v", err) - } - - switch event := event.User.(type) { - case SectorRestart: - // noop - case SectorFatalError: - log.Errorf("Fatal error on sector %d: %+v", state.SectorID, event.error) - // TODO: Do we want to mark the state as unrecoverable? - // I feel like this should be a softer error, where the user would - // be able to send a retry event of some kind - return nil, nil - - // // TODO: Incoming - // TODO: for those - look at dealIDs matching chain - - // // Unsealed - - case SectorSealFailed: - // TODO: try to find out the reason, maybe retry - state.State = api.SealFailed - - // // PreCommit - - case SectorPreCommitFailed: - // TODO: try to find out the reason, maybe retry - state.State = api.PreCommitFailed - - // // Commit - - case SectorSealCommitFailed: - // TODO: try to find out the reason, maybe retry - state.State = api.SealCommitFailed - case SectorCommitFailed: - // TODO: try to find out the reason, maybe retry - state.State = api.SealFailed - case SectorFaultReported: - state.FaultReportMsg = &event.reportMsg - state.State = api.FaultReported - case SectorFaultedFinal: - state.State = api.FaultedFinal - - // // Debug triggers - case SectorForceState: - state.State = event.state - } - } - ///// // Now decide what to do next @@ -190,8 +156,10 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta func planCommitting(events []statemachine.Event, state *SectorInfo) error { for _, event := range events { switch e := event.User.(type) { - case SectorRestart: - // noop + case globalMutator: + if e.applyGlobal(state) { + return nil + } case SectorCommitted: // the normal case e.apply(state) state.State = api.CommitWait @@ -204,6 +172,10 @@ func planCommitting(events []statemachine.Event, state *SectorInfo) error { e.apply(state) state.State = api.Committing return nil + case SectorSealCommitFailed: + state.State = api.SealCommitFailed + case SectorSealFailed: + state.State = api.CommitFailed default: return xerrors.Errorf("planCommitting got event of unknown type %T, events: %+v", event.User, events) } @@ -245,6 +217,12 @@ func on(mut mutator, next api.SectorState) func() (mutator, api.SectorState) { func planOne(ts ...func() (mut mutator, next api.SectorState)) func(events []statemachine.Event, state *SectorInfo) error { return func(events []statemachine.Event, state *SectorInfo) error { if len(events) != 1 { + for _, event := range events { + if gm, ok := event.User.(globalMutator); !ok { + gm.applyGlobal(state) + return nil + } + } return xerrors.Errorf("planner for state %s only has a plan for a single event only, got %+v", api.SectorStates[state.State], events) } diff --git a/fsm_events.go b/fsm_events.go index 3e230d02d..a33861d42 100644 --- a/fsm_events.go +++ b/fsm_events.go @@ -1,15 +1,45 @@ package sealing import ( - "github.com/ipfs/go-cid" - "github.com/filecoin-project/lotus/api" + "github.com/ipfs/go-cid" ) type mutator interface { apply(state *SectorInfo) } +// globalMutator is an event which can apply in every state +type globalMutator interface { + // applyGlobal applies the event to the state. If if returns true, + // event processing should be interrupted + applyGlobal(state *SectorInfo) bool +} + +// Global events + +type SectorRestart struct{} +func (evt SectorRestart) applyGlobal(*SectorInfo) bool { return false } + +type SectorFatalError struct{ error } +func (evt SectorFatalError) applyGlobal(state *SectorInfo) bool { + log.Errorf("Fatal error on sector %d: %+v", state.SectorID, evt.error) + // TODO: Do we want to mark the state as unrecoverable? + // I feel like this should be a softer error, where the user would + // be able to send a retry event of some kind + return true +} + +type SectorForceState struct { + state api.SectorState +} +func (evt SectorForceState) applyGlobal(state *SectorInfo) bool { + state.State = evt.state + return true +} + +// Normal path + type SectorStart struct { id uint64 pieces []Piece @@ -19,10 +49,6 @@ func (evt SectorStart) apply(state *SectorInfo) { state.Pieces = evt.pieces } -type SectorRestart struct{} - -type SectorFatalError struct{ error } - type SectorPacked struct{ pieces []Piece } func (evt SectorPacked) apply(state *SectorInfo) { state.Pieces = append(state.Pieces, evt.pieces...) @@ -40,8 +66,10 @@ func (evt SectorSealed) apply(state *SectorInfo) { } type SectorSealFailed struct{ error } +func (evt SectorSealFailed) apply(*SectorInfo) {} type SectorPreCommitFailed struct{ error } +func (evt SectorPreCommitFailed) apply(*SectorInfo) {} type SectorPreCommitted struct { message cid.Cid @@ -71,9 +99,12 @@ func (evt SectorCommitted) apply(state *SectorInfo) { type SectorProving struct{} func (evt SectorProving) apply(*SectorInfo) {} -type SectorFaultReported struct{ reportMsg cid.Cid } -type SectorFaultedFinal struct{} +type SectorFaulty struct{} +func (evt SectorFaulty) apply(state *SectorInfo) {} -type SectorForceState struct { - state api.SectorState +type SectorFaultReported struct{ reportMsg cid.Cid } +func (evt SectorFaultReported) apply(state *SectorInfo) { + state.FaultReportMsg = &evt.reportMsg } + +type SectorFaultedFinal struct{} diff --git a/states.go b/states.go index 1dbc6e4d4..8280be5eb 100644 --- a/states.go +++ b/states.go @@ -173,6 +173,8 @@ func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) GasPrice: types.NewInt(1), } + // TODO: check seed / ticket are up to date + smsg, err := m.api.MpoolPushMessage(ctx.Context(), msg) if err != nil { return ctx.Send(SectorCommitFailed{xerrors.Errorf("pushing message to mpool: %w", err)}) From 347e788eb6a6d484c75ce1fddb9cab6e2b9a7cc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 16 Jan 2020 03:54:57 +0100 Subject: [PATCH 005/126] sealing: gofmt --- fsm.go | 4 ++-- fsm_events.go | 14 ++++++++++++++ fsm_test.go | 4 ++-- sealing.go | 11 +++++------ 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/fsm.go b/fsm.go index 163e0eccd..5c37020d2 100644 --- a/fsm.go +++ b/fsm.go @@ -28,9 +28,9 @@ func (m *Sealing) Plan(events []statemachine.Event, user interface{}) (interface }, nil } -var fsmPlanners = []func(events []statemachine.Event, state *SectorInfo) error { +var fsmPlanners = []func(events []statemachine.Event, state *SectorInfo) error{ api.UndefinedSectorState: planOne(on(SectorStart{}, api.Packing)), - api.Packing: planOne(on(SectorPacked{}, api.Unsealed)), + api.Packing: planOne(on(SectorPacked{}, api.Unsealed)), api.Unsealed: planOne( on(SectorSealed{}, api.PreCommitting), on(SectorSealFailed{}, api.SealFailed), diff --git a/fsm_events.go b/fsm_events.go index a33861d42..ddab56451 100644 --- a/fsm_events.go +++ b/fsm_events.go @@ -19,9 +19,11 @@ type globalMutator interface { // Global events type SectorRestart struct{} + func (evt SectorRestart) applyGlobal(*SectorInfo) bool { return false } type SectorFatalError struct{ error } + func (evt SectorFatalError) applyGlobal(state *SectorInfo) bool { log.Errorf("Fatal error on sector %d: %+v", state.SectorID, evt.error) // TODO: Do we want to mark the state as unrecoverable? @@ -33,6 +35,7 @@ func (evt SectorFatalError) applyGlobal(state *SectorInfo) bool { type SectorForceState struct { state api.SectorState } + func (evt SectorForceState) applyGlobal(state *SectorInfo) bool { state.State = evt.state return true @@ -44,12 +47,14 @@ type SectorStart struct { id uint64 pieces []Piece } + func (evt SectorStart) apply(state *SectorInfo) { state.SectorID = evt.id state.Pieces = evt.pieces } type SectorPacked struct{ pieces []Piece } + func (evt SectorPacked) apply(state *SectorInfo) { state.Pieces = append(state.Pieces, evt.pieces...) } @@ -59,6 +64,7 @@ type SectorSealed struct { commD []byte ticket SealTicket } + func (evt SectorSealed) apply(state *SectorInfo) { state.CommD = evt.commD state.CommR = evt.commR @@ -66,14 +72,17 @@ func (evt SectorSealed) apply(state *SectorInfo) { } type SectorSealFailed struct{ error } + func (evt SectorSealFailed) apply(*SectorInfo) {} type SectorPreCommitFailed struct{ error } + func (evt SectorPreCommitFailed) apply(*SectorInfo) {} type SectorPreCommitted struct { message cid.Cid } + func (evt SectorPreCommitted) apply(state *SectorInfo) { state.PreCommitMessage = &evt.message } @@ -81,6 +90,7 @@ func (evt SectorPreCommitted) apply(state *SectorInfo) { type SectorSeedReady struct { seed SealSeed } + func (evt SectorSeedReady) apply(state *SectorInfo) { state.Seed = evt.seed } @@ -91,18 +101,22 @@ type SectorCommitted struct { message cid.Cid proof []byte } + func (evt SectorCommitted) apply(state *SectorInfo) { state.Proof = evt.proof state.CommitMessage = &evt.message } type SectorProving struct{} + func (evt SectorProving) apply(*SectorInfo) {} type SectorFaulty struct{} + func (evt SectorFaulty) apply(state *SectorInfo) {} type SectorFaultReported struct{ reportMsg cid.Cid } + func (evt SectorFaultReported) apply(state *SectorInfo) { state.FaultReportMsg = &evt.reportMsg } diff --git a/fsm_test.go b/fsm_test.go index fb31f5192..a76a547dc 100644 --- a/fsm_test.go +++ b/fsm_test.go @@ -72,12 +72,12 @@ func TestSeedRevert(t *testing.T) { m.planSingle(SectorSeedReady{}) require.Equal(m.t, m.state.State, api.Committing) - _, err := m.s.plan([]statemachine.Event{{SectorSeedReady{seed:SealSeed{BlockHeight: 5,}}}, {SectorCommitted{}}}, m.state) + _, err := m.s.plan([]statemachine.Event{{SectorSeedReady{seed: SealSeed{BlockHeight: 5}}}, {SectorCommitted{}}}, m.state) require.NoError(t, err) require.Equal(m.t, m.state.State, api.Committing) // not changing the seed this time - _, err = m.s.plan([]statemachine.Event{{SectorSeedReady{seed:SealSeed{BlockHeight: 5,}}}, {SectorCommitted{}}}, m.state) + _, err = m.s.plan([]statemachine.Event{{SectorSeedReady{seed: SealSeed{BlockHeight: 5}}}, {SectorCommitted{}}}, m.state) require.Equal(m.t, m.state.State, api.CommitWait) m.planSingle(SectorProving{}) diff --git a/sealing.go b/sealing.go index f0c2b3d50..45e3d6451 100644 --- a/sealing.go +++ b/sealing.go @@ -66,13 +66,13 @@ type Sealing struct { func New(api sealingApi, events *events.Events, maddr address.Address, worker address.Address, ds datastore.Batching, sb sectorbuilder.Interface, tktFn TicketFn) *Sealing { s := &Sealing{ - api: api, + api: api, events: events, - maddr: maddr, - worker: worker, - sb: sb, - tktFn: tktFn, + maddr: maddr, + worker: worker, + sb: sb, + tktFn: tktFn, } s.sectors = statemachine.New(namespace.Wrap(ds, datastore.NewKey(SectorStorePrefix)), s, SectorInfo{}) @@ -133,4 +133,3 @@ func (m *Sealing) newSector(ctx context.Context, sid uint64, dealID uint64, ppi }, }) } - From a3747f8c71330b760daf1c03f1a4f2ca4950dd9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 16 Jan 2020 03:55:12 +0100 Subject: [PATCH 006/126] Merge branch 'master' into feat/event-states --- fsm_events.go | 3 ++- sealing.go | 11 +++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/fsm_events.go b/fsm_events.go index ddab56451..8392d13e7 100644 --- a/fsm_events.go +++ b/fsm_events.go @@ -1,8 +1,9 @@ package sealing import ( - "github.com/filecoin-project/lotus/api" "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/api" ) type mutator interface { diff --git a/sealing.go b/sealing.go index 45e3d6451..5b8ce1bb5 100644 --- a/sealing.go +++ b/sealing.go @@ -2,17 +2,16 @@ package sealing import ( "context" - "github.com/ipfs/go-datastore" - "github.com/ipfs/go-datastore/namespace" "io" - "github.com/filecoin-project/lotus/lib/padreader" - logging "github.com/ipfs/go-log/v2" - "golang.org/x/xerrors" - "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-sectorbuilder" + "github.com/filecoin-project/lotus/lib/padreader" "github.com/ipfs/go-cid" + "github.com/ipfs/go-datastore" + "github.com/ipfs/go-datastore/namespace" + logging "github.com/ipfs/go-log/v2" + "golang.org/x/xerrors" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/events" From 49461b2e686cd105c968bfa5baee41591b3d4bcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 18 Jan 2020 14:40:50 +0100 Subject: [PATCH 007/126] Merge branch 'master' into feat/event-states --- states.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/states.go b/states.go index 8280be5eb..1bebdb243 100644 --- a/states.go +++ b/states.go @@ -212,9 +212,7 @@ func (m *Sealing) handleFaulty(ctx statemachine.Context, sector SectorInfo) erro bf := types.NewBitField() bf.Set(sector.SectorID) - fp := &actors.DeclareFaultsParams{bf} - _ = fp - enc, aerr := actors.SerializeParams(nil) + enc, aerr := actors.SerializeParams(&actors.DeclareFaultsParams{bf}) if aerr != nil { return xerrors.Errorf("failed to serialize declare fault params: %w", aerr) } From 7566d75aeb708f272c44db3d32b1f31a169587f7 Mon Sep 17 00:00:00 2001 From: dtynn Date: Mon, 20 Jan 2020 16:23:56 +0800 Subject: [PATCH 008/126] small fixes --- fsm.go | 7 +++++-- fsm_events.go | 4 ++++ sealing.go | 2 -- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/fsm.go b/fsm.go index 5c37020d2..e470290a9 100644 --- a/fsm.go +++ b/fsm.go @@ -44,7 +44,10 @@ var fsmPlanners = []func(events []statemachine.Event, state *SectorInfo) error{ on(SectorPreCommitFailed{}, api.PreCommitFailed), ), api.Committing: planCommitting, - api.CommitWait: planOne(on(SectorProving{}, api.Proving)), + api.CommitWait: planOne( + on(SectorProving{}, api.Proving), + on(SectorCommitFailed{}, api.CommitFailed), + ), api.Proving: planOne( on(SectorFaultReported{}, api.FaultReported), @@ -238,6 +241,6 @@ func planOne(ts ...func() (mut mutator, next api.SectorState)) func(events []sta return nil } - return xerrors.Errorf("planner for state %s received unexpected event %+v", events[0]) + return xerrors.Errorf("planner for state %s received unexpected event %+v", api.SectorStates[state.State], events[0]) } } diff --git a/fsm_events.go b/fsm_events.go index 8392d13e7..4f7c61d15 100644 --- a/fsm_events.go +++ b/fsm_events.go @@ -97,7 +97,11 @@ func (evt SectorSeedReady) apply(state *SectorInfo) { } type SectorSealCommitFailed struct{ error } + type SectorCommitFailed struct{ error } + +func (evt SectorCommitFailed) apply(*SectorInfo) {} + type SectorCommitted struct { message cid.Cid proof []byte diff --git a/sealing.go b/sealing.go index 5b8ce1bb5..7899415e8 100644 --- a/sealing.go +++ b/sealing.go @@ -80,8 +80,6 @@ func New(api sealingApi, events *events.Events, maddr address.Address, worker ad } func (m *Sealing) Run(ctx context.Context) error { - m.events = events.NewEvents(ctx, m.api) - if err := m.restartSectors(ctx); err != nil { log.Errorf("%+v", err) return xerrors.Errorf("failed load sector states: %w", err) From 93453ed68387da3f09ea67a7f3802f7986da332a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 20 Jan 2020 23:03:50 +0100 Subject: [PATCH 009/126] sealing: WIP SectorInfo sanity checks --- checks.go | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 checks.go diff --git a/checks.go b/checks.go new file mode 100644 index 000000000..05647de6c --- /dev/null +++ b/checks.go @@ -0,0 +1,73 @@ +package sealing + +import ( + "context" + + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/types" +) + +func checkPieces(ctx context.Context, si *SectorInfo, api sealingApi) error { + for i, piece := range si.Pieces { + deal, err := api.StateMarketStorageDeal(ctx, piece.DealID, nil) + if err != nil { + return xerrors.Errorf("getting deal %d for piece %d: %w", piece.DealID, i, err) + } + + if string(deal.PieceRef) != string(piece.CommP) { + return xerrors.Errorf("piece %d of sector %d refers deal %d with wrong CommP: %x != %x", i, si.SectorID, piece.DealID, piece.CommP, deal.PieceRef) + } + + if piece.Size != deal.PieceSize { + return xerrors.Errorf("piece %d of sector %d refers deal %d with different size: %d != %d", i, si.SectorID, piece.DealID, piece.Size, deal.PieceSize) + } + } + + return nil +} + +func checkSeal(ctx context.Context, maddr address.Address, si *SectorInfo, api sealingApi) (err error) { + ssize, err := api.StateMinerSectorSize(ctx, maddr, nil) + if err != nil { + return err + } + + ccparams, err := actors.SerializeParams(&actors.ComputeDataCommitmentParams{ + DealIDs: si.deals(), + SectorSize: ssize, + }) + if err != nil { + return xerrors.Errorf("computing params for ComputeDataCommitment: %w", err) + } + + ccmt := &types.Message{ + To: actors.StorageMarketAddress, + From: actors.StorageMarketAddress, + Value: types.NewInt(0), + GasPrice: types.NewInt(0), + GasLimit: types.NewInt(9999999999), + Method: actors.SMAMethods.ComputeDataCommitment, + Params: ccparams, + } + r, err := api.StateCall(ctx, ccmt, nil) + if err != nil { + return xerrors.Errorf("calling ComputeDataCommitment: %w", err) + } + if r.ExitCode != 0 { + return xerrors.Errorf("receipt for ComputeDataCommitment han exit code %d", r.ExitCode) + } + if string(r.Return) != string(si.CommD) { + return xerrors.Errorf("on chain CommD differs from sector: %x != %x", r.Return, si.CommD) + } + + + // TODO: Validate ticket + // TODO: Verify commp / commr / proof + // TODO: (StateCall PreCommit) + return nil + + +} From f121570d60b65da862731b23a98e082dcbd4d2e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 20 Jan 2020 23:04:46 +0100 Subject: [PATCH 010/126] sealing: Some state renaming --- fsm.go | 12 ++++++------ fsm_events.go | 2 +- fsm_test.go | 4 ++-- sealing.go | 4 +++- states.go | 4 ++-- types.go | 4 ++-- 6 files changed, 16 insertions(+), 14 deletions(-) diff --git a/fsm.go b/fsm.go index 5c37020d2..7459b7487 100644 --- a/fsm.go +++ b/fsm.go @@ -36,10 +36,10 @@ var fsmPlanners = []func(events []statemachine.Event, state *SectorInfo) error{ on(SectorSealFailed{}, api.SealFailed), ), api.PreCommitting: planOne( - on(SectorPreCommitted{}, api.PreCommitted), + on(SectorPreCommitted{}, api.WaitSeed), on(SectorPreCommitFailed{}, api.PreCommitFailed), ), - api.PreCommitted: planOne( + api.WaitSeed: planOne( on(SectorSeedReady{}, api.Committing), on(SectorPreCommitFailed{}, api.PreCommitFailed), ), @@ -87,7 +87,7 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta * PreCommitting <--> PreCommitFailed | | ^ | v | - *<- PreCommitted ------/ + *<- WaitSeed ----------/ | ||| | vvv v--> SealCommitFailed *<- Committing @@ -115,8 +115,8 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta return m.handleUnsealed, nil case api.PreCommitting: return m.handlePreCommitting, nil - case api.PreCommitted: - return m.handlePreCommitted, nil + case api.WaitSeed: + return m.handleWaitSeed, nil case api.Committing: return m.handleCommitting, nil case api.CommitWait: @@ -172,7 +172,7 @@ func planCommitting(events []statemachine.Event, state *SectorInfo) error { e.apply(state) state.State = api.Committing return nil - case SectorSealCommitFailed: + case SectorComputeProofFailed: state.State = api.SealCommitFailed case SectorSealFailed: state.State = api.CommitFailed diff --git a/fsm_events.go b/fsm_events.go index 8392d13e7..662379e9a 100644 --- a/fsm_events.go +++ b/fsm_events.go @@ -96,7 +96,7 @@ func (evt SectorSeedReady) apply(state *SectorInfo) { state.Seed = evt.seed } -type SectorSealCommitFailed struct{ error } +type SectorComputeProofFailed struct{ error } type SectorCommitFailed struct{ error } type SectorCommitted struct { message cid.Cid diff --git a/fsm_test.go b/fsm_test.go index a76a547dc..2dada5470 100644 --- a/fsm_test.go +++ b/fsm_test.go @@ -41,7 +41,7 @@ func TestHappyPath(t *testing.T) { require.Equal(m.t, m.state.State, api.PreCommitting) m.planSingle(SectorPreCommitted{}) - require.Equal(m.t, m.state.State, api.PreCommitted) + require.Equal(m.t, m.state.State, api.WaitSeed) m.planSingle(SectorSeedReady{}) require.Equal(m.t, m.state.State, api.Committing) @@ -67,7 +67,7 @@ func TestSeedRevert(t *testing.T) { require.Equal(m.t, m.state.State, api.PreCommitting) m.planSingle(SectorPreCommitted{}) - require.Equal(m.t, m.state.State, api.PreCommitted) + require.Equal(m.t, m.state.State, api.WaitSeed) m.planSingle(SectorSeedReady{}) require.Equal(m.t, m.state.State, api.Committing) diff --git a/sealing.go b/sealing.go index 5b8ce1bb5..5a486f6ef 100644 --- a/sealing.go +++ b/sealing.go @@ -6,7 +6,6 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-sectorbuilder" - "github.com/filecoin-project/lotus/lib/padreader" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/namespace" @@ -14,9 +13,11 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/events" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/lib/padreader" "github.com/filecoin-project/lotus/lib/statemachine" ) @@ -37,6 +38,7 @@ type sealingApi interface { // TODO: trim down StateWaitMsg(context.Context, cid.Cid) (*api.MsgWait, error) // TODO: removeme eventually StateGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error) StateGetReceipt(context.Context, cid.Cid, *types.TipSet) (*types.MessageReceipt, error) + StateMarketStorageDeal(context.Context, uint64, *types.TipSet) (*actors.OnChainDeal, error) MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error) diff --git a/states.go b/states.go index 1bebdb243..ad4a8f542 100644 --- a/states.go +++ b/states.go @@ -97,7 +97,7 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf return ctx.Send(SectorPreCommitted{message: smsg.Cid()}) } -func (m *Sealing) handlePreCommitted(ctx statemachine.Context, sector SectorInfo) error { +func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) error { // would be ideal to just use the events.Called handler, but it wouldnt be able to handle individual message timeouts log.Info("Sector precommitted: ", sector.SectorID) mw, err := m.api.StateWaitMsg(ctx.Context(), *sector.PreCommitMessage) @@ -147,7 +147,7 @@ func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) proof, err := m.sb.SealCommit(ctx.Context(), sector.SectorID, sector.Ticket.SB(), sector.Seed.SB(), sector.pieceInfos(), sector.rspco()) if err != nil { - return ctx.Send(SectorSealCommitFailed{xerrors.Errorf("computing seal proof failed: %w", err)}) + return ctx.Send(SectorComputeProofFailed{xerrors.Errorf("computing seal proof failed: %w", err)}) } // TODO: Consider splitting states and persist proof for faster recovery diff --git a/types.go b/types.go index 6e248050e..096e83d08 100644 --- a/types.go +++ b/types.go @@ -49,7 +49,7 @@ func (p *Piece) ppi() (out sectorbuilder.PublicPieceInfo) { type SectorInfo struct { State api.SectorState SectorID uint64 - Nonce uint64 + Nonce uint64 // TODO: remove // Packing @@ -63,7 +63,7 @@ type SectorInfo struct { PreCommitMessage *cid.Cid - // PreCommitted + // WaitSeed Seed SealSeed // Committing From 7c6a8849801a67a9ab8c697dec39907fc8a330b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 21 Jan 2020 17:05:10 +0100 Subject: [PATCH 011/126] cobr-gen: Soft struct-map unmarshaling --- cbor_gen.go | 885 +++++++++++++++++++++------------------------------- fsm.go | 4 + 2 files changed, 361 insertions(+), 528 deletions(-) diff --git a/cbor_gen.go b/cbor_gen.go index 62c6241dc..61ad5b606 100644 --- a/cbor_gen.go +++ b/cbor_gen.go @@ -73,68 +73,61 @@ func (t *SealTicket) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input should be of type map") } - if extra != 2 { - return fmt.Errorf("cbor input had wrong number of fields") + if extra > cbg.MaxLength { + return fmt.Errorf("SealTicket: map struct too large (%d)", extra) } var name string + n := extra - // t.BlockHeight (uint64) (uint64) + for i := uint64(0); i < n; i++ { - { - sval, err := cbg.ReadString(br) - if err != nil { - return err + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + name = string(sval) } - name = string(sval) - } + switch name { + // t.BlockHeight (uint64) (uint64) + case "BlockHeight": - if name != "BlockHeight" { - return fmt.Errorf("expected struct map entry %s to be BlockHeight", name) - } + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.BlockHeight = uint64(extra) + // t.TicketBytes ([]uint8) (slice) + case "TicketBytes": - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.BlockHeight = uint64(extra) - // t.TicketBytes ([]uint8) (slice) + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } - { - sval, err := cbg.ReadString(br) - if err != nil { - return err + if extra > cbg.ByteArrayMaxLen { + return fmt.Errorf("t.TicketBytes: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.TicketBytes = make([]byte, extra) + if _, err := io.ReadFull(br, t.TicketBytes); err != nil { + return err + } + + default: } - - name = string(sval) } - if name != "TicketBytes" { - return fmt.Errorf("expected struct map entry %s to be TicketBytes", name) - } - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.ByteArrayMaxLen { - return fmt.Errorf("t.TicketBytes: byte array too large (%d)", extra) - } - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") - } - t.TicketBytes = make([]byte, extra) - if _, err := io.ReadFull(br, t.TicketBytes); err != nil { - return err - } return nil } - func (t *SealSeed) MarshalCBOR(w io.Writer) error { if t == nil { _, err := w.Write(cbg.CborNull) @@ -196,68 +189,61 @@ func (t *SealSeed) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input should be of type map") } - if extra != 2 { - return fmt.Errorf("cbor input had wrong number of fields") + if extra > cbg.MaxLength { + return fmt.Errorf("SealSeed: map struct too large (%d)", extra) } var name string + n := extra - // t.BlockHeight (uint64) (uint64) + for i := uint64(0); i < n; i++ { - { - sval, err := cbg.ReadString(br) - if err != nil { - return err + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + name = string(sval) } - name = string(sval) - } + switch name { + // t.BlockHeight (uint64) (uint64) + case "BlockHeight": - if name != "BlockHeight" { - return fmt.Errorf("expected struct map entry %s to be BlockHeight", name) - } + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.BlockHeight = uint64(extra) + // t.TicketBytes ([]uint8) (slice) + case "TicketBytes": - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.BlockHeight = uint64(extra) - // t.TicketBytes ([]uint8) (slice) + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } - { - sval, err := cbg.ReadString(br) - if err != nil { - return err + if extra > cbg.ByteArrayMaxLen { + return fmt.Errorf("t.TicketBytes: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.TicketBytes = make([]byte, extra) + if _, err := io.ReadFull(br, t.TicketBytes); err != nil { + return err + } + + default: } - - name = string(sval) } - if name != "TicketBytes" { - return fmt.Errorf("expected struct map entry %s to be TicketBytes", name) - } - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.ByteArrayMaxLen { - return fmt.Errorf("t.TicketBytes: byte array too large (%d)", extra) - } - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") - } - t.TicketBytes = make([]byte, extra) - if _, err := io.ReadFull(br, t.TicketBytes); err != nil { - return err - } return nil } - func (t *Piece) MarshalCBOR(w io.Writer) error { if t == nil { _, err := w.Write(cbg.CborNull) @@ -335,91 +321,72 @@ func (t *Piece) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input should be of type map") } - if extra != 3 { - return fmt.Errorf("cbor input had wrong number of fields") + if extra > cbg.MaxLength { + return fmt.Errorf("Piece: map struct too large (%d)", extra) } var name string + n := extra - // t.DealID (uint64) (uint64) + for i := uint64(0); i < n; i++ { - { - sval, err := cbg.ReadString(br) - if err != nil { - return err + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + name = string(sval) } - name = string(sval) - } + switch name { + // t.DealID (uint64) (uint64) + case "DealID": - if name != "DealID" { - return fmt.Errorf("expected struct map entry %s to be DealID", name) - } + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.DealID = uint64(extra) + // t.Size (uint64) (uint64) + case "Size": - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.DealID = uint64(extra) - // t.Size (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.Size = uint64(extra) + // t.CommP ([]uint8) (slice) + case "CommP": - { - sval, err := cbg.ReadString(br) - if err != nil { - return err + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + + if extra > cbg.ByteArrayMaxLen { + return fmt.Errorf("t.CommP: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.CommP = make([]byte, extra) + if _, err := io.ReadFull(br, t.CommP); err != nil { + return err + } + + default: } - - name = string(sval) } - if name != "Size" { - return fmt.Errorf("expected struct map entry %s to be Size", name) - } - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.Size = uint64(extra) - // t.CommP ([]uint8) (slice) - - { - sval, err := cbg.ReadString(br) - if err != nil { - return err - } - - name = string(sval) - } - - if name != "CommP" { - return fmt.Errorf("expected struct map entry %s to be CommP", name) - } - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.ByteArrayMaxLen { - return fmt.Errorf("t.CommP: byte array too large (%d)", extra) - } - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") - } - t.CommP = make([]byte, extra) - if _, err := io.ReadFull(br, t.CommP); err != nil { - return err - } return nil } - func (t *SectorInfo) MarshalCBOR(w io.Writer) error { if t == nil { _, err := w.Write(cbg.CborNull) @@ -477,7 +444,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { return err } - // t.Pieces ([]storage.Piece) (slice) + // t.Pieces ([]sealing.Piece) (slice) if len("Pieces") > cbg.MaxLength { return xerrors.Errorf("Value in field \"Pieces\" was too long") } @@ -571,7 +538,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { return err } - // t.Ticket (storage.SealTicket) (struct) + // t.Ticket (sealing.SealTicket) (struct) if len("Ticket") > cbg.MaxLength { return xerrors.Errorf("Value in field \"Ticket\" was too long") } @@ -609,7 +576,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { } } - // t.Seed (storage.SealSeed) (struct) + // t.Seed (sealing.SealSeed) (struct) if len("Seed") > cbg.MaxLength { return xerrors.Errorf("Value in field \"Seed\" was too long") } @@ -705,388 +672,250 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input should be of type map") } - if extra != 13 { - return fmt.Errorf("cbor input had wrong number of fields") + if extra > cbg.MaxLength { + return fmt.Errorf("SectorInfo: map struct too large (%d)", extra) } var name string + n := extra - // t.State (uint64) (uint64) + for i := uint64(0); i < n; i++ { - { - sval, err := cbg.ReadString(br) - if err != nil { - return err - } - - name = string(sval) - } - - if name != "State" { - return fmt.Errorf("expected struct map entry %s to be State", name) - } - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.State = uint64(extra) - // t.SectorID (uint64) (uint64) - - { - sval, err := cbg.ReadString(br) - if err != nil { - return err - } - - name = string(sval) - } - - if name != "SectorID" { - return fmt.Errorf("expected struct map entry %s to be SectorID", name) - } - - 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.Nonce (uint64) (uint64) - - { - sval, err := cbg.ReadString(br) - if err != nil { - return err - } - - name = string(sval) - } - - if name != "Nonce" { - return fmt.Errorf("expected struct map entry %s to be Nonce", name) - } - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.Nonce = uint64(extra) - // t.Pieces ([]storage.Piece) (slice) - - { - sval, err := cbg.ReadString(br) - if err != nil { - return err - } - - name = string(sval) - } - - if name != "Pieces" { - return fmt.Errorf("expected struct map entry %s to be Pieces", name) - } - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.MaxLength { - return fmt.Errorf("t.Pieces: array too large (%d)", extra) - } - - if maj != cbg.MajArray { - return fmt.Errorf("expected cbor array") - } - if extra > 0 { - t.Pieces = make([]Piece, extra) - } - for i := 0; i < int(extra); i++ { - - var v Piece - if err := v.UnmarshalCBOR(br); err != nil { - return err - } - - t.Pieces[i] = v - } - - // t.CommD ([]uint8) (slice) - - { - sval, err := cbg.ReadString(br) - if err != nil { - return err - } - - name = string(sval) - } - - if name != "CommD" { - return fmt.Errorf("expected struct map entry %s to be CommD", name) - } - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.ByteArrayMaxLen { - return fmt.Errorf("t.CommD: byte array too large (%d)", extra) - } - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") - } - t.CommD = make([]byte, extra) - if _, err := io.ReadFull(br, t.CommD); err != nil { - return err - } - // t.CommR ([]uint8) (slice) - - { - sval, err := cbg.ReadString(br) - if err != nil { - return err - } - - name = string(sval) - } - - if name != "CommR" { - return fmt.Errorf("expected struct map entry %s to be CommR", name) - } - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.ByteArrayMaxLen { - return fmt.Errorf("t.CommR: byte array too large (%d)", extra) - } - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") - } - t.CommR = make([]byte, extra) - if _, err := io.ReadFull(br, t.CommR); err != nil { - return err - } - // t.Proof ([]uint8) (slice) - - { - sval, err := cbg.ReadString(br) - if err != nil { - return err - } - - name = string(sval) - } - - if name != "Proof" { - return fmt.Errorf("expected struct map entry %s to be Proof", name) - } - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.ByteArrayMaxLen { - return fmt.Errorf("t.Proof: byte 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.Ticket (storage.SealTicket) (struct) - - { - sval, err := cbg.ReadString(br) - if err != nil { - return err - } - - name = string(sval) - } - - if name != "Ticket" { - return fmt.Errorf("expected struct map entry %s to be Ticket", name) - } - - { - - if err := t.Ticket.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.PreCommitMessage (cid.Cid) (struct) - - { - sval, err := cbg.ReadString(br) - if err != nil { - return err - } - - name = string(sval) - } - - if name != "PreCommitMessage" { - return fmt.Errorf("expected struct map entry %s to be PreCommitMessage", name) - } - - { - - 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 { + { + sval, err := cbg.ReadString(br) + if err != nil { return err } - } else { - c, err := cbg.ReadCid(br) + name = string(sval) + } + + switch name { + // t.State (uint64) (uint64) + case "State": + + maj, extra, err = cbg.CborReadHeader(br) if err != nil { - return xerrors.Errorf("failed to read cid field t.PreCommitMessage: %w", err) - } - - t.PreCommitMessage = &c - } - - } - // t.Seed (storage.SealSeed) (struct) - - { - sval, err := cbg.ReadString(br) - if err != nil { - return err - } - - name = string(sval) - } - - if name != "Seed" { - return fmt.Errorf("expected struct map entry %s to be Seed", name) - } - - { - - if err := t.Seed.UnmarshalCBOR(br); err != nil { - return err - } - - } - // t.CommitMessage (cid.Cid) (struct) - - { - sval, err := cbg.ReadString(br) - if err != nil { - return err - } - - name = string(sval) - } - - if name != "CommitMessage" { - return fmt.Errorf("expected struct map entry %s to be CommitMessage", name) - } - - { - - 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 { - - c, err := cbg.ReadCid(br) - if err != nil { - return xerrors.Errorf("failed to read cid field t.CommitMessage: %w", err) + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") } + t.State = uint64(extra) + // t.SectorID (uint64) (uint64) + case "SectorID": - t.CommitMessage = &c - } - - } - // t.FaultReportMsg (cid.Cid) (struct) - - { - sval, err := cbg.ReadString(br) - if err != nil { - return err - } - - name = string(sval) - } - - if name != "FaultReportMsg" { - return fmt.Errorf("expected struct map entry %s to be FaultReportMsg", name) - } - - { - - 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 { + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { return err } - } else { + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.SectorID = uint64(extra) + // t.Nonce (uint64) (uint64) + case "Nonce": - c, err := cbg.ReadCid(br) + maj, extra, err = cbg.CborReadHeader(br) if err != nil { - return xerrors.Errorf("failed to read cid field t.FaultReportMsg: %w", err) + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Nonce = uint64(extra) + // t.Pieces ([]sealing.Piece) (slice) + case "Pieces": + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err } - t.FaultReportMsg = &c + if extra > cbg.MaxLength { + return fmt.Errorf("t.Pieces: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + if extra > 0 { + t.Pieces = make([]Piece, extra) + } + for i := 0; i < int(extra); i++ { + + var v Piece + if err := v.UnmarshalCBOR(br); err != nil { + return err + } + + t.Pieces[i] = v + } + + // t.CommD ([]uint8) (slice) + case "CommD": + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + + if extra > cbg.ByteArrayMaxLen { + return fmt.Errorf("t.CommD: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.CommD = make([]byte, extra) + if _, err := io.ReadFull(br, t.CommD); err != nil { + return err + } + // t.CommR ([]uint8) (slice) + case "CommR": + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + + if extra > cbg.ByteArrayMaxLen { + return fmt.Errorf("t.CommR: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.CommR = make([]byte, extra) + if _, err := io.ReadFull(br, t.CommR); err != nil { + return err + } + // t.Proof ([]uint8) (slice) + case "Proof": + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + + if extra > cbg.ByteArrayMaxLen { + return fmt.Errorf("t.Proof: byte 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.Ticket (sealing.SealTicket) (struct) + case "Ticket": + + { + + if err := t.Ticket.UnmarshalCBOR(br); err != nil { + return err + } + + } + // t.PreCommitMessage (cid.Cid) (struct) + case "PreCommitMessage": + + { + + 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 { + + c, err := cbg.ReadCid(br) + if err != nil { + return xerrors.Errorf("failed to read cid field t.PreCommitMessage: %w", err) + } + + t.PreCommitMessage = &c + } + + } + // t.Seed (sealing.SealSeed) (struct) + case "Seed": + + { + + if err := t.Seed.UnmarshalCBOR(br); err != nil { + return err + } + + } + // t.CommitMessage (cid.Cid) (struct) + case "CommitMessage": + + { + + 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 { + + c, err := cbg.ReadCid(br) + if err != nil { + return xerrors.Errorf("failed to read cid field t.CommitMessage: %w", err) + } + + t.CommitMessage = &c + } + + } + // t.FaultReportMsg (cid.Cid) (struct) + case "FaultReportMsg": + + { + + 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 { + + c, err := cbg.ReadCid(br) + if err != nil { + return xerrors.Errorf("failed to read cid field t.FaultReportMsg: %w", err) + } + + t.FaultReportMsg = &c + } + + } + // t.LastErr (string) (string) + case "LastErr": + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + t.LastErr = string(sval) + } + + default: } - - } - // t.LastErr (string) (string) - - { - sval, err := cbg.ReadString(br) - if err != nil { - return err - } - - name = string(sval) } - if name != "LastErr" { - return fmt.Errorf("expected struct map entry %s to be LastErr", name) - } - - { - sval, err := cbg.ReadString(br) - if err != nil { - return err - } - - t.LastErr = string(sval) - } return nil } diff --git a/fsm.go b/fsm.go index e470290a9..8c5f04c2f 100644 --- a/fsm.go +++ b/fsm.go @@ -236,6 +236,10 @@ func planOne(ts ...func() (mut mutator, next api.SectorState)) func(events []sta continue } + if err, iserr := events[0].User.(error); iserr { + log.Warnf("sector %d got error event %T: %+v", state.SectorID, events[0].User, err) + } + events[0].User.(mutator).apply(state) state.State = next return nil From 793bf7f5795d21abc80a82e3a931f2a1804968ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 21 Jan 2020 17:28:55 +0100 Subject: [PATCH 012/126] Update cbor-gen, error on unknown fields --- cbor_gen.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cbor_gen.go b/cbor_gen.go index 61ad5b606..1e48bc7d5 100644 --- a/cbor_gen.go +++ b/cbor_gen.go @@ -123,6 +123,7 @@ func (t *SealTicket) UnmarshalCBOR(r io.Reader) error { } default: + return fmt.Errorf("unknown struct field %d: '%s'", i, name) } } @@ -239,6 +240,7 @@ func (t *SealSeed) UnmarshalCBOR(r io.Reader) error { } default: + return fmt.Errorf("unknown struct field %d: '%s'", i, name) } } @@ -382,6 +384,7 @@ func (t *Piece) UnmarshalCBOR(r io.Reader) error { } default: + return fmt.Errorf("unknown struct field %d: '%s'", i, name) } } @@ -914,6 +917,7 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { } default: + return fmt.Errorf("unknown struct field %d: '%s'", i, name) } } From a77c19a60db44497f0ed59adae3cda07aea2ef58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 21 Jan 2020 19:51:17 +0100 Subject: [PATCH 013/126] Fix master build --- sealing.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sealing.go b/sealing.go index 7899415e8..3eeda978e 100644 --- a/sealing.go +++ b/sealing.go @@ -28,7 +28,7 @@ type TicketFn func(context.Context) (*sectorbuilder.SealTicket, error) type sealingApi interface { // TODO: trim down // Call a read only method on actors (no interaction with the chain required) - StateCall(ctx context.Context, msg *types.Message, ts *types.TipSet) (*types.MessageReceipt, error) + StateCall(context.Context, *types.Message, *types.TipSet) (*api.MethodCall, error) StateMinerWorker(context.Context, address.Address, *types.TipSet) (address.Address, error) StateMinerElectionPeriodStart(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error) StateMinerSectors(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error) From 3a2047dcd78cc19ef34e50bd3f3bd59dddfe2581 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 22 Jan 2020 03:41:39 +0100 Subject: [PATCH 014/126] sealing: Add Log field to SectorInfo --- cbor_gen.go | 273 +++++++++++++++++++++++++++++++++++++++++++++++++++- checks.go | 2 - types.go | 16 ++- 3 files changed, 285 insertions(+), 6 deletions(-) diff --git a/cbor_gen.go b/cbor_gen.go index 1e48bc7d5..e13bcf43a 100644 --- a/cbor_gen.go +++ b/cbor_gen.go @@ -395,7 +395,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { _, err := w.Write(cbg.CborNull) return err } - if _, err := w.Write([]byte{173}); err != nil { + if _, err := w.Write([]byte{174}); err != nil { return err } @@ -661,6 +661,31 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { if _, err := w.Write([]byte(t.LastErr)); err != nil { return err } + + // t.Log ([]sealing.Log) (slice) + if len("Log") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"Log\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Log")))); err != nil { + return err + } + if _, err := w.Write([]byte("Log")); err != nil { + return err + } + + if len(t.Log) > cbg.MaxLength { + return xerrors.Errorf("Slice value in field t.Log was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Log)))); err != nil { + return err + } + for _, v := range t.Log { + if err := v.MarshalCBOR(w); err != nil { + return err + } + } return nil } @@ -915,6 +940,252 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { t.LastErr = string(sval) } + // t.Log ([]sealing.Log) (slice) + case "Log": + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + + if extra > cbg.MaxLength { + return fmt.Errorf("t.Log: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + if extra > 0 { + t.Log = make([]Log, extra) + } + for i := 0; i < int(extra); i++ { + + var v Log + if err := v.UnmarshalCBOR(br); err != nil { + return err + } + + t.Log[i] = v + } + + default: + return fmt.Errorf("unknown struct field %d: '%s'", i, name) + } + } + + return nil +} +func (t *Log) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write([]byte{165}); err != nil { + return err + } + + // t.Timestamp (uint64) (uint64) + if len("Timestamp") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"Timestamp\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Timestamp")))); err != nil { + return err + } + if _, err := w.Write([]byte("Timestamp")); err != nil { + return err + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Timestamp))); err != nil { + return err + } + + // t.Trace (string) (string) + if len("Trace") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"Trace\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Trace")))); err != nil { + return err + } + if _, err := w.Write([]byte("Trace")); err != nil { + return err + } + + if len(t.Trace) > cbg.MaxLength { + return xerrors.Errorf("Value in field t.Trace was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.Trace)))); err != nil { + return err + } + if _, err := w.Write([]byte(t.Trace)); err != nil { + return err + } + + // t.Message (string) (string) + if len("Message") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"Message\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Message")))); err != nil { + return err + } + if _, err := w.Write([]byte("Message")); err != nil { + return err + } + + if len(t.Message) > cbg.MaxLength { + return xerrors.Errorf("Value in field t.Message was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.Message)))); err != nil { + return err + } + if _, err := w.Write([]byte(t.Message)); err != nil { + return err + } + + // t.Kind (string) (string) + if len("Kind") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"Kind\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Kind")))); err != nil { + return err + } + if _, err := w.Write([]byte("Kind")); err != nil { + return err + } + + if len(t.Kind) > cbg.MaxLength { + return xerrors.Errorf("Value in field t.Kind was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.Kind)))); err != nil { + return err + } + if _, err := w.Write([]byte(t.Kind)); err != nil { + return err + } + + // t.Params ([]uint8) (slice) + if len("Params") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"Params\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Params")))); err != nil { + return err + } + if _, err := w.Write([]byte("Params")); err != nil { + return err + } + + if len(t.Params) > cbg.ByteArrayMaxLen { + return xerrors.Errorf("Byte array in field t.Params was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Params)))); err != nil { + return err + } + if _, err := w.Write(t.Params); err != nil { + return err + } + return nil +} + +func (t *Log) UnmarshalCBOR(r io.Reader) error { + br := cbg.GetPeeker(r) + + maj, extra, err := cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("Log: map struct too large (%d)", extra) + } + + var name string + n := extra + + for i := uint64(0); i < n; i++ { + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + name = string(sval) + } + + switch name { + // t.Timestamp (uint64) (uint64) + case "Timestamp": + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Timestamp = uint64(extra) + // t.Trace (string) (string) + case "Trace": + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + t.Trace = string(sval) + } + // t.Message (string) (string) + case "Message": + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + t.Message = string(sval) + } + // t.Kind (string) (string) + case "Kind": + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + t.Kind = string(sval) + } + // t.Params ([]uint8) (slice) + case "Params": + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + + if extra > cbg.ByteArrayMaxLen { + return fmt.Errorf("t.Params: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.Params = make([]byte, extra) + if _, err := io.ReadFull(br, t.Params); err != nil { + return err + } default: return fmt.Errorf("unknown struct field %d: '%s'", i, name) diff --git a/checks.go b/checks.go index 05647de6c..9e12bf943 100644 --- a/checks.go +++ b/checks.go @@ -63,11 +63,9 @@ func checkSeal(ctx context.Context, maddr address.Address, si *SectorInfo, api s return xerrors.Errorf("on chain CommD differs from sector: %x != %x", r.Return, si.CommD) } - // TODO: Validate ticket // TODO: Verify commp / commr / proof // TODO: (StateCall PreCommit) return nil - } diff --git a/types.go b/types.go index 096e83d08..ae8d7ac23 100644 --- a/types.go +++ b/types.go @@ -2,9 +2,8 @@ package sealing import ( sectorbuilder "github.com/filecoin-project/go-sectorbuilder" - "github.com/ipfs/go-cid" - "github.com/filecoin-project/lotus/api" + "github.com/ipfs/go-cid" ) type SealTicket struct { @@ -46,6 +45,17 @@ func (p *Piece) ppi() (out sectorbuilder.PublicPieceInfo) { return out } +type Log struct { + Timestamp uint64 + Trace string // for errors + + Message string + + // additional data (Event info) + Kind string + Params []byte +} + type SectorInfo struct { State api.SectorState SectorID uint64 @@ -75,7 +85,7 @@ type SectorInfo struct { // Debug LastErr string - // TODO: Log []struct{ts, msg, trace string} + Log []Log } func (t *SectorInfo) pieceInfos() []sectorbuilder.PublicPieceInfo { From 032b2d877c6975c6c8a74a1bdd3291efae7610af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 22 Jan 2020 19:30:56 +0100 Subject: [PATCH 015/126] sealing: Fix planOne for global events --- checks.go | 3 --- fsm.go | 7 ++++++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/checks.go b/checks.go index 9e12bf943..e6ee9f7e8 100644 --- a/checks.go +++ b/checks.go @@ -63,9 +63,6 @@ func checkSeal(ctx context.Context, maddr address.Address, si *SectorInfo, api s return xerrors.Errorf("on chain CommD differs from sector: %x != %x", r.Return, si.CommD) } - // TODO: Validate ticket - // TODO: Verify commp / commr / proof - // TODO: (StateCall PreCommit) return nil } diff --git a/fsm.go b/fsm.go index 7e46b6eb5..ce4e74408 100644 --- a/fsm.go +++ b/fsm.go @@ -229,6 +229,11 @@ func planOne(ts ...func() (mut mutator, next api.SectorState)) func(events []sta return xerrors.Errorf("planner for state %s only has a plan for a single event only, got %+v", api.SectorStates[state.State], events) } + if gm, ok := events[0].User.(globalMutator); !ok { + gm.applyGlobal(state) + return nil + } + for _, t := range ts { mut, next := t() @@ -245,6 +250,6 @@ func planOne(ts ...func() (mut mutator, next api.SectorState)) func(events []sta return nil } - return xerrors.Errorf("planner for state %s received unexpected event %+v", api.SectorStates[state.State], events[0]) + return xerrors.Errorf("planner for state %s received unexpected event %T (%+v)", api.SectorStates[state.State], events[0].User, events[0]) } } From 7463ee72d0f7c3ec039d0aa4d48354568dc66ef3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 22 Jan 2020 20:47:29 +0100 Subject: [PATCH 016/126] sealing: wire up checkPieces and checkSeal --- checks.go | 8 ++++---- fsm.go | 6 ++++-- fsm_events.go | 4 ++++ states.go | 8 ++++++++ 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/checks.go b/checks.go index e6ee9f7e8..a14099c12 100644 --- a/checks.go +++ b/checks.go @@ -10,7 +10,7 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) -func checkPieces(ctx context.Context, si *SectorInfo, api sealingApi) error { +func checkPieces(ctx context.Context, si SectorInfo, api sealingApi) error { for i, piece := range si.Pieces { deal, err := api.StateMarketStorageDeal(ctx, piece.DealID, nil) if err != nil { @@ -29,7 +29,7 @@ func checkPieces(ctx context.Context, si *SectorInfo, api sealingApi) error { return nil } -func checkSeal(ctx context.Context, maddr address.Address, si *SectorInfo, api sealingApi) (err error) { +func checkSeal(ctx context.Context, maddr address.Address, si SectorInfo, api sealingApi) (err error) { ssize, err := api.StateMinerSectorSize(ctx, maddr, nil) if err != nil { return err @@ -45,7 +45,7 @@ func checkSeal(ctx context.Context, maddr address.Address, si *SectorInfo, api s ccmt := &types.Message{ To: actors.StorageMarketAddress, - From: actors.StorageMarketAddress, + From: maddr, Value: types.NewInt(0), GasPrice: types.NewInt(0), GasLimit: types.NewInt(9999999999), @@ -57,7 +57,7 @@ func checkSeal(ctx context.Context, maddr address.Address, si *SectorInfo, api s return xerrors.Errorf("calling ComputeDataCommitment: %w", err) } if r.ExitCode != 0 { - return xerrors.Errorf("receipt for ComputeDataCommitment han exit code %d", r.ExitCode) + return xerrors.Errorf("receipt for ComputeDataCommitment had exit code %d", r.ExitCode) } if string(r.Return) != string(si.CommD) { return xerrors.Errorf("on chain CommD differs from sector: %x != %x", r.Return, si.CommD) diff --git a/fsm.go b/fsm.go index ce4e74408..ba2702696 100644 --- a/fsm.go +++ b/fsm.go @@ -34,8 +34,10 @@ var fsmPlanners = []func(events []statemachine.Event, state *SectorInfo) error{ api.Unsealed: planOne( on(SectorSealed{}, api.PreCommitting), on(SectorSealFailed{}, api.SealFailed), + on(SectorPackingFailed{}, api.PackingFailed), ), api.PreCommitting: planOne( + on(SectorSealFailed{}, api.SealFailed), on(SectorPreCommitted{}, api.WaitSeed), on(SectorPreCommitFailed{}, api.PreCommitFailed), ), @@ -221,7 +223,7 @@ func planOne(ts ...func() (mut mutator, next api.SectorState)) func(events []sta return func(events []statemachine.Event, state *SectorInfo) error { if len(events) != 1 { for _, event := range events { - if gm, ok := event.User.(globalMutator); !ok { + if gm, ok := event.User.(globalMutator); ok { gm.applyGlobal(state) return nil } @@ -229,7 +231,7 @@ func planOne(ts ...func() (mut mutator, next api.SectorState)) func(events []sta return xerrors.Errorf("planner for state %s only has a plan for a single event only, got %+v", api.SectorStates[state.State], events) } - if gm, ok := events[0].User.(globalMutator); !ok { + if gm, ok := events[0].User.(globalMutator); ok { gm.applyGlobal(state) return nil } diff --git a/fsm_events.go b/fsm_events.go index 12c47f046..d25668da2 100644 --- a/fsm_events.go +++ b/fsm_events.go @@ -60,6 +60,10 @@ func (evt SectorPacked) apply(state *SectorInfo) { state.Pieces = append(state.Pieces, evt.pieces...) } +type SectorPackingFailed struct{ error } + +func (evt SectorPackingFailed) apply(*SectorInfo) {} + type SectorSealed struct { commR []byte commD []byte diff --git a/states.go b/states.go index ad4a8f542..219e26475 100644 --- a/states.go +++ b/states.go @@ -44,6 +44,10 @@ func (m *Sealing) handlePacking(ctx statemachine.Context, sector SectorInfo) err } func (m *Sealing) handleUnsealed(ctx statemachine.Context, sector SectorInfo) error { + if err := checkPieces(ctx.Context(), sector, m.api); err != nil { // Sanity check state + return ctx.Send(SectorPackingFailed{xerrors.Errorf("checkPieces error: %w", err)}) + } + log.Infow("performing sector replication...", "sector", sector.SectorID) ticket, err := m.tktFn(ctx.Context()) if err != nil { @@ -66,6 +70,10 @@ func (m *Sealing) handleUnsealed(ctx statemachine.Context, sector SectorInfo) er } func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInfo) error { + if err := checkSeal(ctx.Context(), m.maddr, sector, m.api); err != nil { + return ctx.Send(SectorSealFailed{xerrors.Errorf("checkPieces error: %w", err)}) + } + params := &actors.SectorPreCommitInfo{ SectorNumber: sector.SectorID, From ee34cf612f979f418f022d9c0484dbb45a6da457 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 22 Jan 2020 21:29:19 +0100 Subject: [PATCH 017/126] sealing: Wire up sector event log --- cbor_gen.go | 43 +------------------------------------------ fsm.go | 16 ++++++++++++++++ types.go | 1 - 3 files changed, 17 insertions(+), 43 deletions(-) diff --git a/cbor_gen.go b/cbor_gen.go index e13bcf43a..f83d35990 100644 --- a/cbor_gen.go +++ b/cbor_gen.go @@ -980,7 +980,7 @@ func (t *Log) MarshalCBOR(w io.Writer) error { _, err := w.Write(cbg.CborNull) return err } - if _, err := w.Write([]byte{165}); err != nil { + if _, err := w.Write([]byte{164}); err != nil { return err } @@ -1068,29 +1068,6 @@ func (t *Log) MarshalCBOR(w io.Writer) error { if _, err := w.Write([]byte(t.Kind)); err != nil { return err } - - // t.Params ([]uint8) (slice) - if len("Params") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"Params\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Params")))); err != nil { - return err - } - if _, err := w.Write([]byte("Params")); err != nil { - return err - } - - if len(t.Params) > cbg.ByteArrayMaxLen { - return xerrors.Errorf("Byte array in field t.Params was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Params)))); err != nil { - return err - } - if _, err := w.Write(t.Params); err != nil { - return err - } return nil } @@ -1168,24 +1145,6 @@ func (t *Log) UnmarshalCBOR(r io.Reader) error { t.Kind = string(sval) } - // t.Params ([]uint8) (slice) - case "Params": - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.ByteArrayMaxLen { - return fmt.Errorf("t.Params: byte array too large (%d)", extra) - } - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") - } - t.Params = make([]byte, extra) - if _, err := io.ReadFull(br, t.Params); err != nil { - return err - } default: return fmt.Errorf("unknown struct field %d: '%s'", i, name) diff --git a/fsm.go b/fsm.go index ba2702696..fced052aa 100644 --- a/fsm.go +++ b/fsm.go @@ -2,7 +2,9 @@ package sealing import ( "context" + "fmt" "reflect" + "time" "golang.org/x/xerrors" @@ -66,6 +68,20 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta ///// // First process all events + for _, event := range events { + l := Log{ + Timestamp: uint64(time.Now().Unix()), + Message: fmt.Sprintf("%+v", event), + Kind: fmt.Sprintf("event;%T", event.User), + } + + if err, iserr := event.User.(xerrors.Formatter); iserr { + l.Trace = fmt.Sprintf("%+v", err) + } + + state.Log = append(state.Log, l) + } + p := fsmPlanners[state.State] if p == nil { return nil, xerrors.Errorf("planner for state %d not found", state.State) diff --git a/types.go b/types.go index ae8d7ac23..952c5ec22 100644 --- a/types.go +++ b/types.go @@ -53,7 +53,6 @@ type Log struct { // additional data (Event info) Kind string - Params []byte } type SectorInfo struct { From c80099173ec61859443b30451f3b514c12274f67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 22 Jan 2020 22:16:45 +0100 Subject: [PATCH 018/126] sealing: Not getting seal ticket isn't fatal --- states.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/states.go b/states.go index 219e26475..cb6c03811 100644 --- a/states.go +++ b/states.go @@ -51,7 +51,7 @@ func (m *Sealing) handleUnsealed(ctx statemachine.Context, sector SectorInfo) er log.Infow("performing sector replication...", "sector", sector.SectorID) ticket, err := m.tktFn(ctx.Context()) if err != nil { - return err + return ctx.Send(SectorSealFailed{xerrors.Errorf("getting ticket failed: %w", err)}) } rspco, err := m.sb.SealPreCommit(ctx.Context(), sector.SectorID, *ticket, sector.pieceInfos()) From 08a5030b46657c034e0a79207ab6a57f58f1b0f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 23 Jan 2020 11:02:20 +0100 Subject: [PATCH 019/126] sealing: Nonzero exit on commit isn't fatal --- states.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/states.go b/states.go index cb6c03811..754e88d04 100644 --- a/states.go +++ b/states.go @@ -206,8 +206,7 @@ func (m *Sealing) handleCommitWait(ctx statemachine.Context, sector SectorInfo) } if mw.Receipt.ExitCode != 0 { - log.Errorf("UNHANDLED: submitting sector proof failed (exit=%d, msg=%s) (t:%x; s:%x(%d); p:%x)", mw.Receipt.ExitCode, sector.CommitMessage, sector.Ticket.TicketBytes, sector.Seed.TicketBytes, sector.Seed.BlockHeight, sector.Proof) - return xerrors.Errorf("UNHANDLED: submitting sector proof failed (exit: %d)", mw.Receipt.ExitCode) + return ctx.Send(SectorCommitFailed{xerrors.Errorf("submitting sector proof failed (exit=%d, msg=%s) (t:%x; s:%x(%d); p:%x)", mw.Receipt.ExitCode, sector.CommitMessage, sector.Ticket.TicketBytes, sector.Seed.TicketBytes, sector.Seed.BlockHeight, sector.Proof)}) } return ctx.Send(SectorProving{}) From 2aa9b16dbccbc28be1a4c8ab38d8c4c9ca8fb4b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 23 Jan 2020 13:17:45 +0100 Subject: [PATCH 020/126] sealing: check deal expiration --- checks.go | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/checks.go b/checks.go index a14099c12..01960a09f 100644 --- a/checks.go +++ b/checks.go @@ -10,19 +10,33 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) +type ErrApi error + +type ErrInvalidDeals error +type ErrExpiredDeals error + func checkPieces(ctx context.Context, si SectorInfo, api sealingApi) error { + head, err := api.ChainHead(ctx) + if err != nil { + return ErrApi(xerrors.Errorf("getting chain head: %w", err)) + } + for i, piece := range si.Pieces { deal, err := api.StateMarketStorageDeal(ctx, piece.DealID, nil) if err != nil { - return xerrors.Errorf("getting deal %d for piece %d: %w", piece.DealID, i, err) + return ErrApi(xerrors.Errorf("getting deal %d for piece %d: %w", piece.DealID, i, err)) } if string(deal.PieceRef) != string(piece.CommP) { - return xerrors.Errorf("piece %d of sector %d refers deal %d with wrong CommP: %x != %x", i, si.SectorID, piece.DealID, piece.CommP, deal.PieceRef) + return ErrInvalidDeals(xerrors.Errorf("piece %d of sector %d refers deal %d with wrong CommP: %x != %x", i, si.SectorID, piece.DealID, piece.CommP, deal.PieceRef)) } if piece.Size != deal.PieceSize { - return xerrors.Errorf("piece %d of sector %d refers deal %d with different size: %d != %d", i, si.SectorID, piece.DealID, piece.Size, deal.PieceSize) + return ErrInvalidDeals(xerrors.Errorf("piece %d of sector %d refers deal %d with different size: %d != %d", i, si.SectorID, piece.DealID, piece.Size, deal.PieceSize)) + } + + if head.Height() >= deal.ProposalExpiration { + return ErrExpiredDeals(xerrors.Errorf("piece %d of sector %d refers expired deal %d - expires %d, head %d", i, si.SectorID, piece.DealID, deal.ProposalExpiration, head.Height())) } } From 9d0d15d51cacbd2aa871cfd2878555667c6e9314 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 23 Jan 2020 15:05:44 +0100 Subject: [PATCH 021/126] sealing: Check ticket expiration --- checks.go | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/checks.go b/checks.go index 01960a09f..bc95ba0fd 100644 --- a/checks.go +++ b/checks.go @@ -6,6 +6,8 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/go-address" + + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/types" ) @@ -15,6 +17,9 @@ type ErrApi error type ErrInvalidDeals error type ErrExpiredDeals error +type ErrBadCommD error +type ErrExpiredTicket error + func checkPieces(ctx context.Context, si SectorInfo, api sealingApi) error { head, err := api.ChainHead(ctx) if err != nil { @@ -44,9 +49,14 @@ func checkPieces(ctx context.Context, si SectorInfo, api sealingApi) error { } func checkSeal(ctx context.Context, maddr address.Address, si SectorInfo, api sealingApi) (err error) { - ssize, err := api.StateMinerSectorSize(ctx, maddr, nil) + head, err := api.ChainHead(ctx) if err != nil { - return err + return ErrApi(xerrors.Errorf("getting chain head: %w", err)) + } + + ssize, err := api.StateMinerSectorSize(ctx, maddr, head) + if err != nil { + return ErrApi(err) } ccparams, err := actors.SerializeParams(&actors.ComputeDataCommitmentParams{ @@ -71,10 +81,14 @@ func checkSeal(ctx context.Context, maddr address.Address, si SectorInfo, api se return xerrors.Errorf("calling ComputeDataCommitment: %w", err) } if r.ExitCode != 0 { - return xerrors.Errorf("receipt for ComputeDataCommitment had exit code %d", r.ExitCode) + return ErrBadCommD(xerrors.Errorf("receipt for ComputeDataCommitment had exit code %d", r.ExitCode)) } if string(r.Return) != string(si.CommD) { - return xerrors.Errorf("on chain CommD differs from sector: %x != %x", r.Return, si.CommD) + return ErrBadCommD(xerrors.Errorf("on chain CommD differs from sector: %x != %x", r.Return, si.CommD)) + } + + if int64(head.Height()) - int64(si.Ticket.BlockHeight + build.SealRandomnessLookback) > build.SealRandomnessLookbackLimit { + return ErrExpiredTicket(xerrors.Errorf("ticket expired: seal height: %d, head: %d", si.Ticket.BlockHeight + build.SealRandomnessLookback, head.Height())) } return nil From 3ec83f23185f419a2bfaa24f4b68d62bf462e485 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 23 Jan 2020 15:18:05 +0100 Subject: [PATCH 022/126] storageminer: log flag for sector status --- checks.go | 4 ++-- types.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/checks.go b/checks.go index bc95ba0fd..3ec86b9f3 100644 --- a/checks.go +++ b/checks.go @@ -87,8 +87,8 @@ func checkSeal(ctx context.Context, maddr address.Address, si SectorInfo, api se return ErrBadCommD(xerrors.Errorf("on chain CommD differs from sector: %x != %x", r.Return, si.CommD)) } - if int64(head.Height()) - int64(si.Ticket.BlockHeight + build.SealRandomnessLookback) > build.SealRandomnessLookbackLimit { - return ErrExpiredTicket(xerrors.Errorf("ticket expired: seal height: %d, head: %d", si.Ticket.BlockHeight + build.SealRandomnessLookback, head.Height())) + if int64(head.Height())-int64(si.Ticket.BlockHeight+build.SealRandomnessLookback) > build.SealRandomnessLookbackLimit { + return ErrExpiredTicket(xerrors.Errorf("ticket expired: seal height: %d, head: %d", si.Ticket.BlockHeight+build.SealRandomnessLookback, head.Height())) } return nil diff --git a/types.go b/types.go index 952c5ec22..f0fbe09a4 100644 --- a/types.go +++ b/types.go @@ -52,7 +52,7 @@ type Log struct { Message string // additional data (Event info) - Kind string + Kind string } type SectorInfo struct { From 2715ff763fbb7ca34c3e4dde63e90f3f3bd5446e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 23 Jan 2020 16:38:01 +0100 Subject: [PATCH 023/126] sealing: implement handler for sealFailed --- checks.go | 4 +++- fsm.go | 6 +++++- fsm_events.go | 8 +++++++ sealing.go | 1 + states.go | 24 +++++++++++++++++++-- states_failed.go | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 94 insertions(+), 4 deletions(-) create mode 100644 states_failed.go diff --git a/checks.go b/checks.go index 3ec86b9f3..491e330b0 100644 --- a/checks.go +++ b/checks.go @@ -12,6 +12,8 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) +// TODO: For now we handle this by halting state execution, when we get jsonrpc reconnecting +// We should implement some wait-for-api logic type ErrApi error type ErrInvalidDeals error @@ -78,7 +80,7 @@ func checkSeal(ctx context.Context, maddr address.Address, si SectorInfo, api se } r, err := api.StateCall(ctx, ccmt, nil) if err != nil { - return xerrors.Errorf("calling ComputeDataCommitment: %w", err) + return ErrApi(xerrors.Errorf("calling ComputeDataCommitment: %w", err)) } if r.ExitCode != 0 { return ErrBadCommD(xerrors.Errorf("receipt for ComputeDataCommitment had exit code %d", r.ExitCode)) diff --git a/fsm.go b/fsm.go index fced052aa..d6bd4160e 100644 --- a/fsm.go +++ b/fsm.go @@ -58,6 +58,10 @@ var fsmPlanners = []func(events []statemachine.Event, state *SectorInfo) error{ on(SectorFaulty{}, api.Faulty), ), + api.SealFailed: planOne( + on(SectorRetrySeal{}, api.Unsealed), + ), + api.Faulty: planOne( on(SectorFaultReported{}, api.FaultReported), ), @@ -84,7 +88,7 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta p := fsmPlanners[state.State] if p == nil { - return nil, xerrors.Errorf("planner for state %d not found", state.State) + return nil, xerrors.Errorf("planner for state %s not found", state.State, api.SectorStates[state.State]) } if err := p(events, state); err != nil { diff --git a/fsm_events.go b/fsm_events.go index d25668da2..948a1653b 100644 --- a/fsm_events.go +++ b/fsm_events.go @@ -120,6 +120,14 @@ type SectorProving struct{} func (evt SectorProving) apply(*SectorInfo) {} +// Failed state recovery + +type SectorRetrySeal struct{} + +func (evt SectorRetrySeal) apply(state *SectorInfo) {} + +// Faults + type SectorFaulty struct{} func (evt SectorFaulty) apply(state *SectorInfo) {} diff --git a/sealing.go b/sealing.go index 6d235488e..45034047e 100644 --- a/sealing.go +++ b/sealing.go @@ -39,6 +39,7 @@ type sealingApi interface { // TODO: trim down StateGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error) StateGetReceipt(context.Context, cid.Cid, *types.TipSet) (*types.MessageReceipt, error) StateMarketStorageDeal(context.Context, uint64, *types.TipSet) (*actors.OnChainDeal, error) + StateReadState(ctx context.Context, act *types.Actor, ts *types.TipSet) (*api.ActorState, error) MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error) diff --git a/states.go b/states.go index 754e88d04..81c3549df 100644 --- a/states.go +++ b/states.go @@ -45,7 +45,17 @@ func (m *Sealing) handlePacking(ctx statemachine.Context, sector SectorInfo) err func (m *Sealing) handleUnsealed(ctx statemachine.Context, sector SectorInfo) error { if err := checkPieces(ctx.Context(), sector, m.api); err != nil { // Sanity check state - return ctx.Send(SectorPackingFailed{xerrors.Errorf("checkPieces error: %w", err)}) + switch err.(type) { + case ErrApi: + log.Errorf("handleUnsealed: api error, not proceeding: %+v", err) + return nil + case ErrInvalidDeals: + return ctx.Send(SectorPackingFailed{xerrors.Errorf("invalid deals in sector: %w", err)}) + case ErrExpiredDeals: // Probably not much we can do here, maybe re-pack the sector? + return ctx.Send(SectorPackingFailed{xerrors.Errorf("expired deals in sector: %w", err)}) + default: + return xerrors.Errorf("checkPieces sanity check error: %w", err) + } } log.Infow("performing sector replication...", "sector", sector.SectorID) @@ -71,7 +81,17 @@ func (m *Sealing) handleUnsealed(ctx statemachine.Context, sector SectorInfo) er func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInfo) error { if err := checkSeal(ctx.Context(), m.maddr, sector, m.api); err != nil { - return ctx.Send(SectorSealFailed{xerrors.Errorf("checkPieces error: %w", err)}) + switch err.(type) { + case ErrApi: + log.Errorf("handlePreCommitting: api error, not proceeding: %+v", err) + return nil + case ErrBadCommD: // TODO: Should this just back to packing? (not really needed since handleUnsealed will do that too) + return ctx.Send(SectorSealFailed{xerrors.Errorf("bad CommD error: %w", err)}) + case ErrExpiredTicket: + return ctx.Send(SectorSealFailed{xerrors.Errorf("bad CommD error: %w", err)}) + default: + return xerrors.Errorf("checkSeal sanity check error: %w", err) + } } params := &actors.SectorPreCommitInfo{ diff --git a/states_failed.go b/states_failed.go new file mode 100644 index 000000000..5d125c2be --- /dev/null +++ b/states_failed.go @@ -0,0 +1,55 @@ +package sealing + +import ( + "fmt" + "time" + + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/lib/statemachine" +) + +const minRetryTime = 1 * time.Minute + +func failedCooldown(ctx statemachine.Context, sector SectorInfo) error { + retryStart := time.Unix(int64(sector.Log[len(sector.Log)-1].Timestamp), 0).Add(minRetryTime) + if len(sector.Log) > 0 && !time.Now().After(retryStart) { + log.Infof("%s(%d), waiting %s before retrying", api.SectorStates[sector.State], time.Until(retryStart)) + select { + case <-time.After(time.Until(retryStart)): + case <-ctx.Context().Done(): + return ctx.Context().Err() + } + } + + return nil +} + +func (m *Sealing) handleSealFailed(ctx statemachine.Context, sector SectorInfo) error { + // TODO: + + act, err := m.api.StateGetActor(ctx.Context(), m.maddr, nil) + if err != nil { + log.Errorf("handleSealFailed(%d): temp error: %+v", sector.SectorID, err) + return nil + } + + st, err := m.api.StateReadState(ctx.Context(), act, nil) + if err != nil { + log.Errorf("handleSealFailed(%d): temp error: %+v", sector.SectorID, err) + return nil + } + + _, found := st.State.(map[string]interface{})["PreCommittedSectors"].(map[string]interface{})[fmt.Sprint(sector.SectorID)] + if found { + // TODO: If not expired yet, we can just try reusing sealticket + log.Errorf("sector found in miner preseal array: %+v", sector.SectorID, err) + return nil + } + // + + if err := failedCooldown(ctx, sector); err != nil { + return err + } + + return ctx.Send(SectorRetrySeal{}) +} From 74095b25c574ffc91c4f68fb91dc176de3f2a703 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 23 Jan 2020 16:47:33 +0100 Subject: [PATCH 024/126] sealing: Actually call handleSealFailed --- fsm.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fsm.go b/fsm.go index d6bd4160e..e105a328e 100644 --- a/fsm.go +++ b/fsm.go @@ -88,7 +88,7 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta p := fsmPlanners[state.State] if p == nil { - return nil, xerrors.Errorf("planner for state %s not found", state.State, api.SectorStates[state.State]) + return nil, xerrors.Errorf("planner for state %s not found", api.SectorStates[state.State]) } if err := p(events, state); err != nil { @@ -152,7 +152,7 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta // Handled failure modes case api.SealFailed: - log.Warnf("sector %d entered unimplemented state 'SealFailed'", state.SectorID) + return m.handleSealFailed, nil case api.PreCommitFailed: log.Warnf("sector %d entered unimplemented state 'PreCommitFailed'", state.SectorID) case api.SealCommitFailed: From 82343460dd0690c7867d480d7b9c9711563392cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 23 Jan 2020 16:57:14 +0100 Subject: [PATCH 025/126] sealing: Error types that can actually be checked --- checks.go | 32 ++++++++++++++++---------------- states_failed.go | 2 +- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/checks.go b/checks.go index 491e330b0..18e48faed 100644 --- a/checks.go +++ b/checks.go @@ -14,36 +14,36 @@ import ( // TODO: For now we handle this by halting state execution, when we get jsonrpc reconnecting // We should implement some wait-for-api logic -type ErrApi error +type ErrApi struct{error} -type ErrInvalidDeals error -type ErrExpiredDeals error +type ErrInvalidDeals struct{error} +type ErrExpiredDeals struct{error} -type ErrBadCommD error -type ErrExpiredTicket error +type ErrBadCommD struct{error} +type ErrExpiredTicket struct{error} func checkPieces(ctx context.Context, si SectorInfo, api sealingApi) error { head, err := api.ChainHead(ctx) if err != nil { - return ErrApi(xerrors.Errorf("getting chain head: %w", err)) + return &ErrApi{xerrors.Errorf("getting chain head: %w", err)} } for i, piece := range si.Pieces { deal, err := api.StateMarketStorageDeal(ctx, piece.DealID, nil) if err != nil { - return ErrApi(xerrors.Errorf("getting deal %d for piece %d: %w", piece.DealID, i, err)) + return &ErrApi{xerrors.Errorf("getting deal %d for piece %d: %w", piece.DealID, i, err)} } if string(deal.PieceRef) != string(piece.CommP) { - return ErrInvalidDeals(xerrors.Errorf("piece %d of sector %d refers deal %d with wrong CommP: %x != %x", i, si.SectorID, piece.DealID, piece.CommP, deal.PieceRef)) + return &ErrInvalidDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers deal %d with wrong CommP: %x != %x", i, len(si.Pieces), si.SectorID, piece.DealID, piece.CommP, deal.PieceRef)} } if piece.Size != deal.PieceSize { - return ErrInvalidDeals(xerrors.Errorf("piece %d of sector %d refers deal %d with different size: %d != %d", i, si.SectorID, piece.DealID, piece.Size, deal.PieceSize)) + return &ErrInvalidDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers deal %d with different size: %d != %d", i, len(si.Pieces), si.SectorID, piece.DealID, piece.Size, deal.PieceSize)} } if head.Height() >= deal.ProposalExpiration { - return ErrExpiredDeals(xerrors.Errorf("piece %d of sector %d refers expired deal %d - expires %d, head %d", i, si.SectorID, piece.DealID, deal.ProposalExpiration, head.Height())) + return &ErrExpiredDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers expired deal %d - expires %d, head %d", i, len(si.Pieces), si.SectorID, piece.DealID, deal.ProposalExpiration, head.Height())} } } @@ -53,12 +53,12 @@ func checkPieces(ctx context.Context, si SectorInfo, api sealingApi) error { func checkSeal(ctx context.Context, maddr address.Address, si SectorInfo, api sealingApi) (err error) { head, err := api.ChainHead(ctx) if err != nil { - return ErrApi(xerrors.Errorf("getting chain head: %w", err)) + return &ErrApi{xerrors.Errorf("getting chain head: %w", err)} } ssize, err := api.StateMinerSectorSize(ctx, maddr, head) if err != nil { - return ErrApi(err) + return &ErrApi{err} } ccparams, err := actors.SerializeParams(&actors.ComputeDataCommitmentParams{ @@ -80,17 +80,17 @@ func checkSeal(ctx context.Context, maddr address.Address, si SectorInfo, api se } r, err := api.StateCall(ctx, ccmt, nil) if err != nil { - return ErrApi(xerrors.Errorf("calling ComputeDataCommitment: %w", err)) + return &ErrApi{xerrors.Errorf("calling ComputeDataCommitment: %w", err)} } if r.ExitCode != 0 { - return ErrBadCommD(xerrors.Errorf("receipt for ComputeDataCommitment had exit code %d", r.ExitCode)) + return &ErrBadCommD{xerrors.Errorf("receipt for ComputeDataCommitment had exit code %d", r.ExitCode)} } if string(r.Return) != string(si.CommD) { - return ErrBadCommD(xerrors.Errorf("on chain CommD differs from sector: %x != %x", r.Return, si.CommD)) + return &ErrBadCommD{xerrors.Errorf("on chain CommD differs from sector: %x != %x", r.Return, si.CommD)} } if int64(head.Height())-int64(si.Ticket.BlockHeight+build.SealRandomnessLookback) > build.SealRandomnessLookbackLimit { - return ErrExpiredTicket(xerrors.Errorf("ticket expired: seal height: %d, head: %d", si.Ticket.BlockHeight+build.SealRandomnessLookback, head.Height())) + return &ErrExpiredTicket{xerrors.Errorf("ticket expired: seal height: %d, head: %d", si.Ticket.BlockHeight+build.SealRandomnessLookback, head.Height())} } return nil diff --git a/states_failed.go b/states_failed.go index 5d125c2be..8582471e7 100644 --- a/states_failed.go +++ b/states_failed.go @@ -13,7 +13,7 @@ const minRetryTime = 1 * time.Minute func failedCooldown(ctx statemachine.Context, sector SectorInfo) error { retryStart := time.Unix(int64(sector.Log[len(sector.Log)-1].Timestamp), 0).Add(minRetryTime) if len(sector.Log) > 0 && !time.Now().After(retryStart) { - log.Infof("%s(%d), waiting %s before retrying", api.SectorStates[sector.State], time.Until(retryStart)) + log.Infof("%s(%d), waiting %s before retrying", api.SectorStates[sector.State], sector.SectorID, time.Until(retryStart)) select { case <-time.After(time.Until(retryStart)): case <-ctx.Context().Done(): From 54289225e8d3aa8f789efddfc8d75360756ca6cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 23 Jan 2020 17:02:55 +0100 Subject: [PATCH 026/126] sealing: Errors are hard --- states.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/states.go b/states.go index 81c3549df..519245e03 100644 --- a/states.go +++ b/states.go @@ -46,12 +46,12 @@ func (m *Sealing) handlePacking(ctx statemachine.Context, sector SectorInfo) err func (m *Sealing) handleUnsealed(ctx statemachine.Context, sector SectorInfo) error { if err := checkPieces(ctx.Context(), sector, m.api); err != nil { // Sanity check state switch err.(type) { - case ErrApi: + case *ErrApi: log.Errorf("handleUnsealed: api error, not proceeding: %+v", err) return nil - case ErrInvalidDeals: + case *ErrInvalidDeals: return ctx.Send(SectorPackingFailed{xerrors.Errorf("invalid deals in sector: %w", err)}) - case ErrExpiredDeals: // Probably not much we can do here, maybe re-pack the sector? + case *ErrExpiredDeals: // Probably not much we can do here, maybe re-pack the sector? return ctx.Send(SectorPackingFailed{xerrors.Errorf("expired deals in sector: %w", err)}) default: return xerrors.Errorf("checkPieces sanity check error: %w", err) @@ -82,12 +82,12 @@ func (m *Sealing) handleUnsealed(ctx statemachine.Context, sector SectorInfo) er func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInfo) error { if err := checkSeal(ctx.Context(), m.maddr, sector, m.api); err != nil { switch err.(type) { - case ErrApi: + case *ErrApi: log.Errorf("handlePreCommitting: api error, not proceeding: %+v", err) return nil - case ErrBadCommD: // TODO: Should this just back to packing? (not really needed since handleUnsealed will do that too) + case *ErrBadCommD: // TODO: Should this just back to packing? (not really needed since handleUnsealed will do that too) return ctx.Send(SectorSealFailed{xerrors.Errorf("bad CommD error: %w", err)}) - case ErrExpiredTicket: + case *ErrExpiredTicket: return ctx.Send(SectorSealFailed{xerrors.Errorf("bad CommD error: %w", err)}) default: return xerrors.Errorf("checkSeal sanity check error: %w", err) From 943197e65cc5bc9e49a599bffda19823c33a522b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 23 Jan 2020 17:11:58 +0100 Subject: [PATCH 027/126] sealing: Don't infinite-loop on fatal errors --- fsm.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fsm.go b/fsm.go index e105a328e..3d3253072 100644 --- a/fsm.go +++ b/fsm.go @@ -21,9 +21,8 @@ func (m *Sealing) Plan(events []statemachine.Event, user interface{}) (interface return func(ctx statemachine.Context, si SectorInfo) error { err := next(ctx, si) if err != nil { - if err := ctx.Send(SectorFatalError{error: err}); err != nil { - return xerrors.Errorf("error while sending error: reporting %+v: %w", err, err) - } + log.Errorf("unhandled sector error (%d): %+v", si.SectorID, err) + return nil } return nil From ddf5cce6dd4a12656e5f3e625c2e23fe8289eff1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 23 Jan 2020 17:15:45 +0100 Subject: [PATCH 028/126] storageminer: Use tabwriter in sectors list --- checks.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/checks.go b/checks.go index 18e48faed..94ad95771 100644 --- a/checks.go +++ b/checks.go @@ -14,13 +14,13 @@ import ( // TODO: For now we handle this by halting state execution, when we get jsonrpc reconnecting // We should implement some wait-for-api logic -type ErrApi struct{error} +type ErrApi struct{ error } -type ErrInvalidDeals struct{error} -type ErrExpiredDeals struct{error} +type ErrInvalidDeals struct{ error } +type ErrExpiredDeals struct{ error } -type ErrBadCommD struct{error} -type ErrExpiredTicket struct{error} +type ErrBadCommD struct{ error } +type ErrExpiredTicket struct{ error } func checkPieces(ctx context.Context, si SectorInfo, api sealingApi) error { head, err := api.ChainHead(ctx) From 75670290fe1784caa77b1a4b8defcdb3cf4678ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 23 Jan 2020 18:34:04 +0100 Subject: [PATCH 029/126] sealing: Handlef for PreCommitFailed --- fsm.go | 6 +++- fsm_events.go | 8 +++++ sealing.go | 2 +- states_failed.go | 84 ++++++++++++++++++++++++++++++++++++++++++------ 4 files changed, 88 insertions(+), 12 deletions(-) diff --git a/fsm.go b/fsm.go index 3d3253072..60bab48d0 100644 --- a/fsm.go +++ b/fsm.go @@ -60,6 +60,10 @@ var fsmPlanners = []func(events []statemachine.Event, state *SectorInfo) error{ api.SealFailed: planOne( on(SectorRetrySeal{}, api.Unsealed), ), + api.PreCommitFailed: planOne( + on(SectorRetryPreCommit{}, api.PreCommitting), + on(SectorRetryWaitSeed{}, api.WaitSeed), + ), api.Faulty: planOne( on(SectorFaultReported{}, api.FaultReported), @@ -153,7 +157,7 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta case api.SealFailed: return m.handleSealFailed, nil case api.PreCommitFailed: - log.Warnf("sector %d entered unimplemented state 'PreCommitFailed'", state.SectorID) + return m.handlePreCommitFailed, nil case api.SealCommitFailed: log.Warnf("sector %d entered unimplemented state 'SealCommitFailed'", state.SectorID) case api.CommitFailed: diff --git a/fsm_events.go b/fsm_events.go index 948a1653b..ee4963750 100644 --- a/fsm_events.go +++ b/fsm_events.go @@ -126,6 +126,14 @@ type SectorRetrySeal struct{} func (evt SectorRetrySeal) apply(state *SectorInfo) {} +type SectorRetryPreCommit struct{} + +func (evt SectorRetryPreCommit) apply(state *SectorInfo) {} + +type SectorRetryWaitSeed struct{} + +func (evt SectorRetryWaitSeed) apply(state *SectorInfo) {} + // Faults type SectorFaulty struct{} diff --git a/sealing.go b/sealing.go index 45034047e..6d0c6bb46 100644 --- a/sealing.go +++ b/sealing.go @@ -39,7 +39,6 @@ type sealingApi interface { // TODO: trim down StateGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error) StateGetReceipt(context.Context, cid.Cid, *types.TipSet) (*types.MessageReceipt, error) StateMarketStorageDeal(context.Context, uint64, *types.TipSet) (*actors.OnChainDeal, error) - StateReadState(ctx context.Context, act *types.Actor, ts *types.TipSet) (*api.ActorState, error) MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error) @@ -48,6 +47,7 @@ type sealingApi interface { // TODO: trim down ChainGetRandomness(context.Context, types.TipSetKey, int64) ([]byte, error) ChainGetTipSetByHeight(context.Context, uint64, *types.TipSet) (*types.TipSet, error) ChainGetBlockMessages(context.Context, cid.Cid) (*api.BlockMessages, error) + ChainReadObj(context.Context, cid.Cid) ([]byte, error) WalletSign(context.Context, address.Address, []byte) (*types.Signature, error) WalletBalance(context.Context, address.Address) (types.BigInt, error) diff --git a/states_failed.go b/states_failed.go index 8582471e7..fcef3b30c 100644 --- a/states_failed.go +++ b/states_failed.go @@ -1,10 +1,14 @@ package sealing import ( + "bytes" "fmt" "time" + "golang.org/x/xerrors" + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/lib/statemachine" ) @@ -24,28 +28,41 @@ func failedCooldown(ctx statemachine.Context, sector SectorInfo) error { return nil } -func (m *Sealing) handleSealFailed(ctx statemachine.Context, sector SectorInfo) error { - // TODO: - +func (m *Sealing) checkPreCommitted(ctx statemachine.Context, sector SectorInfo) (*actors.PreCommittedSector, bool) { act, err := m.api.StateGetActor(ctx.Context(), m.maddr, nil) if err != nil { log.Errorf("handleSealFailed(%d): temp error: %+v", sector.SectorID, err) - return nil + return nil, true } - st, err := m.api.StateReadState(ctx.Context(), act, nil) + st, err := m.api.ChainReadObj(ctx.Context(), act.Head) if err != nil { log.Errorf("handleSealFailed(%d): temp error: %+v", sector.SectorID, err) - return nil + return nil, true } - _, found := st.State.(map[string]interface{})["PreCommittedSectors"].(map[string]interface{})[fmt.Sprint(sector.SectorID)] + var state actors.StorageMinerActorState + if err := state.UnmarshalCBOR(bytes.NewReader(st)); err != nil { + log.Errorf("handleSealFailed(%d): temp error: unmarshaling miner state: %+v", sector.SectorID, err) + return nil, true + } + + pci, found := state.PreCommittedSectors[fmt.Sprint(sector.SectorID)] if found { // TODO: If not expired yet, we can just try reusing sealticket - log.Errorf("sector found in miner preseal array: %+v", sector.SectorID, err) - return nil + log.Errorf("sector %d found in miner preseal array: %+v", sector.SectorID, err) + return pci, true + } + + return nil, false +} + +func (m *Sealing) handleSealFailed(ctx statemachine.Context, sector SectorInfo) error { + + if _, is := m.checkPreCommitted(ctx, sector); is { + // TODO: Remove this after we can re-precommit + return nil // noop, for now } - // if err := failedCooldown(ctx, sector); err != nil { return err @@ -53,3 +70,50 @@ func (m *Sealing) handleSealFailed(ctx statemachine.Context, sector SectorInfo) return ctx.Send(SectorRetrySeal{}) } + +func (m *Sealing) handlePreCommitFailed(ctx statemachine.Context, sector SectorInfo) error { + if err := checkSeal(ctx.Context(), m.maddr, sector, m.api); err != nil { + switch err.(type) { + case *ErrApi: + log.Errorf("handlePreCommitFailed: api error, not proceeding: %+v", err) + return nil + case *ErrBadCommD: // TODO: Should this just back to packing? (not really needed since handleUnsealed will do that too) + return ctx.Send(SectorSealFailed{xerrors.Errorf("bad CommD error: %w", err)}) + case *ErrExpiredTicket: + return ctx.Send(SectorSealFailed{xerrors.Errorf("bad CommD error: %w", err)}) + default: + return xerrors.Errorf("checkSeal sanity check error: %w", err) + } + } + + if pci, is := m.checkPreCommitted(ctx, sector); is && pci != nil { + if sector.PreCommitMessage != nil { + log.Warn("sector %d is precommitted on chain, but we don't have precommit message", sector.SectorID) + return nil // TODO: SeedWait needs this currently + } + + if string(pci.Info.CommR) != string(sector.CommR) { + log.Warn("sector %d is precommitted on chain, with different CommR: %x != %x", sector.SectorID, pci.Info.CommR, sector.CommR) + return nil // TODO: remove when the actor allows re-precommit + } + + // TODO: we could compare more things, but I don't think we really need to + // CommR tells us that CommD (and CommPs), and the ticket are all matching + + if err := failedCooldown(ctx, sector); err != nil { + return err + } + + return ctx.Send(SectorRetryWaitSeed{}) + } + + if sector.PreCommitMessage != nil { + log.Warn("retrying precommit even though the message failed to apply") + } + + if err := failedCooldown(ctx, sector); err != nil { + return err + } + + return ctx.Send(SectorRetryPreCommit{}) +} From db5f1d2235c99582539883204bb42ae31a64ad73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 23 Jan 2020 18:45:57 +0100 Subject: [PATCH 030/126] sealing: PreCommitFailed can go to SealFailed --- fsm.go | 1 + states_failed.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/fsm.go b/fsm.go index 60bab48d0..ad0803488 100644 --- a/fsm.go +++ b/fsm.go @@ -63,6 +63,7 @@ var fsmPlanners = []func(events []statemachine.Event, state *SectorInfo) error{ api.PreCommitFailed: planOne( on(SectorRetryPreCommit{}, api.PreCommitting), on(SectorRetryWaitSeed{}, api.WaitSeed), + on(SectorSealFailed{}, api.SealFailed), ), api.Faulty: planOne( diff --git a/states_failed.go b/states_failed.go index fcef3b30c..4004edc90 100644 --- a/states_failed.go +++ b/states_failed.go @@ -80,7 +80,7 @@ func (m *Sealing) handlePreCommitFailed(ctx statemachine.Context, sector SectorI case *ErrBadCommD: // TODO: Should this just back to packing? (not really needed since handleUnsealed will do that too) return ctx.Send(SectorSealFailed{xerrors.Errorf("bad CommD error: %w", err)}) case *ErrExpiredTicket: - return ctx.Send(SectorSealFailed{xerrors.Errorf("bad CommD error: %w", err)}) + return ctx.Send(SectorSealFailed{xerrors.Errorf("ticket expired error: %w", err)}) default: return xerrors.Errorf("checkSeal sanity check error: %w", err) } From 0dfbb7d83ed2db45547a7f96f192ca3ad73d673b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 24 Jan 2020 01:53:52 +0100 Subject: [PATCH 031/126] Merge remote-tracking branch 'origin/master' into feat/sector-recovery --- states_failed.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/states_failed.go b/states_failed.go index 4004edc90..680ba6891 100644 --- a/states_failed.go +++ b/states_failed.go @@ -50,7 +50,7 @@ func (m *Sealing) checkPreCommitted(ctx statemachine.Context, sector SectorInfo) pci, found := state.PreCommittedSectors[fmt.Sprint(sector.SectorID)] if found { // TODO: If not expired yet, we can just try reusing sealticket - log.Errorf("sector %d found in miner preseal array: %+v", sector.SectorID, err) + log.Warnf("sector %d found in miner preseal array", sector.SectorID) return pci, true } From 248a362c3e6847770fc7371ada723df1fec03b7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 24 Jan 2020 21:15:02 +0100 Subject: [PATCH 032/126] sealing: docstrings for sanity-checks --- checks.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/checks.go b/checks.go index 94ad95771..9baf2d993 100644 --- a/checks.go +++ b/checks.go @@ -22,6 +22,11 @@ type ErrExpiredDeals struct{ error } type ErrBadCommD struct{ error } type ErrExpiredTicket struct{ error } +// checkPieces validates that: +// - Each piece han a corresponding on chain deal +// - Piece commitments match with on chain deals +// - Piece sizes match +// - Deals aren't expired func checkPieces(ctx context.Context, si SectorInfo, api sealingApi) error { head, err := api.ChainHead(ctx) if err != nil { @@ -50,6 +55,8 @@ func checkPieces(ctx context.Context, si SectorInfo, api sealingApi) error { return nil } +// checkSeal checks that data commitment generated in the sealing process +// matches pieces, and that the seal ticket isn't expired func checkSeal(ctx context.Context, maddr address.Address, si SectorInfo, api sealingApi) (err error) { head, err := api.ChainHead(ctx) if err != nil { From f6b12a33a2b4c9d847ea2c5a4d522bac61202dfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 25 Jan 2020 12:15:28 +0100 Subject: [PATCH 033/126] sealing: Parallel CommP calc in pledge sector --- garbage.go | 54 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/garbage.go b/garbage.go index 1c3925671..a6b439258 100644 --- a/garbage.go +++ b/garbage.go @@ -6,14 +6,61 @@ import ( "io" "math" "math/rand" + "runtime" + "sync" sectorbuilder "github.com/filecoin-project/go-sectorbuilder" + "github.com/hashicorp/go-multierror" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/types" ) +func (m *Sealing) fastPledgeCommitment(size uint64, parts uint64) (commP [sectorbuilder.CommLen]byte, err error) { + piece := sectorbuilder.UserBytesForSectorSize((size / 127 + size) / parts) + out := make([]sectorbuilder.PublicPieceInfo, parts) + var lk sync.Mutex + + var wg sync.WaitGroup + wg.Add(int(parts)) + for i := uint64(0); i < parts; i++ { + go func(i uint64) { + defer wg.Done() + + commP, perr := sectorbuilder.GeneratePieceCommitment(io.LimitReader(rand.New(rand.NewSource(42 + int64(i))), int64(piece)), piece) + + lk.Lock() + if perr != nil { + err = multierror.Append(err, perr) + } + out[i] = sectorbuilder.PublicPieceInfo{ + Size: piece, + CommP: commP, + } + lk.Unlock() + }(i) + } + wg.Wait() + + if err != nil { + return [32]byte{}, err + } + + return sectorbuilder.GenerateDataCommitment(m.sb.SectorSize(), out) +} + +func (m *Sealing) pledgeReader(size uint64, parts uint64) io.Reader { + piece := sectorbuilder.UserBytesForSectorSize((size / 127 + size) / parts) + + readers := make([]io.Reader, parts) + for i := range readers { + readers[i] = io.LimitReader(rand.New(rand.NewSource(42 + int64(i))), int64(piece)) + } + + return io.MultiReader(readers...) +} + func (m *Sealing) pledgeSector(ctx context.Context, sectorID uint64, existingPieceSizes []uint64, sizes ...uint64) ([]Piece, error) { if len(sizes) == 0 { return nil, nil @@ -21,10 +68,7 @@ func (m *Sealing) pledgeSector(ctx context.Context, sectorID uint64, existingPie deals := make([]actors.StorageDealProposal, len(sizes)) for i, size := range sizes { - release := m.sb.RateLimit() - commP, err := sectorbuilder.GeneratePieceCommitment(io.LimitReader(rand.New(rand.NewSource(42)), int64(size)), size) - release() - + commP, err := m.fastPledgeCommitment(size, uint64(runtime.NumCPU())) if err != nil { return nil, err } @@ -81,7 +125,7 @@ func (m *Sealing) pledgeSector(ctx context.Context, sectorID uint64, existingPie out := make([]Piece, len(sizes)) for i, size := range sizes { - ppi, err := m.sb.AddPiece(size, sectorID, io.LimitReader(rand.New(rand.NewSource(42)), int64(size)), existingPieceSizes) + ppi, err := m.sb.AddPiece(size, sectorID, m.pledgeReader(size, uint64(runtime.NumCPU())), existingPieceSizes) if err != nil { return nil, err } From e62515c04254584c4787170a63cf5adf5bf877cb Mon Sep 17 00:00:00 2001 From: laser Date: Tue, 28 Jan 2020 11:46:26 -0800 Subject: [PATCH 034/126] planCommitting must handle SectorCommitFailed The SectorCommitFailed struct can be created from within Sealing#handleCommitting, and is created if actors.SerializeParams(params) produces an error or if m.api.MpoolPushMessage(ctx.Context(), msg) produces an error. --- fsm.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fsm.go b/fsm.go index ad0803488..4fdd81d35 100644 --- a/fsm.go +++ b/fsm.go @@ -205,6 +205,8 @@ func planCommitting(events []statemachine.Event, state *SectorInfo) error { state.State = api.SealCommitFailed case SectorSealFailed: state.State = api.CommitFailed + case SectorCommitFailed: + state.State = api.CommitFailed default: return xerrors.Errorf("planCommitting got event of unknown type %T, events: %+v", event.User, events) } From debf107b5426d970115e49018fadaa5ba9106d0c Mon Sep 17 00:00:00 2001 From: laser Date: Tue, 28 Jan 2020 12:39:07 -0800 Subject: [PATCH 035/126] write basic test affirming state change --- fsm_test.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/fsm_test.go b/fsm_test.go index 2dada5470..7430bb634 100644 --- a/fsm_test.go +++ b/fsm_test.go @@ -83,3 +83,17 @@ func TestSeedRevert(t *testing.T) { m.planSingle(SectorProving{}) require.Equal(m.t, m.state.State, api.Proving) } + +func TestPlanCommittingHandlesSectorCommitFailed(t *testing.T) { + m := test{ + s: &Sealing{}, + t: t, + state: &SectorInfo{State: api.Committing}, + } + + events := []statemachine.Event{{SectorCommitFailed{}}} + + require.NoError(t, planCommitting(events, m.state)) + + require.Equal(t, api.SectorStates[api.CommitFailed], api.SectorStates[m.state.State]) +} From 73839692d9b1db6204e061a8d1d21b1ae4c87703 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 29 Jan 2020 00:08:02 +0100 Subject: [PATCH 036/126] initial sectorbuilder FS refactor integration --- garbage.go | 4 ++-- sealing.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/garbage.go b/garbage.go index 1c3925671..32dff004f 100644 --- a/garbage.go +++ b/garbage.go @@ -81,9 +81,9 @@ func (m *Sealing) pledgeSector(ctx context.Context, sectorID uint64, existingPie out := make([]Piece, len(sizes)) for i, size := range sizes { - ppi, err := m.sb.AddPiece(size, sectorID, io.LimitReader(rand.New(rand.NewSource(42)), int64(size)), existingPieceSizes) + ppi, err := m.sb.AddPiece(ctx, size, sectorID, io.LimitReader(rand.New(rand.NewSource(42)), int64(size)), existingPieceSizes) if err != nil { - return nil, err + return nil, xerrors.Errorf("add piece: %w", err) } existingPieceSizes = append(existingPieceSizes, size) diff --git a/sealing.go b/sealing.go index 6d0c6bb46..e6e45c0eb 100644 --- a/sealing.go +++ b/sealing.go @@ -112,7 +112,7 @@ func (m *Sealing) AllocatePiece(size uint64) (sectorID uint64, offset uint64, er func (m *Sealing) SealPiece(ctx context.Context, size uint64, r io.Reader, sectorID uint64, dealID uint64) error { log.Infof("Seal piece for deal %d", dealID) - ppi, err := m.sb.AddPiece(size, sectorID, r, []uint64{}) + ppi, err := m.sb.AddPiece(ctx, size, sectorID, r, []uint64{}) if err != nil { return xerrors.Errorf("adding piece to sector: %w", err) } From 367062aee4651c83777771ad3f09de37a4be83bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 29 Jan 2020 20:12:08 +0100 Subject: [PATCH 037/126] sealing: round parts in fastPledgeCommitment --- garbage.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/garbage.go b/garbage.go index a6b439258..d33b63276 100644 --- a/garbage.go +++ b/garbage.go @@ -5,6 +5,7 @@ import ( "context" "io" "math" + "math/bits" "math/rand" "runtime" "sync" @@ -18,7 +19,9 @@ import ( ) func (m *Sealing) fastPledgeCommitment(size uint64, parts uint64) (commP [sectorbuilder.CommLen]byte, err error) { - piece := sectorbuilder.UserBytesForSectorSize((size / 127 + size) / parts) + parts = 1 << bits.Len64(parts) // round down to nearest power of 2 + + piece := sectorbuilder.UserBytesForSectorSize((size/127 + size) / parts) out := make([]sectorbuilder.PublicPieceInfo, parts) var lk sync.Mutex @@ -28,7 +31,7 @@ func (m *Sealing) fastPledgeCommitment(size uint64, parts uint64) (commP [sector go func(i uint64) { defer wg.Done() - commP, perr := sectorbuilder.GeneratePieceCommitment(io.LimitReader(rand.New(rand.NewSource(42 + int64(i))), int64(piece)), piece) + commP, perr := sectorbuilder.GeneratePieceCommitment(io.LimitReader(rand.New(rand.NewSource(42+int64(i))), int64(piece)), piece) lk.Lock() if perr != nil { @@ -51,11 +54,11 @@ func (m *Sealing) fastPledgeCommitment(size uint64, parts uint64) (commP [sector } func (m *Sealing) pledgeReader(size uint64, parts uint64) io.Reader { - piece := sectorbuilder.UserBytesForSectorSize((size / 127 + size) / parts) + piece := sectorbuilder.UserBytesForSectorSize((size/127 + size) / parts) readers := make([]io.Reader, parts) for i := range readers { - readers[i] = io.LimitReader(rand.New(rand.NewSource(42 + int64(i))), int64(piece)) + readers[i] = io.LimitReader(rand.New(rand.NewSource(42+int64(i))), int64(piece)) } return io.MultiReader(readers...) From 731660c76ffb406f80a0549f81e8cb4a4e2fb3e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 29 Jan 2020 21:01:20 +0100 Subject: [PATCH 038/126] test fastPledgeCommitment --- garbage.go | 38 -------------------------------------- utils.go | 40 ++++++++++++++++++++++++++++++++++++++++ utils_test.go | 11 ++++++++++- 3 files changed, 50 insertions(+), 39 deletions(-) diff --git a/garbage.go b/garbage.go index d33b63276..4a3b1331b 100644 --- a/garbage.go +++ b/garbage.go @@ -5,54 +5,16 @@ import ( "context" "io" "math" - "math/bits" "math/rand" "runtime" - "sync" sectorbuilder "github.com/filecoin-project/go-sectorbuilder" - "github.com/hashicorp/go-multierror" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/types" ) -func (m *Sealing) fastPledgeCommitment(size uint64, parts uint64) (commP [sectorbuilder.CommLen]byte, err error) { - parts = 1 << bits.Len64(parts) // round down to nearest power of 2 - - piece := sectorbuilder.UserBytesForSectorSize((size/127 + size) / parts) - out := make([]sectorbuilder.PublicPieceInfo, parts) - var lk sync.Mutex - - var wg sync.WaitGroup - wg.Add(int(parts)) - for i := uint64(0); i < parts; i++ { - go func(i uint64) { - defer wg.Done() - - commP, perr := sectorbuilder.GeneratePieceCommitment(io.LimitReader(rand.New(rand.NewSource(42+int64(i))), int64(piece)), piece) - - lk.Lock() - if perr != nil { - err = multierror.Append(err, perr) - } - out[i] = sectorbuilder.PublicPieceInfo{ - Size: piece, - CommP: commP, - } - lk.Unlock() - }(i) - } - wg.Wait() - - if err != nil { - return [32]byte{}, err - } - - return sectorbuilder.GenerateDataCommitment(m.sb.SectorSize(), out) -} - func (m *Sealing) pledgeReader(size uint64, parts uint64) io.Reader { piece := sectorbuilder.UserBytesForSectorSize((size/127 + size) / parts) diff --git a/utils.go b/utils.go index 8fa887d3c..b235a8a83 100644 --- a/utils.go +++ b/utils.go @@ -1,7 +1,12 @@ package sealing import ( + "io" "math/bits" + "math/rand" + "sync" + + "github.com/hashicorp/go-multierror" sectorbuilder "github.com/filecoin-project/go-sectorbuilder" ) @@ -42,6 +47,41 @@ func fillersFromRem(toFill uint64) ([]uint64, error) { return out, nil } +func (m *Sealing) fastPledgeCommitment(size uint64, parts uint64) (commP [sectorbuilder.CommLen]byte, err error) { + parts = 1 << bits.Len64(parts) // round down to nearest power of 2 + + piece := sectorbuilder.UserBytesForSectorSize(size / parts) + out := make([]sectorbuilder.PublicPieceInfo, parts) + var lk sync.Mutex + + var wg sync.WaitGroup + wg.Add(int(parts)) + for i := uint64(0); i < parts; i++ { + go func(i uint64) { + defer wg.Done() + + commP, perr := sectorbuilder.GeneratePieceCommitment(io.LimitReader(rand.New(rand.NewSource(42+int64(i))), int64(piece)), piece) + + lk.Lock() + if perr != nil { + err = multierror.Append(err, perr) + } + out[i] = sectorbuilder.PublicPieceInfo{ + Size: piece, + CommP: commP, + } + lk.Unlock() + }(i) + } + wg.Wait() + + if err != nil { + return [32]byte{}, err + } + + return sectorbuilder.GenerateDataCommitment(m.sb.SectorSize(), out) +} + func (m *Sealing) ListSectors() ([]SectorInfo, error) { var sectors []SectorInfo if err := m.sectors.List(§ors); err != nil { diff --git a/utils_test.go b/utils_test.go index 02746a3d8..14d512a52 100644 --- a/utils_test.go +++ b/utils_test.go @@ -1,6 +1,7 @@ package sealing import ( + "github.com/filecoin-project/lotus/storage/sbmock" "testing" "github.com/stretchr/testify/assert" @@ -42,5 +43,13 @@ func TestFillersFromRem(t *testing.T) { ub = sectorbuilder.UserBytesForSectorSize(uint64(9) << i) testFill(t, ub, []uint64{ub1, ub4}) } - +} + +func TestFastPledge(t *testing.T) { + sz := uint64(16 << 20) + + s := Sealing{sb: sbmock.NewMockSectorBuilder(0, sz)} + if _, err := s.fastPledgeCommitment(sz, 5); err != nil { + t.Fatalf("%+v", err) + } } From 4ce9d005ddec7e7789843fc398012b3ce01c910e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 29 Jan 2020 22:25:06 +0100 Subject: [PATCH 039/126] sealing: FinalizeSector step --- fsm.go | 8 +++++++- fsm_events.go | 8 ++++++++ states.go | 8 ++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/fsm.go b/fsm.go index ad0803488..4e48be15e 100644 --- a/fsm.go +++ b/fsm.go @@ -48,10 +48,14 @@ var fsmPlanners = []func(events []statemachine.Event, state *SectorInfo) error{ ), api.Committing: planCommitting, api.CommitWait: planOne( - on(SectorProving{}, api.Proving), + on(SectorProving{}, api.FinalizeSector), on(SectorCommitFailed{}, api.CommitFailed), ), + api.FinalizeSector: planOne( + on(SectorFinalized{}, api.Proving), + ), + api.Proving: planOne( on(SectorFaultReported{}, api.FaultReported), on(SectorFaulty{}, api.Faulty), @@ -150,6 +154,8 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta return m.handleCommitting, nil case api.CommitWait: return m.handleCommitWait, nil + case api.FinalizeSector: + case api.Proving: // TODO: track sector health / expiration log.Infof("Proving sector %d", state.SectorID) diff --git a/fsm_events.go b/fsm_events.go index ee4963750..84b1120c8 100644 --- a/fsm_events.go +++ b/fsm_events.go @@ -120,6 +120,14 @@ type SectorProving struct{} func (evt SectorProving) apply(*SectorInfo) {} +type SectorFinalized struct{} + +func (evt SectorFinalized) apply(*SectorInfo) {} + +type SectorFinalizeFailed struct{ error } + +func (evt SectorFinalizeFailed) apply(*SectorInfo) {} + // Failed state recovery type SectorRetrySeal struct{} diff --git a/states.go b/states.go index 519245e03..22a7f642b 100644 --- a/states.go +++ b/states.go @@ -232,6 +232,14 @@ func (m *Sealing) handleCommitWait(ctx statemachine.Context, sector SectorInfo) return ctx.Send(SectorProving{}) } +func (m *Sealing) handleFinalizeSector(ctx statemachine.Context, sector SectorInfo) error { + if err := m.sb.FinalizeSector(ctx.Context(), sector.SectorID); err != nil { + return ctx.Send(SectorCommitFailed{err}) + } + + return ctx.Send(SectorFinalized{}) +} + func (m *Sealing) handleFaulty(ctx statemachine.Context, sector SectorInfo) error { // TODO: check if the fault has already been reported, and that this sector is even valid From c4e9a77be491a13019cb62f4bc3feea31fb8d34b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 29 Jan 2020 23:37:31 +0100 Subject: [PATCH 040/126] actually call finalizeSector --- fsm.go | 2 +- states.go | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/fsm.go b/fsm.go index 4e48be15e..2355c68bd 100644 --- a/fsm.go +++ b/fsm.go @@ -155,7 +155,7 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta case api.CommitWait: return m.handleCommitWait, nil case api.FinalizeSector: - + return m.handleFinalizeSector, nil case api.Proving: // TODO: track sector health / expiration log.Infof("Proving sector %d", state.SectorID) diff --git a/states.go b/states.go index 22a7f642b..5d70533bc 100644 --- a/states.go +++ b/states.go @@ -233,8 +233,14 @@ func (m *Sealing) handleCommitWait(ctx statemachine.Context, sector SectorInfo) } func (m *Sealing) handleFinalizeSector(ctx statemachine.Context, sector SectorInfo) error { + // TODO: Maybe wait for some finality + if err := m.sb.FinalizeSector(ctx.Context(), sector.SectorID); err != nil { - return ctx.Send(SectorCommitFailed{err}) + return ctx.Send(SectorCommitFailed{xerrors.Errorf("finalize sector: %w", err)}) + } + + if err := m.sb.DropStaged(ctx.Context(), sector.SectorID); err != nil { + return ctx.Send(SectorCommitFailed{xerrors.Errorf("drop staged: %w", err)}) } return ctx.Send(SectorFinalized{}) From 90b855094eb6ebbaddd1ef4d91a55a03eaf9f04a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 30 Jan 2020 02:01:10 +0100 Subject: [PATCH 041/126] Fix fast pledge math --- utils.go | 2 +- utils_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/utils.go b/utils.go index b235a8a83..21d6b76bf 100644 --- a/utils.go +++ b/utils.go @@ -50,7 +50,7 @@ func fillersFromRem(toFill uint64) ([]uint64, error) { func (m *Sealing) fastPledgeCommitment(size uint64, parts uint64) (commP [sectorbuilder.CommLen]byte, err error) { parts = 1 << bits.Len64(parts) // round down to nearest power of 2 - piece := sectorbuilder.UserBytesForSectorSize(size / parts) + piece := sectorbuilder.UserBytesForSectorSize((size + size / 127) / parts) out := make([]sectorbuilder.PublicPieceInfo, parts) var lk sync.Mutex diff --git a/utils_test.go b/utils_test.go index 14d512a52..9f9ca3880 100644 --- a/utils_test.go +++ b/utils_test.go @@ -49,7 +49,7 @@ func TestFastPledge(t *testing.T) { sz := uint64(16 << 20) s := Sealing{sb: sbmock.NewMockSectorBuilder(0, sz)} - if _, err := s.fastPledgeCommitment(sz, 5); err != nil { + if _, err := s.fastPledgeCommitment(sectorbuilder.UserBytesForSectorSize(sz), 5); err != nil { t.Fatalf("%+v", err) } } From c63fc61a52f2b979af2429687acc9b8f9187a55d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 30 Jan 2020 07:41:30 +0100 Subject: [PATCH 042/126] sealing: Fix pledgeReader --- garbage.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/garbage.go b/garbage.go index 2173759d2..22a282229 100644 --- a/garbage.go +++ b/garbage.go @@ -5,6 +5,7 @@ import ( "context" "io" "math" + "math/bits" "math/rand" "runtime" @@ -16,6 +17,8 @@ import ( ) func (m *Sealing) pledgeReader(size uint64, parts uint64) io.Reader { + parts = 1 << bits.Len64(parts) // round down to nearest power of 2 + piece := sectorbuilder.UserBytesForSectorSize((size/127 + size) / parts) readers := make([]io.Reader, parts) From b001a73da10fba29c82e791a66ffec2647a7c50d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 31 Jan 2020 02:18:48 +0100 Subject: [PATCH 043/126] Update sectorbuilder --- utils.go | 3 +++ utils_test.go | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/utils.go b/utils.go index 21d6b76bf..f317301ba 100644 --- a/utils.go +++ b/utils.go @@ -49,6 +49,9 @@ func fillersFromRem(toFill uint64) ([]uint64, error) { func (m *Sealing) fastPledgeCommitment(size uint64, parts uint64) (commP [sectorbuilder.CommLen]byte, err error) { parts = 1 << bits.Len64(parts) // round down to nearest power of 2 + if size / parts < 127 { + parts = size / 127 + } piece := sectorbuilder.UserBytesForSectorSize((size + size / 127) / parts) out := make([]sectorbuilder.PublicPieceInfo, parts) diff --git a/utils_test.go b/utils_test.go index 9f9ca3880..94bf858c1 100644 --- a/utils_test.go +++ b/utils_test.go @@ -52,4 +52,11 @@ func TestFastPledge(t *testing.T) { if _, err := s.fastPledgeCommitment(sectorbuilder.UserBytesForSectorSize(sz), 5); err != nil { t.Fatalf("%+v", err) } + + sz = uint64(1024) + + s = Sealing{sb: sbmock.NewMockSectorBuilder(0, sz)} + if _, err := s.fastPledgeCommitment(sectorbuilder.UserBytesForSectorSize(sz), 64); err != nil { + t.Fatalf("%+v", err) + } } From 52ff34c13ebef0d92106914f89ded6a5e164a488 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 31 Jan 2020 02:27:38 +0100 Subject: [PATCH 044/126] Fix tests --- fsm_test.go | 6 ++++++ utils.go | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/fsm_test.go b/fsm_test.go index 7430bb634..24145a2a1 100644 --- a/fsm_test.go +++ b/fsm_test.go @@ -50,6 +50,9 @@ func TestHappyPath(t *testing.T) { require.Equal(m.t, m.state.State, api.CommitWait) m.planSingle(SectorProving{}) + require.Equal(m.t, m.state.State, api.FinalizeSector) + + m.planSingle(SectorFinalized{}) require.Equal(m.t, m.state.State, api.Proving) } @@ -81,6 +84,9 @@ func TestSeedRevert(t *testing.T) { require.Equal(m.t, m.state.State, api.CommitWait) m.planSingle(SectorProving{}) + require.Equal(m.t, m.state.State, api.FinalizeSector) + + m.planSingle(SectorFinalized{}) require.Equal(m.t, m.state.State, api.Proving) } diff --git a/utils.go b/utils.go index f317301ba..b2221b278 100644 --- a/utils.go +++ b/utils.go @@ -49,11 +49,11 @@ func fillersFromRem(toFill uint64) ([]uint64, error) { func (m *Sealing) fastPledgeCommitment(size uint64, parts uint64) (commP [sectorbuilder.CommLen]byte, err error) { parts = 1 << bits.Len64(parts) // round down to nearest power of 2 - if size / parts < 127 { + if size/parts < 127 { parts = size / 127 } - piece := sectorbuilder.UserBytesForSectorSize((size + size / 127) / parts) + piece := sectorbuilder.UserBytesForSectorSize((size + size/127) / parts) out := make([]sectorbuilder.PublicPieceInfo, parts) var lk sync.Mutex From edfbe71b0f5018e157237a2ebf7e1fe0b00b03bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 31 Jan 2020 20:07:20 +0100 Subject: [PATCH 045/126] fix pledgeReader with small sectors --- garbage.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/garbage.go b/garbage.go index 22a282229..ac49ac668 100644 --- a/garbage.go +++ b/garbage.go @@ -18,6 +18,9 @@ import ( func (m *Sealing) pledgeReader(size uint64, parts uint64) io.Reader { parts = 1 << bits.Len64(parts) // round down to nearest power of 2 + if size/parts < 127 { + parts = size / 127 + } piece := sectorbuilder.UserBytesForSectorSize((size/127 + size) / parts) From bd766ab3cd7cfea73f1e04d528a2fe1ccd8adf19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 31 Jan 2020 20:22:31 +0100 Subject: [PATCH 046/126] sealing: more logging in pledge sector flow --- garbage.go | 9 +++++++-- sealing.go | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/garbage.go b/garbage.go index ac49ac668..3274f6aec 100644 --- a/garbage.go +++ b/garbage.go @@ -37,6 +37,8 @@ func (m *Sealing) pledgeSector(ctx context.Context, sectorID uint64, existingPie return nil, nil } + log.Infof("Pledge %d, contains %+v", sectorID, existingPieceSizes) + deals := make([]actors.StorageDealProposal, len(sizes)) for i, size := range sizes { commP, err := m.fastPledgeCommitment(size, uint64(runtime.NumCPU())) @@ -59,6 +61,8 @@ func (m *Sealing) pledgeSector(ctx context.Context, sectorID uint64, existingPie deals[i] = sdp } + log.Infof("Publishing deals for %d", sectorID) + params, aerr := actors.SerializeParams(&actors.PublishStorageDealsParams{ Deals: deals, }) @@ -78,7 +82,7 @@ func (m *Sealing) pledgeSector(ctx context.Context, sectorID uint64, existingPie if err != nil { return nil, err } - r, err := m.api.StateWaitMsg(ctx, smsg.Cid()) + r, err := m.api.StateWaitMsg(ctx, smsg.Cid()) // TODO: more finality if err != nil { return nil, err } @@ -93,8 +97,9 @@ func (m *Sealing) pledgeSector(ctx context.Context, sectorID uint64, existingPie return nil, xerrors.New("got unexpected number of DealIDs from PublishStorageDeals") } - out := make([]Piece, len(sizes)) + log.Infof("Deals for sector %d: %+v", sectorID, resp.DealIDs) + out := make([]Piece, len(sizes)) for i, size := range sizes { ppi, err := m.sb.AddPiece(ctx, size, sectorID, m.pledgeReader(size, uint64(runtime.NumCPU())), existingPieceSizes) if err != nil { diff --git a/sealing.go b/sealing.go index e6e45c0eb..6e562001d 100644 --- a/sealing.go +++ b/sealing.go @@ -121,6 +121,7 @@ func (m *Sealing) SealPiece(ctx context.Context, size uint64, r io.Reader, secto } func (m *Sealing) newSector(ctx context.Context, sid uint64, dealID uint64, ppi sectorbuilder.PublicPieceInfo) error { + log.Infof("Start sealing %d", sid) return m.sectors.Send(sid, SectorStart{ id: sid, pieces: []Piece{ From 2d6f0cc5898c5e60471c33c16e64653cc51e76e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sun, 2 Feb 2020 20:36:15 +0100 Subject: [PATCH 047/126] sealing: fix finalize with cache only --- states.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/states.go b/states.go index 5d70533bc..723a2d843 100644 --- a/states.go +++ b/states.go @@ -4,6 +4,7 @@ import ( "context" sectorbuilder "github.com/filecoin-project/go-sectorbuilder" + "github.com/filecoin-project/go-sectorbuilder/fs" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/build" @@ -236,11 +237,14 @@ func (m *Sealing) handleFinalizeSector(ctx statemachine.Context, sector SectorIn // TODO: Maybe wait for some finality if err := m.sb.FinalizeSector(ctx.Context(), sector.SectorID); err != nil { - return ctx.Send(SectorCommitFailed{xerrors.Errorf("finalize sector: %w", err)}) + if !xerrors.Is(err, fs.ErrNoSuitablePath) { + return ctx.Send(SectorFinalizeFailed{xerrors.Errorf("finalize sector: %w", err)}) + } + log.Warnf("finalize sector: %v", err) } if err := m.sb.DropStaged(ctx.Context(), sector.SectorID); err != nil { - return ctx.Send(SectorCommitFailed{xerrors.Errorf("drop staged: %w", err)}) + return ctx.Send(SectorFinalizeFailed{xerrors.Errorf("drop staged: %w", err)}) } return ctx.Send(SectorFinalized{}) From 4d19bebc03c911fea4dde8af8e4d0dde0f800875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 4 Feb 2020 21:46:31 +0100 Subject: [PATCH 048/126] storageminer: Work around broken fastPledgeCommitment --- garbage.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/garbage.go b/garbage.go index 3274f6aec..ca8c1e454 100644 --- a/garbage.go +++ b/garbage.go @@ -7,7 +7,6 @@ import ( "math" "math/bits" "math/rand" - "runtime" sectorbuilder "github.com/filecoin-project/go-sectorbuilder" "golang.org/x/xerrors" @@ -41,7 +40,7 @@ func (m *Sealing) pledgeSector(ctx context.Context, sectorID uint64, existingPie deals := make([]actors.StorageDealProposal, len(sizes)) for i, size := range sizes { - commP, err := m.fastPledgeCommitment(size, uint64(runtime.NumCPU())) + commP, err := m.fastPledgeCommitment(size, uint64(1)) if err != nil { return nil, err } @@ -101,7 +100,7 @@ func (m *Sealing) pledgeSector(ctx context.Context, sectorID uint64, existingPie out := make([]Piece, len(sizes)) for i, size := range sizes { - ppi, err := m.sb.AddPiece(ctx, size, sectorID, m.pledgeReader(size, uint64(runtime.NumCPU())), existingPieceSizes) + ppi, err := m.sb.AddPiece(ctx, size, sectorID, m.pledgeReader(size, uint64(1)), existingPieceSizes) if err != nil { return nil, xerrors.Errorf("add piece: %w", err) } From 572cf16a516bd8acd83021088ed17b76e3400b46 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Tue, 4 Feb 2020 18:26:42 -0800 Subject: [PATCH 049/126] squash forks and use correct amt library everywhere --- cbor_gen.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cbor_gen.go b/cbor_gen.go index f83d35990..af1a18da2 100644 --- a/cbor_gen.go +++ b/cbor_gen.go @@ -1,3 +1,5 @@ +// Code generated by github.com/whyrusleeping/cbor-gen. DO NOT EDIT. + package sealing import ( @@ -8,8 +10,6 @@ import ( xerrors "golang.org/x/xerrors" ) -// Code generated by github.com/whyrusleeping/cbor-gen. DO NOT EDIT. - var _ = xerrors.Errorf func (t *SealTicket) MarshalCBOR(w io.Writer) error { From 9b5968f1705a31c689d5b8ad41a85ebf18adb32e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 8 Feb 2020 03:18:32 +0100 Subject: [PATCH 050/126] Spec Actors integration --- cbor_gen.go | 14 +------------- checks.go | 16 +++++++++++----- fsm_events.go | 3 ++- garbage.go | 45 ++++++++++++++++++++++++--------------------- sealing.go | 21 +++++++++++---------- states.go | 18 +++++++++--------- types.go | 21 +++++++++++---------- utils.go | 19 ++++++++++--------- 8 files changed, 79 insertions(+), 78 deletions(-) diff --git a/cbor_gen.go b/cbor_gen.go index af1a18da2..21e60741f 100644 --- a/cbor_gen.go +++ b/cbor_gen.go @@ -218,9 +218,7 @@ func (t *SealSeed) UnmarshalCBOR(r io.Reader) error { } if maj != cbg.MajUnsignedInt { return fmt.Errorf("wrong type for uint64 field") - } - t.BlockHeight = uint64(extra) - // t.TicketBytes ([]uint8) (slice) + } // t.TicketBytes ([]uint8) (slice) case "TicketBytes": maj, extra, err = cbg.CborReadHeader(br) @@ -352,18 +350,9 @@ func (t *Piece) UnmarshalCBOR(r io.Reader) error { if maj != cbg.MajUnsignedInt { return fmt.Errorf("wrong type for uint64 field") } - t.DealID = uint64(extra) // t.Size (uint64) (uint64) case "Size": - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.Size = uint64(extra) // t.CommP ([]uint8) (slice) case "CommP": @@ -740,7 +729,6 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { if maj != cbg.MajUnsignedInt { return fmt.Errorf("wrong type for uint64 field") } - t.SectorID = uint64(extra) // t.Nonce (uint64) (uint64) case "Nonce": diff --git a/checks.go b/checks.go index 9baf2d993..a94cd20da 100644 --- a/checks.go +++ b/checks.go @@ -3,6 +3,7 @@ package sealing import ( "context" + "github.com/multiformats/go-multihash" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" @@ -39,16 +40,21 @@ func checkPieces(ctx context.Context, si SectorInfo, api sealingApi) error { return &ErrApi{xerrors.Errorf("getting deal %d for piece %d: %w", piece.DealID, i, err)} } - if string(deal.PieceRef) != string(piece.CommP) { - return &ErrInvalidDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers deal %d with wrong CommP: %x != %x", i, len(si.Pieces), si.SectorID, piece.DealID, piece.CommP, deal.PieceRef)} + h, err := multihash.Decode(deal.PieceCID.Hash()) + if err != nil { + return &ErrInvalidDeals{xerrors.Errorf("decoding piece CID: %w", err)} } - if piece.Size != deal.PieceSize { + if string(h.Digest) != string(piece.CommP) { + return &ErrInvalidDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers deal %d with wrong CommP: %x != %x", i, len(si.Pieces), si.SectorID, piece.DealID, piece.CommP, h.Digest)} + } + + if piece.Size != deal.PieceSize.Unpadded() { return &ErrInvalidDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers deal %d with different size: %d != %d", i, len(si.Pieces), si.SectorID, piece.DealID, piece.Size, deal.PieceSize)} } - if head.Height() >= deal.ProposalExpiration { - return &ErrExpiredDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers expired deal %d - expires %d, head %d", i, len(si.Pieces), si.SectorID, piece.DealID, deal.ProposalExpiration, head.Height())} + if head.Height() >= deal.StartEpoch { + return &ErrExpiredDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers expired deal %d - should start at %d, head %d", i, len(si.Pieces), si.SectorID, piece.DealID, deal.StartEpoch, head.Height())} } } diff --git a/fsm_events.go b/fsm_events.go index 84b1120c8..528da1234 100644 --- a/fsm_events.go +++ b/fsm_events.go @@ -1,6 +1,7 @@ package sealing import ( + "github.com/filecoin-project/specs-actors/actors/abi" "github.com/ipfs/go-cid" "github.com/filecoin-project/lotus/api" @@ -45,7 +46,7 @@ func (evt SectorForceState) applyGlobal(state *SectorInfo) bool { // Normal path type SectorStart struct { - id uint64 + id abi.SectorNumber pieces []Piece } diff --git a/garbage.go b/garbage.go index ca8c1e454..52f2eb9cb 100644 --- a/garbage.go +++ b/garbage.go @@ -8,20 +8,22 @@ import ( "math/bits" "math/rand" - sectorbuilder "github.com/filecoin-project/go-sectorbuilder" + commcid "github.com/filecoin-project/go-fil-commcid" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin/market" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/types" ) -func (m *Sealing) pledgeReader(size uint64, parts uint64) io.Reader { +func (m *Sealing) pledgeReader(size abi.UnpaddedPieceSize, parts uint64) io.Reader { parts = 1 << bits.Len64(parts) // round down to nearest power of 2 - if size/parts < 127 { - parts = size / 127 + if uint64(size)/parts < 127 { + parts = uint64(size) / 127 } - piece := sectorbuilder.UserBytesForSectorSize((size/127 + size) / parts) + piece := abi.PaddedPieceSize(uint64(size.Padded()) / parts).Unpadded() readers := make([]io.Reader, parts) for i := range readers { @@ -31,33 +33,34 @@ func (m *Sealing) pledgeReader(size uint64, parts uint64) io.Reader { return io.MultiReader(readers...) } -func (m *Sealing) pledgeSector(ctx context.Context, sectorID uint64, existingPieceSizes []uint64, sizes ...uint64) ([]Piece, error) { +func (m *Sealing) pledgeSector(ctx context.Context, sectorID abi.SectorNumber, existingPieceSizes []abi.UnpaddedPieceSize, sizes ...abi.UnpaddedPieceSize) ([]Piece, error) { if len(sizes) == 0 { return nil, nil } log.Infof("Pledge %d, contains %+v", sectorID, existingPieceSizes) - deals := make([]actors.StorageDealProposal, len(sizes)) + deals := make([]market.ClientDealProposal, len(sizes)) for i, size := range sizes { commP, err := m.fastPledgeCommitment(size, uint64(1)) if err != nil { return nil, err } - sdp := actors.StorageDealProposal{ - PieceRef: commP[:], - PieceSize: size, + sdp := market.DealProposal{ + PieceCID: commcid.PieceCommitmentV1ToCID(commP[:]), + PieceSize: size.Padded(), Client: m.worker, Provider: m.maddr, - ProposalExpiration: math.MaxUint64, - Duration: math.MaxUint64 / 2, // /2 because overflows + StartEpoch: math.MaxInt64, + EndEpoch: math.MaxInt64, StoragePricePerEpoch: types.NewInt(0), - StorageCollateral: types.NewInt(0), - ProposerSignature: nil, // nil because self dealing + ProviderCollateral: types.NewInt(0), } - deals[i] = sdp + deals[i] = market.ClientDealProposal{ + Proposal: sdp, + } } log.Infof("Publishing deals for %d", sectorID) @@ -92,11 +95,11 @@ func (m *Sealing) pledgeSector(ctx context.Context, sectorID uint64, existingPie if err := resp.UnmarshalCBOR(bytes.NewReader(r.Receipt.Return)); err != nil { return nil, err } - if len(resp.DealIDs) != len(sizes) { + if len(resp.IDs) != len(sizes) { return nil, xerrors.New("got unexpected number of DealIDs from PublishStorageDeals") } - log.Infof("Deals for sector %d: %+v", sectorID, resp.DealIDs) + log.Infof("Deals for sector %d: %+v", sectorID, resp.IDs) out := make([]Piece, len(sizes)) for i, size := range sizes { @@ -108,8 +111,8 @@ func (m *Sealing) pledgeSector(ctx context.Context, sectorID uint64, existingPie existingPieceSizes = append(existingPieceSizes, size) out[i] = Piece{ - DealID: resp.DealIDs[i], - Size: ppi.Size, + DealID: resp.IDs[i], + Size: abi.UnpaddedPieceSize(ppi.Size), CommP: ppi.CommP[:], } } @@ -123,7 +126,7 @@ func (m *Sealing) PledgeSector() error { // this, as we run everything here async, and it's cancelled when the // command exits - size := sectorbuilder.UserBytesForSectorSize(m.sb.SectorSize()) + size := abi.PaddedPieceSize(m.sb.SectorSize()).Unpadded() sid, err := m.sb.AcquireSectorId() if err != nil { @@ -131,7 +134,7 @@ func (m *Sealing) PledgeSector() error { return } - pieces, err := m.pledgeSector(ctx, sid, []uint64{}, size) + pieces, err := m.pledgeSector(ctx, sid, []abi.UnpaddedPieceSize{}, abi.UnpaddedPieceSize(size)) if err != nil { log.Errorf("%+v", err) return diff --git a/sealing.go b/sealing.go index 6e562001d..a9e080328 100644 --- a/sealing.go +++ b/sealing.go @@ -6,6 +6,8 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-sectorbuilder" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin/market" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/namespace" @@ -13,7 +15,6 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/events" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" @@ -31,21 +32,21 @@ type sealingApi interface { // TODO: trim down // Call a read only method on actors (no interaction with the chain required) StateCall(context.Context, *types.Message, *types.TipSet) (*api.MethodCall, error) StateMinerWorker(context.Context, address.Address, *types.TipSet) (address.Address, error) - StateMinerElectionPeriodStart(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error) + StateMinerElectionPeriodStart(ctx context.Context, actor address.Address, ts *types.TipSet) (abi.ChainEpoch, error) StateMinerSectors(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error) StateMinerProvingSet(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error) - StateMinerSectorSize(context.Context, address.Address, *types.TipSet) (uint64, error) + StateMinerSectorSize(context.Context, address.Address, *types.TipSet) (abi.SectorSize, error) StateWaitMsg(context.Context, cid.Cid) (*api.MsgWait, error) // TODO: removeme eventually StateGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error) StateGetReceipt(context.Context, cid.Cid, *types.TipSet) (*types.MessageReceipt, error) - StateMarketStorageDeal(context.Context, uint64, *types.TipSet) (*actors.OnChainDeal, error) + StateMarketStorageDeal(context.Context, abi.DealID, *types.TipSet) (*market.DealProposal, error) MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error) ChainHead(context.Context) (*types.TipSet, error) ChainNotify(context.Context) (<-chan []*store.HeadChange, error) ChainGetRandomness(context.Context, types.TipSetKey, int64) ([]byte, error) - ChainGetTipSetByHeight(context.Context, uint64, *types.TipSet) (*types.TipSet, error) + ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, *types.TipSet) (*types.TipSet, error) ChainGetBlockMessages(context.Context, cid.Cid) (*api.BlockMessages, error) ChainReadObj(context.Context, cid.Cid) ([]byte, error) @@ -95,7 +96,7 @@ func (m *Sealing) Stop(ctx context.Context) error { return m.sectors.Stop(ctx) } -func (m *Sealing) AllocatePiece(size uint64) (sectorID uint64, offset uint64, err error) { +func (m *Sealing) AllocatePiece(size uint64) (sectorID abi.SectorNumber, offset uint64, err error) { if padreader.PaddedSize(size) != size { return 0, 0, xerrors.Errorf("cannot allocate unpadded piece") } @@ -109,10 +110,10 @@ func (m *Sealing) AllocatePiece(size uint64) (sectorID uint64, offset uint64, er return sid, 0, nil } -func (m *Sealing) SealPiece(ctx context.Context, size uint64, r io.Reader, sectorID uint64, dealID uint64) error { +func (m *Sealing) SealPiece(ctx context.Context, size abi.UnpaddedPieceSize, r io.Reader, sectorID abi.SectorNumber, dealID abi.DealID) error { log.Infof("Seal piece for deal %d", dealID) - ppi, err := m.sb.AddPiece(ctx, size, sectorID, r, []uint64{}) + ppi, err := m.sb.AddPiece(ctx, size, sectorID, r, []abi.UnpaddedPieceSize{}) if err != nil { return xerrors.Errorf("adding piece to sector: %w", err) } @@ -120,7 +121,7 @@ func (m *Sealing) SealPiece(ctx context.Context, size uint64, r io.Reader, secto return m.newSector(ctx, sectorID, dealID, ppi) } -func (m *Sealing) newSector(ctx context.Context, sid uint64, dealID uint64, ppi sectorbuilder.PublicPieceInfo) error { +func (m *Sealing) newSector(ctx context.Context, sid abi.SectorNumber, dealID abi.DealID, ppi sectorbuilder.PublicPieceInfo) error { log.Infof("Start sealing %d", sid) return m.sectors.Send(sid, SectorStart{ id: sid, @@ -128,7 +129,7 @@ func (m *Sealing) newSector(ctx context.Context, sid uint64, dealID uint64, ppi { DealID: dealID, - Size: ppi.Size, + Size: abi.UnpaddedPieceSize(ppi.Size), CommP: ppi.CommP[:], }, }, diff --git a/states.go b/states.go index 723a2d843..7288770cc 100644 --- a/states.go +++ b/states.go @@ -3,8 +3,8 @@ package sealing import ( "context" - sectorbuilder "github.com/filecoin-project/go-sectorbuilder" "github.com/filecoin-project/go-sectorbuilder/fs" + "github.com/filecoin-project/specs-actors/actors/abi" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/build" @@ -16,12 +16,12 @@ import ( func (m *Sealing) handlePacking(ctx statemachine.Context, sector SectorInfo) error { log.Infow("performing filling up rest of the sector...", "sector", sector.SectorID) - var allocated uint64 + var allocated abi.UnpaddedPieceSize for _, piece := range sector.Pieces { allocated += piece.Size } - ubytes := sectorbuilder.UserBytesForSectorSize(m.sb.SectorSize()) + ubytes := abi.PaddedPieceSize(m.sb.SectorSize()).Unpadded() if allocated > ubytes { return xerrors.Errorf("too much data in sector: %d > %d", allocated, ubytes) @@ -100,7 +100,7 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf CommR: sector.CommR, SealEpoch: sector.Ticket.BlockHeight, - DealIDs: sector.deals(), + DealIDs: nil, // sector.deals(), // TODO: REFACTOR } enc, aerr := actors.SerializeParams(params) if aerr != nil { @@ -144,7 +144,7 @@ func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) er randHeight := mw.TipSet.Height() + build.InteractivePoRepDelay - 1 // -1 because of how the messages are applied log.Infof("precommit for sector %d made it on chain, will start proof computation at height %d", sector.SectorID, randHeight) - err = m.events.ChainAt(func(ectx context.Context, ts *types.TipSet, curH uint64) error { + err = m.events.ChainAt(func(ectx context.Context, ts *types.TipSet, curH abi.ChainEpoch) error { rand, err := m.api.ChainGetRandomness(ectx, ts.Key(), int64(randHeight)) if err != nil { err = xerrors.Errorf("failed to get randomness for computing seal proof: %w", err) @@ -181,13 +181,13 @@ func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) // TODO: Consider splitting states and persist proof for faster recovery - params := &actors.SectorProveCommitInfo{ + /*params := &actors.SectorProveCommitInfo{ Proof: proof, SectorID: sector.SectorID, DealIDs: sector.deals(), - } + }*/ - enc, aerr := actors.SerializeParams(params) + enc, aerr := actors.SerializeParams(nil) // TODO: REFACTOR: Fix if aerr != nil { return ctx.Send(SectorCommitFailed{xerrors.Errorf("could not serialize commit sector parameters: %w", aerr)}) } @@ -255,7 +255,7 @@ func (m *Sealing) handleFaulty(ctx statemachine.Context, sector SectorInfo) erro // TODO: coalesce faulty sector reporting bf := types.NewBitField() - bf.Set(sector.SectorID) + bf.Set(uint64(sector.SectorID)) enc, aerr := actors.SerializeParams(&actors.DeclareFaultsParams{bf}) if aerr != nil { diff --git a/types.go b/types.go index f0fbe09a4..ebec1ee1c 100644 --- a/types.go +++ b/types.go @@ -3,6 +3,7 @@ package sealing import ( sectorbuilder "github.com/filecoin-project/go-sectorbuilder" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/specs-actors/actors/abi" "github.com/ipfs/go-cid" ) @@ -18,12 +19,12 @@ func (t *SealTicket) SB() sectorbuilder.SealTicket { } type SealSeed struct { - BlockHeight uint64 + BlockHeight abi.ChainEpoch TicketBytes []byte } func (t *SealSeed) SB() sectorbuilder.SealSeed { - out := sectorbuilder.SealSeed{BlockHeight: t.BlockHeight} + out := sectorbuilder.SealSeed{BlockHeight: uint64(t.BlockHeight)} copy(out.TicketBytes[:], t.TicketBytes) return out } @@ -33,14 +34,14 @@ func (t *SealSeed) Equals(o *SealSeed) bool { } type Piece struct { - DealID uint64 + DealID abi.DealID - Size uint64 + Size abi.UnpaddedPieceSize CommP []byte } func (p *Piece) ppi() (out sectorbuilder.PublicPieceInfo) { - out.Size = p.Size + out.Size = uint64(p.Size) copy(out.CommP[:], p.CommP) return out } @@ -57,7 +58,7 @@ type Log struct { type SectorInfo struct { State api.SectorState - SectorID uint64 + SectorID abi.SectorNumber Nonce uint64 // TODO: remove // Packing @@ -95,16 +96,16 @@ func (t *SectorInfo) pieceInfos() []sectorbuilder.PublicPieceInfo { return out } -func (t *SectorInfo) deals() []uint64 { - out := make([]uint64, len(t.Pieces)) +func (t *SectorInfo) deals() []abi.DealID { + out := make([]abi.DealID, len(t.Pieces)) for i, piece := range t.Pieces { out[i] = piece.DealID } return out } -func (t *SectorInfo) existingPieces() []uint64 { - out := make([]uint64, len(t.Pieces)) +func (t *SectorInfo) existingPieces() []abi.UnpaddedPieceSize { + out := make([]abi.UnpaddedPieceSize, len(t.Pieces)) for i, piece := range t.Pieces { out[i] = piece.Size } diff --git a/utils.go b/utils.go index b2221b278..d03393405 100644 --- a/utils.go +++ b/utils.go @@ -6,12 +6,13 @@ import ( "math/rand" "sync" + "github.com/filecoin-project/specs-actors/actors/abi" "github.com/hashicorp/go-multierror" sectorbuilder "github.com/filecoin-project/go-sectorbuilder" ) -func fillersFromRem(toFill uint64) ([]uint64, error) { +func fillersFromRem(in abi.UnpaddedPieceSize) ([]abi.UnpaddedPieceSize, error) { // Convert to in-sector bytes for easier math: // // Sector size to user bytes ratio is constant, e.g. for 1024B we have 1016B @@ -24,13 +25,13 @@ func fillersFromRem(toFill uint64) ([]uint64, error) { // // (we convert to sector bytes as they are nice round binary numbers) - toFill += toFill / 127 + toFill := uint64(in + (in / 127)) // We need to fill the sector with pieces that are powers of 2. Conveniently // computers store numbers in binary, which means we can look at 1s to get // all the piece sizes we need to fill the sector. It also means that number // of pieces is the number of 1s in the number of remaining bytes to fill - out := make([]uint64, bits.OnesCount64(toFill)) + out := make([]abi.UnpaddedPieceSize, bits.OnesCount64(toFill)) for i := range out { // Extract the next lowest non-zero bit next := bits.TrailingZeros64(toFill) @@ -42,18 +43,18 @@ func fillersFromRem(toFill uint64) ([]uint64, error) { toFill ^= psize // Add the piece size to the list of pieces we need to create - out[i] = sectorbuilder.UserBytesForSectorSize(psize) + out[i] = abi.PaddedPieceSize(psize).Unpadded() } return out, nil } -func (m *Sealing) fastPledgeCommitment(size uint64, parts uint64) (commP [sectorbuilder.CommLen]byte, err error) { +func (m *Sealing) fastPledgeCommitment(size abi.UnpaddedPieceSize, parts uint64) (commP [sectorbuilder.CommLen]byte, err error) { parts = 1 << bits.Len64(parts) // round down to nearest power of 2 - if size/parts < 127 { - parts = size / 127 + if uint64(size)/parts < 127 { + parts = uint64(size) / 127 } - piece := sectorbuilder.UserBytesForSectorSize((size + size/127) / parts) + piece := abi.PaddedPieceSize(uint64(size.Padded()) / parts).Unpadded() out := make([]sectorbuilder.PublicPieceInfo, parts) var lk sync.Mutex @@ -70,7 +71,7 @@ func (m *Sealing) fastPledgeCommitment(size uint64, parts uint64) (commP [sector err = multierror.Append(err, perr) } out[i] = sectorbuilder.PublicPieceInfo{ - Size: piece, + Size: uint64(piece), CommP: commP, } lk.Unlock() From 68eb35e0f4bed1d30e44ce2877315afe07d0738e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 8 Feb 2020 03:18:37 +0100 Subject: [PATCH 051/126] gofmt --- garbage.go | 6 +++--- utils.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/garbage.go b/garbage.go index 52f2eb9cb..b55f0c56a 100644 --- a/garbage.go +++ b/garbage.go @@ -52,14 +52,14 @@ func (m *Sealing) pledgeSector(ctx context.Context, sectorID abi.SectorNumber, e PieceSize: size.Padded(), Client: m.worker, Provider: m.maddr, - StartEpoch: math.MaxInt64, + StartEpoch: math.MaxInt64, EndEpoch: math.MaxInt64, StoragePricePerEpoch: types.NewInt(0), - ProviderCollateral: types.NewInt(0), + ProviderCollateral: types.NewInt(0), } deals[i] = market.ClientDealProposal{ - Proposal: sdp, + Proposal: sdp, } } diff --git a/utils.go b/utils.go index d03393405..967e2c9a2 100644 --- a/utils.go +++ b/utils.go @@ -71,7 +71,7 @@ func (m *Sealing) fastPledgeCommitment(size abi.UnpaddedPieceSize, parts uint64) err = multierror.Append(err, perr) } out[i] = sectorbuilder.PublicPieceInfo{ - Size: uint64(piece), + Size: uint64(piece), CommP: commP, } lk.Unlock() From fb495e98b432f2e3383a85d0fcee3d0514160827 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sun, 9 Feb 2020 07:06:32 +0100 Subject: [PATCH 052/126] specs-actors: Fix most compilation errors --- checks.go | 10 +++++----- fsm.go | 3 ++- sealing.go | 6 +++--- utils.go | 2 +- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/checks.go b/checks.go index a94cd20da..d6884d988 100644 --- a/checks.go +++ b/checks.go @@ -40,7 +40,7 @@ func checkPieces(ctx context.Context, si SectorInfo, api sealingApi) error { return &ErrApi{xerrors.Errorf("getting deal %d for piece %d: %w", piece.DealID, i, err)} } - h, err := multihash.Decode(deal.PieceCID.Hash()) + h, err := multihash.Decode(deal.Proposal.PieceCID.Hash()) if err != nil { return &ErrInvalidDeals{xerrors.Errorf("decoding piece CID: %w", err)} } @@ -49,12 +49,12 @@ func checkPieces(ctx context.Context, si SectorInfo, api sealingApi) error { return &ErrInvalidDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers deal %d with wrong CommP: %x != %x", i, len(si.Pieces), si.SectorID, piece.DealID, piece.CommP, h.Digest)} } - if piece.Size != deal.PieceSize.Unpadded() { - return &ErrInvalidDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers deal %d with different size: %d != %d", i, len(si.Pieces), si.SectorID, piece.DealID, piece.Size, deal.PieceSize)} + if piece.Size != deal.Proposal.PieceSize.Unpadded() { + return &ErrInvalidDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers deal %d with different size: %d != %d", i, len(si.Pieces), si.SectorID, piece.DealID, piece.Size, deal.Proposal.PieceSize)} } - if head.Height() >= deal.StartEpoch { - return &ErrExpiredDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers expired deal %d - should start at %d, head %d", i, len(si.Pieces), si.SectorID, piece.DealID, deal.StartEpoch, head.Height())} + if head.Height() >= deal.Proposal.StartEpoch { + return &ErrExpiredDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers expired deal %d - should start at %d, head %d", i, len(si.Pieces), si.SectorID, piece.DealID, deal.Proposal.StartEpoch, head.Height())} } } diff --git a/fsm.go b/fsm.go index 6ed5c0cfc..59449303b 100644 --- a/fsm.go +++ b/fsm.go @@ -6,6 +6,7 @@ import ( "reflect" "time" + "github.com/filecoin-project/specs-actors/actors/abi" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/api" @@ -237,7 +238,7 @@ func (m *Sealing) restartSectors(ctx context.Context) error { return nil } -func (m *Sealing) ForceSectorState(ctx context.Context, id uint64, state api.SectorState) error { +func (m *Sealing) ForceSectorState(ctx context.Context, id abi.SectorNumber, state api.SectorState) error { return m.sectors.Send(id, SectorForceState{state}) } diff --git a/sealing.go b/sealing.go index a9e080328..127a032c2 100644 --- a/sealing.go +++ b/sealing.go @@ -5,15 +5,15 @@ import ( "io" "github.com/filecoin-project/go-address" - "github.com/filecoin-project/go-sectorbuilder" "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/specs-actors/actors/builtin/market" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/namespace" logging "github.com/ipfs/go-log/v2" "golang.org/x/xerrors" + "github.com/filecoin-project/go-sectorbuilder" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/events" "github.com/filecoin-project/lotus/chain/store" @@ -39,7 +39,7 @@ type sealingApi interface { // TODO: trim down StateWaitMsg(context.Context, cid.Cid) (*api.MsgWait, error) // TODO: removeme eventually StateGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error) StateGetReceipt(context.Context, cid.Cid, *types.TipSet) (*types.MessageReceipt, error) - StateMarketStorageDeal(context.Context, abi.DealID, *types.TipSet) (*market.DealProposal, error) + StateMarketStorageDeal(context.Context, abi.DealID, *types.TipSet) (*api.MarketDeal, error) MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error) diff --git a/utils.go b/utils.go index 967e2c9a2..86458ba41 100644 --- a/utils.go +++ b/utils.go @@ -94,7 +94,7 @@ func (m *Sealing) ListSectors() ([]SectorInfo, error) { return sectors, nil } -func (m *Sealing) GetSectorInfo(sid uint64) (SectorInfo, error) { +func (m *Sealing) GetSectorInfo(sid abi.SectorNumber) (SectorInfo, error) { var out SectorInfo err := m.sectors.Get(sid).Get(&out) return out, err From 0225142b901f44c2ffbae7f795e1b2fb14209c35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 10 Feb 2020 20:16:36 +0100 Subject: [PATCH 053/126] specs-actors: Fis some test compilation errors --- utils_test.go | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/utils_test.go b/utils_test.go index 94bf858c1..a5287fd87 100644 --- a/utils_test.go +++ b/utils_test.go @@ -1,20 +1,21 @@ package sealing import ( - "github.com/filecoin-project/lotus/storage/sbmock" "testing" - "github.com/stretchr/testify/assert" + "github.com/filecoin-project/specs-actors/actors/abi" - sectorbuilder "github.com/filecoin-project/go-sectorbuilder" + "github.com/filecoin-project/lotus/storage/sbmock" + + "github.com/stretchr/testify/assert" ) -func testFill(t *testing.T, n uint64, exp []uint64) { +func testFill(t *testing.T, n abi.UnpaddedPieceSize, exp []abi.UnpaddedPieceSize) { f, err := fillersFromRem(n) assert.NoError(t, err) assert.Equal(t, exp, f) - var sum uint64 + var sum abi.UnpaddedPieceSize for _, u := range f { sum += u } @@ -24,39 +25,39 @@ func testFill(t *testing.T, n uint64, exp []uint64) { func TestFillersFromRem(t *testing.T) { for i := 8; i < 32; i++ { // single - ub := sectorbuilder.UserBytesForSectorSize(uint64(1) << i) - testFill(t, ub, []uint64{ub}) + ub := abi.PaddedPieceSize(uint64(1) << i).Unpadded() + testFill(t, ub, []abi.UnpaddedPieceSize{ub}) // 2 - ub = sectorbuilder.UserBytesForSectorSize(uint64(5) << i) - ub1 := sectorbuilder.UserBytesForSectorSize(uint64(1) << i) - ub3 := sectorbuilder.UserBytesForSectorSize(uint64(4) << i) - testFill(t, ub, []uint64{ub1, ub3}) + ub = abi.PaddedPieceSize(uint64(5) << i).Unpadded() + ub1 := abi.PaddedPieceSize(uint64(1) << i).Unpadded() + ub3 := abi.PaddedPieceSize(uint64(4) << i).Unpadded() + testFill(t, ub, []abi.UnpaddedPieceSize{ub1, ub3}) // 4 - ub = sectorbuilder.UserBytesForSectorSize(uint64(15) << i) - ub2 := sectorbuilder.UserBytesForSectorSize(uint64(2) << i) - ub4 := sectorbuilder.UserBytesForSectorSize(uint64(8) << i) - testFill(t, ub, []uint64{ub1, ub2, ub3, ub4}) + ub = abi.PaddedPieceSize(uint64(15) << i).Unpadded() + ub2 := abi.PaddedPieceSize(uint64(2) << i).Unpadded() + ub4 := abi.PaddedPieceSize(uint64(8) << i).Unpadded() + testFill(t, ub, []abi.UnpaddedPieceSize{ub1, ub2, ub3, ub4}) // different 2 - ub = sectorbuilder.UserBytesForSectorSize(uint64(9) << i) - testFill(t, ub, []uint64{ub1, ub4}) + ub = abi.PaddedPieceSize(uint64(9) << i).Unpadded() + testFill(t, ub, []abi.UnpaddedPieceSize{ub1, ub4}) } } func TestFastPledge(t *testing.T) { - sz := uint64(16 << 20) + sz := abi.PaddedPieceSize(16 << 20) - s := Sealing{sb: sbmock.NewMockSectorBuilder(0, sz)} - if _, err := s.fastPledgeCommitment(sectorbuilder.UserBytesForSectorSize(sz), 5); err != nil { + s := Sealing{sb: sbmock.NewMockSectorBuilder(0, abi.SectorSize(sz))} + if _, err := s.fastPledgeCommitment(sz.Unpadded(), 5); err != nil { t.Fatalf("%+v", err) } - sz = uint64(1024) + sz = abi.PaddedPieceSize(1024) - s = Sealing{sb: sbmock.NewMockSectorBuilder(0, sz)} - if _, err := s.fastPledgeCommitment(sectorbuilder.UserBytesForSectorSize(sz), 64); err != nil { + s = Sealing{sb: sbmock.NewMockSectorBuilder(0, abi.SectorSize(sz))} + if _, err := s.fastPledgeCommitment(sz.Unpadded(), 64); err != nil { t.Fatalf("%+v", err) } } From cd31b6721c3651b5ea3326e94b7da85d89dc79b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 11 Feb 2020 02:10:50 +0100 Subject: [PATCH 054/126] Fix compilation after dep updates --- garbage.go | 2 +- sealing.go | 8 ++++---- types.go | 2 +- utils.go | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/garbage.go b/garbage.go index b55f0c56a..89f7f64cb 100644 --- a/garbage.go +++ b/garbage.go @@ -128,7 +128,7 @@ func (m *Sealing) PledgeSector() error { size := abi.PaddedPieceSize(m.sb.SectorSize()).Unpadded() - sid, err := m.sb.AcquireSectorId() + sid, err := m.sb.AcquireSectorNumber() if err != nil { log.Errorf("%+v", err) return diff --git a/sealing.go b/sealing.go index 127a032c2..eb1ef3eb5 100644 --- a/sealing.go +++ b/sealing.go @@ -12,13 +12,13 @@ import ( logging "github.com/ipfs/go-log/v2" "golang.org/x/xerrors" + "github.com/filecoin-project/go-padreader" "github.com/filecoin-project/go-sectorbuilder" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/events" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/lib/padreader" "github.com/filecoin-project/lotus/lib/statemachine" ) @@ -96,12 +96,12 @@ func (m *Sealing) Stop(ctx context.Context) error { return m.sectors.Stop(ctx) } -func (m *Sealing) AllocatePiece(size uint64) (sectorID abi.SectorNumber, offset uint64, err error) { - if padreader.PaddedSize(size) != size { +func (m *Sealing) AllocatePiece(size abi.UnpaddedPieceSize) (sectorID abi.SectorNumber, offset uint64, err error) { + if (padreader.PaddedSize(uint64(size))) != size { return 0, 0, xerrors.Errorf("cannot allocate unpadded piece") } - sid, err := m.sb.AcquireSectorId() // TODO: Put more than one thing in a sector + sid, err := m.sb.AcquireSectorNumber() // TODO: Put more than one thing in a sector if err != nil { return 0, 0, xerrors.Errorf("acquiring sector ID: %w", err) } diff --git a/types.go b/types.go index ebec1ee1c..b45a75a3b 100644 --- a/types.go +++ b/types.go @@ -41,7 +41,7 @@ type Piece struct { } func (p *Piece) ppi() (out sectorbuilder.PublicPieceInfo) { - out.Size = uint64(p.Size) + out.Size = p.Size copy(out.CommP[:], p.CommP) return out } diff --git a/utils.go b/utils.go index 86458ba41..0bfbb30fe 100644 --- a/utils.go +++ b/utils.go @@ -71,7 +71,7 @@ func (m *Sealing) fastPledgeCommitment(size abi.UnpaddedPieceSize, parts uint64) err = multierror.Append(err, perr) } out[i] = sectorbuilder.PublicPieceInfo{ - Size: uint64(piece), + Size: piece, CommP: commP, } lk.Unlock() From f5c78e67b0f4650ddcf286a2ef305845b9ced1d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 11 Feb 2020 03:33:27 +0100 Subject: [PATCH 055/126] stmgr: Update stmgr utils --- checks.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/checks.go b/checks.go index d6884d988..6cfddee26 100644 --- a/checks.go +++ b/checks.go @@ -3,6 +3,7 @@ package sealing import ( "context" + "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/multiformats/go-multihash" "golang.org/x/xerrors" @@ -88,7 +89,7 @@ func checkSeal(ctx context.Context, maddr address.Address, si SectorInfo, api se Value: types.NewInt(0), GasPrice: types.NewInt(0), GasLimit: types.NewInt(9999999999), - Method: actors.SMAMethods.ComputeDataCommitment, + Method: builtin.MethodsMarket.ComputeDataCommitment, Params: ccparams, } r, err := api.StateCall(ctx, ccmt, nil) From 835ca2801c78997323e522d5d553567b8d18d7cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 11 Feb 2020 04:31:28 +0100 Subject: [PATCH 056/126] wip gengen fixing --- states.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/states.go b/states.go index 7288770cc..915f40edf 100644 --- a/states.go +++ b/states.go @@ -5,6 +5,7 @@ import ( "github.com/filecoin-project/go-sectorbuilder/fs" "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin/miner" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/build" @@ -95,7 +96,7 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf } } - params := &actors.SectorPreCommitInfo{ + params := &miner.PreCommitSectorParams{ SectorNumber: sector.SectorID, CommR: sector.CommR, From 0279e8a34a608a5da7c5aec8983a9ce0909bbcac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 11 Feb 2020 21:48:03 +0100 Subject: [PATCH 057/126] genesis: Cleanup the structure --- garbage.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/garbage.go b/garbage.go index 89f7f64cb..914de414a 100644 --- a/garbage.go +++ b/garbage.go @@ -10,6 +10,7 @@ import ( commcid "github.com/filecoin-project/go-fil-commcid" "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/actors/builtin/market" "golang.org/x/xerrors" @@ -65,7 +66,7 @@ func (m *Sealing) pledgeSector(ctx context.Context, sectorID abi.SectorNumber, e log.Infof("Publishing deals for %d", sectorID) - params, aerr := actors.SerializeParams(&actors.PublishStorageDealsParams{ + params, aerr := actors.SerializeParams(&market.PublishStorageDealsParams{ Deals: deals, }) if aerr != nil { @@ -78,7 +79,7 @@ func (m *Sealing) pledgeSector(ctx context.Context, sectorID abi.SectorNumber, e Value: types.NewInt(0), GasPrice: types.NewInt(0), GasLimit: types.NewInt(1000000), - Method: actors.SMAMethods.PublishStorageDeals, + Method: builtin.MethodsMarket.PublishStorageDeals, Params: params, }) if err != nil { From bcea739cffe4440b79fcdf12aae6482fa3ae823b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 12 Feb 2020 01:58:55 +0100 Subject: [PATCH 058/126] genesis: Change template types --- states.go | 13 +++++++++---- types.go | 4 ++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/states.go b/states.go index 915f40edf..cd52a8e46 100644 --- a/states.go +++ b/states.go @@ -3,6 +3,7 @@ package sealing import ( "context" + commcid "github.com/filecoin-project/go-fil-commcid" "github.com/filecoin-project/go-sectorbuilder/fs" "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/builtin/miner" @@ -97,11 +98,15 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf } params := &miner.PreCommitSectorParams{ - SectorNumber: sector.SectorID, + Info: miner.SectorPreCommitInfo{ + Expiration: 0, + SectorNumber: sector.SectorID, + + SealedCID: commcid.ReplicaCommitmentV1ToCID(sector.CommR), + SealEpoch: sector.Ticket.BlockHeight, + DealIDs: nil, // sector.deals(), // TODO: REFACTOR + }, - CommR: sector.CommR, - SealEpoch: sector.Ticket.BlockHeight, - DealIDs: nil, // sector.deals(), // TODO: REFACTOR } enc, aerr := actors.SerializeParams(params) if aerr != nil { diff --git a/types.go b/types.go index b45a75a3b..ccfe50427 100644 --- a/types.go +++ b/types.go @@ -8,12 +8,12 @@ import ( ) type SealTicket struct { - BlockHeight uint64 + BlockHeight abi.ChainEpoch TicketBytes []byte } func (t *SealTicket) SB() sectorbuilder.SealTicket { - out := sectorbuilder.SealTicket{BlockHeight: t.BlockHeight} + out := sectorbuilder.SealTicket{BlockHeight: uint64(t.BlockHeight)} copy(out.TicketBytes[:], t.TicketBytes) return out } From 939610a93034a6e626ab656b3afa9c4eef6a5850 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 12 Feb 2020 08:44:20 +0100 Subject: [PATCH 059/126] Propagate spec actor types more --- cbor_gen.go | 1 - sealing.go | 1 + states.go | 29 ++++++++++++++++------------- states_failed.go | 29 +++++++++++++++++++---------- 4 files changed, 36 insertions(+), 24 deletions(-) diff --git a/cbor_gen.go b/cbor_gen.go index 21e60741f..14d42a933 100644 --- a/cbor_gen.go +++ b/cbor_gen.go @@ -102,7 +102,6 @@ func (t *SealTicket) UnmarshalCBOR(r io.Reader) error { if maj != cbg.MajUnsignedInt { return fmt.Errorf("wrong type for uint64 field") } - t.BlockHeight = uint64(extra) // t.TicketBytes ([]uint8) (slice) case "TicketBytes": diff --git a/sealing.go b/sealing.go index eb1ef3eb5..8882ca62c 100644 --- a/sealing.go +++ b/sealing.go @@ -49,6 +49,7 @@ type sealingApi interface { // TODO: trim down ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, *types.TipSet) (*types.TipSet, error) ChainGetBlockMessages(context.Context, cid.Cid) (*api.BlockMessages, error) ChainReadObj(context.Context, cid.Cid) ([]byte, error) + ChainHasObj(context.Context, cid.Cid) (bool, error) WalletSign(context.Context, address.Address, []byte) (*types.Signature, error) WalletBalance(context.Context, address.Address) (types.BigInt, error) diff --git a/states.go b/states.go index cd52a8e46..33202abbd 100644 --- a/states.go +++ b/states.go @@ -6,6 +6,7 @@ import ( commcid "github.com/filecoin-project/go-fil-commcid" "github.com/filecoin-project/go-sectorbuilder/fs" "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/actors/builtin/miner" "golang.org/x/xerrors" @@ -76,7 +77,7 @@ func (m *Sealing) handleUnsealed(ctx statemachine.Context, sector SectorInfo) er commD: rspco.CommD[:], commR: rspco.CommR[:], ticket: SealTicket{ - BlockHeight: ticket.BlockHeight, + BlockHeight: abi.ChainEpoch(ticket.BlockHeight), TicketBytes: ticket.TicketBytes[:], }, }) @@ -116,7 +117,7 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf msg := &types.Message{ To: m.maddr, From: m.worker, - Method: actors.MAMethods.PreCommitSector, + Method: builtin.MethodsMiner.PreCommitSector, Params: enc, Value: types.NewInt(0), // TODO: need to ensure sufficient collateral GasLimit: types.NewInt(1000000 /* i dont know help */), @@ -187,13 +188,12 @@ func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) // TODO: Consider splitting states and persist proof for faster recovery - /*params := &actors.SectorProveCommitInfo{ - Proof: proof, - SectorID: sector.SectorID, - DealIDs: sector.deals(), - }*/ + params := &miner.ProveCommitSectorParams{ + SectorNumber: sector.SectorID, + Proof: abi.SealProof{ProofBytes:proof}, + } - enc, aerr := actors.SerializeParams(nil) // TODO: REFACTOR: Fix + enc, aerr := actors.SerializeParams(params) if aerr != nil { return ctx.Send(SectorCommitFailed{xerrors.Errorf("could not serialize commit sector parameters: %w", aerr)}) } @@ -201,7 +201,7 @@ func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) msg := &types.Message{ To: m.maddr, From: m.worker, - Method: actors.MAMethods.ProveCommitSector, + Method: builtin.MethodsMiner.ProveCommitSector, Params: enc, Value: types.NewInt(0), // TODO: need to ensure sufficient collateral GasLimit: types.NewInt(1000000 /* i dont know help */), @@ -260,10 +260,13 @@ func (m *Sealing) handleFaulty(ctx statemachine.Context, sector SectorInfo) erro // TODO: check if the fault has already been reported, and that this sector is even valid // TODO: coalesce faulty sector reporting - bf := types.NewBitField() - bf.Set(uint64(sector.SectorID)) + /*bf := types.NewBitField() + bf.Set(uint64(sector.SectorID))*/ - enc, aerr := actors.SerializeParams(&actors.DeclareFaultsParams{bf}) + enc, aerr := actors.SerializeParams(&miner.DeclareTemporaryFaultsParams{ + SectorNumbers: []abi.SectorNumber{sector.SectorID}, + Duration: 99999999, // TODO: This is very unlikely to be the correct number + }) if aerr != nil { return xerrors.Errorf("failed to serialize declare fault params: %w", aerr) } @@ -271,7 +274,7 @@ func (m *Sealing) handleFaulty(ctx statemachine.Context, sector SectorInfo) erro msg := &types.Message{ To: m.maddr, From: m.worker, - Method: actors.MAMethods.DeclareFaults, + Method: builtin.MethodsMiner.DeclareTemporaryFaults, Params: enc, Value: types.NewInt(0), // TODO: need to ensure sufficient collateral GasLimit: types.NewInt(1000000 /* i dont know help */), diff --git a/states_failed.go b/states_failed.go index 680ba6891..faf878b64 100644 --- a/states_failed.go +++ b/states_failed.go @@ -2,13 +2,17 @@ package sealing import ( "bytes" - "fmt" "time" + commcid "github.com/filecoin-project/go-fil-commcid" + "github.com/filecoin-project/specs-actors/actors/builtin/miner" + "github.com/filecoin-project/specs-actors/actors/util/adt" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/apibstore" "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/lib/statemachine" ) @@ -28,7 +32,7 @@ func failedCooldown(ctx statemachine.Context, sector SectorInfo) error { return nil } -func (m *Sealing) checkPreCommitted(ctx statemachine.Context, sector SectorInfo) (*actors.PreCommittedSector, bool) { +func (m *Sealing) checkPreCommitted(ctx statemachine.Context, sector SectorInfo) (*miner.SectorPreCommitOnChainInfo, bool) { act, err := m.api.StateGetActor(ctx.Context(), m.maddr, nil) if err != nil { log.Errorf("handleSealFailed(%d): temp error: %+v", sector.SectorID, err) @@ -47,14 +51,14 @@ func (m *Sealing) checkPreCommitted(ctx statemachine.Context, sector SectorInfo) return nil, true } - pci, found := state.PreCommittedSectors[fmt.Sprint(sector.SectorID)] - if found { - // TODO: If not expired yet, we can just try reusing sealticket - log.Warnf("sector %d found in miner preseal array", sector.SectorID) - return pci, true + var pci miner.SectorPreCommitOnChainInfo + precommits := adt.AsMap(store.ActorStore(ctx.Context(), apibstore.NewAPIBlockstore(m.api)), state.PreCommittedSectors) + if _, err := precommits.Get(adt.IntKey(sector.SectorID), &pci); err != nil { + log.Error(err) + return nil, true } - return nil, false + return &pci, false } func (m *Sealing) handleSealFailed(ctx statemachine.Context, sector SectorInfo) error { @@ -92,8 +96,13 @@ func (m *Sealing) handlePreCommitFailed(ctx statemachine.Context, sector SectorI return nil // TODO: SeedWait needs this currently } - if string(pci.Info.CommR) != string(sector.CommR) { - log.Warn("sector %d is precommitted on chain, with different CommR: %x != %x", sector.SectorID, pci.Info.CommR, sector.CommR) + pciR, err := commcid.CIDToReplicaCommitmentV1(pci.Info.SealedCID) + if err != nil { + return err + } + + if string(pciR) != string(sector.CommR) { + log.Warn("sector %d is precommitted on chain, with different CommR: %x != %x", sector.SectorID, pciR, sector.CommR) return nil // TODO: remove when the actor allows re-precommit } From 8bf95879f796bdd1cf2e146f0a0482d638447df5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 13 Feb 2020 01:10:07 +0100 Subject: [PATCH 060/126] cbor-gen fixes --- states_failed.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/states_failed.go b/states_failed.go index faf878b64..7d851b0e8 100644 --- a/states_failed.go +++ b/states_failed.go @@ -53,7 +53,7 @@ func (m *Sealing) checkPreCommitted(ctx statemachine.Context, sector SectorInfo) var pci miner.SectorPreCommitOnChainInfo precommits := adt.AsMap(store.ActorStore(ctx.Context(), apibstore.NewAPIBlockstore(m.api)), state.PreCommittedSectors) - if _, err := precommits.Get(adt.IntKey(sector.SectorID), &pci); err != nil { + if _, err := precommits.Get(adt.UIntKey(uint64(sector.SectorID)), &pci); err != nil { log.Error(err) return nil, true } From 5a24c2dc5d41e917ff0f3851384f781503c1e19f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 13 Feb 2020 01:15:33 +0100 Subject: [PATCH 061/126] Fix client market impl, gofmt --- states.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/states.go b/states.go index 33202abbd..21b267167 100644 --- a/states.go +++ b/states.go @@ -107,7 +107,6 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf SealEpoch: sector.Ticket.BlockHeight, DealIDs: nil, // sector.deals(), // TODO: REFACTOR }, - } enc, aerr := actors.SerializeParams(params) if aerr != nil { @@ -190,7 +189,7 @@ func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) params := &miner.ProveCommitSectorParams{ SectorNumber: sector.SectorID, - Proof: abi.SealProof{ProofBytes:proof}, + Proof: abi.SealProof{ProofBytes: proof}, } enc, aerr := actors.SerializeParams(params) From 8a5a5022cebbc324ac8f12ec250dee6890f22260 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 13 Feb 2020 02:37:28 +0100 Subject: [PATCH 062/126] Update cbor-gen --- cbor_gen.go | 108 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 82 insertions(+), 26 deletions(-) diff --git a/cbor_gen.go b/cbor_gen.go index 14d42a933..fe25daa2d 100644 --- a/cbor_gen.go +++ b/cbor_gen.go @@ -6,6 +6,7 @@ import ( "fmt" "io" + "github.com/filecoin-project/specs-actors/actors/abi" cbg "github.com/whyrusleeping/cbor-gen" xerrors "golang.org/x/xerrors" ) @@ -21,7 +22,7 @@ func (t *SealTicket) MarshalCBOR(w io.Writer) error { return err } - // t.BlockHeight (uint64) (uint64) + // t.BlockHeight (abi.ChainEpoch) (int64) if len("BlockHeight") > cbg.MaxLength { return xerrors.Errorf("Value in field \"BlockHeight\" was too long") } @@ -33,8 +34,14 @@ func (t *SealTicket) MarshalCBOR(w io.Writer) error { return err } - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.BlockHeight))); err != nil { - return err + if t.BlockHeight >= 0 { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.BlockHeight))); err != nil { + return err + } + } else { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajNegativeInt, uint64(-t.BlockHeight)-1)); err != nil { + return err + } } // t.TicketBytes ([]uint8) (slice) @@ -92,15 +99,31 @@ func (t *SealTicket) UnmarshalCBOR(r io.Reader) error { } switch name { - // t.BlockHeight (uint64) (uint64) + // t.BlockHeight (abi.ChainEpoch) (int64) case "BlockHeight": + { + maj, extra, err := cbg.CborReadHeader(br) + var extraI int64 + if err != nil { + return err + } + switch maj { + case cbg.MajUnsignedInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 positive overflow") + } + case cbg.MajNegativeInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 negative oveflow") + } + extraI = -1 - extraI + default: + return fmt.Errorf("wrong type for int64 field: %d", maj) + } - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") + t.BlockHeight = abi.ChainEpoch(extraI) } // t.TicketBytes ([]uint8) (slice) case "TicketBytes": @@ -137,7 +160,7 @@ func (t *SealSeed) MarshalCBOR(w io.Writer) error { return err } - // t.BlockHeight (uint64) (uint64) + // t.BlockHeight (abi.ChainEpoch) (int64) if len("BlockHeight") > cbg.MaxLength { return xerrors.Errorf("Value in field \"BlockHeight\" was too long") } @@ -149,8 +172,14 @@ func (t *SealSeed) MarshalCBOR(w io.Writer) error { return err } - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.BlockHeight))); err != nil { - return err + if t.BlockHeight >= 0 { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.BlockHeight))); err != nil { + return err + } + } else { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajNegativeInt, uint64(-t.BlockHeight)-1)); err != nil { + return err + } } // t.TicketBytes ([]uint8) (slice) @@ -208,16 +237,33 @@ func (t *SealSeed) UnmarshalCBOR(r io.Reader) error { } switch name { - // t.BlockHeight (uint64) (uint64) + // t.BlockHeight (abi.ChainEpoch) (int64) case "BlockHeight": + { + maj, extra, err := cbg.CborReadHeader(br) + var extraI int64 + if err != nil { + return err + } + switch maj { + case cbg.MajUnsignedInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 positive overflow") + } + case cbg.MajNegativeInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 negative oveflow") + } + extraI = -1 - extraI + default: + return fmt.Errorf("wrong type for int64 field: %d", maj) + } - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + t.BlockHeight = abi.ChainEpoch(extraI) } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } // t.TicketBytes ([]uint8) (slice) + // t.TicketBytes ([]uint8) (slice) case "TicketBytes": maj, extra, err = cbg.CborReadHeader(br) @@ -252,7 +298,7 @@ func (t *Piece) MarshalCBOR(w io.Writer) error { return err } - // t.DealID (uint64) (uint64) + // t.DealID (abi.DealID) (uint64) if len("DealID") > cbg.MaxLength { return xerrors.Errorf("Value in field \"DealID\" was too long") } @@ -268,7 +314,7 @@ func (t *Piece) MarshalCBOR(w io.Writer) error { return err } - // t.Size (uint64) (uint64) + // t.Size (abi.UnpaddedPieceSize) (uint64) if len("Size") > cbg.MaxLength { return xerrors.Errorf("Value in field \"Size\" was too long") } @@ -339,7 +385,7 @@ func (t *Piece) UnmarshalCBOR(r io.Reader) error { } switch name { - // t.DealID (uint64) (uint64) + // t.DealID (abi.DealID) (uint64) case "DealID": maj, extra, err = cbg.CborReadHeader(br) @@ -349,9 +395,18 @@ func (t *Piece) UnmarshalCBOR(r io.Reader) error { if maj != cbg.MajUnsignedInt { return fmt.Errorf("wrong type for uint64 field") } - // t.Size (uint64) (uint64) + t.DealID = abi.DealID(extra) + // t.Size (abi.UnpaddedPieceSize) (uint64) case "Size": + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Size = abi.UnpaddedPieceSize(extra) // t.CommP ([]uint8) (slice) case "CommP": @@ -403,7 +458,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { return err } - // t.SectorID (uint64) (uint64) + // t.SectorID (abi.SectorNumber) (uint64) if len("SectorID") > cbg.MaxLength { return xerrors.Errorf("Value in field \"SectorID\" was too long") } @@ -718,7 +773,7 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("wrong type for uint64 field") } t.State = uint64(extra) - // t.SectorID (uint64) (uint64) + // t.SectorID (abi.SectorNumber) (uint64) case "SectorID": maj, extra, err = cbg.CborReadHeader(br) @@ -728,6 +783,7 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { if maj != cbg.MajUnsignedInt { return fmt.Errorf("wrong type for uint64 field") } + t.SectorID = abi.SectorNumber(extra) // t.Nonce (uint64) (uint64) case "Nonce": From 944ba527f355ae0221416447645a1fb9e376e729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 14 Feb 2020 01:24:24 +0100 Subject: [PATCH 063/126] use specs-actors birfields --- states.go | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/states.go b/states.go index 21b267167..2ec3dd082 100644 --- a/states.go +++ b/states.go @@ -98,16 +98,14 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf } } - params := &miner.PreCommitSectorParams{ - Info: miner.SectorPreCommitInfo{ + params := &miner.SectorPreCommitInfo{ Expiration: 0, SectorNumber: sector.SectorID, SealedCID: commcid.ReplicaCommitmentV1ToCID(sector.CommR), SealEpoch: sector.Ticket.BlockHeight, DealIDs: nil, // sector.deals(), // TODO: REFACTOR - }, - } + } enc, aerr := actors.SerializeParams(params) if aerr != nil { return ctx.Send(SectorPreCommitFailed{xerrors.Errorf("could not serialize commit sector parameters: %w", aerr)}) @@ -259,11 +257,11 @@ func (m *Sealing) handleFaulty(ctx statemachine.Context, sector SectorInfo) erro // TODO: check if the fault has already been reported, and that this sector is even valid // TODO: coalesce faulty sector reporting - /*bf := types.NewBitField() - bf.Set(uint64(sector.SectorID))*/ + bf := abi.NewBitField() + bf.Set(uint64(sector.SectorID)) enc, aerr := actors.SerializeParams(&miner.DeclareTemporaryFaultsParams{ - SectorNumbers: []abi.SectorNumber{sector.SectorID}, + SectorNumbers: bf, Duration: 99999999, // TODO: This is very unlikely to be the correct number }) if aerr != nil { From 175b0e88a3ad8b7769a730c1d70d13487dc03e87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 14 Feb 2020 22:38:30 +0100 Subject: [PATCH 064/126] gofmt --- states.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/states.go b/states.go index 2ec3dd082..6d7f2822b 100644 --- a/states.go +++ b/states.go @@ -99,13 +99,13 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf } params := &miner.SectorPreCommitInfo{ - Expiration: 0, - SectorNumber: sector.SectorID, + Expiration: 0, + SectorNumber: sector.SectorID, - SealedCID: commcid.ReplicaCommitmentV1ToCID(sector.CommR), - SealEpoch: sector.Ticket.BlockHeight, - DealIDs: nil, // sector.deals(), // TODO: REFACTOR - } + SealedCID: commcid.ReplicaCommitmentV1ToCID(sector.CommR), + SealEpoch: sector.Ticket.BlockHeight, + DealIDs: nil, // sector.deals(), // TODO: REFACTOR + } enc, aerr := actors.SerializeParams(params) if aerr != nil { return ctx.Send(SectorPreCommitFailed{xerrors.Errorf("could not serialize commit sector parameters: %w", aerr)}) From 15722b4bb9067b945ab6c539fa5adc8f7b54fdba Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Tue, 11 Feb 2020 15:29:45 -0800 Subject: [PATCH 065/126] Re: #1250: API methods should receive TipSetKeys, not TipSets, as input --- checks.go | 6 +++--- sealing.go | 20 ++++++++++---------- states_failed.go | 3 ++- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/checks.go b/checks.go index 9baf2d993..cbcbca8fc 100644 --- a/checks.go +++ b/checks.go @@ -34,7 +34,7 @@ func checkPieces(ctx context.Context, si SectorInfo, api sealingApi) error { } for i, piece := range si.Pieces { - deal, err := api.StateMarketStorageDeal(ctx, piece.DealID, nil) + deal, err := api.StateMarketStorageDeal(ctx, piece.DealID, types.EmptyTSK) if err != nil { return &ErrApi{xerrors.Errorf("getting deal %d for piece %d: %w", piece.DealID, i, err)} } @@ -63,7 +63,7 @@ func checkSeal(ctx context.Context, maddr address.Address, si SectorInfo, api se return &ErrApi{xerrors.Errorf("getting chain head: %w", err)} } - ssize, err := api.StateMinerSectorSize(ctx, maddr, head) + ssize, err := api.StateMinerSectorSize(ctx, maddr, head.Key()) if err != nil { return &ErrApi{err} } @@ -85,7 +85,7 @@ func checkSeal(ctx context.Context, maddr address.Address, si SectorInfo, api se Method: actors.SMAMethods.ComputeDataCommitment, Params: ccparams, } - r, err := api.StateCall(ctx, ccmt, nil) + r, err := api.StateCall(ctx, ccmt, types.EmptyTSK) if err != nil { return &ErrApi{xerrors.Errorf("calling ComputeDataCommitment: %w", err)} } diff --git a/sealing.go b/sealing.go index 6e562001d..c39b98257 100644 --- a/sealing.go +++ b/sealing.go @@ -29,23 +29,23 @@ type TicketFn func(context.Context) (*sectorbuilder.SealTicket, error) type sealingApi interface { // TODO: trim down // Call a read only method on actors (no interaction with the chain required) - StateCall(context.Context, *types.Message, *types.TipSet) (*api.MethodCall, error) - StateMinerWorker(context.Context, address.Address, *types.TipSet) (address.Address, error) - StateMinerElectionPeriodStart(ctx context.Context, actor address.Address, ts *types.TipSet) (uint64, error) - StateMinerSectors(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error) - StateMinerProvingSet(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error) - StateMinerSectorSize(context.Context, address.Address, *types.TipSet) (uint64, error) + StateCall(context.Context, *types.Message, types.TipSetKey) (*api.MethodCall, error) + StateMinerWorker(context.Context, address.Address, types.TipSetKey) (address.Address, error) + StateMinerElectionPeriodStart(ctx context.Context, actor address.Address, tsk types.TipSetKey) (uint64, error) + StateMinerSectors(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) + StateMinerProvingSet(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) + StateMinerSectorSize(context.Context, address.Address, types.TipSetKey) (uint64, error) StateWaitMsg(context.Context, cid.Cid) (*api.MsgWait, error) // TODO: removeme eventually - StateGetActor(ctx context.Context, actor address.Address, ts *types.TipSet) (*types.Actor, error) - StateGetReceipt(context.Context, cid.Cid, *types.TipSet) (*types.MessageReceipt, error) - StateMarketStorageDeal(context.Context, uint64, *types.TipSet) (*actors.OnChainDeal, error) + StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) + StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) + StateMarketStorageDeal(context.Context, uint64, types.TipSetKey) (*actors.OnChainDeal, error) MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error) ChainHead(context.Context) (*types.TipSet, error) ChainNotify(context.Context) (<-chan []*store.HeadChange, error) ChainGetRandomness(context.Context, types.TipSetKey, int64) ([]byte, error) - ChainGetTipSetByHeight(context.Context, uint64, *types.TipSet) (*types.TipSet, error) + ChainGetTipSetByHeight(context.Context, uint64, types.TipSetKey) (*types.TipSet, error) ChainGetBlockMessages(context.Context, cid.Cid) (*api.BlockMessages, error) ChainReadObj(context.Context, cid.Cid) ([]byte, error) diff --git a/states_failed.go b/states_failed.go index 680ba6891..642469dd6 100644 --- a/states_failed.go +++ b/states_failed.go @@ -3,6 +3,7 @@ package sealing import ( "bytes" "fmt" + "github.com/filecoin-project/lotus/chain/types" "time" "golang.org/x/xerrors" @@ -29,7 +30,7 @@ func failedCooldown(ctx statemachine.Context, sector SectorInfo) error { } func (m *Sealing) checkPreCommitted(ctx statemachine.Context, sector SectorInfo) (*actors.PreCommittedSector, bool) { - act, err := m.api.StateGetActor(ctx.Context(), m.maddr, nil) + act, err := m.api.StateGetActor(ctx.Context(), m.maddr, types.EmptyTSK) if err != nil { log.Errorf("handleSealFailed(%d): temp error: %+v", sector.SectorID, err) return nil, true From b82d26aee7b49bd134ecbccd3538d574f21f8b2c Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Mon, 17 Feb 2020 23:15:30 -0800 Subject: [PATCH 066/126] working towards a working genesis generator --- states.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/states.go b/states.go index 6d7f2822b..d2d06a7ca 100644 --- a/states.go +++ b/states.go @@ -187,7 +187,7 @@ func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) params := &miner.ProveCommitSectorParams{ SectorNumber: sector.SectorID, - Proof: abi.SealProof{ProofBytes: proof}, + Proof: proof, } enc, aerr := actors.SerializeParams(params) From e5b838bac87c5b85e1f001c611be450b6f07fbb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 21 Feb 2020 17:57:40 +0100 Subject: [PATCH 067/126] update specs-actors --- states.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/states.go b/states.go index d2d06a7ca..0a8cfe1d0 100644 --- a/states.go +++ b/states.go @@ -103,7 +103,7 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf SectorNumber: sector.SectorID, SealedCID: commcid.ReplicaCommitmentV1ToCID(sector.CommR), - SealEpoch: sector.Ticket.BlockHeight, + SealRandEpoch: sector.Ticket.BlockHeight, DealIDs: nil, // sector.deals(), // TODO: REFACTOR } enc, aerr := actors.SerializeParams(params) From 70263b6fbab04455bc5da2293ef8fe0238d1df64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 21 Feb 2020 18:43:44 +0100 Subject: [PATCH 068/126] storageminer: Update api interfaces --- sealing.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sealing.go b/sealing.go index 8882ca62c..9f230d578 100644 --- a/sealing.go +++ b/sealing.go @@ -5,7 +5,6 @@ import ( "io" "github.com/filecoin-project/go-address" - "github.com/filecoin-project/specs-actors/actors/abi" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/namespace" @@ -14,6 +13,8 @@ import ( "github.com/filecoin-project/go-padreader" "github.com/filecoin-project/go-sectorbuilder" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin/miner" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/events" @@ -32,7 +33,7 @@ type sealingApi interface { // TODO: trim down // Call a read only method on actors (no interaction with the chain required) StateCall(context.Context, *types.Message, *types.TipSet) (*api.MethodCall, error) StateMinerWorker(context.Context, address.Address, *types.TipSet) (address.Address, error) - StateMinerElectionPeriodStart(ctx context.Context, actor address.Address, ts *types.TipSet) (abi.ChainEpoch, error) + StateMinerPostState(ctx context.Context, actor address.Address, ts *types.TipSet) (*miner.PoStState, error) StateMinerSectors(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error) StateMinerProvingSet(context.Context, address.Address, *types.TipSet) ([]*api.ChainSectorInfo, error) StateMinerSectorSize(context.Context, address.Address, *types.TipSet) (abi.SectorSize, error) From 9b40fa6c761ed102bb4e1fbde833ef4fe06533e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 21 Feb 2020 20:28:20 +0100 Subject: [PATCH 069/126] gofmt; mod tidy --- states.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/states.go b/states.go index 0a8cfe1d0..4cd6549a8 100644 --- a/states.go +++ b/states.go @@ -102,9 +102,9 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf Expiration: 0, SectorNumber: sector.SectorID, - SealedCID: commcid.ReplicaCommitmentV1ToCID(sector.CommR), + SealedCID: commcid.ReplicaCommitmentV1ToCID(sector.CommR), SealRandEpoch: sector.Ticket.BlockHeight, - DealIDs: nil, // sector.deals(), // TODO: REFACTOR + DealIDs: nil, // sector.deals(), // TODO: REFACTOR } enc, aerr := actors.SerializeParams(params) if aerr != nil { From 65b91a95d2f26503986ea4e9be76f8de04cb8cf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 22 Feb 2020 14:10:46 +0100 Subject: [PATCH 070/126] get chain to runnable state --- garbage.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/garbage.go b/garbage.go index 914de414a..52a035999 100644 --- a/garbage.go +++ b/garbage.go @@ -135,7 +135,7 @@ func (m *Sealing) PledgeSector() error { return } - pieces, err := m.pledgeSector(ctx, sid, []abi.UnpaddedPieceSize{}, abi.UnpaddedPieceSize(size)) + pieces, err := m.pledgeSector(ctx, sid, []abi.UnpaddedPieceSize{}, size) if err != nil { log.Errorf("%+v", err) return From da236a26fc028efe0a025ee48f9d3a706e3972c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 22 Feb 2020 15:03:32 +0100 Subject: [PATCH 071/126] Generate zero CommP table --- garbage.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/garbage.go b/garbage.go index 52a035999..cb68eda48 100644 --- a/garbage.go +++ b/garbage.go @@ -90,7 +90,7 @@ func (m *Sealing) pledgeSector(ctx context.Context, sectorID abi.SectorNumber, e return nil, err } if r.Receipt.ExitCode != 0 { - log.Error(xerrors.Errorf("publishing deal failed: exit %d", r.Receipt.ExitCode)) + log.Error(xerrors.Errorf("publishing deal (ts %s) %s failed: exit %d", r.TipSet.Key(), smsg.Cid(), r.Receipt.ExitCode)) } var resp actors.PublishStorageDealResponse if err := resp.UnmarshalCBOR(bytes.NewReader(r.Receipt.Return)); err != nil { From d04c304c93af4024bf7398f535af91cfbad3d70d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sun, 23 Feb 2020 01:47:47 +0100 Subject: [PATCH 072/126] Implement committed capacity sectors --- cbor_gen.go | 130 ++++++++++++++++++++++++++++++++++------------------ checks.go | 27 ++++++++++- fsm.go | 2 +- garbage.go | 102 ++++++----------------------------------- sealing.go | 22 ++++----- states.go | 3 +- types.go | 11 +++-- utils.go | 49 +------------------- 8 files changed, 148 insertions(+), 198 deletions(-) diff --git a/cbor_gen.go b/cbor_gen.go index fe25daa2d..3cd9b6451 100644 --- a/cbor_gen.go +++ b/cbor_gen.go @@ -310,8 +310,14 @@ func (t *Piece) MarshalCBOR(w io.Writer) error { return err } - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.DealID))); err != nil { - return err + if t.DealID == nil { + if _, err := w.Write(cbg.CborNull); err != nil { + return err + } + } else { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(*t.DealID))); err != nil { + return err + } } // t.Size (abi.UnpaddedPieceSize) (uint64) @@ -388,25 +394,45 @@ func (t *Piece) UnmarshalCBOR(r io.Reader) error { // t.DealID (abi.DealID) (uint64) case "DealID": - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + { + + 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 { + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + typed := abi.DealID(extra) + t.DealID = &typed + } + } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.DealID = abi.DealID(extra) // t.Size (abi.UnpaddedPieceSize) (uint64) case "Size": - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + { + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Size = abi.UnpaddedPieceSize(extra) + } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.Size = abi.UnpaddedPieceSize(extra) // t.CommP ([]uint8) (slice) case "CommP": @@ -765,36 +791,48 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { // t.State (uint64) (uint64) case "State": - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + { + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.State = uint64(extra) + } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.State = uint64(extra) // t.SectorID (abi.SectorNumber) (uint64) case "SectorID": - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + { + + 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 = abi.SectorNumber(extra) + } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.SectorID = abi.SectorNumber(extra) // t.Nonce (uint64) (uint64) case "Nonce": - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + { + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Nonce = uint64(extra) + } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.Nonce = uint64(extra) // t.Pieces ([]sealing.Piece) (slice) case "Pieces": @@ -1147,14 +1185,18 @@ func (t *Log) UnmarshalCBOR(r io.Reader) error { // t.Timestamp (uint64) (uint64) case "Timestamp": - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err + { + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Timestamp = uint64(extra) + } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.Timestamp = uint64(extra) // t.Trace (string) (string) case "Trace": diff --git a/checks.go b/checks.go index 6cfddee26..1c5df91bc 100644 --- a/checks.go +++ b/checks.go @@ -1,7 +1,12 @@ package sealing import ( + "bytes" "context" + commcid "github.com/filecoin-project/go-fil-commcid" + "github.com/filecoin-project/lotus/lib/zerocomm" + "github.com/ipfs/go-cid" + cbg "github.com/whyrusleeping/cbor-gen" "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/multiformats/go-multihash" @@ -19,6 +24,7 @@ import ( type ErrApi struct{ error } type ErrInvalidDeals struct{ error } +type ErrInvalidPiece struct{ error } type ErrExpiredDeals struct{ error } type ErrBadCommD struct{ error } @@ -36,7 +42,14 @@ func checkPieces(ctx context.Context, si SectorInfo, api sealingApi) error { } for i, piece := range si.Pieces { - deal, err := api.StateMarketStorageDeal(ctx, piece.DealID, nil) + if piece.DealID == nil { + exp := zerocomm.ForSize(piece.Size) + if string(piece.CommP) != string(exp[:]) { + return &ErrInvalidPiece{xerrors.Errorf("deal %d piece %d had non-zero CommP %+v", piece.DealID, i, piece.CommP)} + } + continue + } + deal, err := api.StateMarketStorageDeal(ctx, *piece.DealID, nil) if err != nil { return &ErrApi{xerrors.Errorf("getting deal %d for piece %d: %w", piece.DealID, i, err)} } @@ -99,7 +112,17 @@ func checkSeal(ctx context.Context, maddr address.Address, si SectorInfo, api se if r.ExitCode != 0 { return &ErrBadCommD{xerrors.Errorf("receipt for ComputeDataCommitment had exit code %d", r.ExitCode)} } - if string(r.Return) != string(si.CommD) { + + var c cbg.CborCid + if err := c.UnmarshalCBOR(bytes.NewReader(r.Return)); err != nil { + return err + } + cd, err := commcid.CIDToDataCommitmentV1(cid.Cid(c)) + if err != nil { + return err + } + + if string(cd) != string(si.CommD) { return &ErrBadCommD{xerrors.Errorf("on chain CommD differs from sector: %x != %x", r.Return, si.CommD)} } diff --git a/fsm.go b/fsm.go index 59449303b..06ba11354 100644 --- a/fsm.go +++ b/fsm.go @@ -228,7 +228,7 @@ func (m *Sealing) restartSectors(ctx context.Context) error { } for _, sector := range trackedSectors { - if err := m.sectors.Send(sector.SectorID, SectorRestart{}); err != nil { + if err := m.sectors.Send(uint64(sector.SectorID), SectorRestart{}); err != nil { log.Errorf("restarting sector %d: %+v", sector.SectorID, err) } } diff --git a/garbage.go b/garbage.go index cb68eda48..ecf0a1179 100644 --- a/garbage.go +++ b/garbage.go @@ -1,37 +1,25 @@ package sealing import ( - "bytes" "context" "io" - "math" - "math/bits" - "math/rand" - commcid "github.com/filecoin-project/go-fil-commcid" - "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/specs-actors/actors/builtin" - "github.com/filecoin-project/specs-actors/actors/builtin/market" "golang.org/x/xerrors" - "github.com/filecoin-project/lotus/chain/actors" - "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/specs-actors/actors/abi" ) -func (m *Sealing) pledgeReader(size abi.UnpaddedPieceSize, parts uint64) io.Reader { - parts = 1 << bits.Len64(parts) // round down to nearest power of 2 - if uint64(size)/parts < 127 { - parts = uint64(size) / 127 +type nullReader struct {} + +func (nullReader) Read(out []byte) (int, error) { + for i := range out { + out[i] = 0 } + return len(out), nil +} - piece := abi.PaddedPieceSize(uint64(size.Padded()) / parts).Unpadded() - - readers := make([]io.Reader, parts) - for i := range readers { - readers[i] = io.LimitReader(rand.New(rand.NewSource(42+int64(i))), int64(piece)) - } - - return io.MultiReader(readers...) +func (m *Sealing) pledgeReader(size abi.UnpaddedPieceSize) io.Reader { + return io.LimitReader(&nullReader{}, int64(size)) } func (m *Sealing) pledgeSector(ctx context.Context, sectorID abi.SectorNumber, existingPieceSizes []abi.UnpaddedPieceSize, sizes ...abi.UnpaddedPieceSize) ([]Piece, error) { @@ -41,70 +29,9 @@ func (m *Sealing) pledgeSector(ctx context.Context, sectorID abi.SectorNumber, e log.Infof("Pledge %d, contains %+v", sectorID, existingPieceSizes) - deals := make([]market.ClientDealProposal, len(sizes)) - for i, size := range sizes { - commP, err := m.fastPledgeCommitment(size, uint64(1)) - if err != nil { - return nil, err - } - - sdp := market.DealProposal{ - PieceCID: commcid.PieceCommitmentV1ToCID(commP[:]), - PieceSize: size.Padded(), - Client: m.worker, - Provider: m.maddr, - StartEpoch: math.MaxInt64, - EndEpoch: math.MaxInt64, - StoragePricePerEpoch: types.NewInt(0), - ProviderCollateral: types.NewInt(0), - } - - deals[i] = market.ClientDealProposal{ - Proposal: sdp, - } - } - - log.Infof("Publishing deals for %d", sectorID) - - params, aerr := actors.SerializeParams(&market.PublishStorageDealsParams{ - Deals: deals, - }) - if aerr != nil { - return nil, xerrors.Errorf("serializing PublishStorageDeals params failed: ", aerr) - } - - 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: builtin.MethodsMarket.PublishStorageDeals, - Params: params, - }) - if err != nil { - return nil, err - } - r, err := m.api.StateWaitMsg(ctx, smsg.Cid()) // TODO: more finality - if err != nil { - return nil, err - } - if r.Receipt.ExitCode != 0 { - log.Error(xerrors.Errorf("publishing deal (ts %s) %s failed: exit %d", r.TipSet.Key(), smsg.Cid(), r.Receipt.ExitCode)) - } - var resp actors.PublishStorageDealResponse - if err := resp.UnmarshalCBOR(bytes.NewReader(r.Receipt.Return)); err != nil { - return nil, err - } - if len(resp.IDs) != len(sizes) { - return nil, xerrors.New("got unexpected number of DealIDs from PublishStorageDeals") - } - - log.Infof("Deals for sector %d: %+v", sectorID, resp.IDs) - out := make([]Piece, len(sizes)) for i, size := range sizes { - ppi, err := m.sb.AddPiece(ctx, size, sectorID, m.pledgeReader(size, uint64(1)), existingPieceSizes) + ppi, err := m.sb.AddPiece(ctx, size, sectorID, m.pledgeReader(size), existingPieceSizes) if err != nil { return nil, xerrors.Errorf("add piece: %w", err) } @@ -112,9 +39,8 @@ func (m *Sealing) pledgeSector(ctx context.Context, sectorID abi.SectorNumber, e existingPieceSizes = append(existingPieceSizes, size) out[i] = Piece{ - DealID: resp.IDs[i], - Size: abi.UnpaddedPieceSize(ppi.Size), - CommP: ppi.CommP[:], + Size: ppi.Size, + CommP: ppi.CommP[:], } } @@ -141,7 +67,7 @@ func (m *Sealing) PledgeSector() error { return } - if err := m.newSector(context.TODO(), sid, pieces[0].DealID, pieces[0].ppi()); err != nil { + if err := m.newSector(sid, pieces); err != nil { log.Errorf("%+v", err) return } diff --git a/sealing.go b/sealing.go index 9f230d578..1ad733935 100644 --- a/sealing.go +++ b/sealing.go @@ -120,20 +120,20 @@ func (m *Sealing) SealPiece(ctx context.Context, size abi.UnpaddedPieceSize, r i return xerrors.Errorf("adding piece to sector: %w", err) } - return m.newSector(ctx, sectorID, dealID, ppi) + return m.newSector(sectorID, []Piece{ + { + DealID: &dealID, + + Size: ppi.Size, + CommP: ppi.CommP[:], + }, + },) } -func (m *Sealing) newSector(ctx context.Context, sid abi.SectorNumber, dealID abi.DealID, ppi sectorbuilder.PublicPieceInfo) error { +func (m *Sealing) newSector(sid abi.SectorNumber, pieces []Piece) error { log.Infof("Start sealing %d", sid) - return m.sectors.Send(sid, SectorStart{ + return m.sectors.Send(uint64(sid), SectorStart{ id: sid, - pieces: []Piece{ - { - DealID: dealID, - - Size: abi.UnpaddedPieceSize(ppi.Size), - CommP: ppi.CommP[:], - }, - }, + pieces: pieces, }) } diff --git a/states.go b/states.go index 4cd6549a8..273f9fd4f 100644 --- a/states.go +++ b/states.go @@ -99,8 +99,9 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf } params := &miner.SectorPreCommitInfo{ - Expiration: 0, + Expiration: 10000000, // TODO: implement SectorNumber: sector.SectorID, + RegisteredProof: abi.RegisteredProof_StackedDRG32GiBSeal, SealedCID: commcid.ReplicaCommitmentV1ToCID(sector.CommR), SealRandEpoch: sector.Ticket.BlockHeight, diff --git a/types.go b/types.go index ccfe50427..e2a2c049d 100644 --- a/types.go +++ b/types.go @@ -34,7 +34,7 @@ func (t *SealSeed) Equals(o *SealSeed) bool { } type Piece struct { - DealID abi.DealID + DealID *abi.DealID Size abi.UnpaddedPieceSize CommP []byte @@ -97,9 +97,12 @@ func (t *SectorInfo) pieceInfos() []sectorbuilder.PublicPieceInfo { } func (t *SectorInfo) deals() []abi.DealID { - out := make([]abi.DealID, len(t.Pieces)) - for i, piece := range t.Pieces { - out[i] = piece.DealID + out := make([]abi.DealID, 0, len(t.Pieces)) + for _, piece := range t.Pieces { + if piece.DealID == nil { + continue + } + out = append(out, *piece.DealID) } return out } diff --git a/utils.go b/utils.go index 0bfbb30fe..cfc17734c 100644 --- a/utils.go +++ b/utils.go @@ -1,15 +1,8 @@ package sealing import ( - "io" - "math/bits" - "math/rand" - "sync" - "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/hashicorp/go-multierror" - - sectorbuilder "github.com/filecoin-project/go-sectorbuilder" + "math/bits" ) func fillersFromRem(in abi.UnpaddedPieceSize) ([]abi.UnpaddedPieceSize, error) { @@ -48,44 +41,6 @@ func fillersFromRem(in abi.UnpaddedPieceSize) ([]abi.UnpaddedPieceSize, error) { return out, nil } -func (m *Sealing) fastPledgeCommitment(size abi.UnpaddedPieceSize, parts uint64) (commP [sectorbuilder.CommLen]byte, err error) { - parts = 1 << bits.Len64(parts) // round down to nearest power of 2 - if uint64(size)/parts < 127 { - parts = uint64(size) / 127 - } - - piece := abi.PaddedPieceSize(uint64(size.Padded()) / parts).Unpadded() - out := make([]sectorbuilder.PublicPieceInfo, parts) - var lk sync.Mutex - - var wg sync.WaitGroup - wg.Add(int(parts)) - for i := uint64(0); i < parts; i++ { - go func(i uint64) { - defer wg.Done() - - commP, perr := sectorbuilder.GeneratePieceCommitment(io.LimitReader(rand.New(rand.NewSource(42+int64(i))), int64(piece)), piece) - - lk.Lock() - if perr != nil { - err = multierror.Append(err, perr) - } - out[i] = sectorbuilder.PublicPieceInfo{ - Size: piece, - CommP: commP, - } - lk.Unlock() - }(i) - } - wg.Wait() - - if err != nil { - return [32]byte{}, err - } - - return sectorbuilder.GenerateDataCommitment(m.sb.SectorSize(), out) -} - func (m *Sealing) ListSectors() ([]SectorInfo, error) { var sectors []SectorInfo if err := m.sectors.List(§ors); err != nil { @@ -96,6 +51,6 @@ func (m *Sealing) ListSectors() ([]SectorInfo, error) { func (m *Sealing) GetSectorInfo(sid abi.SectorNumber) (SectorInfo, error) { var out SectorInfo - err := m.sectors.Get(sid).Get(&out) + err := m.sectors.Get(uint64(sid)).Get(&out) return out, err } From 4b4368a8989ae4213e544466e48f678d4a744126 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sun, 23 Feb 2020 16:50:36 +0100 Subject: [PATCH 073/126] Deal flow fixes --- garbage.go | 2 +- sealing.go | 4 ++-- states.go | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/garbage.go b/garbage.go index ecf0a1179..0a7b33324 100644 --- a/garbage.go +++ b/garbage.go @@ -9,7 +9,7 @@ import ( "github.com/filecoin-project/specs-actors/actors/abi" ) -type nullReader struct {} +type nullReader struct{} func (nullReader) Read(out []byte) (int, error) { for i := range out { diff --git a/sealing.go b/sealing.go index 1ad733935..029c053f0 100644 --- a/sealing.go +++ b/sealing.go @@ -127,13 +127,13 @@ func (m *Sealing) SealPiece(ctx context.Context, size abi.UnpaddedPieceSize, r i Size: ppi.Size, CommP: ppi.CommP[:], }, - },) + }) } func (m *Sealing) newSector(sid abi.SectorNumber, pieces []Piece) error { log.Infof("Start sealing %d", sid) return m.sectors.Send(uint64(sid), SectorStart{ - id: sid, + id: sid, pieces: pieces, }) } diff --git a/states.go b/states.go index 273f9fd4f..1622011a3 100644 --- a/states.go +++ b/states.go @@ -99,8 +99,8 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf } params := &miner.SectorPreCommitInfo{ - Expiration: 10000000, // TODO: implement - SectorNumber: sector.SectorID, + Expiration: 10000000, // TODO: implement + SectorNumber: sector.SectorID, RegisteredProof: abi.RegisteredProof_StackedDRG32GiBSeal, SealedCID: commcid.ReplicaCommitmentV1ToCID(sector.CommR), From ed8569eb9981978bbc8267388bde359cd9071424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sun, 23 Feb 2020 21:00:47 +0100 Subject: [PATCH 074/126] More unified randomness handling --- sealing.go | 3 ++- states.go | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/sealing.go b/sealing.go index 029c053f0..ce30be446 100644 --- a/sealing.go +++ b/sealing.go @@ -15,6 +15,7 @@ import ( "github.com/filecoin-project/go-sectorbuilder" "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/builtin/miner" + "github.com/filecoin-project/specs-actors/actors/crypto" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/events" @@ -46,7 +47,7 @@ type sealingApi interface { // TODO: trim down ChainHead(context.Context) (*types.TipSet, error) ChainNotify(context.Context) (<-chan []*store.HeadChange, error) - ChainGetRandomness(context.Context, types.TipSetKey, int64) ([]byte, error) + ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, *types.TipSet) (*types.TipSet, error) ChainGetBlockMessages(context.Context, cid.Cid) (*api.BlockMessages, error) ChainReadObj(context.Context, cid.Cid) ([]byte, error) diff --git a/states.go b/states.go index 1622011a3..2408ad09c 100644 --- a/states.go +++ b/states.go @@ -2,6 +2,7 @@ package sealing import ( "context" + "github.com/filecoin-project/specs-actors/actors/crypto" commcid "github.com/filecoin-project/go-fil-commcid" "github.com/filecoin-project/go-sectorbuilder/fs" @@ -146,11 +147,11 @@ func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) er } log.Info("precommit message landed on chain: ", sector.SectorID) - randHeight := mw.TipSet.Height() + build.InteractivePoRepDelay - 1 // -1 because of how the messages are applied + randHeight := mw.TipSet.Height() + miner.PreCommitChallengeDelay - 1 // -1 because of how the messages are applied log.Infof("precommit for sector %d made it on chain, will start proof computation at height %d", sector.SectorID, randHeight) err = m.events.ChainAt(func(ectx context.Context, ts *types.TipSet, curH abi.ChainEpoch) error { - rand, err := m.api.ChainGetRandomness(ectx, ts.Key(), int64(randHeight)) + rand, err := m.api.ChainGetRandomness(ectx, ts.Key(), crypto.DomainSeparationTag_InteractiveSealChallengeSeed, randHeight, nil) if err != nil { err = xerrors.Errorf("failed to get randomness for computing seal proof: %w", err) @@ -168,7 +169,7 @@ func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) er log.Warn("revert in interactive commit sector step") // TODO: need to cancel running process and restart... return nil - }, build.InteractivePoRepConfidence, mw.TipSet.Height()+build.InteractivePoRepDelay) + }, build.InteractivePoRepConfidence, mw.TipSet.Height()+miner.PreCommitChallengeDelay) if err != nil { log.Warn("waitForPreCommitMessage ChainAt errored: ", err) } From 1dc80d4c04af7802282474f43899564227e07f79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sun, 23 Feb 2020 21:32:14 +0100 Subject: [PATCH 075/126] Fix Sealing in TestAPIDealFlow --- states.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/states.go b/states.go index 2408ad09c..a23647502 100644 --- a/states.go +++ b/states.go @@ -106,7 +106,7 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf SealedCID: commcid.ReplicaCommitmentV1ToCID(sector.CommR), SealRandEpoch: sector.Ticket.BlockHeight, - DealIDs: nil, // sector.deals(), // TODO: REFACTOR + DealIDs: sector.deals(), } enc, aerr := actors.SerializeParams(params) if aerr != nil { @@ -180,6 +180,8 @@ func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) er func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) error { log.Info("scheduling seal proof computation...") + log.Infof("KOMIT %d %x(%d); %x(%d); %v; r:%x; d:%x", sector.SectorID, sector.Ticket.TicketBytes, sector.Ticket.BlockHeight, sector.Seed.TicketBytes, sector.Seed.BlockHeight, sector.pieceInfos(), sector.CommR, sector.CommD) + proof, err := m.sb.SealCommit(ctx.Context(), sector.SectorID, sector.Ticket.SB(), sector.Seed.SB(), sector.pieceInfos(), sector.rspco()) if err != nil { return ctx.Send(SectorComputeProofFailed{xerrors.Errorf("computing seal proof failed: %w", err)}) From 2f22fa416d44e751ecd79921604c7d3f9ad67e5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 24 Feb 2020 18:45:25 +0100 Subject: [PATCH 076/126] post-upstream-merge fixes --- sealing.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sealing.go b/sealing.go index facd88840..5ce52deac 100644 --- a/sealing.go +++ b/sealing.go @@ -45,7 +45,7 @@ type sealingApi interface { // TODO: trim down MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error) - ChainHead(context.Context) (types.TipSetKey, error) + ChainHead(context.Context) (*types.TipSet, error) ChainNotify(context.Context) (<-chan []*store.HeadChange, error) ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error) From fc4fa38c9b83bb36b2d695dbbc90784faa7b4f73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 25 Feb 2020 21:35:15 +0100 Subject: [PATCH 077/126] actors: drop a bunch of type aliases --- checks.go | 13 +++++++------ states_failed.go | 3 +-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/checks.go b/checks.go index 8770dd1af..35b37daab 100644 --- a/checks.go +++ b/checks.go @@ -3,20 +3,21 @@ package sealing import ( "bytes" "context" - commcid "github.com/filecoin-project/go-fil-commcid" - "github.com/filecoin-project/lotus/lib/zerocomm" - "github.com/ipfs/go-cid" - cbg "github.com/whyrusleeping/cbor-gen" - "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/ipfs/go-cid" "github.com/multiformats/go-multihash" + cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" + commcid "github.com/filecoin-project/go-fil-commcid" + "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/builtin/market" "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/lib/zerocomm" ) // TODO: For now we handle this by halting state execution, when we get jsonrpc reconnecting @@ -88,7 +89,7 @@ func checkSeal(ctx context.Context, maddr address.Address, si SectorInfo, api se return &ErrApi{err} } - ccparams, err := actors.SerializeParams(&actors.ComputeDataCommitmentParams{ + ccparams, err := actors.SerializeParams(&market.ComputeDataCommitmentParams{ DealIDs: si.deals(), SectorSize: ssize, }) diff --git a/states_failed.go b/states_failed.go index f6ccc5057..aaffe8b43 100644 --- a/states_failed.go +++ b/states_failed.go @@ -11,7 +11,6 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/apibstore" - "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/lib/statemachine" @@ -46,7 +45,7 @@ func (m *Sealing) checkPreCommitted(ctx statemachine.Context, sector SectorInfo) return nil, true } - var state actors.StorageMinerActorState + var state miner.State if err := state.UnmarshalCBOR(bytes.NewReader(st)); err != nil { log.Errorf("handleSealFailed(%d): temp error: unmarshaling miner state: %+v", sector.SectorID, err) return nil, true From 9c5d2fff1aa880815123cb7fd01df5bae14d460f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 25 Feb 2020 21:54:58 +0100 Subject: [PATCH 078/126] actors: Remove addrass aliases --- checks.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checks.go b/checks.go index 35b37daab..b45966d9f 100644 --- a/checks.go +++ b/checks.go @@ -98,7 +98,7 @@ func checkSeal(ctx context.Context, maddr address.Address, si SectorInfo, api se } ccmt := &types.Message{ - To: actors.StorageMarketAddress, + To: builtin.StorageMarketActorAddr, From: maddr, Value: types.NewInt(0), GasPrice: types.NewInt(0), From 5649f5a87f1b3cc82f745f4bb6ef0aeb89a53a2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 25 Feb 2020 22:09:22 +0100 Subject: [PATCH 079/126] types: Drop some redundant alias types --- sealing.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sealing.go b/sealing.go index 5ce52deac..9851d77a9 100644 --- a/sealing.go +++ b/sealing.go @@ -53,7 +53,7 @@ type sealingApi interface { // TODO: trim down ChainReadObj(context.Context, cid.Cid) ([]byte, error) ChainHasObj(context.Context, cid.Cid) (bool, error) - WalletSign(context.Context, address.Address, []byte) (*types.Signature, error) + WalletSign(context.Context, address.Address, []byte) (*crypto.Signature, error) WalletBalance(context.Context, address.Address) (types.BigInt, error) WalletHas(context.Context, address.Address) (bool, error) } From d1c15a26663dbd4cb1ce24b72b63abd418633d8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 26 Feb 2020 10:05:22 +0100 Subject: [PATCH 080/126] Some test fixes --- types_test.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/types_test.go b/types_test.go index f14051a15..75460d3f8 100644 --- a/types_test.go +++ b/types_test.go @@ -4,18 +4,21 @@ import ( "bytes" "testing" + "github.com/filecoin-project/specs-actors/actors/abi" "gotest.tools/assert" "github.com/filecoin-project/go-cbor-util" ) func TestSectorInfoSelialization(t *testing.T) { + d := abi.DealID(1234) + si := &SectorInfo{ State: 123, SectorID: 234, Nonce: 345, Pieces: []Piece{{ - DealID: 1234, + DealID: &d, Size: 5, CommP: []byte{3}, }}, From 300264bee17cf8126a4e0659817d1e722789c1cf Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Wed, 26 Feb 2020 16:42:39 -0800 Subject: [PATCH 081/126] more fixes for random garbage --- cbor_gen.go | 52 ------------------------------------------------ checks.go | 26 +++++------------------- fsm_events.go | 10 ++++++---- garbage.go | 4 ++-- sealing.go | 6 +++--- states.go | 19 ++++++++---------- states_failed.go | 10 ++-------- types.go | 49 ++++++++++++--------------------------------- types_test.go | 9 ++++++--- utils_test.go | 18 ----------------- 10 files changed, 45 insertions(+), 158 deletions(-) diff --git a/cbor_gen.go b/cbor_gen.go index 3cd9b6451..d13847a99 100644 --- a/cbor_gen.go +++ b/cbor_gen.go @@ -348,16 +348,6 @@ func (t *Piece) MarshalCBOR(w io.Writer) error { return err } - if len(t.CommP) > cbg.ByteArrayMaxLen { - return xerrors.Errorf("Byte array in field t.CommP was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.CommP)))); err != nil { - return err - } - if _, err := w.Write(t.CommP); err != nil { - return err - } return nil } @@ -447,10 +437,6 @@ func (t *Piece) UnmarshalCBOR(r io.Reader) error { if maj != cbg.MajByteString { return fmt.Errorf("expected byte array") } - t.CommP = make([]byte, extra) - if _, err := io.ReadFull(br, t.CommP); err != nil { - return err - } default: return fmt.Errorf("unknown struct field %d: '%s'", i, name) @@ -553,17 +539,6 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { return err } - if len(t.CommD) > cbg.ByteArrayMaxLen { - return xerrors.Errorf("Byte array in field t.CommD was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.CommD)))); err != nil { - return err - } - if _, err := w.Write(t.CommD); err != nil { - return err - } - // t.CommR ([]uint8) (slice) if len("CommR") > cbg.MaxLength { return xerrors.Errorf("Value in field \"CommR\" was too long") @@ -576,17 +551,6 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { return err } - if len(t.CommR) > cbg.ByteArrayMaxLen { - return xerrors.Errorf("Byte array in field t.CommR was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.CommR)))); err != nil { - return err - } - if _, err := w.Write(t.CommR); err != nil { - return err - } - // t.Proof ([]uint8) (slice) if len("Proof") > cbg.MaxLength { return xerrors.Errorf("Value in field \"Proof\" was too long") @@ -622,10 +586,6 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { return err } - if err := t.Ticket.MarshalCBOR(w); err != nil { - return err - } - // t.PreCommitMessage (cid.Cid) (struct) if len("PreCommitMessage") > cbg.MaxLength { return xerrors.Errorf("Value in field \"PreCommitMessage\" was too long") @@ -875,10 +835,6 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { if maj != cbg.MajByteString { return fmt.Errorf("expected byte array") } - t.CommD = make([]byte, extra) - if _, err := io.ReadFull(br, t.CommD); err != nil { - return err - } // t.CommR ([]uint8) (slice) case "CommR": @@ -893,10 +849,6 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { if maj != cbg.MajByteString { return fmt.Errorf("expected byte array") } - t.CommR = make([]byte, extra) - if _, err := io.ReadFull(br, t.CommR); err != nil { - return err - } // t.Proof ([]uint8) (slice) case "Proof": @@ -920,10 +872,6 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { { - if err := t.Ticket.UnmarshalCBOR(br); err != nil { - return err - } - } // t.PreCommitMessage (cid.Cid) (struct) case "PreCommitMessage": diff --git a/checks.go b/checks.go index b45966d9f..ff19afcb7 100644 --- a/checks.go +++ b/checks.go @@ -5,12 +5,10 @@ import ( "context" "github.com/ipfs/go-cid" - "github.com/multiformats/go-multihash" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" - commcid "github.com/filecoin-project/go-fil-commcid" "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/actors/builtin/market" @@ -45,7 +43,7 @@ func checkPieces(ctx context.Context, si SectorInfo, api sealingApi) error { for i, piece := range si.Pieces { if piece.DealID == nil { exp := zerocomm.ForSize(piece.Size) - if string(piece.CommP) != string(exp[:]) { + if piece.CommP != exp { return &ErrInvalidPiece{xerrors.Errorf("deal %d piece %d had non-zero CommP %+v", piece.DealID, i, piece.CommP)} } continue @@ -55,13 +53,8 @@ func checkPieces(ctx context.Context, si SectorInfo, api sealingApi) error { return &ErrApi{xerrors.Errorf("getting deal %d for piece %d: %w", piece.DealID, i, err)} } - h, err := multihash.Decode(deal.Proposal.PieceCID.Hash()) - if err != nil { - return &ErrInvalidDeals{xerrors.Errorf("decoding piece CID: %w", err)} - } - - if string(h.Digest) != string(piece.CommP) { - return &ErrInvalidDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers deal %d with wrong CommP: %x != %x", i, len(si.Pieces), si.SectorID, piece.DealID, piece.CommP, h.Digest)} + if deal.Proposal.PieceCID != piece.CommP { + return &ErrInvalidDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers deal %d with wrong CommP: %x != %x", i, len(si.Pieces), si.SectorID, piece.DealID, piece.CommP, deal.Proposal.PieceCID)} } if piece.Size != deal.Proposal.PieceSize.Unpadded() { @@ -84,14 +77,9 @@ func checkSeal(ctx context.Context, maddr address.Address, si SectorInfo, api se return &ErrApi{xerrors.Errorf("getting chain head: %w", err)} } - ssize, err := api.StateMinerSectorSize(ctx, maddr, head.Key()) - if err != nil { - return &ErrApi{err} - } - ccparams, err := actors.SerializeParams(&market.ComputeDataCommitmentParams{ DealIDs: si.deals(), - SectorSize: ssize, + SectorType: si.SectorType, }) if err != nil { return xerrors.Errorf("computing params for ComputeDataCommitment: %w", err) @@ -118,12 +106,8 @@ func checkSeal(ctx context.Context, maddr address.Address, si SectorInfo, api se if err := c.UnmarshalCBOR(bytes.NewReader(r.Return)); err != nil { return err } - cd, err := commcid.CIDToDataCommitmentV1(cid.Cid(c)) - if err != nil { - return err - } - if string(cd) != string(si.CommD) { + if cid.Cid(c) != *si.CommD { return &ErrBadCommD{xerrors.Errorf("on chain CommD differs from sector: %x != %x", r.Return, si.CommD)} } diff --git a/fsm_events.go b/fsm_events.go index 528da1234..535f3fd86 100644 --- a/fsm_events.go +++ b/fsm_events.go @@ -66,14 +66,16 @@ type SectorPackingFailed struct{ error } func (evt SectorPackingFailed) apply(*SectorInfo) {} type SectorSealed struct { - commR []byte - commD []byte + commR cid.Cid + commD cid.Cid ticket SealTicket } func (evt SectorSealed) apply(state *SectorInfo) { - state.CommD = evt.commD - state.CommR = evt.commR + commd := evt.commD + state.CommD = &commd + commr := evt.commR + state.CommR = &commr state.Ticket = evt.ticket } diff --git a/garbage.go b/garbage.go index 0a7b33324..289ff2c1a 100644 --- a/garbage.go +++ b/garbage.go @@ -39,8 +39,8 @@ func (m *Sealing) pledgeSector(ctx context.Context, sectorID abi.SectorNumber, e existingPieceSizes = append(existingPieceSizes, size) out[i] = Piece{ - Size: ppi.Size, - CommP: ppi.CommP[:], + Size: ppi.Size.Unpadded(), + CommP: ppi.PieceCID, } } diff --git a/sealing.go b/sealing.go index 9851d77a9..2e1e65ceb 100644 --- a/sealing.go +++ b/sealing.go @@ -28,7 +28,7 @@ const SectorStorePrefix = "/sectors" var log = logging.Logger("sectors") -type TicketFn func(context.Context) (*sectorbuilder.SealTicket, error) +type TicketFn func(context.Context) (SealTicket, error) type sealingApi interface { // TODO: trim down // Call a read only method on actors (no interaction with the chain required) @@ -125,8 +125,8 @@ func (m *Sealing) SealPiece(ctx context.Context, size abi.UnpaddedPieceSize, r i { DealID: &dealID, - Size: ppi.Size, - CommP: ppi.CommP[:], + Size: ppi.Size.Unpadded(), + CommP: ppi.PieceCID, }, }) } diff --git a/states.go b/states.go index a23647502..9dae76694 100644 --- a/states.go +++ b/states.go @@ -2,9 +2,9 @@ package sealing import ( "context" + "github.com/filecoin-project/specs-actors/actors/crypto" - commcid "github.com/filecoin-project/go-fil-commcid" "github.com/filecoin-project/go-sectorbuilder/fs" "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/builtin" @@ -69,18 +69,15 @@ func (m *Sealing) handleUnsealed(ctx statemachine.Context, sector SectorInfo) er return ctx.Send(SectorSealFailed{xerrors.Errorf("getting ticket failed: %w", err)}) } - rspco, err := m.sb.SealPreCommit(ctx.Context(), sector.SectorID, *ticket, sector.pieceInfos()) + sealed, unsealed, err := m.sb.SealPreCommit(ctx.Context(), sector.SectorID, ticket.TicketBytes, sector.pieceInfos()) if err != nil { return ctx.Send(SectorSealFailed{xerrors.Errorf("seal pre commit failed: %w", err)}) } return ctx.Send(SectorSealed{ - commD: rspco.CommD[:], - commR: rspco.CommR[:], - ticket: SealTicket{ - BlockHeight: abi.ChainEpoch(ticket.BlockHeight), - TicketBytes: ticket.TicketBytes[:], - }, + commD: unsealed, + commR: sealed, + ticket: ticket, }) } @@ -104,7 +101,7 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf SectorNumber: sector.SectorID, RegisteredProof: abi.RegisteredProof_StackedDRG32GiBSeal, - SealedCID: commcid.ReplicaCommitmentV1ToCID(sector.CommR), + SealedCID: *sector.CommR, SealRandEpoch: sector.Ticket.BlockHeight, DealIDs: sector.deals(), } @@ -161,7 +158,7 @@ func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) er ctx.Send(SectorSeedReady{seed: SealSeed{ BlockHeight: randHeight, - TicketBytes: rand, + TicketBytes: abi.InteractiveSealRandomness(rand), }}) return nil @@ -182,7 +179,7 @@ func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) log.Infof("KOMIT %d %x(%d); %x(%d); %v; r:%x; d:%x", sector.SectorID, sector.Ticket.TicketBytes, sector.Ticket.BlockHeight, sector.Seed.TicketBytes, sector.Seed.BlockHeight, sector.pieceInfos(), sector.CommR, sector.CommD) - proof, err := m.sb.SealCommit(ctx.Context(), sector.SectorID, sector.Ticket.SB(), sector.Seed.SB(), sector.pieceInfos(), sector.rspco()) + proof, err := m.sb.SealCommit(ctx.Context(), sector.SectorID, sector.Ticket.TicketBytes, sector.Seed.TicketBytes, sector.pieceInfos(), *sector.CommR, *sector.CommD) if err != nil { return ctx.Send(SectorComputeProofFailed{xerrors.Errorf("computing seal proof failed: %w", err)}) } diff --git a/states_failed.go b/states_failed.go index aaffe8b43..a7dfe36a9 100644 --- a/states_failed.go +++ b/states_failed.go @@ -4,7 +4,6 @@ import ( "bytes" "time" - commcid "github.com/filecoin-project/go-fil-commcid" "github.com/filecoin-project/specs-actors/actors/builtin/miner" "github.com/filecoin-project/specs-actors/actors/util/adt" "golang.org/x/xerrors" @@ -96,13 +95,8 @@ func (m *Sealing) handlePreCommitFailed(ctx statemachine.Context, sector SectorI return nil // TODO: SeedWait needs this currently } - pciR, err := commcid.CIDToReplicaCommitmentV1(pci.Info.SealedCID) - if err != nil { - return err - } - - if string(pciR) != string(sector.CommR) { - log.Warn("sector %d is precommitted on chain, with different CommR: %x != %x", sector.SectorID, pciR, sector.CommR) + if pci.Info.SealedCID != *sector.CommR { + log.Warn("sector %d is precommitted on chain, with different CommR: %x != %x", sector.SectorID, pci.Info.SealedCID, sector.CommR) return nil // TODO: remove when the actor allows re-precommit } diff --git a/types.go b/types.go index e2a2c049d..3c181ef81 100644 --- a/types.go +++ b/types.go @@ -1,7 +1,6 @@ package sealing import ( - sectorbuilder "github.com/filecoin-project/go-sectorbuilder" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/specs-actors/actors/abi" "github.com/ipfs/go-cid" @@ -9,24 +8,12 @@ import ( type SealTicket struct { BlockHeight abi.ChainEpoch - TicketBytes []byte -} - -func (t *SealTicket) SB() sectorbuilder.SealTicket { - out := sectorbuilder.SealTicket{BlockHeight: uint64(t.BlockHeight)} - copy(out.TicketBytes[:], t.TicketBytes) - return out + TicketBytes abi.SealRandomness } type SealSeed struct { BlockHeight abi.ChainEpoch - TicketBytes []byte -} - -func (t *SealSeed) SB() sectorbuilder.SealSeed { - out := sectorbuilder.SealSeed{BlockHeight: uint64(t.BlockHeight)} - copy(out.TicketBytes[:], t.TicketBytes) - return out + TicketBytes abi.InteractiveSealRandomness } func (t *SealSeed) Equals(o *SealSeed) bool { @@ -37,13 +24,7 @@ type Piece struct { DealID *abi.DealID Size abi.UnpaddedPieceSize - CommP []byte -} - -func (p *Piece) ppi() (out sectorbuilder.PublicPieceInfo) { - out.Size = p.Size - copy(out.CommP[:], p.CommP) - return out + CommP cid.Cid } type Log struct { @@ -61,13 +42,15 @@ type SectorInfo struct { SectorID abi.SectorNumber Nonce uint64 // TODO: remove + SectorType abi.RegisteredProof + // Packing Pieces []Piece // PreCommit - CommD []byte - CommR []byte + CommD *cid.Cid + CommR *cid.Cid Proof []byte Ticket SealTicket @@ -88,10 +71,13 @@ type SectorInfo struct { Log []Log } -func (t *SectorInfo) pieceInfos() []sectorbuilder.PublicPieceInfo { - out := make([]sectorbuilder.PublicPieceInfo, len(t.Pieces)) +func (t *SectorInfo) pieceInfos() []abi.PieceInfo { + out := make([]abi.PieceInfo, len(t.Pieces)) for i, piece := range t.Pieces { - out[i] = piece.ppi() + out[i] = abi.PieceInfo{ + Size: piece.Size.Padded(), + PieceCID: piece.CommP, + } } return out } @@ -114,12 +100,3 @@ func (t *SectorInfo) existingPieces() []abi.UnpaddedPieceSize { } return out } - -func (t *SectorInfo) rspco() sectorbuilder.RawSealPreCommitOutput { - var out sectorbuilder.RawSealPreCommitOutput - - copy(out.CommD[:], t.CommD) - copy(out.CommR[:], t.CommR) - - return out -} diff --git a/types_test.go b/types_test.go index 75460d3f8..32849e40c 100644 --- a/types_test.go +++ b/types_test.go @@ -5,14 +5,17 @@ import ( "testing" "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin" "gotest.tools/assert" - "github.com/filecoin-project/go-cbor-util" + cborutil "github.com/filecoin-project/go-cbor-util" ) func TestSectorInfoSelialization(t *testing.T) { d := abi.DealID(1234) + dummyCid := builtin.AccountActorCodeID + si := &SectorInfo{ State: 123, SectorID: 234, @@ -20,9 +23,9 @@ func TestSectorInfoSelialization(t *testing.T) { Pieces: []Piece{{ DealID: &d, Size: 5, - CommP: []byte{3}, + CommP: dummyCid, }}, - CommD: []byte{32, 4}, + CommD: &dummyCid, CommR: nil, Proof: nil, Ticket: SealTicket{ diff --git a/utils_test.go b/utils_test.go index a5287fd87..1d6b6c515 100644 --- a/utils_test.go +++ b/utils_test.go @@ -5,8 +5,6 @@ import ( "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/lotus/storage/sbmock" - "github.com/stretchr/testify/assert" ) @@ -45,19 +43,3 @@ func TestFillersFromRem(t *testing.T) { testFill(t, ub, []abi.UnpaddedPieceSize{ub1, ub4}) } } - -func TestFastPledge(t *testing.T) { - sz := abi.PaddedPieceSize(16 << 20) - - s := Sealing{sb: sbmock.NewMockSectorBuilder(0, abi.SectorSize(sz))} - if _, err := s.fastPledgeCommitment(sz.Unpadded(), 5); err != nil { - t.Fatalf("%+v", err) - } - - sz = abi.PaddedPieceSize(1024) - - s = Sealing{sb: sbmock.NewMockSectorBuilder(0, abi.SectorSize(sz))} - if _, err := s.fastPledgeCommitment(sz.Unpadded(), 64); err != nil { - t.Fatalf("%+v", err) - } -} From cec0b3c15f3bcbc33d7062a2d809b4ce4470f683 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 27 Feb 2020 01:54:39 +0100 Subject: [PATCH 082/126] zerocomm: 'Fix' the test --- garbage.go | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/garbage.go b/garbage.go index 0a7b33324..93446c3c6 100644 --- a/garbage.go +++ b/garbage.go @@ -7,19 +7,12 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/specs-actors/actors/abi" + + "github.com/filecoin-project/lotus/lib/nullreader" ) -type nullReader struct{} - -func (nullReader) Read(out []byte) (int, error) { - for i := range out { - out[i] = 0 - } - return len(out), nil -} - func (m *Sealing) pledgeReader(size abi.UnpaddedPieceSize) io.Reader { - return io.LimitReader(&nullReader{}, int64(size)) + return io.LimitReader(&nullreader.Reader{}, int64(size)) } func (m *Sealing) pledgeSector(ctx context.Context, sectorID abi.SectorNumber, existingPieceSizes []abi.UnpaddedPieceSize, sizes ...abi.UnpaddedPieceSize) ([]Piece, error) { From 9e77a046a1f7ac4834c7a3fbd477f5199e13b880 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Thu, 27 Feb 2020 13:45:31 -0800 Subject: [PATCH 083/126] make it all build finally --- cbor_gen.go | 284 -------------------------------------------------- checks.go | 4 +- fsm_events.go | 4 +- fsm_test.go | 4 +- sealing.go | 2 +- states.go | 19 ++-- types.go | 18 +--- types_test.go | 9 +- 8 files changed, 24 insertions(+), 320 deletions(-) diff --git a/cbor_gen.go b/cbor_gen.go index d13847a99..e8cf29ec2 100644 --- a/cbor_gen.go +++ b/cbor_gen.go @@ -13,282 +13,6 @@ import ( var _ = xerrors.Errorf -func (t *SealTicket) MarshalCBOR(w io.Writer) error { - if t == nil { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{162}); err != nil { - return err - } - - // t.BlockHeight (abi.ChainEpoch) (int64) - if len("BlockHeight") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"BlockHeight\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("BlockHeight")))); err != nil { - return err - } - if _, err := w.Write([]byte("BlockHeight")); err != nil { - return err - } - - if t.BlockHeight >= 0 { - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.BlockHeight))); err != nil { - return err - } - } else { - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajNegativeInt, uint64(-t.BlockHeight)-1)); err != nil { - return err - } - } - - // t.TicketBytes ([]uint8) (slice) - if len("TicketBytes") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"TicketBytes\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("TicketBytes")))); err != nil { - return err - } - if _, err := w.Write([]byte("TicketBytes")); err != nil { - return err - } - - if len(t.TicketBytes) > cbg.ByteArrayMaxLen { - return xerrors.Errorf("Byte array in field t.TicketBytes was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.TicketBytes)))); err != nil { - return err - } - if _, err := w.Write(t.TicketBytes); err != nil { - return err - } - return nil -} - -func (t *SealTicket) UnmarshalCBOR(r io.Reader) error { - br := cbg.GetPeeker(r) - - maj, extra, err := cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajMap { - return fmt.Errorf("cbor input should be of type map") - } - - if extra > cbg.MaxLength { - return fmt.Errorf("SealTicket: map struct too large (%d)", extra) - } - - var name string - n := extra - - for i := uint64(0); i < n; i++ { - - { - sval, err := cbg.ReadString(br) - if err != nil { - return err - } - - name = string(sval) - } - - switch name { - // t.BlockHeight (abi.ChainEpoch) (int64) - case "BlockHeight": - { - maj, extra, err := cbg.CborReadHeader(br) - var extraI int64 - if err != nil { - return err - } - switch maj { - case cbg.MajUnsignedInt: - extraI = int64(extra) - if extraI < 0 { - return fmt.Errorf("int64 positive overflow") - } - case cbg.MajNegativeInt: - extraI = int64(extra) - if extraI < 0 { - return fmt.Errorf("int64 negative oveflow") - } - extraI = -1 - extraI - default: - return fmt.Errorf("wrong type for int64 field: %d", maj) - } - - t.BlockHeight = abi.ChainEpoch(extraI) - } - // t.TicketBytes ([]uint8) (slice) - case "TicketBytes": - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.ByteArrayMaxLen { - return fmt.Errorf("t.TicketBytes: byte array too large (%d)", extra) - } - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") - } - t.TicketBytes = make([]byte, extra) - if _, err := io.ReadFull(br, t.TicketBytes); err != nil { - return err - } - - default: - return fmt.Errorf("unknown struct field %d: '%s'", i, name) - } - } - - return nil -} -func (t *SealSeed) MarshalCBOR(w io.Writer) error { - if t == nil { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{162}); err != nil { - return err - } - - // t.BlockHeight (abi.ChainEpoch) (int64) - if len("BlockHeight") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"BlockHeight\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("BlockHeight")))); err != nil { - return err - } - if _, err := w.Write([]byte("BlockHeight")); err != nil { - return err - } - - if t.BlockHeight >= 0 { - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.BlockHeight))); err != nil { - return err - } - } else { - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajNegativeInt, uint64(-t.BlockHeight)-1)); err != nil { - return err - } - } - - // t.TicketBytes ([]uint8) (slice) - if len("TicketBytes") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"TicketBytes\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("TicketBytes")))); err != nil { - return err - } - if _, err := w.Write([]byte("TicketBytes")); err != nil { - return err - } - - if len(t.TicketBytes) > cbg.ByteArrayMaxLen { - return xerrors.Errorf("Byte array in field t.TicketBytes was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.TicketBytes)))); err != nil { - return err - } - if _, err := w.Write(t.TicketBytes); err != nil { - return err - } - return nil -} - -func (t *SealSeed) UnmarshalCBOR(r io.Reader) error { - br := cbg.GetPeeker(r) - - maj, extra, err := cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajMap { - return fmt.Errorf("cbor input should be of type map") - } - - if extra > cbg.MaxLength { - return fmt.Errorf("SealSeed: map struct too large (%d)", extra) - } - - var name string - n := extra - - for i := uint64(0); i < n; i++ { - - { - sval, err := cbg.ReadString(br) - if err != nil { - return err - } - - name = string(sval) - } - - switch name { - // t.BlockHeight (abi.ChainEpoch) (int64) - case "BlockHeight": - { - maj, extra, err := cbg.CborReadHeader(br) - var extraI int64 - if err != nil { - return err - } - switch maj { - case cbg.MajUnsignedInt: - extraI = int64(extra) - if extraI < 0 { - return fmt.Errorf("int64 positive overflow") - } - case cbg.MajNegativeInt: - extraI = int64(extra) - if extraI < 0 { - return fmt.Errorf("int64 negative oveflow") - } - extraI = -1 - extraI - default: - return fmt.Errorf("wrong type for int64 field: %d", maj) - } - - t.BlockHeight = abi.ChainEpoch(extraI) - } - // t.TicketBytes ([]uint8) (slice) - case "TicketBytes": - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.ByteArrayMaxLen { - return fmt.Errorf("t.TicketBytes: byte array too large (%d)", extra) - } - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") - } - t.TicketBytes = make([]byte, extra) - if _, err := io.ReadFull(br, t.TicketBytes); err != nil { - return err - } - - default: - return fmt.Errorf("unknown struct field %d: '%s'", i, name) - } - } - - return nil -} func (t *Piece) MarshalCBOR(w io.Writer) error { if t == nil { _, err := w.Write(cbg.CborNull) @@ -620,10 +344,6 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { return err } - if err := t.Seed.MarshalCBOR(w); err != nil { - return err - } - // t.CommitMessage (cid.Cid) (struct) if len("CommitMessage") > cbg.MaxLength { return xerrors.Errorf("Value in field \"CommitMessage\" was too long") @@ -903,10 +623,6 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { { - if err := t.Seed.UnmarshalCBOR(br); err != nil { - return err - } - } // t.CommitMessage (cid.Cid) (struct) case "CommitMessage": diff --git a/checks.go b/checks.go index ff19afcb7..4fad2315b 100644 --- a/checks.go +++ b/checks.go @@ -111,8 +111,8 @@ func checkSeal(ctx context.Context, maddr address.Address, si SectorInfo, api se return &ErrBadCommD{xerrors.Errorf("on chain CommD differs from sector: %x != %x", r.Return, si.CommD)} } - if int64(head.Height())-int64(si.Ticket.BlockHeight+build.SealRandomnessLookback) > build.SealRandomnessLookbackLimit { - return &ErrExpiredTicket{xerrors.Errorf("ticket expired: seal height: %d, head: %d", si.Ticket.BlockHeight+build.SealRandomnessLookback, head.Height())} + if int64(head.Height())-int64(si.Ticket.Epoch+build.SealRandomnessLookback) > build.SealRandomnessLookbackLimit { + return &ErrExpiredTicket{xerrors.Errorf("ticket expired: seal height: %d, head: %d", si.Ticket.Epoch+build.SealRandomnessLookback, head.Height())} } return nil diff --git a/fsm_events.go b/fsm_events.go index 535f3fd86..dc773b966 100644 --- a/fsm_events.go +++ b/fsm_events.go @@ -68,7 +68,7 @@ func (evt SectorPackingFailed) apply(*SectorInfo) {} type SectorSealed struct { commR cid.Cid commD cid.Cid - ticket SealTicket + ticket api.SealTicket } func (evt SectorSealed) apply(state *SectorInfo) { @@ -96,7 +96,7 @@ func (evt SectorPreCommitted) apply(state *SectorInfo) { } type SectorSeedReady struct { - seed SealSeed + seed api.SealSeed } func (evt SectorSeedReady) apply(state *SectorInfo) { diff --git a/fsm_test.go b/fsm_test.go index 24145a2a1..a4d53d018 100644 --- a/fsm_test.go +++ b/fsm_test.go @@ -75,12 +75,12 @@ func TestSeedRevert(t *testing.T) { m.planSingle(SectorSeedReady{}) require.Equal(m.t, m.state.State, api.Committing) - _, err := m.s.plan([]statemachine.Event{{SectorSeedReady{seed: SealSeed{BlockHeight: 5}}}, {SectorCommitted{}}}, m.state) + _, err := m.s.plan([]statemachine.Event{{SectorSeedReady{seed: api.SealSeed{Epoch: 5}}}, {SectorCommitted{}}}, m.state) require.NoError(t, err) require.Equal(m.t, m.state.State, api.Committing) // not changing the seed this time - _, err = m.s.plan([]statemachine.Event{{SectorSeedReady{seed: SealSeed{BlockHeight: 5}}}, {SectorCommitted{}}}, m.state) + _, err = m.s.plan([]statemachine.Event{{SectorSeedReady{seed: api.SealSeed{Epoch: 5}}}, {SectorCommitted{}}}, m.state) require.Equal(m.t, m.state.State, api.CommitWait) m.planSingle(SectorProving{}) diff --git a/sealing.go b/sealing.go index 2e1e65ceb..8fd16cc17 100644 --- a/sealing.go +++ b/sealing.go @@ -28,7 +28,7 @@ const SectorStorePrefix = "/sectors" var log = logging.Logger("sectors") -type TicketFn func(context.Context) (SealTicket, error) +type TicketFn func(context.Context) (*api.SealTicket, error) type sealingApi interface { // TODO: trim down // Call a read only method on actors (no interaction with the chain required) diff --git a/states.go b/states.go index 9dae76694..426f028ad 100644 --- a/states.go +++ b/states.go @@ -11,6 +11,7 @@ import ( "github.com/filecoin-project/specs-actors/actors/builtin/miner" "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/types" @@ -69,7 +70,7 @@ func (m *Sealing) handleUnsealed(ctx statemachine.Context, sector SectorInfo) er return ctx.Send(SectorSealFailed{xerrors.Errorf("getting ticket failed: %w", err)}) } - sealed, unsealed, err := m.sb.SealPreCommit(ctx.Context(), sector.SectorID, ticket.TicketBytes, sector.pieceInfos()) + sealed, unsealed, err := m.sb.SealPreCommit(ctx.Context(), sector.SectorID, ticket.Value, sector.pieceInfos()) if err != nil { return ctx.Send(SectorSealFailed{xerrors.Errorf("seal pre commit failed: %w", err)}) } @@ -77,7 +78,7 @@ func (m *Sealing) handleUnsealed(ctx statemachine.Context, sector SectorInfo) er return ctx.Send(SectorSealed{ commD: unsealed, commR: sealed, - ticket: ticket, + ticket: *ticket, }) } @@ -102,7 +103,7 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf RegisteredProof: abi.RegisteredProof_StackedDRG32GiBSeal, SealedCID: *sector.CommR, - SealRandEpoch: sector.Ticket.BlockHeight, + SealRandEpoch: sector.Ticket.Epoch, DealIDs: sector.deals(), } enc, aerr := actors.SerializeParams(params) @@ -156,9 +157,9 @@ func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) er return err } - ctx.Send(SectorSeedReady{seed: SealSeed{ - BlockHeight: randHeight, - TicketBytes: abi.InteractiveSealRandomness(rand), + ctx.Send(SectorSeedReady{seed: api.SealSeed{ + Epoch: randHeight, + Value: abi.InteractiveSealRandomness(rand), }}) return nil @@ -177,9 +178,9 @@ func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) er func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) error { log.Info("scheduling seal proof computation...") - log.Infof("KOMIT %d %x(%d); %x(%d); %v; r:%x; d:%x", sector.SectorID, sector.Ticket.TicketBytes, sector.Ticket.BlockHeight, sector.Seed.TicketBytes, sector.Seed.BlockHeight, sector.pieceInfos(), sector.CommR, sector.CommD) + log.Infof("KOMIT %d %x(%d); %x(%d); %v; r:%x; d:%x", sector.SectorID, sector.Ticket.Value, sector.Ticket.Epoch, sector.Seed.Value, sector.Seed.Epoch, sector.pieceInfos(), sector.CommR, sector.CommD) - proof, err := m.sb.SealCommit(ctx.Context(), sector.SectorID, sector.Ticket.TicketBytes, sector.Seed.TicketBytes, sector.pieceInfos(), *sector.CommR, *sector.CommD) + proof, err := m.sb.SealCommit(ctx.Context(), sector.SectorID, sector.Ticket.Value, sector.Seed.Value, sector.pieceInfos(), *sector.CommR, *sector.CommD) if err != nil { return ctx.Send(SectorComputeProofFailed{xerrors.Errorf("computing seal proof failed: %w", err)}) } @@ -231,7 +232,7 @@ func (m *Sealing) handleCommitWait(ctx statemachine.Context, sector SectorInfo) } if mw.Receipt.ExitCode != 0 { - return ctx.Send(SectorCommitFailed{xerrors.Errorf("submitting sector proof failed (exit=%d, msg=%s) (t:%x; s:%x(%d); p:%x)", mw.Receipt.ExitCode, sector.CommitMessage, sector.Ticket.TicketBytes, sector.Seed.TicketBytes, sector.Seed.BlockHeight, sector.Proof)}) + return ctx.Send(SectorCommitFailed{xerrors.Errorf("submitting sector proof failed (exit=%d, msg=%s) (t:%x; s:%x(%d); p:%x)", mw.Receipt.ExitCode, sector.CommitMessage, sector.Ticket.Value, sector.Seed.Value, sector.Seed.Epoch, sector.Proof)}) } return ctx.Send(SectorProving{}) diff --git a/types.go b/types.go index 3c181ef81..b25a43ef8 100644 --- a/types.go +++ b/types.go @@ -6,20 +6,6 @@ import ( "github.com/ipfs/go-cid" ) -type SealTicket struct { - BlockHeight abi.ChainEpoch - TicketBytes abi.SealRandomness -} - -type SealSeed struct { - BlockHeight abi.ChainEpoch - TicketBytes abi.InteractiveSealRandomness -} - -func (t *SealSeed) Equals(o *SealSeed) bool { - return string(t.TicketBytes) == string(o.TicketBytes) && t.BlockHeight == o.BlockHeight -} - type Piece struct { DealID *abi.DealID @@ -52,12 +38,12 @@ type SectorInfo struct { CommD *cid.Cid CommR *cid.Cid Proof []byte - Ticket SealTicket + Ticket api.SealTicket PreCommitMessage *cid.Cid // WaitSeed - Seed SealSeed + Seed api.SealSeed // Committing CommitMessage *cid.Cid diff --git a/types_test.go b/types_test.go index 32849e40c..f3ec17aa3 100644 --- a/types_test.go +++ b/types_test.go @@ -4,6 +4,7 @@ import ( "bytes" "testing" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/builtin" "gotest.tools/assert" @@ -28,12 +29,12 @@ func TestSectorInfoSelialization(t *testing.T) { CommD: &dummyCid, CommR: nil, Proof: nil, - Ticket: SealTicket{ - BlockHeight: 345, - TicketBytes: []byte{87, 78, 7, 87}, + Ticket: api.SealTicket{ + Epoch: 345, + Value: []byte{87, 78, 7, 87}, }, PreCommitMessage: nil, - Seed: SealSeed{}, + Seed: api.SealSeed{}, CommitMessage: nil, FaultReportMsg: nil, LastErr: "hi", From c45a376dd66c0e3f0a4e211efb47f44fa813a0aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 28 Feb 2020 00:34:48 +0100 Subject: [PATCH 084/126] Regen cbor marshalers --- cbor_gen.go | 185 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 147 insertions(+), 38 deletions(-) diff --git a/cbor_gen.go b/cbor_gen.go index e8cf29ec2..6fe46d985 100644 --- a/cbor_gen.go +++ b/cbor_gen.go @@ -60,7 +60,7 @@ func (t *Piece) MarshalCBOR(w io.Writer) error { return err } - // t.CommP ([]uint8) (slice) + // t.CommP (cid.Cid) (struct) if len("CommP") > cbg.MaxLength { return xerrors.Errorf("Value in field \"CommP\" was too long") } @@ -72,6 +72,10 @@ func (t *Piece) MarshalCBOR(w io.Writer) error { return err } + if err := cbg.WriteCid(w, t.CommP); err != nil { + return xerrors.Errorf("failed to write cid field t.CommP: %w", err) + } + return nil } @@ -147,19 +151,18 @@ func (t *Piece) UnmarshalCBOR(r io.Reader) error { t.Size = abi.UnpaddedPieceSize(extra) } - // t.CommP ([]uint8) (slice) + // t.CommP (cid.Cid) (struct) case "CommP": - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } + { + + c, err := cbg.ReadCid(br) + if err != nil { + return xerrors.Errorf("failed to read cid field t.CommP: %w", err) + } + + t.CommP = c - if extra > cbg.ByteArrayMaxLen { - return fmt.Errorf("t.CommP: byte array too large (%d)", extra) - } - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") } default: @@ -174,7 +177,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { _, err := w.Write(cbg.CborNull) return err } - if _, err := w.Write([]byte{174}); err != nil { + if _, err := w.Write([]byte{175}); err != nil { return err } @@ -226,6 +229,28 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { return err } + // t.SectorType (abi.RegisteredProof) (int64) + if len("SectorType") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"SectorType\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("SectorType")))); err != nil { + return err + } + if _, err := w.Write([]byte("SectorType")); err != nil { + return err + } + + if t.SectorType >= 0 { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SectorType))); err != nil { + return err + } + } else { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajNegativeInt, uint64(-t.SectorType)-1)); err != nil { + return err + } + } + // t.Pieces ([]sealing.Piece) (slice) if len("Pieces") > cbg.MaxLength { return xerrors.Errorf("Value in field \"Pieces\" was too long") @@ -251,7 +276,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { } } - // t.CommD ([]uint8) (slice) + // t.CommD (cid.Cid) (struct) if len("CommD") > cbg.MaxLength { return xerrors.Errorf("Value in field \"CommD\" was too long") } @@ -263,7 +288,17 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { return err } - // t.CommR ([]uint8) (slice) + if t.CommD == nil { + if _, err := w.Write(cbg.CborNull); err != nil { + return err + } + } else { + if err := cbg.WriteCid(w, *t.CommD); err != nil { + return xerrors.Errorf("failed to write cid field t.CommD: %w", err) + } + } + + // t.CommR (cid.Cid) (struct) if len("CommR") > cbg.MaxLength { return xerrors.Errorf("Value in field \"CommR\" was too long") } @@ -275,6 +310,16 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { return err } + if t.CommR == nil { + if _, err := w.Write(cbg.CborNull); err != nil { + return err + } + } else { + if err := cbg.WriteCid(w, *t.CommR); err != nil { + return xerrors.Errorf("failed to write cid field t.CommR: %w", err) + } + } + // t.Proof ([]uint8) (slice) if len("Proof") > cbg.MaxLength { return xerrors.Errorf("Value in field \"Proof\" was too long") @@ -298,7 +343,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { return err } - // t.Ticket (sealing.SealTicket) (struct) + // t.Ticket (api.SealTicket) (struct) if len("Ticket") > cbg.MaxLength { return xerrors.Errorf("Value in field \"Ticket\" was too long") } @@ -310,6 +355,10 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { return err } + if err := t.Ticket.MarshalCBOR(w); err != nil { + return err + } + // t.PreCommitMessage (cid.Cid) (struct) if len("PreCommitMessage") > cbg.MaxLength { return xerrors.Errorf("Value in field \"PreCommitMessage\" was too long") @@ -332,7 +381,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { } } - // t.Seed (sealing.SealSeed) (struct) + // t.Seed (api.SealSeed) (struct) if len("Seed") > cbg.MaxLength { return xerrors.Errorf("Value in field \"Seed\" was too long") } @@ -344,6 +393,10 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { return err } + if err := t.Seed.MarshalCBOR(w); err != nil { + return err + } + // t.CommitMessage (cid.Cid) (struct) if len("CommitMessage") > cbg.MaxLength { return xerrors.Errorf("Value in field \"CommitMessage\" was too long") @@ -513,6 +566,32 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { t.Nonce = uint64(extra) } + // t.SectorType (abi.RegisteredProof) (int64) + case "SectorType": + { + maj, extra, err := cbg.CborReadHeader(br) + var extraI int64 + if err != nil { + return err + } + switch maj { + case cbg.MajUnsignedInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 positive overflow") + } + case cbg.MajNegativeInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 negative oveflow") + } + extraI = -1 - extraI + default: + return fmt.Errorf("wrong type for int64 field: %d", maj) + } + + t.SectorType = abi.RegisteredProof(extraI) + } // t.Pieces ([]sealing.Piece) (slice) case "Pieces": @@ -541,33 +620,55 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { t.Pieces[i] = v } - // t.CommD ([]uint8) (slice) + // t.CommD (cid.Cid) (struct) case "CommD": - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } + { + + 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 { + + c, err := cbg.ReadCid(br) + if err != nil { + return xerrors.Errorf("failed to read cid field t.CommD: %w", err) + } + + t.CommD = &c + } - if extra > cbg.ByteArrayMaxLen { - return fmt.Errorf("t.CommD: byte array too large (%d)", extra) } - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") - } - // t.CommR ([]uint8) (slice) + // t.CommR (cid.Cid) (struct) case "CommR": - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } + { + + 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 { + + c, err := cbg.ReadCid(br) + if err != nil { + return xerrors.Errorf("failed to read cid field t.CommR: %w", err) + } + + t.CommR = &c + } - if extra > cbg.ByteArrayMaxLen { - return fmt.Errorf("t.CommR: byte array too large (%d)", extra) - } - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") } // t.Proof ([]uint8) (slice) case "Proof": @@ -587,11 +688,15 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { if _, err := io.ReadFull(br, t.Proof); err != nil { return err } - // t.Ticket (sealing.SealTicket) (struct) + // t.Ticket (api.SealTicket) (struct) case "Ticket": { + if err := t.Ticket.UnmarshalCBOR(br); err != nil { + return err + } + } // t.PreCommitMessage (cid.Cid) (struct) case "PreCommitMessage": @@ -618,11 +723,15 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { } } - // t.Seed (sealing.SealSeed) (struct) + // t.Seed (api.SealSeed) (struct) case "Seed": { + if err := t.Seed.UnmarshalCBOR(br); err != nil { + return err + } + } // t.CommitMessage (cid.Cid) (struct) case "CommitMessage": From 47901c3fb781364c784dfbc2886e81f06602013b Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Fri, 28 Feb 2020 10:01:43 -0800 Subject: [PATCH 085/126] fixing miner logic to make more tests pass --- fsm_events.go | 6 ++++-- garbage.go | 9 ++++++++- sealing.go | 14 ++++++++++---- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/fsm_events.go b/fsm_events.go index dc773b966..e809685eb 100644 --- a/fsm_events.go +++ b/fsm_events.go @@ -46,13 +46,15 @@ func (evt SectorForceState) applyGlobal(state *SectorInfo) bool { // Normal path type SectorStart struct { - id abi.SectorNumber - pieces []Piece + id abi.SectorNumber + sectorType abi.RegisteredProof + pieces []Piece } func (evt SectorStart) apply(state *SectorInfo) { state.SectorID = evt.id state.Pieces = evt.pieces + state.SectorType = evt.sectorType } type SectorPacked struct{ pieces []Piece } diff --git a/garbage.go b/garbage.go index d0874f66c..660a2604a 100644 --- a/garbage.go +++ b/garbage.go @@ -8,6 +8,7 @@ import ( "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/lib/nullreader" ) @@ -48,6 +49,12 @@ func (m *Sealing) PledgeSector() error { size := abi.PaddedPieceSize(m.sb.SectorSize()).Unpadded() + rt, _, err := api.ProofTypeFromSectorSize(m.sb.SectorSize()) + if err != nil { + log.Error(err) + return + } + sid, err := m.sb.AcquireSectorNumber() if err != nil { log.Errorf("%+v", err) @@ -60,7 +67,7 @@ func (m *Sealing) PledgeSector() error { return } - if err := m.newSector(sid, pieces); err != nil { + if err := m.newSector(sid, rt, pieces); err != nil { log.Errorf("%+v", err) return } diff --git a/sealing.go b/sealing.go index 8fd16cc17..8ad74b841 100644 --- a/sealing.go +++ b/sealing.go @@ -121,7 +121,12 @@ func (m *Sealing) SealPiece(ctx context.Context, size abi.UnpaddedPieceSize, r i return xerrors.Errorf("adding piece to sector: %w", err) } - return m.newSector(sectorID, []Piece{ + rt, _, err := api.ProofTypeFromSectorSize(m.sb.SectorSize()) + if err != nil { + return xerrors.Errorf("bad sector size: %w", err) + } + + return m.newSector(sectorID, rt, []Piece{ { DealID: &dealID, @@ -131,10 +136,11 @@ func (m *Sealing) SealPiece(ctx context.Context, size abi.UnpaddedPieceSize, r i }) } -func (m *Sealing) newSector(sid abi.SectorNumber, pieces []Piece) error { +func (m *Sealing) newSector(sid abi.SectorNumber, rt abi.RegisteredProof, pieces []Piece) error { log.Infof("Start sealing %d", sid) return m.sectors.Send(uint64(sid), SectorStart{ - id: sid, - pieces: pieces, + id: sid, + pieces: pieces, + sectorType: rt, }) } From cacb797d160cbbf05587beea4df70f072234e1e0 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Fri, 28 Feb 2020 12:52:14 -0800 Subject: [PATCH 086/126] pass on proper sector types --- states.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/states.go b/states.go index 426f028ad..b3f033a9d 100644 --- a/states.go +++ b/states.go @@ -100,7 +100,7 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf params := &miner.SectorPreCommitInfo{ Expiration: 10000000, // TODO: implement SectorNumber: sector.SectorID, - RegisteredProof: abi.RegisteredProof_StackedDRG32GiBSeal, + RegisteredProof: sector.SectorType, SealedCID: *sector.CommR, SealRandEpoch: sector.Ticket.Epoch, From 94073cfb5a26684cdb0d260f641e1daa3c02eccb Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Fri, 28 Feb 2020 14:00:34 -0800 Subject: [PATCH 087/126] progress is made incrementally --- sealing.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sealing.go b/sealing.go index 8ad74b841..cd2f6ff5f 100644 --- a/sealing.go +++ b/sealing.go @@ -121,7 +121,7 @@ func (m *Sealing) SealPiece(ctx context.Context, size abi.UnpaddedPieceSize, r i return xerrors.Errorf("adding piece to sector: %w", err) } - rt, _, err := api.ProofTypeFromSectorSize(m.sb.SectorSize()) + _, rt, err := api.ProofTypeFromSectorSize(m.sb.SectorSize()) if err != nil { return xerrors.Errorf("bad sector size: %w", err) } From ed6c9570014e60def81ca9fe7bbf3b8afcd24185 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Sun, 1 Mar 2020 17:09:38 -0800 Subject: [PATCH 088/126] more misc fixes --- checks.go | 2 +- states.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/checks.go b/checks.go index 4fad2315b..cbede661f 100644 --- a/checks.go +++ b/checks.go @@ -108,7 +108,7 @@ func checkSeal(ctx context.Context, maddr address.Address, si SectorInfo, api se } if cid.Cid(c) != *si.CommD { - return &ErrBadCommD{xerrors.Errorf("on chain CommD differs from sector: %x != %x", r.Return, si.CommD)} + return &ErrBadCommD{xerrors.Errorf("on chain CommD differs from sector: %s != %s", cid.Cid(c), si.CommD)} } if int64(head.Height())-int64(si.Ticket.Epoch+build.SealRandomnessLookback) > build.SealRandomnessLookbackLimit { diff --git a/states.go b/states.go index b3f033a9d..ae5c3d8ad 100644 --- a/states.go +++ b/states.go @@ -91,7 +91,7 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf case *ErrBadCommD: // TODO: Should this just back to packing? (not really needed since handleUnsealed will do that too) return ctx.Send(SectorSealFailed{xerrors.Errorf("bad CommD error: %w", err)}) case *ErrExpiredTicket: - return ctx.Send(SectorSealFailed{xerrors.Errorf("bad CommD error: %w", err)}) + return ctx.Send(SectorSealFailed{xerrors.Errorf("ticket expired: %w", err)}) default: return xerrors.Errorf("checkSeal sanity check error: %w", err) } From b31c8a56f7523156cafe61def021ce13a9f4bcd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 3 Mar 2020 23:19:22 +0100 Subject: [PATCH 089/126] Storage Manager refactor --- garbage.go | 8 ++++---- sealing.go | 14 +++++++------- states.go | 28 +++++++++++++++------------- types.go | 3 ++- 4 files changed, 28 insertions(+), 25 deletions(-) diff --git a/garbage.go b/garbage.go index 660a2604a..42d1bc80a 100644 --- a/garbage.go +++ b/garbage.go @@ -25,7 +25,7 @@ func (m *Sealing) pledgeSector(ctx context.Context, sectorID abi.SectorNumber, e out := make([]Piece, len(sizes)) for i, size := range sizes { - ppi, err := m.sb.AddPiece(ctx, size, sectorID, m.pledgeReader(size), existingPieceSizes) + ppi, err := m.sealer.AddPiece(ctx, size, sectorID, m.pledgeReader(size), existingPieceSizes) if err != nil { return nil, xerrors.Errorf("add piece: %w", err) } @@ -47,15 +47,15 @@ func (m *Sealing) PledgeSector() error { // this, as we run everything here async, and it's cancelled when the // command exits - size := abi.PaddedPieceSize(m.sb.SectorSize()).Unpadded() + size := abi.PaddedPieceSize(m.sealer.SectorSize()).Unpadded() - rt, _, err := api.ProofTypeFromSectorSize(m.sb.SectorSize()) + rt, _, err := api.ProofTypeFromSectorSize(m.sealer.SectorSize()) if err != nil { log.Error(err) return } - sid, err := m.sb.AcquireSectorNumber() + sid, err := m.sealer.NewSector() if err != nil { log.Errorf("%+v", err) return diff --git a/sealing.go b/sealing.go index cd2f6ff5f..a7d11586a 100644 --- a/sealing.go +++ b/sealing.go @@ -12,7 +12,6 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/go-padreader" - "github.com/filecoin-project/go-sectorbuilder" "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/builtin/miner" "github.com/filecoin-project/specs-actors/actors/crypto" @@ -22,6 +21,7 @@ import ( "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/lib/statemachine" + "github.com/filecoin-project/lotus/storage/sealmgr" ) const SectorStorePrefix = "/sectors" @@ -65,19 +65,19 @@ type Sealing struct { maddr address.Address worker address.Address - sb sectorbuilder.Interface + sealer sealmgr.Manager sectors *statemachine.StateGroup tktFn TicketFn } -func New(api sealingApi, events *events.Events, maddr address.Address, worker address.Address, ds datastore.Batching, sb sectorbuilder.Interface, tktFn TicketFn) *Sealing { +func New(api sealingApi, events *events.Events, maddr address.Address, worker address.Address, ds datastore.Batching, sealer sealmgr.Manager, tktFn TicketFn) *Sealing { s := &Sealing{ api: api, events: events, maddr: maddr, worker: worker, - sb: sb, + sealer: sealer, tktFn: tktFn, } @@ -104,7 +104,7 @@ func (m *Sealing) AllocatePiece(size abi.UnpaddedPieceSize) (sectorID abi.Sector return 0, 0, xerrors.Errorf("cannot allocate unpadded piece") } - sid, err := m.sb.AcquireSectorNumber() // TODO: Put more than one thing in a sector + sid, err := m.sealer.NewSector() // TODO: Put more than one thing in a sector if err != nil { return 0, 0, xerrors.Errorf("acquiring sector ID: %w", err) } @@ -116,12 +116,12 @@ func (m *Sealing) AllocatePiece(size abi.UnpaddedPieceSize) (sectorID abi.Sector func (m *Sealing) SealPiece(ctx context.Context, size abi.UnpaddedPieceSize, r io.Reader, sectorID abi.SectorNumber, dealID abi.DealID) error { log.Infof("Seal piece for deal %d", dealID) - ppi, err := m.sb.AddPiece(ctx, size, sectorID, r, []abi.UnpaddedPieceSize{}) + ppi, err := m.sealer.AddPiece(ctx, size, sectorID, r, []abi.UnpaddedPieceSize{}) if err != nil { return xerrors.Errorf("adding piece to sector: %w", err) } - _, rt, err := api.ProofTypeFromSectorSize(m.sb.SectorSize()) + _, rt, err := api.ProofTypeFromSectorSize(m.sealer.SectorSize()) if err != nil { return xerrors.Errorf("bad sector size: %w", err) } diff --git a/states.go b/states.go index b3f033a9d..d7966a373 100644 --- a/states.go +++ b/states.go @@ -5,7 +5,6 @@ import ( "github.com/filecoin-project/specs-actors/actors/crypto" - "github.com/filecoin-project/go-sectorbuilder/fs" "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/actors/builtin/miner" @@ -26,7 +25,7 @@ func (m *Sealing) handlePacking(ctx statemachine.Context, sector SectorInfo) err allocated += piece.Size } - ubytes := abi.PaddedPieceSize(m.sb.SectorSize()).Unpadded() + ubytes := abi.PaddedPieceSize(m.sealer.SectorSize()).Unpadded() if allocated > ubytes { return xerrors.Errorf("too much data in sector: %d > %d", allocated, ubytes) @@ -70,7 +69,12 @@ func (m *Sealing) handleUnsealed(ctx statemachine.Context, sector SectorInfo) er return ctx.Send(SectorSealFailed{xerrors.Errorf("getting ticket failed: %w", err)}) } - sealed, unsealed, err := m.sb.SealPreCommit(ctx.Context(), sector.SectorID, ticket.Value, sector.pieceInfos()) + pc1o, err := m.sealer.SealPreCommit1(ctx.Context(), sector.SectorID, ticket.Value, sector.pieceInfos()) + if err != nil { + return ctx.Send(SectorSealFailed{xerrors.Errorf("seal pre commit failed: %w", err)}) + } + + sealed, unsealed, err := m.sealer.SealPreCommit2(ctx.Context(), sector.SectorID, pc1o) if err != nil { return ctx.Send(SectorSealFailed{xerrors.Errorf("seal pre commit failed: %w", err)}) } @@ -180,7 +184,12 @@ func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) log.Infof("KOMIT %d %x(%d); %x(%d); %v; r:%x; d:%x", sector.SectorID, sector.Ticket.Value, sector.Ticket.Epoch, sector.Seed.Value, sector.Seed.Epoch, sector.pieceInfos(), sector.CommR, sector.CommD) - proof, err := m.sb.SealCommit(ctx.Context(), sector.SectorID, sector.Ticket.Value, sector.Seed.Value, sector.pieceInfos(), *sector.CommR, *sector.CommD) + c2in, err := m.sealer.SealCommit1(ctx.Context(), sector.SectorID, sector.Ticket.Value, sector.Seed.Value, sector.pieceInfos(), *sector.CommR, *sector.CommD) + if err != nil { + return ctx.Send(SectorComputeProofFailed{xerrors.Errorf("computing seal proof failed: %w", err)}) + } + + proof, err := m.sealer.SealCommit2(ctx.Context(), sector.SectorID, c2in) if err != nil { return ctx.Send(SectorComputeProofFailed{xerrors.Errorf("computing seal proof failed: %w", err)}) } @@ -241,15 +250,8 @@ func (m *Sealing) handleCommitWait(ctx statemachine.Context, sector SectorInfo) func (m *Sealing) handleFinalizeSector(ctx statemachine.Context, sector SectorInfo) error { // TODO: Maybe wait for some finality - if err := m.sb.FinalizeSector(ctx.Context(), sector.SectorID); err != nil { - if !xerrors.Is(err, fs.ErrNoSuitablePath) { - return ctx.Send(SectorFinalizeFailed{xerrors.Errorf("finalize sector: %w", err)}) - } - log.Warnf("finalize sector: %v", err) - } - - if err := m.sb.DropStaged(ctx.Context(), sector.SectorID); err != nil { - return ctx.Send(SectorFinalizeFailed{xerrors.Errorf("drop staged: %w", err)}) + if err := m.sealer.FinalizeSector(ctx.Context(), sector.SectorID); err != nil { + return ctx.Send(SectorFinalizeFailed{xerrors.Errorf("finalize sector: %w", err)}) } return ctx.Send(SectorFinalized{}) diff --git a/types.go b/types.go index b25a43ef8..4e9e0dccc 100644 --- a/types.go +++ b/types.go @@ -1,9 +1,10 @@ package sealing import ( - "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/specs-actors/actors/abi" "github.com/ipfs/go-cid" + + "github.com/filecoin-project/lotus/api" ) type Piece struct { From 0e195410b58a5ad11940a0799e07815d18468128 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 5 Mar 2020 19:18:33 +0100 Subject: [PATCH 090/126] sealmgr: Implement all sealing steps --- garbage.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/garbage.go b/garbage.go index 42d1bc80a..47634eb5d 100644 --- a/garbage.go +++ b/garbage.go @@ -49,7 +49,7 @@ func (m *Sealing) PledgeSector() error { size := abi.PaddedPieceSize(m.sealer.SectorSize()).Unpadded() - rt, _, err := api.ProofTypeFromSectorSize(m.sealer.SectorSize()) + _, rt, err := api.ProofTypeFromSectorSize(m.sealer.SectorSize()) if err != nil { log.Error(err) return From 732ea1b8823bfbf06f717275f6d80048690d6abf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 6 Mar 2020 06:30:47 +0100 Subject: [PATCH 091/126] sectorbuilder type updates --- garbage.go | 2 +- sealing.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/garbage.go b/garbage.go index 47634eb5d..445ba8969 100644 --- a/garbage.go +++ b/garbage.go @@ -25,7 +25,7 @@ func (m *Sealing) pledgeSector(ctx context.Context, sectorID abi.SectorNumber, e out := make([]Piece, len(sizes)) for i, size := range sizes { - ppi, err := m.sealer.AddPiece(ctx, size, sectorID, m.pledgeReader(size), existingPieceSizes) + ppi, err := m.sealer.AddPiece(ctx, sectorID, existingPieceSizes, size, m.pledgeReader(size)) if err != nil { return nil, xerrors.Errorf("add piece: %w", err) } diff --git a/sealing.go b/sealing.go index a7d11586a..a3652485e 100644 --- a/sealing.go +++ b/sealing.go @@ -116,7 +116,7 @@ func (m *Sealing) AllocatePiece(size abi.UnpaddedPieceSize) (sectorID abi.Sector func (m *Sealing) SealPiece(ctx context.Context, size abi.UnpaddedPieceSize, r io.Reader, sectorID abi.SectorNumber, dealID abi.DealID) error { log.Infof("Seal piece for deal %d", dealID) - ppi, err := m.sealer.AddPiece(ctx, size, sectorID, r, []abi.UnpaddedPieceSize{}) + ppi, err := m.sealer.AddPiece(ctx, sectorID, []abi.UnpaddedPieceSize{}, size, r) if err != nil { return xerrors.Errorf("adding piece to sector: %w", err) } From d5a4051c7f87e013537b7ca898c17d9aec52de7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 6 Mar 2020 19:50:41 +0100 Subject: [PATCH 092/126] libs: Use zerocomm from sectorbuilder --- checks.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/checks.go b/checks.go index cbede661f..381be0196 100644 --- a/checks.go +++ b/checks.go @@ -4,6 +4,7 @@ import ( "bytes" "context" + "github.com/filecoin-project/go-sectorbuilder" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" @@ -15,7 +16,6 @@ import ( "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/lib/zerocomm" ) // TODO: For now we handle this by halting state execution, when we get jsonrpc reconnecting @@ -42,7 +42,7 @@ func checkPieces(ctx context.Context, si SectorInfo, api sealingApi) error { for i, piece := range si.Pieces { if piece.DealID == nil { - exp := zerocomm.ForSize(piece.Size) + exp := sectorbuilder.ZeroPieceCommitment(piece.Size) if piece.CommP != exp { return &ErrInvalidPiece{xerrors.Errorf("deal %d piece %d had non-zero CommP %+v", piece.DealID, i, piece.CommP)} } From dbca774e17f9fe44bc9e007624e113116114cb64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 6 Mar 2020 19:59:08 +0100 Subject: [PATCH 093/126] libs: Use go-statemachine --- fsm.go | 11 ++++++----- fsm_test.go | 3 ++- sealing.go | 2 +- states.go | 2 +- states_failed.go | 2 +- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/fsm.go b/fsm.go index 06ba11354..43be0077c 100644 --- a/fsm.go +++ b/fsm.go @@ -6,17 +6,18 @@ import ( "reflect" "time" - "github.com/filecoin-project/specs-actors/actors/abi" "golang.org/x/xerrors" + "github.com/filecoin-project/go-statemachine" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/lib/statemachine" ) -func (m *Sealing) Plan(events []statemachine.Event, user interface{}) (interface{}, error) { +func (m *Sealing) Plan(events []statemachine.Event, user interface{}) (interface{}, uint64, error) { next, err := m.plan(events, user.(*SectorInfo)) if err != nil || next == nil { - return nil, err + return nil, 0, err } return func(ctx statemachine.Context, si SectorInfo) error { @@ -27,7 +28,7 @@ func (m *Sealing) Plan(events []statemachine.Event, user interface{}) (interface } return nil - }, nil + }, uint64(len(events)), nil // TODO: This processed event count is not very correct } var fsmPlanners = []func(events []statemachine.Event, state *SectorInfo) error{ diff --git a/fsm_test.go b/fsm_test.go index a4d53d018..41becc4f3 100644 --- a/fsm_test.go +++ b/fsm_test.go @@ -6,8 +6,9 @@ import ( logging "github.com/ipfs/go-log/v2" "github.com/stretchr/testify/require" + "github.com/filecoin-project/go-statemachine" + "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/lib/statemachine" ) func init() { diff --git a/sealing.go b/sealing.go index a3652485e..89294eb91 100644 --- a/sealing.go +++ b/sealing.go @@ -12,6 +12,7 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/go-padreader" + "github.com/filecoin-project/go-statemachine" "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/builtin/miner" "github.com/filecoin-project/specs-actors/actors/crypto" @@ -20,7 +21,6 @@ import ( "github.com/filecoin-project/lotus/chain/events" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/lib/statemachine" "github.com/filecoin-project/lotus/storage/sealmgr" ) diff --git a/states.go b/states.go index b083096e9..e12860447 100644 --- a/states.go +++ b/states.go @@ -5,6 +5,7 @@ import ( "github.com/filecoin-project/specs-actors/actors/crypto" + "github.com/filecoin-project/go-statemachine" "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/actors/builtin/miner" @@ -14,7 +15,6 @@ import ( "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/lib/statemachine" ) func (m *Sealing) handlePacking(ctx statemachine.Context, sector SectorInfo) error { diff --git a/states_failed.go b/states_failed.go index a7dfe36a9..d5667f57e 100644 --- a/states_failed.go +++ b/states_failed.go @@ -4,6 +4,7 @@ import ( "bytes" "time" + "github.com/filecoin-project/go-statemachine" "github.com/filecoin-project/specs-actors/actors/builtin/miner" "github.com/filecoin-project/specs-actors/actors/util/adt" "golang.org/x/xerrors" @@ -12,7 +13,6 @@ import ( "github.com/filecoin-project/lotus/api/apibstore" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/lib/statemachine" ) const minRetryTime = 1 * time.Minute From 2fec889a113382d9a156b86979be6afab427ab85 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Tue, 3 Mar 2020 15:32:17 -0800 Subject: [PATCH 094/126] Unify MethodCall and ReplayResults into SimulationResult - Call and Replay now return the same type, which includes both Message and MessageReceipt --- checks.go | 8 ++++---- sealing.go | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/checks.go b/checks.go index cbcbca8fc..5bcca3f92 100644 --- a/checks.go +++ b/checks.go @@ -89,11 +89,11 @@ func checkSeal(ctx context.Context, maddr address.Address, si SectorInfo, api se if err != nil { return &ErrApi{xerrors.Errorf("calling ComputeDataCommitment: %w", err)} } - if r.ExitCode != 0 { - return &ErrBadCommD{xerrors.Errorf("receipt for ComputeDataCommitment had exit code %d", r.ExitCode)} + if r.MsgRct.ExitCode != 0 { + return &ErrBadCommD{xerrors.Errorf("receipt for ComputeDataCommitment had exit code %d", r.MsgRct.ExitCode)} } - if string(r.Return) != string(si.CommD) { - return &ErrBadCommD{xerrors.Errorf("on chain CommD differs from sector: %x != %x", r.Return, si.CommD)} + if string(r.MsgRct.Return) != string(si.CommD) { + return &ErrBadCommD{xerrors.Errorf("on chain CommD differs from sector: %x != %x", r.MsgRct.Return, si.CommD)} } if int64(head.Height())-int64(si.Ticket.BlockHeight+build.SealRandomnessLookback) > build.SealRandomnessLookbackLimit { diff --git a/sealing.go b/sealing.go index c39b98257..b2f8442e3 100644 --- a/sealing.go +++ b/sealing.go @@ -29,7 +29,7 @@ type TicketFn func(context.Context) (*sectorbuilder.SealTicket, error) type sealingApi interface { // TODO: trim down // Call a read only method on actors (no interaction with the chain required) - StateCall(context.Context, *types.Message, types.TipSetKey) (*api.MethodCall, error) + StateCall(context.Context, *types.Message, types.TipSetKey) (*api.InvocResult, error) StateMinerWorker(context.Context, address.Address, types.TipSetKey) (address.Address, error) StateMinerElectionPeriodStart(ctx context.Context, actor address.Address, tsk types.TipSetKey) (uint64, error) StateMinerSectors(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) From 9476452c494833ca950b12ee48f9601fc7469a2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 7 Mar 2020 00:03:57 +0100 Subject: [PATCH 095/126] sealing: Fix noop plan loop --- fsm.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsm.go b/fsm.go index 43be0077c..7bfb0c340 100644 --- a/fsm.go +++ b/fsm.go @@ -17,7 +17,7 @@ import ( func (m *Sealing) Plan(events []statemachine.Event, user interface{}) (interface{}, uint64, error) { next, err := m.plan(events, user.(*SectorInfo)) if err != nil || next == nil { - return nil, 0, err + return nil, uint64(len(events)), err } return func(ctx statemachine.Context, si SectorInfo) error { From 6ce8cda0a3d40af544174584680d8d69ea43dd48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 17 Mar 2020 21:19:52 +0100 Subject: [PATCH 096/126] Use new specs-storage interface --- garbage.go | 11 ++++++++--- sealing.go | 32 +++++++++++++++++++++++++++++--- states.go | 21 +++++++++++++-------- 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/garbage.go b/garbage.go index 445ba8969..4903abf25 100644 --- a/garbage.go +++ b/garbage.go @@ -16,7 +16,7 @@ func (m *Sealing) pledgeReader(size abi.UnpaddedPieceSize) io.Reader { return io.LimitReader(&nullreader.Reader{}, int64(size)) } -func (m *Sealing) pledgeSector(ctx context.Context, sectorID abi.SectorNumber, existingPieceSizes []abi.UnpaddedPieceSize, sizes ...abi.UnpaddedPieceSize) ([]Piece, error) { +func (m *Sealing) pledgeSector(ctx context.Context, sectorID abi.SectorID, existingPieceSizes []abi.UnpaddedPieceSize, sizes ...abi.UnpaddedPieceSize) ([]Piece, error) { if len(sizes) == 0 { return nil, nil } @@ -55,13 +55,18 @@ func (m *Sealing) PledgeSector() error { return } - sid, err := m.sealer.NewSector() + sid, err := m.sc.Next() + if err != nil { + log.Errorf("%+v", err) + return + } + err = m.sealer.NewSector(ctx, m.minerSector(sid)) if err != nil { log.Errorf("%+v", err) return } - pieces, err := m.pledgeSector(ctx, sid, []abi.UnpaddedPieceSize{}, size) + pieces, err := m.pledgeSector(ctx, m.minerSector(sid), []abi.UnpaddedPieceSize{}, size) if err != nil { log.Errorf("%+v", err) return diff --git a/sealing.go b/sealing.go index b74d34db1..ed793b0ae 100644 --- a/sealing.go +++ b/sealing.go @@ -30,6 +30,10 @@ var log = logging.Logger("sectors") type TicketFn func(context.Context) (*api.SealTicket, error) +type SectorIDCounter interface { + Next() (abi.SectorNumber, error) +} + type sealingApi interface { // TODO: trim down // Call a read only method on actors (no interaction with the chain required) StateCall(context.Context, *types.Message, types.TipSetKey) (*api.InvocResult, error) @@ -68,6 +72,7 @@ type Sealing struct { sealer sealmgr.Manager sectors *statemachine.StateGroup tktFn TicketFn + sc SectorIDCounter } func New(api sealingApi, events *events.Events, maddr address.Address, worker address.Address, ds datastore.Batching, sealer sealmgr.Manager, tktFn TicketFn) *Sealing { @@ -104,9 +109,14 @@ func (m *Sealing) AllocatePiece(size abi.UnpaddedPieceSize) (sectorID abi.Sector return 0, 0, xerrors.Errorf("cannot allocate unpadded piece") } - sid, err := m.sealer.NewSector() // TODO: Put more than one thing in a sector + sid, err := m.sc.Next() if err != nil { - return 0, 0, xerrors.Errorf("acquiring sector ID: %w", err) + return 0, 0, xerrors.Errorf("getting sector number: %w", err) + } + + err = m.sealer.NewSector(context.TODO(), m.minerSector(sid)) // TODO: Put more than one thing in a sector + if err != nil { + return 0, 0, xerrors.Errorf("initializing sector: %w", err) } // offset hard-coded to 0 since we only put one thing in a sector for now @@ -116,7 +126,7 @@ func (m *Sealing) AllocatePiece(size abi.UnpaddedPieceSize) (sectorID abi.Sector func (m *Sealing) SealPiece(ctx context.Context, size abi.UnpaddedPieceSize, r io.Reader, sectorID abi.SectorNumber, dealID abi.DealID) error { log.Infof("Seal piece for deal %d", dealID) - ppi, err := m.sealer.AddPiece(ctx, sectorID, []abi.UnpaddedPieceSize{}, size, r) + ppi, err := m.sealer.AddPiece(ctx, m.minerSector(sectorID), []abi.UnpaddedPieceSize{}, size, r) if err != nil { return xerrors.Errorf("adding piece to sector: %w", err) } @@ -144,3 +154,19 @@ func (m *Sealing) newSector(sid abi.SectorNumber, rt abi.RegisteredProof, pieces sectorType: rt, }) } + +func (m *Sealing) minerSector(num abi.SectorNumber) abi.SectorID { + mid, err := address.IDFromAddress(m.maddr) + if err != nil { + panic(err) + } + + return abi.SectorID{ + Number: num, + Miner: abi.ActorID(mid), + } +} + +func (m *Sealing) Address() address.Address { + return m.maddr +} diff --git a/states.go b/states.go index e12860447..ca02e90f4 100644 --- a/states.go +++ b/states.go @@ -2,6 +2,7 @@ package sealing import ( "context" + "github.com/filecoin-project/specs-storage/storage" "github.com/filecoin-project/specs-actors/actors/crypto" @@ -40,7 +41,7 @@ func (m *Sealing) handlePacking(ctx statemachine.Context, sector SectorInfo) err log.Warnf("Creating %d filler pieces for sector %d", len(fillerSizes), sector.SectorID) } - pieces, err := m.pledgeSector(ctx.Context(), sector.SectorID, sector.existingPieces(), fillerSizes...) + pieces, err := m.pledgeSector(ctx.Context(), m.minerSector(sector.SectorID), sector.existingPieces(), fillerSizes...) if err != nil { return xerrors.Errorf("filling up the sector (%v): %w", fillerSizes, err) } @@ -69,19 +70,19 @@ func (m *Sealing) handleUnsealed(ctx statemachine.Context, sector SectorInfo) er return ctx.Send(SectorSealFailed{xerrors.Errorf("getting ticket failed: %w", err)}) } - pc1o, err := m.sealer.SealPreCommit1(ctx.Context(), sector.SectorID, ticket.Value, sector.pieceInfos()) + pc1o, err := m.sealer.SealPreCommit1(ctx.Context(), m.minerSector(sector.SectorID), ticket.Value, sector.pieceInfos()) if err != nil { return ctx.Send(SectorSealFailed{xerrors.Errorf("seal pre commit failed: %w", err)}) } - sealed, unsealed, err := m.sealer.SealPreCommit2(ctx.Context(), sector.SectorID, pc1o) + cids, err := m.sealer.SealPreCommit2(ctx.Context(), m.minerSector(sector.SectorID), pc1o) if err != nil { return ctx.Send(SectorSealFailed{xerrors.Errorf("seal pre commit failed: %w", err)}) } return ctx.Send(SectorSealed{ - commD: unsealed, - commR: sealed, + commD: cids.Unsealed, + commR: cids.Sealed, ticket: *ticket, }) } @@ -184,12 +185,16 @@ func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) log.Infof("KOMIT %d %x(%d); %x(%d); %v; r:%x; d:%x", sector.SectorID, sector.Ticket.Value, sector.Ticket.Epoch, sector.Seed.Value, sector.Seed.Epoch, sector.pieceInfos(), sector.CommR, sector.CommD) - c2in, err := m.sealer.SealCommit1(ctx.Context(), sector.SectorID, sector.Ticket.Value, sector.Seed.Value, sector.pieceInfos(), *sector.CommR, *sector.CommD) + cids := storage.SectorCids{ + Unsealed: *sector.CommD, + Sealed: *sector.CommR, + } + c2in, err := m.sealer.SealCommit1(ctx.Context(), m.minerSector(sector.SectorID), sector.Ticket.Value, sector.Seed.Value, sector.pieceInfos(), cids) if err != nil { return ctx.Send(SectorComputeProofFailed{xerrors.Errorf("computing seal proof failed: %w", err)}) } - proof, err := m.sealer.SealCommit2(ctx.Context(), sector.SectorID, c2in) + proof, err := m.sealer.SealCommit2(ctx.Context(), m.minerSector(sector.SectorID), c2in) if err != nil { return ctx.Send(SectorComputeProofFailed{xerrors.Errorf("computing seal proof failed: %w", err)}) } @@ -250,7 +255,7 @@ func (m *Sealing) handleCommitWait(ctx statemachine.Context, sector SectorInfo) func (m *Sealing) handleFinalizeSector(ctx statemachine.Context, sector SectorInfo) error { // TODO: Maybe wait for some finality - if err := m.sealer.FinalizeSector(ctx.Context(), sector.SectorID); err != nil { + if err := m.sealer.FinalizeSector(ctx.Context(), m.minerSector(sector.SectorID)); err != nil { return ctx.Send(SectorFinalizeFailed{xerrors.Errorf("finalize sector: %w", err)}) } From 0a3d61435e76faccef39e6644a61254fea2550b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 18 Mar 2020 02:08:11 +0100 Subject: [PATCH 097/126] Fix tests after specs-storage changes --- sealing.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sealing.go b/sealing.go index ed793b0ae..3c50a1507 100644 --- a/sealing.go +++ b/sealing.go @@ -75,7 +75,7 @@ type Sealing struct { sc SectorIDCounter } -func New(api sealingApi, events *events.Events, maddr address.Address, worker address.Address, ds datastore.Batching, sealer sealmgr.Manager, tktFn TicketFn) *Sealing { +func New(api sealingApi, events *events.Events, maddr address.Address, worker address.Address, ds datastore.Batching, sealer sealmgr.Manager, sc SectorIDCounter, tktFn TicketFn) *Sealing { s := &Sealing{ api: api, events: events, @@ -84,6 +84,7 @@ func New(api sealingApi, events *events.Events, maddr address.Address, worker ad worker: worker, sealer: sealer, tktFn: tktFn, + sc: sc, } s.sectors = statemachine.New(namespace.Wrap(ds, datastore.NewKey(SectorStorePrefix)), s, SectorInfo{}) @@ -163,7 +164,7 @@ func (m *Sealing) minerSector(num abi.SectorNumber) abi.SectorID { return abi.SectorID{ Number: num, - Miner: abi.ActorID(mid), + Miner: abi.ActorID(mid), } } From e035f055645005d6c92396237ffc84e2bdc7c3ce Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Wed, 18 Mar 2020 13:45:37 -0700 Subject: [PATCH 098/126] change gas limit to be a normal int64 --- checks.go | 2 +- states.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/checks.go b/checks.go index c7bec0228..ce0f5c385 100644 --- a/checks.go +++ b/checks.go @@ -90,7 +90,7 @@ func checkSeal(ctx context.Context, maddr address.Address, si SectorInfo, api se From: maddr, Value: types.NewInt(0), GasPrice: types.NewInt(0), - GasLimit: types.NewInt(9999999999), + GasLimit: 9999999999, Method: builtin.MethodsMarket.ComputeDataCommitment, Params: ccparams, } diff --git a/states.go b/states.go index e12860447..f66c97905 100644 --- a/states.go +++ b/states.go @@ -121,7 +121,7 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf Method: builtin.MethodsMiner.PreCommitSector, Params: enc, Value: types.NewInt(0), // TODO: need to ensure sufficient collateral - GasLimit: types.NewInt(1000000 /* i dont know help */), + GasLimit: 1000000, /* i dont know help */ GasPrice: types.NewInt(1), } @@ -212,7 +212,7 @@ func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) Method: builtin.MethodsMiner.ProveCommitSector, Params: enc, Value: types.NewInt(0), // TODO: need to ensure sufficient collateral - GasLimit: types.NewInt(1000000 /* i dont know help */), + GasLimit: 1000000, /* i dont know help */ GasPrice: types.NewInt(1), } @@ -278,7 +278,7 @@ func (m *Sealing) handleFaulty(ctx statemachine.Context, sector SectorInfo) erro Method: builtin.MethodsMiner.DeclareTemporaryFaults, Params: enc, Value: types.NewInt(0), // TODO: need to ensure sufficient collateral - GasLimit: types.NewInt(1000000 /* i dont know help */), + GasLimit: 1000000, /* i dont know help */ GasPrice: types.NewInt(1), } From 0b4979d20af847d84fc9c7ba2930f94f4d50ed7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 19 Mar 2020 20:17:43 +0100 Subject: [PATCH 099/126] workers: get sectors back to miner process after precommit --- states.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/states.go b/states.go index a1babd17d..24f44fdf0 100644 --- a/states.go +++ b/states.go @@ -72,12 +72,12 @@ func (m *Sealing) handleUnsealed(ctx statemachine.Context, sector SectorInfo) er pc1o, err := m.sealer.SealPreCommit1(ctx.Context(), m.minerSector(sector.SectorID), ticket.Value, sector.pieceInfos()) if err != nil { - return ctx.Send(SectorSealFailed{xerrors.Errorf("seal pre commit failed: %w", err)}) + return ctx.Send(SectorSealFailed{xerrors.Errorf("seal pre commit(1) failed: %w", err)}) } cids, err := m.sealer.SealPreCommit2(ctx.Context(), m.minerSector(sector.SectorID), pc1o) if err != nil { - return ctx.Send(SectorSealFailed{xerrors.Errorf("seal pre commit failed: %w", err)}) + return ctx.Send(SectorSealFailed{xerrors.Errorf("seal pre commit(2) failed: %w", err)}) } return ctx.Send(SectorSealed{ From 80c774ec4928a0f29e0ad3cf2c4f654ec77ad5ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 20 Mar 2020 01:20:01 +0100 Subject: [PATCH 100/126] storageminer: Fix preseal meta import for genesis miners --- fsm.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsm.go b/fsm.go index 7bfb0c340..bd3031aca 100644 --- a/fsm.go +++ b/fsm.go @@ -85,7 +85,7 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta for _, event := range events { l := Log{ Timestamp: uint64(time.Now().Unix()), - Message: fmt.Sprintf("%+v", event), + Message: fmt.Sprintf("%s", event), Kind: fmt.Sprintf("event;%T", event.User), } From ea4c93a0440832f2992e21233df421f75acd192b Mon Sep 17 00:00:00 2001 From: Jeromy Date: Sat, 21 Mar 2020 14:17:01 -0700 Subject: [PATCH 101/126] update and rerun cbor gen --- cbor_gen.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cbor_gen.go b/cbor_gen.go index 6fe46d985..42ad7c029 100644 --- a/cbor_gen.go +++ b/cbor_gen.go @@ -694,7 +694,7 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { { if err := t.Ticket.UnmarshalCBOR(br); err != nil { - return err + return xerrors.Errorf("unmarshaling t.Ticket: %w", err) } } @@ -729,7 +729,7 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { { if err := t.Seed.UnmarshalCBOR(br); err != nil { - return err + return xerrors.Errorf("unmarshaling t.Seed: %w", err) } } From 2fc1114ad2080b49a1779f982297993d4394b7b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sun, 22 Mar 2020 21:44:27 +0100 Subject: [PATCH 102/126] sealing: Improve sector log --- fsm.go | 12 +++++++++-- fsm_events.go | 60 +++++++++++++++++++++++++++------------------------ fsm_test.go | 4 ++-- sealing.go | 6 +++--- states.go | 16 +++++++------- 5 files changed, 55 insertions(+), 43 deletions(-) diff --git a/fsm.go b/fsm.go index bd3031aca..89d27178c 100644 --- a/fsm.go +++ b/fsm.go @@ -2,6 +2,7 @@ package sealing import ( "context" + "encoding/json" "fmt" "reflect" "time" @@ -82,10 +83,17 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta ///// // First process all events + for _, event := range events { + e, err := json.Marshal(event) + if err != nil { + log.Errorf("marshaling event for logging: %+v", err) + continue + } + l := Log{ Timestamp: uint64(time.Now().Unix()), - Message: fmt.Sprintf("%s", event), + Message: string(e), Kind: fmt.Sprintf("event;%T", event.User), } @@ -201,7 +209,7 @@ func planCommitting(events []statemachine.Event, state *SectorInfo) error { e.apply(state) state.State = api.CommitWait case SectorSeedReady: // seed changed :/ - if e.seed.Equals(&state.Seed) { + if e.Seed.Equals(&state.Seed) { log.Warnf("planCommitting: got SectorSeedReady, but the seed didn't change") continue // or it didn't! } diff --git a/fsm_events.go b/fsm_events.go index e809685eb..d358ba360 100644 --- a/fsm_events.go +++ b/fsm_events.go @@ -3,6 +3,7 @@ package sealing import ( "github.com/filecoin-project/specs-actors/actors/abi" "github.com/ipfs/go-cid" + "golang.org/x/xerrors" "github.com/filecoin-project/lotus/api" ) @@ -25,6 +26,7 @@ type SectorRestart struct{} func (evt SectorRestart) applyGlobal(*SectorInfo) bool { return false } type SectorFatalError struct{ error } +func (evt SectorFatalError) FormatError(xerrors.Printer) (next error) {return evt.error} func (evt SectorFatalError) applyGlobal(state *SectorInfo) bool { log.Errorf("Fatal error on sector %d: %+v", state.SectorID, evt.error) @@ -35,32 +37,32 @@ func (evt SectorFatalError) applyGlobal(state *SectorInfo) bool { } type SectorForceState struct { - state api.SectorState + State api.SectorState } func (evt SectorForceState) applyGlobal(state *SectorInfo) bool { - state.State = evt.state + state.State = evt.State return true } // Normal path type SectorStart struct { - id abi.SectorNumber - sectorType abi.RegisteredProof - pieces []Piece + ID abi.SectorNumber + SectorType abi.RegisteredProof + Pieces []Piece } func (evt SectorStart) apply(state *SectorInfo) { - state.SectorID = evt.id - state.Pieces = evt.pieces - state.SectorType = evt.sectorType + state.SectorID = evt.ID + state.Pieces = evt.Pieces + state.SectorType = evt.SectorType } -type SectorPacked struct{ pieces []Piece } +type SectorPacked struct{ Pieces []Piece } func (evt SectorPacked) apply(state *SectorInfo) { - state.Pieces = append(state.Pieces, evt.pieces...) + state.Pieces = append(state.Pieces, evt.Pieces...) } type SectorPackingFailed struct{ error } @@ -68,57 +70,59 @@ type SectorPackingFailed struct{ error } func (evt SectorPackingFailed) apply(*SectorInfo) {} type SectorSealed struct { - commR cid.Cid - commD cid.Cid - ticket api.SealTicket + Sealed cid.Cid + Unsealed cid.Cid + Ticket api.SealTicket } func (evt SectorSealed) apply(state *SectorInfo) { - commd := evt.commD + commd := evt.Unsealed state.CommD = &commd - commr := evt.commR + commr := evt.Sealed state.CommR = &commr - state.Ticket = evt.ticket + state.Ticket = evt.Ticket } type SectorSealFailed struct{ error } - +func (evt SectorSealFailed) FormatError(xerrors.Printer) (next error) {return evt.error} func (evt SectorSealFailed) apply(*SectorInfo) {} type SectorPreCommitFailed struct{ error } - +func (evt SectorPreCommitFailed) FormatError(xerrors.Printer) (next error) {return evt.error} func (evt SectorPreCommitFailed) apply(*SectorInfo) {} type SectorPreCommitted struct { - message cid.Cid + Message cid.Cid } func (evt SectorPreCommitted) apply(state *SectorInfo) { - state.PreCommitMessage = &evt.message + state.PreCommitMessage = &evt.Message } type SectorSeedReady struct { - seed api.SealSeed + Seed api.SealSeed } func (evt SectorSeedReady) apply(state *SectorInfo) { - state.Seed = evt.seed + state.Seed = evt.Seed } type SectorComputeProofFailed struct{ error } +func (evt SectorComputeProofFailed) FormatError(xerrors.Printer) (next error) {return evt.error} +func (evt SectorComputeProofFailed) apply(*SectorInfo) {} type SectorCommitFailed struct{ error } - +func (evt SectorCommitFailed) FormatError(xerrors.Printer) (next error) {return evt.error} func (evt SectorCommitFailed) apply(*SectorInfo) {} type SectorCommitted struct { - message cid.Cid - proof []byte + Message cid.Cid + Proof []byte } func (evt SectorCommitted) apply(state *SectorInfo) { - state.Proof = evt.proof - state.CommitMessage = &evt.message + state.Proof = evt.Proof + state.CommitMessage = &evt.Message } type SectorProving struct{} @@ -130,7 +134,7 @@ type SectorFinalized struct{} func (evt SectorFinalized) apply(*SectorInfo) {} type SectorFinalizeFailed struct{ error } - +func (evt SectorFinalizeFailed) FormatError(xerrors.Printer) (next error) {return evt.error} func (evt SectorFinalizeFailed) apply(*SectorInfo) {} // Failed state recovery diff --git a/fsm_test.go b/fsm_test.go index 41becc4f3..9b1a5d3e8 100644 --- a/fsm_test.go +++ b/fsm_test.go @@ -76,12 +76,12 @@ func TestSeedRevert(t *testing.T) { m.planSingle(SectorSeedReady{}) require.Equal(m.t, m.state.State, api.Committing) - _, err := m.s.plan([]statemachine.Event{{SectorSeedReady{seed: api.SealSeed{Epoch: 5}}}, {SectorCommitted{}}}, m.state) + _, err := m.s.plan([]statemachine.Event{{SectorSeedReady{Seed: api.SealSeed{Epoch: 5}}}, {SectorCommitted{}}}, m.state) require.NoError(t, err) require.Equal(m.t, m.state.State, api.Committing) // not changing the seed this time - _, err = m.s.plan([]statemachine.Event{{SectorSeedReady{seed: api.SealSeed{Epoch: 5}}}, {SectorCommitted{}}}, m.state) + _, err = m.s.plan([]statemachine.Event{{SectorSeedReady{Seed: api.SealSeed{Epoch: 5}}}, {SectorCommitted{}}}, m.state) require.Equal(m.t, m.state.State, api.CommitWait) m.planSingle(SectorProving{}) diff --git a/sealing.go b/sealing.go index 3c50a1507..bcfdab3b2 100644 --- a/sealing.go +++ b/sealing.go @@ -150,9 +150,9 @@ func (m *Sealing) SealPiece(ctx context.Context, size abi.UnpaddedPieceSize, r i func (m *Sealing) newSector(sid abi.SectorNumber, rt abi.RegisteredProof, pieces []Piece) error { log.Infof("Start sealing %d", sid) return m.sectors.Send(uint64(sid), SectorStart{ - id: sid, - pieces: pieces, - sectorType: rt, + ID: sid, + Pieces: pieces, + SectorType: rt, }) } diff --git a/states.go b/states.go index 24f44fdf0..3e6037b6d 100644 --- a/states.go +++ b/states.go @@ -46,7 +46,7 @@ func (m *Sealing) handlePacking(ctx statemachine.Context, sector SectorInfo) err return xerrors.Errorf("filling up the sector (%v): %w", fillerSizes, err) } - return ctx.Send(SectorPacked{pieces: pieces}) + return ctx.Send(SectorPacked{Pieces: pieces}) } func (m *Sealing) handleUnsealed(ctx statemachine.Context, sector SectorInfo) error { @@ -81,9 +81,9 @@ func (m *Sealing) handleUnsealed(ctx statemachine.Context, sector SectorInfo) er } return ctx.Send(SectorSealed{ - commD: cids.Unsealed, - commR: cids.Sealed, - ticket: *ticket, + Unsealed: cids.Unsealed, + Sealed: cids.Sealed, + Ticket: *ticket, }) } @@ -132,7 +132,7 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf return ctx.Send(SectorPreCommitFailed{xerrors.Errorf("pushing message to mpool: %w", err)}) } - return ctx.Send(SectorPreCommitted{message: smsg.Cid()}) + return ctx.Send(SectorPreCommitted{Message: smsg.Cid()}) } func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) error { @@ -162,7 +162,7 @@ func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) er return err } - ctx.Send(SectorSeedReady{seed: api.SealSeed{ + ctx.Send(SectorSeedReady{Seed: api.SealSeed{ Epoch: randHeight, Value: abi.InteractiveSealRandomness(rand), }}) @@ -229,8 +229,8 @@ func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) } return ctx.Send(SectorCommitted{ - proof: proof, - message: smsg.Cid(), + Proof: proof, + Message: smsg.Cid(), }) } From 88ad4858ec12a7ae6396d9723bd37f785ea4f1f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sun, 22 Mar 2020 22:39:27 +0100 Subject: [PATCH 103/126] gofmt --- fsm.go | 1 - fsm_events.go | 28 +++++++++++++++++----------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/fsm.go b/fsm.go index 89d27178c..0911bfba5 100644 --- a/fsm.go +++ b/fsm.go @@ -83,7 +83,6 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta ///// // First process all events - for _, event := range events { e, err := json.Marshal(event) if err != nil { diff --git a/fsm_events.go b/fsm_events.go index d358ba360..d433765ee 100644 --- a/fsm_events.go +++ b/fsm_events.go @@ -26,7 +26,8 @@ type SectorRestart struct{} func (evt SectorRestart) applyGlobal(*SectorInfo) bool { return false } type SectorFatalError struct{ error } -func (evt SectorFatalError) FormatError(xerrors.Printer) (next error) {return evt.error} + +func (evt SectorFatalError) FormatError(xerrors.Printer) (next error) { return evt.error } func (evt SectorFatalError) applyGlobal(state *SectorInfo) bool { log.Errorf("Fatal error on sector %d: %+v", state.SectorID, evt.error) @@ -84,12 +85,14 @@ func (evt SectorSealed) apply(state *SectorInfo) { } type SectorSealFailed struct{ error } -func (evt SectorSealFailed) FormatError(xerrors.Printer) (next error) {return evt.error} -func (evt SectorSealFailed) apply(*SectorInfo) {} + +func (evt SectorSealFailed) FormatError(xerrors.Printer) (next error) { return evt.error } +func (evt SectorSealFailed) apply(*SectorInfo) {} type SectorPreCommitFailed struct{ error } -func (evt SectorPreCommitFailed) FormatError(xerrors.Printer) (next error) {return evt.error} -func (evt SectorPreCommitFailed) apply(*SectorInfo) {} + +func (evt SectorPreCommitFailed) FormatError(xerrors.Printer) (next error) { return evt.error } +func (evt SectorPreCommitFailed) apply(*SectorInfo) {} type SectorPreCommitted struct { Message cid.Cid @@ -108,12 +111,14 @@ func (evt SectorSeedReady) apply(state *SectorInfo) { } type SectorComputeProofFailed struct{ error } -func (evt SectorComputeProofFailed) FormatError(xerrors.Printer) (next error) {return evt.error} -func (evt SectorComputeProofFailed) apply(*SectorInfo) {} + +func (evt SectorComputeProofFailed) FormatError(xerrors.Printer) (next error) { return evt.error } +func (evt SectorComputeProofFailed) apply(*SectorInfo) {} type SectorCommitFailed struct{ error } -func (evt SectorCommitFailed) FormatError(xerrors.Printer) (next error) {return evt.error} -func (evt SectorCommitFailed) apply(*SectorInfo) {} + +func (evt SectorCommitFailed) FormatError(xerrors.Printer) (next error) { return evt.error } +func (evt SectorCommitFailed) apply(*SectorInfo) {} type SectorCommitted struct { Message cid.Cid @@ -134,8 +139,9 @@ type SectorFinalized struct{} func (evt SectorFinalized) apply(*SectorInfo) {} type SectorFinalizeFailed struct{ error } -func (evt SectorFinalizeFailed) FormatError(xerrors.Printer) (next error) {return evt.error} -func (evt SectorFinalizeFailed) apply(*SectorInfo) {} + +func (evt SectorFinalizeFailed) FormatError(xerrors.Printer) (next error) { return evt.error } +func (evt SectorFinalizeFailed) apply(*SectorInfo) {} // Failed state recovery From a9443774a963c96a71324bd2df5fc4d95a6216d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 23 Mar 2020 12:40:02 +0100 Subject: [PATCH 104/126] Rename agvmgr+sealmgr to sectorstorage --- sealing.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sealing.go b/sealing.go index bcfdab3b2..97d2cee51 100644 --- a/sealing.go +++ b/sealing.go @@ -21,7 +21,7 @@ import ( "github.com/filecoin-project/lotus/chain/events" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/storage/sealmgr" + "github.com/filecoin-project/lotus/storage/sectorstorage" ) const SectorStorePrefix = "/sectors" @@ -69,13 +69,13 @@ type Sealing struct { maddr address.Address worker address.Address - sealer sealmgr.Manager + sealer sectorstorage.SectorManager sectors *statemachine.StateGroup tktFn TicketFn sc SectorIDCounter } -func New(api sealingApi, events *events.Events, maddr address.Address, worker address.Address, ds datastore.Batching, sealer sealmgr.Manager, sc SectorIDCounter, tktFn TicketFn) *Sealing { +func New(api sealingApi, events *events.Events, maddr address.Address, worker address.Address, ds datastore.Batching, sealer sectorstorage.SectorManager, sc SectorIDCounter, tktFn TicketFn) *Sealing { s := &Sealing{ api: api, events: events, From 01828ef8854cece281f1a7565e6743d73fde74fb Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Wed, 18 Mar 2020 19:06:53 -0400 Subject: [PATCH 105/126] Re: #1412: Add a non-blocking version of StateWaitMsg - This commit adds a new method called StateSearchMsg - We can probably overhaul StateWaitMsg onto this new method at a later point in time --- sealing.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sealing.go b/sealing.go index b74d34db1..402ff8a11 100644 --- a/sealing.go +++ b/sealing.go @@ -38,7 +38,7 @@ type sealingApi interface { // TODO: trim down StateMinerSectors(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) StateMinerProvingSet(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) StateMinerSectorSize(context.Context, address.Address, types.TipSetKey) (abi.SectorSize, error) - StateWaitMsg(context.Context, cid.Cid) (*api.MsgWait, error) // TODO: removeme eventually + StateWaitMsg(context.Context, cid.Cid) (*api.MsgLookup, error) // TODO: removeme eventually StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error) StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) StateMarketStorageDeal(context.Context, abi.DealID, types.TipSetKey) (*api.MarketDeal, error) From 2dfa38f5728648fdf93f719f605fd3354b7882f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 26 Mar 2020 03:50:56 +0100 Subject: [PATCH 106/126] Merge sectorbuilder into sectorstorage --- checks.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/checks.go b/checks.go index ce0f5c385..810d77300 100644 --- a/checks.go +++ b/checks.go @@ -3,8 +3,8 @@ package sealing import ( "bytes" "context" + "github.com/filecoin-project/lotus/storage/sectorstorage/zerocomm" - "github.com/filecoin-project/go-sectorbuilder" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" @@ -42,7 +42,7 @@ func checkPieces(ctx context.Context, si SectorInfo, api sealingApi) error { for i, piece := range si.Pieces { if piece.DealID == nil { - exp := sectorbuilder.ZeroPieceCommitment(piece.Size) + exp := zerocomm.ZeroPieceCommitment(piece.Size) if piece.CommP != exp { return &ErrInvalidPiece{xerrors.Errorf("deal %d piece %d had non-zero CommP %+v", piece.DealID, i, piece.CommP)} } From ed6202d202197be27513c1ea133aaae0e1623df0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 26 Mar 2020 20:34:38 +0100 Subject: [PATCH 107/126] Cleanup after dropping sectorbuilder --- checks.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checks.go b/checks.go index 810d77300..cdba23d13 100644 --- a/checks.go +++ b/checks.go @@ -3,7 +3,6 @@ package sealing import ( "bytes" "context" - "github.com/filecoin-project/lotus/storage/sectorstorage/zerocomm" "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" @@ -16,6 +15,7 @@ import ( "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/storage/sectorstorage/zerocomm" ) // TODO: For now we handle this by halting state execution, when we get jsonrpc reconnecting From 089c76937385ae258010d65faebc9756b221c9c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 27 Mar 2020 21:08:06 +0100 Subject: [PATCH 108/126] sectorstorage: Untangle from lotus deps --- garbage.go | 4 ++-- sealing.go | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/garbage.go b/garbage.go index 4903abf25..1f989fc1f 100644 --- a/garbage.go +++ b/garbage.go @@ -2,13 +2,13 @@ package sealing import ( "context" + "github.com/filecoin-project/lotus/storage/sectorstorage/ffiwrapper" "io" "golang.org/x/xerrors" "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/lib/nullreader" ) @@ -49,7 +49,7 @@ func (m *Sealing) PledgeSector() error { size := abi.PaddedPieceSize(m.sealer.SectorSize()).Unpadded() - _, rt, err := api.ProofTypeFromSectorSize(m.sealer.SectorSize()) + _, rt, err := ffiwrapper.ProofTypeFromSectorSize(m.sealer.SectorSize()) if err != nil { log.Error(err) return diff --git a/sealing.go b/sealing.go index 6b78dd909..5f085216c 100644 --- a/sealing.go +++ b/sealing.go @@ -2,6 +2,7 @@ package sealing import ( "context" + "github.com/filecoin-project/lotus/storage/sectorstorage/ffiwrapper" "io" "github.com/filecoin-project/go-address" @@ -132,7 +133,7 @@ func (m *Sealing) SealPiece(ctx context.Context, size abi.UnpaddedPieceSize, r i return xerrors.Errorf("adding piece to sector: %w", err) } - _, rt, err := api.ProofTypeFromSectorSize(m.sealer.SectorSize()) + _, rt, err := ffiwrapper.ProofTypeFromSectorSize(m.sealer.SectorSize()) if err != nil { return xerrors.Errorf("bad sector size: %w", err) } From c8928ff5d92f71fef391a7152f725f9a73c1e3c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 28 Mar 2020 00:00:21 +0100 Subject: [PATCH 109/126] Extract sector-storage --- checks.go | 2 +- garbage.go | 2 +- sealing.go | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/checks.go b/checks.go index cdba23d13..d43cd82df 100644 --- a/checks.go +++ b/checks.go @@ -15,7 +15,7 @@ import ( "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/storage/sectorstorage/zerocomm" + "github.com/filecoin-project/sector-storage/zerocomm" ) // TODO: For now we handle this by halting state execution, when we get jsonrpc reconnecting diff --git a/garbage.go b/garbage.go index 1f989fc1f..fcc3505c7 100644 --- a/garbage.go +++ b/garbage.go @@ -2,7 +2,7 @@ package sealing import ( "context" - "github.com/filecoin-project/lotus/storage/sectorstorage/ffiwrapper" + "github.com/filecoin-project/sector-storage/ffiwrapper" "io" "golang.org/x/xerrors" diff --git a/sealing.go b/sealing.go index 5f085216c..71a72ddd9 100644 --- a/sealing.go +++ b/sealing.go @@ -2,7 +2,7 @@ package sealing import ( "context" - "github.com/filecoin-project/lotus/storage/sectorstorage/ffiwrapper" + "github.com/filecoin-project/sector-storage/ffiwrapper" "io" "github.com/filecoin-project/go-address" @@ -22,7 +22,7 @@ import ( "github.com/filecoin-project/lotus/chain/events" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/storage/sectorstorage" + "github.com/filecoin-project/sector-storage" ) const SectorStorePrefix = "/sectors" From abb433aa4233942d8869c11ed3a0781e477ede65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 3 Apr 2020 18:24:45 +0200 Subject: [PATCH 110/126] Change api.SectorState to a string --- cbor_gen.go | 22 +++++++++++++--------- fsm.go | 12 ++++++------ states_failed.go | 3 +-- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/cbor_gen.go b/cbor_gen.go index 42ad7c029..b69e95c68 100644 --- a/cbor_gen.go +++ b/cbor_gen.go @@ -6,6 +6,7 @@ import ( "fmt" "io" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/specs-actors/actors/abi" cbg "github.com/whyrusleeping/cbor-gen" xerrors "golang.org/x/xerrors" @@ -181,7 +182,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { return err } - // t.State (uint64) (uint64) + // t.State (api.SectorState) (string) if len("State") > cbg.MaxLength { return xerrors.Errorf("Value in field \"State\" was too long") } @@ -193,7 +194,14 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { return err } - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.State))); err != nil { + if len(t.State) > cbg.MaxLength { + return xerrors.Errorf("Value in field t.State was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.State)))); err != nil { + return err + } + if _, err := w.Write([]byte(t.State)); err != nil { return err } @@ -521,20 +529,16 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { } switch name { - // t.State (uint64) (uint64) + // t.State (api.SectorState) (string) case "State": { - - maj, extra, err = cbg.CborReadHeader(br) + sval, err := cbg.ReadString(br) if err != nil { return err } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.State = uint64(extra) + t.State = api.SectorState(sval) } // t.SectorID (abi.SectorNumber) (uint64) case "SectorID": diff --git a/fsm.go b/fsm.go index 0911bfba5..a2951d807 100644 --- a/fsm.go +++ b/fsm.go @@ -32,7 +32,7 @@ func (m *Sealing) Plan(events []statemachine.Event, user interface{}) (interface }, uint64(len(events)), nil // TODO: This processed event count is not very correct } -var fsmPlanners = []func(events []statemachine.Event, state *SectorInfo) error{ +var fsmPlanners = map[api.SectorState]func(events []statemachine.Event, state *SectorInfo) error{ api.UndefinedSectorState: planOne(on(SectorStart{}, api.Packing)), api.Packing: planOne(on(SectorPacked{}, api.Unsealed)), api.Unsealed: planOne( @@ -105,11 +105,11 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta p := fsmPlanners[state.State] if p == nil { - return nil, xerrors.Errorf("planner for state %s not found", api.SectorStates[state.State]) + return nil, xerrors.Errorf("planner for state %s not found", state.State) } if err := p(events, state); err != nil { - return nil, xerrors.Errorf("running planner for state %s failed: %w", api.SectorStates[state.State], err) + return nil, xerrors.Errorf("running planner for state %s failed: %w", state.State, err) } ///// @@ -251,7 +251,7 @@ func (m *Sealing) ForceSectorState(ctx context.Context, id abi.SectorNumber, sta } func final(events []statemachine.Event, state *SectorInfo) error { - return xerrors.Errorf("didn't expect any events in state %s, got %+v", api.SectorStates[state.State], events) + return xerrors.Errorf("didn't expect any events in state %s, got %+v", state.State, events) } func on(mut mutator, next api.SectorState) func() (mutator, api.SectorState) { @@ -269,7 +269,7 @@ func planOne(ts ...func() (mut mutator, next api.SectorState)) func(events []sta return nil } } - return xerrors.Errorf("planner for state %s only has a plan for a single event only, got %+v", api.SectorStates[state.State], events) + return xerrors.Errorf("planner for state %s only has a plan for a single event only, got %+v", state.State, events) } if gm, ok := events[0].User.(globalMutator); ok { @@ -293,6 +293,6 @@ func planOne(ts ...func() (mut mutator, next api.SectorState)) func(events []sta return nil } - return xerrors.Errorf("planner for state %s received unexpected event %T (%+v)", api.SectorStates[state.State], events[0].User, events[0]) + return xerrors.Errorf("planner for state %s received unexpected event %T (%+v)", state.State, events[0].User, events[0]) } } diff --git a/states_failed.go b/states_failed.go index d5667f57e..da5227683 100644 --- a/states_failed.go +++ b/states_failed.go @@ -9,7 +9,6 @@ import ( "github.com/filecoin-project/specs-actors/actors/util/adt" "golang.org/x/xerrors" - "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/apibstore" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" @@ -20,7 +19,7 @@ const minRetryTime = 1 * time.Minute func failedCooldown(ctx statemachine.Context, sector SectorInfo) error { retryStart := time.Unix(int64(sector.Log[len(sector.Log)-1].Timestamp), 0).Add(minRetryTime) if len(sector.Log) > 0 && !time.Now().After(retryStart) { - log.Infof("%s(%d), waiting %s before retrying", api.SectorStates[sector.State], sector.SectorID, time.Until(retryStart)) + log.Infof("%s(%d), waiting %s before retrying", sector.State, sector.SectorID, time.Until(retryStart)) select { case <-time.After(time.Until(retryStart)): case <-ctx.Context().Done(): From 5977db883341a50ba222e23921ad4b69b044fe30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 3 Apr 2020 18:36:48 +0200 Subject: [PATCH 111/126] fsm: Fix tests after changisg SectorState to a string --- fsm_test.go | 2 +- types_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fsm_test.go b/fsm_test.go index 9b1a5d3e8..490b01771 100644 --- a/fsm_test.go +++ b/fsm_test.go @@ -102,5 +102,5 @@ func TestPlanCommittingHandlesSectorCommitFailed(t *testing.T) { require.NoError(t, planCommitting(events, m.state)) - require.Equal(t, api.SectorStates[api.CommitFailed], api.SectorStates[m.state.State]) + require.Equal(t, api.CommitFailed, m.state.State) } diff --git a/types_test.go b/types_test.go index f3ec17aa3..93bffc20c 100644 --- a/types_test.go +++ b/types_test.go @@ -18,7 +18,7 @@ func TestSectorInfoSelialization(t *testing.T) { dummyCid := builtin.AccountActorCodeID si := &SectorInfo{ - State: 123, + State: "stateful", SectorID: 234, Nonce: 345, Pieces: []Piece{{ From 8c824dfaf7af2bc39b75bbb86ff659ecdc297cc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 3 Apr 2020 18:54:01 +0200 Subject: [PATCH 112/126] sealing fsm: Separate precommit 1/2 --- fsm.go | 33 ++++++++++++++++++++------------- fsm_events.go | 33 +++++++++++++++++++++------------ fsm_test.go | 8 ++++---- states.go | 36 +++++++++++++++++++++--------------- states_failed.go | 6 +++--- types.go | 14 +++++++++----- 6 files changed, 78 insertions(+), 52 deletions(-) diff --git a/fsm.go b/fsm.go index a2951d807..93aa4c1e9 100644 --- a/fsm.go +++ b/fsm.go @@ -34,20 +34,25 @@ func (m *Sealing) Plan(events []statemachine.Event, user interface{}) (interface var fsmPlanners = map[api.SectorState]func(events []statemachine.Event, state *SectorInfo) error{ api.UndefinedSectorState: planOne(on(SectorStart{}, api.Packing)), - api.Packing: planOne(on(SectorPacked{}, api.Unsealed)), - api.Unsealed: planOne( - on(SectorSealed{}, api.PreCommitting), - on(SectorSealFailed{}, api.SealFailed), + api.Packing: planOne(on(SectorPacked{}, api.PreCommit1)), + api.PreCommit1: planOne( + on(SectorPreCommit1{}, api.PreCommit2), + on(SectorSealPreCommitFailed{}, api.SealFailed), + on(SectorPackingFailed{}, api.PackingFailed), + ), + api.PreCommit2: planOne( + on(SectorPreCommit2{}, api.PreCommitting), + on(SectorSealPreCommitFailed{}, api.SealFailed), on(SectorPackingFailed{}, api.PackingFailed), ), api.PreCommitting: planOne( - on(SectorSealFailed{}, api.SealFailed), + on(SectorSealPreCommitFailed{}, api.SealFailed), on(SectorPreCommitted{}, api.WaitSeed), - on(SectorPreCommitFailed{}, api.PreCommitFailed), + on(SectorChainPreCommitFailed{}, api.PreCommitFailed), ), api.WaitSeed: planOne( on(SectorSeedReady{}, api.Committing), - on(SectorPreCommitFailed{}, api.PreCommitFailed), + on(SectorChainPreCommitFailed{}, api.PreCommitFailed), ), api.Committing: planCommitting, api.CommitWait: planOne( @@ -65,12 +70,12 @@ var fsmPlanners = map[api.SectorState]func(events []statemachine.Event, state *S ), api.SealFailed: planOne( - on(SectorRetrySeal{}, api.Unsealed), + on(SectorRetrySeal{}, api.PreCommit1), ), api.PreCommitFailed: planOne( on(SectorRetryPreCommit{}, api.PreCommitting), on(SectorRetryWaitSeed{}, api.WaitSeed), - on(SectorSealFailed{}, api.SealFailed), + on(SectorSealPreCommitFailed{}, api.SealFailed), ), api.Faulty: planOne( @@ -123,7 +128,7 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta *<- Packing <- incoming | | | v - *<- Unsealed <--> SealFailed + *<- PreCommit1 <--> SealFailed | | | v * PreCommitting <--> PreCommitFailed @@ -153,8 +158,10 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta // Happy path case api.Packing: return m.handlePacking, nil - case api.Unsealed: - return m.handleUnsealed, nil + case api.PreCommit1: + return m.handlePreCommit1, nil + case api.PreCommit2: + return m.handlePreCommit2, nil case api.PreCommitting: return m.handlePreCommitting, nil case api.WaitSeed: @@ -218,7 +225,7 @@ func planCommitting(events []statemachine.Event, state *SectorInfo) error { return nil case SectorComputeProofFailed: state.State = api.SealCommitFailed - case SectorSealFailed: + case SectorSealPreCommitFailed: state.State = api.CommitFailed case SectorCommitFailed: state.State = api.CommitFailed diff --git a/fsm_events.go b/fsm_events.go index d433765ee..e7c9a69b7 100644 --- a/fsm_events.go +++ b/fsm_events.go @@ -2,6 +2,7 @@ package sealing import ( "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-storage/storage" "github.com/ipfs/go-cid" "golang.org/x/xerrors" @@ -70,29 +71,37 @@ type SectorPackingFailed struct{ error } func (evt SectorPackingFailed) apply(*SectorInfo) {} -type SectorSealed struct { - Sealed cid.Cid - Unsealed cid.Cid - Ticket api.SealTicket +type SectorPreCommit1 struct { + PreCommit1Out storage.PreCommit1Out + Ticket api.SealTicket } -func (evt SectorSealed) apply(state *SectorInfo) { +func (evt SectorPreCommit1) apply(state *SectorInfo) { + state.PreCommit1Out = evt.PreCommit1Out + state.Ticket = evt.Ticket +} + +type SectorPreCommit2 struct { + Sealed cid.Cid + Unsealed cid.Cid +} + +func (evt SectorPreCommit2) apply(state *SectorInfo) { commd := evt.Unsealed state.CommD = &commd commr := evt.Sealed state.CommR = &commr - state.Ticket = evt.Ticket } -type SectorSealFailed struct{ error } +type SectorSealPreCommitFailed struct{ error } -func (evt SectorSealFailed) FormatError(xerrors.Printer) (next error) { return evt.error } -func (evt SectorSealFailed) apply(*SectorInfo) {} +func (evt SectorSealPreCommitFailed) FormatError(xerrors.Printer) (next error) { return evt.error } +func (evt SectorSealPreCommitFailed) apply(*SectorInfo) {} -type SectorPreCommitFailed struct{ error } +type SectorChainPreCommitFailed struct{ error } -func (evt SectorPreCommitFailed) FormatError(xerrors.Printer) (next error) { return evt.error } -func (evt SectorPreCommitFailed) apply(*SectorInfo) {} +func (evt SectorChainPreCommitFailed) FormatError(xerrors.Printer) (next error) { return evt.error } +func (evt SectorChainPreCommitFailed) apply(*SectorInfo) {} type SectorPreCommitted struct { Message cid.Cid diff --git a/fsm_test.go b/fsm_test.go index 490b01771..57e478e6f 100644 --- a/fsm_test.go +++ b/fsm_test.go @@ -36,9 +36,9 @@ func TestHappyPath(t *testing.T) { } m.planSingle(SectorPacked{}) - require.Equal(m.t, m.state.State, api.Unsealed) + require.Equal(m.t, m.state.State, api.PreCommit1) - m.planSingle(SectorSealed{}) + m.planSingle(SectorPreCommit2{}) require.Equal(m.t, m.state.State, api.PreCommitting) m.planSingle(SectorPreCommitted{}) @@ -65,9 +65,9 @@ func TestSeedRevert(t *testing.T) { } m.planSingle(SectorPacked{}) - require.Equal(m.t, m.state.State, api.Unsealed) + require.Equal(m.t, m.state.State, api.PreCommit1) - m.planSingle(SectorSealed{}) + m.planSingle(SectorPreCommit2{}) require.Equal(m.t, m.state.State, api.PreCommitting) m.planSingle(SectorPreCommitted{}) diff --git a/states.go b/states.go index 3e6037b6d..69f36d314 100644 --- a/states.go +++ b/states.go @@ -49,11 +49,11 @@ func (m *Sealing) handlePacking(ctx statemachine.Context, sector SectorInfo) err return ctx.Send(SectorPacked{Pieces: pieces}) } -func (m *Sealing) handleUnsealed(ctx statemachine.Context, sector SectorInfo) error { +func (m *Sealing) handlePreCommit1(ctx statemachine.Context, sector SectorInfo) error { if err := checkPieces(ctx.Context(), sector, m.api); err != nil { // Sanity check state switch err.(type) { case *ErrApi: - log.Errorf("handleUnsealed: api error, not proceeding: %+v", err) + log.Errorf("handlePreCommit1: api error, not proceeding: %+v", err) return nil case *ErrInvalidDeals: return ctx.Send(SectorPackingFailed{xerrors.Errorf("invalid deals in sector: %w", err)}) @@ -67,23 +67,29 @@ func (m *Sealing) handleUnsealed(ctx statemachine.Context, sector SectorInfo) er log.Infow("performing sector replication...", "sector", sector.SectorID) ticket, err := m.tktFn(ctx.Context()) if err != nil { - return ctx.Send(SectorSealFailed{xerrors.Errorf("getting ticket failed: %w", err)}) + return ctx.Send(SectorSealPreCommitFailed{xerrors.Errorf("getting ticket failed: %w", err)}) } pc1o, err := m.sealer.SealPreCommit1(ctx.Context(), m.minerSector(sector.SectorID), ticket.Value, sector.pieceInfos()) if err != nil { - return ctx.Send(SectorSealFailed{xerrors.Errorf("seal pre commit(1) failed: %w", err)}) + return ctx.Send(SectorSealPreCommitFailed{xerrors.Errorf("seal pre commit(1) failed: %w", err)}) } - cids, err := m.sealer.SealPreCommit2(ctx.Context(), m.minerSector(sector.SectorID), pc1o) + return ctx.Send(SectorPreCommit1{ + PreCommit1Out: pc1o, + Ticket: *ticket, + }) +} + +func (m *Sealing) handlePreCommit2(ctx statemachine.Context, sector SectorInfo) error { + cids, err := m.sealer.SealPreCommit2(ctx.Context(), m.minerSector(sector.SectorID), sector.PreCommit1Out) if err != nil { - return ctx.Send(SectorSealFailed{xerrors.Errorf("seal pre commit(2) failed: %w", err)}) + return ctx.Send(SectorSealPreCommitFailed{xerrors.Errorf("seal pre commit(2) failed: %w", err)}) } - return ctx.Send(SectorSealed{ + return ctx.Send(SectorPreCommit2{ Unsealed: cids.Unsealed, Sealed: cids.Sealed, - Ticket: *ticket, }) } @@ -93,10 +99,10 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf case *ErrApi: log.Errorf("handlePreCommitting: api error, not proceeding: %+v", err) return nil - case *ErrBadCommD: // TODO: Should this just back to packing? (not really needed since handleUnsealed will do that too) - return ctx.Send(SectorSealFailed{xerrors.Errorf("bad CommD error: %w", err)}) + case *ErrBadCommD: // TODO: Should this just back to packing? (not really needed since handlePreCommit1 will do that too) + return ctx.Send(SectorSealPreCommitFailed{xerrors.Errorf("bad CommD error: %w", err)}) case *ErrExpiredTicket: - return ctx.Send(SectorSealFailed{xerrors.Errorf("ticket expired: %w", err)}) + return ctx.Send(SectorSealPreCommitFailed{xerrors.Errorf("ticket expired: %w", err)}) default: return xerrors.Errorf("checkSeal sanity check error: %w", err) } @@ -113,7 +119,7 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf } enc, aerr := actors.SerializeParams(params) if aerr != nil { - return ctx.Send(SectorPreCommitFailed{xerrors.Errorf("could not serialize commit sector parameters: %w", aerr)}) + return ctx.Send(SectorChainPreCommitFailed{xerrors.Errorf("could not serialize commit sector parameters: %w", aerr)}) } msg := &types.Message{ @@ -129,7 +135,7 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf log.Info("submitting precommit for sector: ", sector.SectorID) smsg, err := m.api.MpoolPushMessage(ctx.Context(), msg) if err != nil { - return ctx.Send(SectorPreCommitFailed{xerrors.Errorf("pushing message to mpool: %w", err)}) + return ctx.Send(SectorChainPreCommitFailed{xerrors.Errorf("pushing message to mpool: %w", err)}) } return ctx.Send(SectorPreCommitted{Message: smsg.Cid()}) @@ -140,13 +146,13 @@ func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) er log.Info("Sector precommitted: ", sector.SectorID) mw, err := m.api.StateWaitMsg(ctx.Context(), *sector.PreCommitMessage) if err != nil { - return ctx.Send(SectorPreCommitFailed{err}) + return ctx.Send(SectorChainPreCommitFailed{err}) } if mw.Receipt.ExitCode != 0 { log.Error("sector precommit failed: ", mw.Receipt.ExitCode) err := xerrors.Errorf("sector precommit failed: %d", mw.Receipt.ExitCode) - return ctx.Send(SectorPreCommitFailed{err}) + return ctx.Send(SectorChainPreCommitFailed{err}) } log.Info("precommit message landed on chain: ", sector.SectorID) diff --git a/states_failed.go b/states_failed.go index da5227683..8c0cc46f8 100644 --- a/states_failed.go +++ b/states_failed.go @@ -79,10 +79,10 @@ func (m *Sealing) handlePreCommitFailed(ctx statemachine.Context, sector SectorI case *ErrApi: log.Errorf("handlePreCommitFailed: api error, not proceeding: %+v", err) return nil - case *ErrBadCommD: // TODO: Should this just back to packing? (not really needed since handleUnsealed will do that too) - return ctx.Send(SectorSealFailed{xerrors.Errorf("bad CommD error: %w", err)}) + case *ErrBadCommD: // TODO: Should this just back to packing? (not really needed since handlePreCommit1 will do that too) + return ctx.Send(SectorSealPreCommitFailed{xerrors.Errorf("bad CommD error: %w", err)}) case *ErrExpiredTicket: - return ctx.Send(SectorSealFailed{xerrors.Errorf("ticket expired error: %w", err)}) + return ctx.Send(SectorSealPreCommitFailed{xerrors.Errorf("ticket expired error: %w", err)}) default: return xerrors.Errorf("checkSeal sanity check error: %w", err) } diff --git a/types.go b/types.go index 4e9e0dccc..197bf6e15 100644 --- a/types.go +++ b/types.go @@ -2,6 +2,7 @@ package sealing import ( "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-storage/storage" "github.com/ipfs/go-cid" "github.com/filecoin-project/lotus/api" @@ -35,11 +36,14 @@ type SectorInfo struct { Pieces []Piece - // PreCommit - CommD *cid.Cid - CommR *cid.Cid - Proof []byte - Ticket api.SealTicket + // PreCommit1 + Ticket api.SealTicket + PreCommit1Out storage.PreCommit1Out + + // PreCommit2 + CommD *cid.Cid + CommR *cid.Cid + Proof []byte PreCommitMessage *cid.Cid From 4a6c5c25b0c07f82ed29c8e63df983c6df897edc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 3 Apr 2020 19:45:48 +0200 Subject: [PATCH 113/126] fsm: Implement handlers for Commit errors --- checks.go | 30 ++++++++++++++++++++++++--- fsm.go | 39 +++++++++++++++++++++++------------ fsm_events.go | 4 ++++ states.go | 4 ++-- states_failed.go | 53 ++++++++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 110 insertions(+), 20 deletions(-) diff --git a/checks.go b/checks.go index d43cd82df..cc68459ba 100644 --- a/checks.go +++ b/checks.go @@ -11,6 +11,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/actors/builtin/market" + "github.com/filecoin-project/specs-actors/actors/crypto" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors" @@ -29,6 +30,8 @@ type ErrExpiredDeals struct{ error } type ErrBadCommD struct{ error } type ErrExpiredTicket struct{ error } +type ErrBadSeed struct{ error } + // checkPieces validates that: // - Each piece han a corresponding on chain deal // - Piece commitments match with on chain deals @@ -69,9 +72,9 @@ func checkPieces(ctx context.Context, si SectorInfo, api sealingApi) error { return nil } -// checkSeal checks that data commitment generated in the sealing process +// checkPrecommit checks that data commitment generated in the sealing process // matches pieces, and that the seal ticket isn't expired -func checkSeal(ctx context.Context, maddr address.Address, si SectorInfo, api sealingApi) (err error) { +func checkPrecommit(ctx context.Context, maddr address.Address, si SectorInfo, api sealingApi) (err error) { head, err := api.ChainHead(ctx) if err != nil { return &ErrApi{xerrors.Errorf("getting chain head: %w", err)} @@ -116,5 +119,26 @@ func checkSeal(ctx context.Context, maddr address.Address, si SectorInfo, api se } return nil - +} + +func checkCommit(ctx context.Context, si SectorInfo, api sealingApi) (err error) { + head, err := api.ChainHead(ctx) + if err != nil { + return &ErrApi{xerrors.Errorf("getting chain head: %w", err)} + } + + if si.Seed.Epoch == 0 { + return &ErrBadSeed{xerrors.Errorf("seed epoch was not set")} + } + + rand, err := api.ChainGetRandomness(ctx, head.Key(), crypto.DomainSeparationTag_InteractiveSealChallengeSeed, si.Seed.Epoch, nil) + if err != nil { + return &ErrApi{xerrors.Errorf("failed to get randomness for computing seal proof: %w", err)} + } + + if string(rand) != string(si.Seed.Value) { + return &ErrBadSeed{xerrors.Errorf("seed has changed")} + } + + return nil } diff --git a/fsm.go b/fsm.go index 93aa4c1e9..f3f79d763 100644 --- a/fsm.go +++ b/fsm.go @@ -77,6 +77,14 @@ var fsmPlanners = map[api.SectorState]func(events []statemachine.Event, state *S on(SectorRetryWaitSeed{}, api.WaitSeed), on(SectorSealPreCommitFailed{}, api.SealFailed), ), + api.ComputeProofFailed: planOne( + on(SectorRetryComputeProof{}, api.Committing), + ), + api.CommitFailed: planOne( + on(SectorSealPreCommitFailed{}, api.SealFailed), + on(SectorRetryWaitSeed{}, api.WaitSeed), + on(SectorRetryComputeProof{}, api.Committing), + ), api.Faulty: planOne( on(SectorFaultReported{}, api.FaultReported), @@ -129,15 +137,20 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta | | | v *<- PreCommit1 <--> SealFailed - | | - | v - * PreCommitting <--> PreCommitFailed - | | ^ - | v | - *<- WaitSeed ----------/ - | ||| - | vvv v--> SealCommitFailed - *<- Committing + | | ^^^ + | v ||| + *<- PreCommit2 -------/|| + | | || + | v /-------/| + * PreCommitting <-----+---> PreCommitFailed + | | | ^ + | v | | + *<- WaitSeed -----------+-----/ + | ||| ^ | + | ||| \--------*-----/ + | ||| | + | vvv v----+----> ComputeProofFailed + *<- Committing | | | ^--> CommitFailed | v ^ *<- CommitWait ---/ @@ -181,10 +194,10 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta return m.handleSealFailed, nil case api.PreCommitFailed: return m.handlePreCommitFailed, nil - case api.SealCommitFailed: - log.Warnf("sector %d entered unimplemented state 'SealCommitFailed'", state.SectorID) + case api.ComputeProofFailed: + return m.handleComputeProofFailed, nil case api.CommitFailed: - log.Warnf("sector %d entered unimplemented state 'CommitFailed'", state.SectorID) + return m.handleCommitFailed, nil // Faults case api.Faulty: @@ -224,7 +237,7 @@ func planCommitting(events []statemachine.Event, state *SectorInfo) error { state.State = api.Committing return nil case SectorComputeProofFailed: - state.State = api.SealCommitFailed + state.State = api.ComputeProofFailed case SectorSealPreCommitFailed: state.State = api.CommitFailed case SectorCommitFailed: diff --git a/fsm_events.go b/fsm_events.go index e7c9a69b7..3aac561e3 100644 --- a/fsm_events.go +++ b/fsm_events.go @@ -166,6 +166,10 @@ type SectorRetryWaitSeed struct{} func (evt SectorRetryWaitSeed) apply(state *SectorInfo) {} +type SectorRetryComputeProof struct{} + +func (evt SectorRetryComputeProof) apply(state *SectorInfo) {} + // Faults type SectorFaulty struct{} diff --git a/states.go b/states.go index 69f36d314..07287b9e3 100644 --- a/states.go +++ b/states.go @@ -94,7 +94,7 @@ func (m *Sealing) handlePreCommit2(ctx statemachine.Context, sector SectorInfo) } func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInfo) error { - if err := checkSeal(ctx.Context(), m.maddr, sector, m.api); err != nil { + if err := checkPrecommit(ctx.Context(), m.maddr, sector, m.api); err != nil { switch err.(type) { case *ErrApi: log.Errorf("handlePreCommitting: api error, not proceeding: %+v", err) @@ -104,7 +104,7 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf case *ErrExpiredTicket: return ctx.Send(SectorSealPreCommitFailed{xerrors.Errorf("ticket expired: %w", err)}) default: - return xerrors.Errorf("checkSeal sanity check error: %w", err) + return xerrors.Errorf("checkPrecommit sanity check error: %w", err) } } diff --git a/states_failed.go b/states_failed.go index 8c0cc46f8..538cebca4 100644 --- a/states_failed.go +++ b/states_failed.go @@ -17,6 +17,8 @@ import ( const minRetryTime = 1 * time.Minute func failedCooldown(ctx statemachine.Context, sector SectorInfo) error { + // TODO: Exponential backoff when we see consecutive failures + retryStart := time.Unix(int64(sector.Log[len(sector.Log)-1].Timestamp), 0).Add(minRetryTime) if len(sector.Log) > 0 && !time.Now().After(retryStart) { log.Infof("%s(%d), waiting %s before retrying", sector.State, sector.SectorID, time.Until(retryStart)) @@ -74,7 +76,7 @@ func (m *Sealing) handleSealFailed(ctx statemachine.Context, sector SectorInfo) } func (m *Sealing) handlePreCommitFailed(ctx statemachine.Context, sector SectorInfo) error { - if err := checkSeal(ctx.Context(), m.maddr, sector, m.api); err != nil { + if err := checkPrecommit(ctx.Context(), m.maddr, sector, m.api); err != nil { switch err.(type) { case *ErrApi: log.Errorf("handlePreCommitFailed: api error, not proceeding: %+v", err) @@ -84,7 +86,7 @@ func (m *Sealing) handlePreCommitFailed(ctx statemachine.Context, sector SectorI case *ErrExpiredTicket: return ctx.Send(SectorSealPreCommitFailed{xerrors.Errorf("ticket expired error: %w", err)}) default: - return xerrors.Errorf("checkSeal sanity check error: %w", err) + return xerrors.Errorf("checkPrecommit sanity check error: %w", err) } } @@ -119,3 +121,50 @@ func (m *Sealing) handlePreCommitFailed(ctx statemachine.Context, sector SectorI return ctx.Send(SectorRetryPreCommit{}) } + +func (m *Sealing) handleComputeProofFailed(ctx statemachine.Context, sector SectorInfo) error { + // TODO: Check sector files + + if err := failedCooldown(ctx, sector); err != nil { + return err + } + + return ctx.Send(SectorRetryComputeProof{}) +} + +func (m *Sealing) handleCommitFailed(ctx statemachine.Context, sector SectorInfo) error { + if err := checkPrecommit(ctx.Context(), m.maddr, sector, m.api); err != nil { + switch err.(type) { + case *ErrApi: + log.Errorf("handleCommitFailed: api error, not proceeding: %+v", err) + return nil + case *ErrBadCommD: + return ctx.Send(SectorSealPreCommitFailed{xerrors.Errorf("bad CommD error: %w", err)}) + case *ErrExpiredTicket: + return ctx.Send(SectorSealPreCommitFailed{xerrors.Errorf("ticket expired error: %w", err)}) + default: + return xerrors.Errorf("checkPrecommit sanity check error: %w", err) + } + } + + if err := checkCommit(ctx.Context(), sector, m.api); err != nil { + switch err.(type) { + case *ErrApi: + log.Errorf("handleCommitFailed: api error, not proceeding: %+v", err) + return nil + case *ErrBadSeed: + log.Errorf("seed changed, will retry: %+v", err) + return ctx.Send(SectorRetryWaitSeed{}) + default: + return xerrors.Errorf("checkCommit sanity check error: %w", err) + } + } + + // TODO: Check sector files + + if err := failedCooldown(ctx, sector); err != nil { + return err + } + + return ctx.Send(SectorRetryComputeProof{}) +} From 25bd37364cd8f608e9c76fdd4be42e60c4ac3cbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 3 Apr 2020 21:34:20 +0200 Subject: [PATCH 114/126] fsm: Update cbor-gen --- cbor_gen.go | 95 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 68 insertions(+), 27 deletions(-) diff --git a/cbor_gen.go b/cbor_gen.go index b69e95c68..2215914a9 100644 --- a/cbor_gen.go +++ b/cbor_gen.go @@ -178,7 +178,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { _, err := w.Write(cbg.CborNull) return err } - if _, err := w.Write([]byte{175}); err != nil { + if _, err := w.Write([]byte{176}); err != nil { return err } @@ -284,6 +284,45 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { } } + // t.Ticket (api.SealTicket) (struct) + if len("Ticket") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"Ticket\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Ticket")))); err != nil { + return err + } + if _, err := w.Write([]byte("Ticket")); err != nil { + return err + } + + if err := t.Ticket.MarshalCBOR(w); err != nil { + return err + } + + // t.PreCommit1Out (storage.PreCommit1Out) (slice) + if len("PreCommit1Out") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"PreCommit1Out\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("PreCommit1Out")))); err != nil { + return err + } + if _, err := w.Write([]byte("PreCommit1Out")); err != nil { + return err + } + + if len(t.PreCommit1Out) > cbg.ByteArrayMaxLen { + return xerrors.Errorf("Byte array in field t.PreCommit1Out was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.PreCommit1Out)))); err != nil { + return err + } + if _, err := w.Write(t.PreCommit1Out); err != nil { + return err + } + // t.CommD (cid.Cid) (struct) if len("CommD") > cbg.MaxLength { return xerrors.Errorf("Value in field \"CommD\" was too long") @@ -351,22 +390,6 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { return err } - // t.Ticket (api.SealTicket) (struct) - if len("Ticket") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"Ticket\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Ticket")))); err != nil { - return err - } - if _, err := w.Write([]byte("Ticket")); err != nil { - return err - } - - if err := t.Ticket.MarshalCBOR(w); err != nil { - return err - } - // t.PreCommitMessage (cid.Cid) (struct) if len("PreCommitMessage") > cbg.MaxLength { return xerrors.Errorf("Value in field \"PreCommitMessage\" was too long") @@ -624,6 +647,34 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { t.Pieces[i] = v } + // t.Ticket (api.SealTicket) (struct) + case "Ticket": + + { + + if err := t.Ticket.UnmarshalCBOR(br); err != nil { + return xerrors.Errorf("unmarshaling t.Ticket: %w", err) + } + + } + // t.PreCommit1Out (storage.PreCommit1Out) (slice) + case "PreCommit1Out": + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + + if extra > cbg.ByteArrayMaxLen { + return fmt.Errorf("t.PreCommit1Out: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.PreCommit1Out = make([]byte, extra) + if _, err := io.ReadFull(br, t.PreCommit1Out); err != nil { + return err + } // t.CommD (cid.Cid) (struct) case "CommD": @@ -692,16 +743,6 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { if _, err := io.ReadFull(br, t.Proof); err != nil { return err } - // t.Ticket (api.SealTicket) (struct) - case "Ticket": - - { - - if err := t.Ticket.UnmarshalCBOR(br); err != nil { - return xerrors.Errorf("unmarshaling t.Ticket: %w", err) - } - - } // t.PreCommitMessage (cid.Cid) (struct) case "PreCommitMessage": From dcfd0943d527be1406c1dbe7ebb4f3162eee3e17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 4 Apr 2020 03:50:05 +0200 Subject: [PATCH 115/126] fsm: Handle invalid Commits --- cbor_gen.go | 33 ++++++++++++++++++++++++++++++++- checks.go | 42 ++++++++++++++++++++++++++++++++++++++---- fsm.go | 1 + fsm_events.go | 11 ++++++++++- states.go | 4 ++++ states_failed.go | 12 +++++++++++- types.go | 1 + 7 files changed, 97 insertions(+), 7 deletions(-) diff --git a/cbor_gen.go b/cbor_gen.go index 2215914a9..ab12aa155 100644 --- a/cbor_gen.go +++ b/cbor_gen.go @@ -178,7 +178,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { _, err := w.Write(cbg.CborNull) return err } - if _, err := w.Write([]byte{176}); err != nil { + if _, err := w.Write([]byte{177}); err != nil { return err } @@ -450,6 +450,22 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { } } + // t.InvalidProofs (uint64) (uint64) + if len("InvalidProofs") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"InvalidProofs\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("InvalidProofs")))); err != nil { + return err + } + if _, err := w.Write([]byte("InvalidProofs")); err != nil { + return err + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.InvalidProofs))); err != nil { + return err + } + // t.FaultReportMsg (cid.Cid) (struct) if len("FaultReportMsg") > cbg.MaxLength { return xerrors.Errorf("Value in field \"FaultReportMsg\" was too long") @@ -802,6 +818,21 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { t.CommitMessage = &c } + } + // t.InvalidProofs (uint64) (uint64) + case "InvalidProofs": + + { + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.InvalidProofs = uint64(extra) + } // t.FaultReportMsg (cid.Cid) (struct) case "FaultReportMsg": diff --git a/checks.go b/checks.go index cc68459ba..372fc5847 100644 --- a/checks.go +++ b/checks.go @@ -9,6 +9,8 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/sector-storage/ffiwrapper" + "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/actors/builtin/market" "github.com/filecoin-project/specs-actors/actors/crypto" @@ -31,6 +33,7 @@ type ErrBadCommD struct{ error } type ErrExpiredTicket struct{ error } type ErrBadSeed struct{ error } +type ErrInvalidProof struct{ error } // checkPieces validates that: // - Each piece han a corresponding on chain deal @@ -121,8 +124,8 @@ func checkPrecommit(ctx context.Context, maddr address.Address, si SectorInfo, a return nil } -func checkCommit(ctx context.Context, si SectorInfo, api sealingApi) (err error) { - head, err := api.ChainHead(ctx) +func (m *Sealing) checkCommit(ctx context.Context, si SectorInfo) (err error) { + head, err := m.api.ChainHead(ctx) if err != nil { return &ErrApi{xerrors.Errorf("getting chain head: %w", err)} } @@ -131,14 +134,45 @@ func checkCommit(ctx context.Context, si SectorInfo, api sealingApi) (err error) return &ErrBadSeed{xerrors.Errorf("seed epoch was not set")} } - rand, err := api.ChainGetRandomness(ctx, head.Key(), crypto.DomainSeparationTag_InteractiveSealChallengeSeed, si.Seed.Epoch, nil) + seed, err := m.api.ChainGetRandomness(ctx, head.Key(), crypto.DomainSeparationTag_InteractiveSealChallengeSeed, si.Seed.Epoch, nil) if err != nil { return &ErrApi{xerrors.Errorf("failed to get randomness for computing seal proof: %w", err)} } - if string(rand) != string(si.Seed.Value) { + if string(seed) != string(si.Seed.Value) { return &ErrBadSeed{xerrors.Errorf("seed has changed")} } + ss, err := m.api.StateMinerSectorSize(ctx, m.maddr, head.Key()) + if err != nil { + return &ErrApi{err} + } + _, spt, err := ffiwrapper.ProofTypeFromSectorSize(ss) + if err != nil { + return err + } + + ok, err := ffiwrapper.ProofVerifier.VerifySeal(abi.SealVerifyInfo{ + SectorID: m.minerSector(si.SectorID), + OnChain: abi.OnChainSealVerifyInfo{ + SealedCID: *si.CommR, + InteractiveEpoch: si.Seed.Epoch, + RegisteredProof: spt, + Proof: si.Proof, + SectorNumber: si.SectorID, + SealRandEpoch: si.Ticket.Epoch, + }, + Randomness: si.Ticket.Value, + InteractiveRandomness: si.Seed.Value, + UnsealedCID: *si.CommD, + }) + if err != nil { + return xerrors.Errorf("verify seal: %w", err) + } + if !ok { + return &ErrInvalidProof{xerrors.New("invalid proof (compute error?)")} + } + + return nil } diff --git a/fsm.go b/fsm.go index f3f79d763..2d1691678 100644 --- a/fsm.go +++ b/fsm.go @@ -84,6 +84,7 @@ var fsmPlanners = map[api.SectorState]func(events []statemachine.Event, state *S on(SectorSealPreCommitFailed{}, api.SealFailed), on(SectorRetryWaitSeed{}, api.WaitSeed), on(SectorRetryComputeProof{}, api.Committing), + on(SectorRetryInvalidProof{}, api.Committing), ), api.Faulty: planOne( diff --git a/fsm_events.go b/fsm_events.go index 3aac561e3..b6d03d26d 100644 --- a/fsm_events.go +++ b/fsm_events.go @@ -96,7 +96,9 @@ func (evt SectorPreCommit2) apply(state *SectorInfo) { type SectorSealPreCommitFailed struct{ error } func (evt SectorSealPreCommitFailed) FormatError(xerrors.Printer) (next error) { return evt.error } -func (evt SectorSealPreCommitFailed) apply(*SectorInfo) {} +func (evt SectorSealPreCommitFailed) apply(si *SectorInfo) { + si.InvalidProofs = 0 // reset counter +} type SectorChainPreCommitFailed struct{ error } @@ -170,6 +172,13 @@ type SectorRetryComputeProof struct{} func (evt SectorRetryComputeProof) apply(state *SectorInfo) {} +type SectorRetryInvalidProof struct{} + +func (evt SectorRetryInvalidProof) apply(state *SectorInfo) { + state.InvalidProofs++ +} + + // Faults type SectorFaulty struct{} diff --git a/states.go b/states.go index 07287b9e3..94f227fc3 100644 --- a/states.go +++ b/states.go @@ -205,6 +205,10 @@ func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) return ctx.Send(SectorComputeProofFailed{xerrors.Errorf("computing seal proof failed: %w", err)}) } + if err := m.checkCommit(ctx.Context(), sector); err != nil { + return ctx.Send(SectorCommitFailed{xerrors.Errorf("commit check error: %w", err)}) + } + // TODO: Consider splitting states and persist proof for faster recovery params := &miner.ProveCommitSectorParams{ diff --git a/states_failed.go b/states_failed.go index 538cebca4..5c26b5a40 100644 --- a/states_failed.go +++ b/states_failed.go @@ -147,7 +147,7 @@ func (m *Sealing) handleCommitFailed(ctx statemachine.Context, sector SectorInfo } } - if err := checkCommit(ctx.Context(), sector, m.api); err != nil { + if err := m.checkCommit(ctx.Context(), sector); err != nil { switch err.(type) { case *ErrApi: log.Errorf("handleCommitFailed: api error, not proceeding: %+v", err) @@ -155,6 +155,16 @@ func (m *Sealing) handleCommitFailed(ctx statemachine.Context, sector SectorInfo case *ErrBadSeed: log.Errorf("seed changed, will retry: %+v", err) return ctx.Send(SectorRetryWaitSeed{}) + case *ErrInvalidProof: + if err := failedCooldown(ctx, sector); err != nil { + return err + } + + if sector.InvalidProofs > 0 { + return ctx.Send(SectorSealPreCommitFailed{xerrors.Errorf("consecutive invalid proofs")}) + } + + return ctx.Send(SectorRetryInvalidProof{}) default: return xerrors.Errorf("checkCommit sanity check error: %w", err) } diff --git a/types.go b/types.go index 197bf6e15..294802ef0 100644 --- a/types.go +++ b/types.go @@ -52,6 +52,7 @@ type SectorInfo struct { // Committing CommitMessage *cid.Cid + InvalidProofs uint64 // failed proof computations (doesn't validate with proof inputs) // Faults FaultReportMsg *cid.Cid From c29cb87d2f894b50adfc9ceeb3f20aab7eb4fff4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 4 Apr 2020 04:55:19 +0200 Subject: [PATCH 116/126] fsm: Get correct interactive randomness if it lands on a nullblock --- checks.go | 27 ++++++++++++++++++++------- fsm_events.go | 1 - fsm_test.go | 6 ++++++ sealing.go | 9 ++++++--- states.go | 11 ++++++++--- states_failed.go | 2 +- 6 files changed, 41 insertions(+), 15 deletions(-) diff --git a/checks.go b/checks.go index 372fc5847..cc0619e43 100644 --- a/checks.go +++ b/checks.go @@ -13,6 +13,7 @@ import ( "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/actors/builtin/market" + "github.com/filecoin-project/specs-actors/actors/builtin/miner" "github.com/filecoin-project/specs-actors/actors/crypto" "github.com/filecoin-project/lotus/build" @@ -124,7 +125,7 @@ func checkPrecommit(ctx context.Context, maddr address.Address, si SectorInfo, a return nil } -func (m *Sealing) checkCommit(ctx context.Context, si SectorInfo) (err error) { +func (m *Sealing) checkCommit(ctx context.Context, si SectorInfo, proof []byte) (err error) { head, err := m.api.ChainHead(ctx) if err != nil { return &ErrApi{xerrors.Errorf("getting chain head: %w", err)} @@ -134,6 +135,15 @@ func (m *Sealing) checkCommit(ctx context.Context, si SectorInfo) (err error) { return &ErrBadSeed{xerrors.Errorf("seed epoch was not set")} } + pci, err := m.api.StateSectorPreCommitInfo(ctx, m.maddr, si.SectorID, types.EmptyTSK) + if err != nil { + return xerrors.Errorf("getting precommit info: %w", err) + } + + if pci.PreCommitEpoch+miner.PreCommitChallengeDelay != si.Seed.Epoch { + return &ErrBadSeed{xerrors.Errorf("seed epoch doesn't match on chain info: %d != %d", pci.PreCommitEpoch+miner.PreCommitChallengeDelay, si.Seed.Epoch)} + } + seed, err := m.api.ChainGetRandomness(ctx, head.Key(), crypto.DomainSeparationTag_InteractiveSealChallengeSeed, si.Seed.Epoch, nil) if err != nil { return &ErrApi{xerrors.Errorf("failed to get randomness for computing seal proof: %w", err)} @@ -152,13 +162,17 @@ func (m *Sealing) checkCommit(ctx context.Context, si SectorInfo) (err error) { return err } - ok, err := ffiwrapper.ProofVerifier.VerifySeal(abi.SealVerifyInfo{ - SectorID: m.minerSector(si.SectorID), - OnChain: abi.OnChainSealVerifyInfo{ - SealedCID: *si.CommR, + if *si.CommR != pci.Info.SealedCID { + log.Warn("on-chain sealed CID doesn't match!") + } + + ok, err := m.verif.VerifySeal(abi.SealVerifyInfo{ + SectorID: m.minerSector(si.SectorID), + OnChain: abi.OnChainSealVerifyInfo{ + SealedCID: pci.Info.SealedCID, InteractiveEpoch: si.Seed.Epoch, RegisteredProof: spt, - Proof: si.Proof, + Proof: proof, SectorNumber: si.SectorID, SealRandEpoch: si.Ticket.Epoch, }, @@ -173,6 +187,5 @@ func (m *Sealing) checkCommit(ctx context.Context, si SectorInfo) (err error) { return &ErrInvalidProof{xerrors.New("invalid proof (compute error?)")} } - return nil } diff --git a/fsm_events.go b/fsm_events.go index b6d03d26d..83d0a5c24 100644 --- a/fsm_events.go +++ b/fsm_events.go @@ -178,7 +178,6 @@ func (evt SectorRetryInvalidProof) apply(state *SectorInfo) { state.InvalidProofs++ } - // Faults type SectorFaulty struct{} diff --git a/fsm_test.go b/fsm_test.go index 57e478e6f..5014f46e9 100644 --- a/fsm_test.go +++ b/fsm_test.go @@ -38,6 +38,9 @@ func TestHappyPath(t *testing.T) { m.planSingle(SectorPacked{}) require.Equal(m.t, m.state.State, api.PreCommit1) + m.planSingle(SectorPreCommit1{}) + require.Equal(m.t, m.state.State, api.PreCommit2) + m.planSingle(SectorPreCommit2{}) require.Equal(m.t, m.state.State, api.PreCommitting) @@ -67,6 +70,9 @@ func TestSeedRevert(t *testing.T) { m.planSingle(SectorPacked{}) require.Equal(m.t, m.state.State, api.PreCommit1) + m.planSingle(SectorPreCommit1{}) + require.Equal(m.t, m.state.State, api.PreCommit2) + m.planSingle(SectorPreCommit2{}) require.Equal(m.t, m.state.State, api.PreCommitting) diff --git a/sealing.go b/sealing.go index 71a72ddd9..b6fe1edb1 100644 --- a/sealing.go +++ b/sealing.go @@ -43,6 +43,7 @@ type sealingApi interface { // TODO: trim down StateMinerSectors(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) StateMinerProvingSet(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) StateMinerSectorSize(context.Context, address.Address, types.TipSetKey) (abi.SectorSize, error) + StateSectorPreCommitInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) StateWaitMsg(context.Context, cid.Cid) (*api.MsgLookup, error) // TODO: removeme eventually StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error) StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) @@ -72,11 +73,12 @@ type Sealing struct { sealer sectorstorage.SectorManager sectors *statemachine.StateGroup - tktFn TicketFn sc SectorIDCounter + verif ffiwrapper.Verifier + tktFn TicketFn } -func New(api sealingApi, events *events.Events, maddr address.Address, worker address.Address, ds datastore.Batching, sealer sectorstorage.SectorManager, sc SectorIDCounter, tktFn TicketFn) *Sealing { +func New(api sealingApi, events *events.Events, maddr address.Address, worker address.Address, ds datastore.Batching, sealer sectorstorage.SectorManager, sc SectorIDCounter, verif ffiwrapper.Verifier, tktFn TicketFn) *Sealing { s := &Sealing{ api: api, events: events, @@ -84,8 +86,9 @@ func New(api sealingApi, events *events.Events, maddr address.Address, worker ad maddr: maddr, worker: worker, sealer: sealer, - tktFn: tktFn, sc: sc, + verif: verif, + tktFn: tktFn, } s.sectors = statemachine.New(namespace.Wrap(ds, datastore.NewKey(SectorStorePrefix)), s, SectorInfo{}) diff --git a/states.go b/states.go index 94f227fc3..072fc4ed8 100644 --- a/states.go +++ b/states.go @@ -156,7 +156,12 @@ func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) er } log.Info("precommit message landed on chain: ", sector.SectorID) - randHeight := mw.TipSet.Height() + miner.PreCommitChallengeDelay - 1 // -1 because of how the messages are applied + pci, err := m.api.StateSectorPreCommitInfo(ctx.Context(), m.maddr, sector.SectorID, mw.TipSet.Key()) + if err != nil { + return xerrors.Errorf("getting precommit info: %w", err) + } + + randHeight := pci.PreCommitEpoch + miner.PreCommitChallengeDelay log.Infof("precommit for sector %d made it on chain, will start proof computation at height %d", sector.SectorID, randHeight) err = m.events.ChainAt(func(ectx context.Context, ts *types.TipSet, curH abi.ChainEpoch) error { @@ -178,7 +183,7 @@ func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) er log.Warn("revert in interactive commit sector step") // TODO: need to cancel running process and restart... return nil - }, build.InteractivePoRepConfidence, mw.TipSet.Height()+miner.PreCommitChallengeDelay) + }, build.InteractivePoRepConfidence, randHeight) if err != nil { log.Warn("waitForPreCommitMessage ChainAt errored: ", err) } @@ -205,7 +210,7 @@ func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) return ctx.Send(SectorComputeProofFailed{xerrors.Errorf("computing seal proof failed: %w", err)}) } - if err := m.checkCommit(ctx.Context(), sector); err != nil { + if err := m.checkCommit(ctx.Context(), sector, proof); err != nil { return ctx.Send(SectorCommitFailed{xerrors.Errorf("commit check error: %w", err)}) } diff --git a/states_failed.go b/states_failed.go index 5c26b5a40..c7b563923 100644 --- a/states_failed.go +++ b/states_failed.go @@ -147,7 +147,7 @@ func (m *Sealing) handleCommitFailed(ctx statemachine.Context, sector SectorInfo } } - if err := m.checkCommit(ctx.Context(), sector); err != nil { + if err := m.checkCommit(ctx.Context(), sector, sector.Proof); err != nil { switch err.(type) { case *ErrApi: log.Errorf("handleCommitFailed: api error, not proceeding: %+v", err) From 9b29210dce2f0f33ee98a8023a641d690eb783aa Mon Sep 17 00:00:00 2001 From: laser Date: Mon, 6 Apr 2020 11:07:26 -0700 Subject: [PATCH 117/126] remove all lotus types from sealing package in preparation for extraction events adapter implement StateWaitMsg and StateComputeDataCommitment implement StateGetSectorPreCommitOnChainInfo implement ChainHead and SendMsg implement remaining methods --- cbor_gen.go | 294 +++++++++++++++++++++++++++-------------------- checks.go | 74 ++++-------- constants.go | 13 +++ events.go | 15 +++ fsm.go | 71 ++++++------ fsm_events.go | 17 ++- fsm_test.go | 33 +++--- garbage.go | 2 +- sealing.go | 80 +++++++------ sector_state.go | 74 ++++++++++++ states.go | 107 ++++++----------- states_failed.go | 31 +---- types.go | 14 ++- types_test.go | 23 ++-- utils.go | 3 +- 15 files changed, 465 insertions(+), 386 deletions(-) create mode 100644 constants.go create mode 100644 events.go create mode 100644 sector_state.go diff --git a/cbor_gen.go b/cbor_gen.go index ab12aa155..d97cebd74 100644 --- a/cbor_gen.go +++ b/cbor_gen.go @@ -6,7 +6,6 @@ import ( "fmt" "io" - "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/specs-actors/actors/abi" cbg "github.com/whyrusleeping/cbor-gen" xerrors "golang.org/x/xerrors" @@ -182,7 +181,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { return err } - // t.State (api.SectorState) (string) + // t.State (uint64) (uint64) if len("State") > cbg.MaxLength { return xerrors.Errorf("Value in field \"State\" was too long") } @@ -194,14 +193,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { return err } - if len(t.State) > cbg.MaxLength { - return xerrors.Errorf("Value in field t.State was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.State)))); err != nil { - return err - } - if _, err := w.Write([]byte(t.State)); err != nil { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.State))); err != nil { return err } @@ -284,45 +276,6 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { } } - // t.Ticket (api.SealTicket) (struct) - if len("Ticket") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"Ticket\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Ticket")))); err != nil { - return err - } - if _, err := w.Write([]byte("Ticket")); err != nil { - return err - } - - if err := t.Ticket.MarshalCBOR(w); err != nil { - return err - } - - // t.PreCommit1Out (storage.PreCommit1Out) (slice) - if len("PreCommit1Out") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"PreCommit1Out\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("PreCommit1Out")))); err != nil { - return err - } - if _, err := w.Write([]byte("PreCommit1Out")); err != nil { - return err - } - - if len(t.PreCommit1Out) > cbg.ByteArrayMaxLen { - return xerrors.Errorf("Byte array in field t.PreCommit1Out was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.PreCommit1Out)))); err != nil { - return err - } - if _, err := w.Write(t.PreCommit1Out); err != nil { - return err - } - // t.CommD (cid.Cid) (struct) if len("CommD") > cbg.MaxLength { return xerrors.Errorf("Value in field \"CommD\" was too long") @@ -390,6 +343,51 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { return err } + // t.TicketValue (abi.SealRandomness) (slice) + if len("TicketValue") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"TicketValue\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("TicketValue")))); err != nil { + return err + } + if _, err := w.Write([]byte("TicketValue")); err != nil { + return err + } + + if len(t.TicketValue) > cbg.ByteArrayMaxLen { + return xerrors.Errorf("Byte array in field t.TicketValue was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.TicketValue)))); err != nil { + return err + } + if _, err := w.Write(t.TicketValue); err != nil { + return err + } + + // t.TicketEpoch (abi.ChainEpoch) (int64) + if len("TicketEpoch") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"TicketEpoch\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("TicketEpoch")))); err != nil { + return err + } + if _, err := w.Write([]byte("TicketEpoch")); err != nil { + return err + } + + if t.TicketEpoch >= 0 { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.TicketEpoch))); err != nil { + return err + } + } else { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajNegativeInt, uint64(-t.TicketEpoch)-1)); err != nil { + return err + } + } + // t.PreCommitMessage (cid.Cid) (struct) if len("PreCommitMessage") > cbg.MaxLength { return xerrors.Errorf("Value in field \"PreCommitMessage\" was too long") @@ -412,21 +410,50 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { } } - // t.Seed (api.SealSeed) (struct) - if len("Seed") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"Seed\" was too long") + // t.SeedValue (abi.InteractiveSealRandomness) (slice) + if len("SeedValue") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"SeedValue\" was too long") } - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Seed")))); err != nil { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("SeedValue")))); err != nil { return err } - if _, err := w.Write([]byte("Seed")); err != nil { + if _, err := w.Write([]byte("SeedValue")); err != nil { return err } - if err := t.Seed.MarshalCBOR(w); err != nil { + if len(t.SeedValue) > cbg.ByteArrayMaxLen { + return xerrors.Errorf("Byte array in field t.SeedValue was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.SeedValue)))); err != nil { return err } + if _, err := w.Write(t.SeedValue); err != nil { + return err + } + + // t.SeedEpoch (abi.ChainEpoch) (int64) + if len("SeedEpoch") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"SeedEpoch\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("SeedEpoch")))); err != nil { + return err + } + if _, err := w.Write([]byte("SeedEpoch")); err != nil { + return err + } + + if t.SeedEpoch >= 0 { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SeedEpoch))); err != nil { + return err + } + } else { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajNegativeInt, uint64(-t.SeedEpoch)-1)); err != nil { + return err + } + } // t.CommitMessage (cid.Cid) (struct) if len("CommitMessage") > cbg.MaxLength { @@ -450,22 +477,6 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { } } - // t.InvalidProofs (uint64) (uint64) - if len("InvalidProofs") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"InvalidProofs\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("InvalidProofs")))); err != nil { - return err - } - if _, err := w.Write([]byte("InvalidProofs")); err != nil { - return err - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.InvalidProofs))); err != nil { - return err - } - // t.FaultReportMsg (cid.Cid) (struct) if len("FaultReportMsg") > cbg.MaxLength { return xerrors.Errorf("Value in field \"FaultReportMsg\" was too long") @@ -568,16 +579,20 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { } switch name { - // t.State (api.SectorState) (string) + // t.State (uint64) (uint64) case "State": { - sval, err := cbg.ReadString(br) + + maj, extra, err = cbg.CborReadHeader(br) if err != nil { return err } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.State = uint64(extra) - t.State = api.SectorState(sval) } // t.SectorID (abi.SectorNumber) (uint64) case "SectorID": @@ -663,34 +678,6 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { t.Pieces[i] = v } - // t.Ticket (api.SealTicket) (struct) - case "Ticket": - - { - - if err := t.Ticket.UnmarshalCBOR(br); err != nil { - return xerrors.Errorf("unmarshaling t.Ticket: %w", err) - } - - } - // t.PreCommit1Out (storage.PreCommit1Out) (slice) - case "PreCommit1Out": - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.ByteArrayMaxLen { - return fmt.Errorf("t.PreCommit1Out: byte array too large (%d)", extra) - } - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") - } - t.PreCommit1Out = make([]byte, extra) - if _, err := io.ReadFull(br, t.PreCommit1Out); err != nil { - return err - } // t.CommD (cid.Cid) (struct) case "CommD": @@ -759,6 +746,50 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { if _, err := io.ReadFull(br, t.Proof); err != nil { return err } + // t.TicketValue (abi.SealRandomness) (slice) + case "TicketValue": + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + + if extra > cbg.ByteArrayMaxLen { + return fmt.Errorf("t.TicketValue: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.TicketValue = make([]byte, extra) + if _, err := io.ReadFull(br, t.TicketValue); err != nil { + return err + } + // t.TicketEpoch (abi.ChainEpoch) (int64) + case "TicketEpoch": + { + maj, extra, err := cbg.CborReadHeader(br) + var extraI int64 + if err != nil { + return err + } + switch maj { + case cbg.MajUnsignedInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 positive overflow") + } + case cbg.MajNegativeInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 negative oveflow") + } + extraI = -1 - extraI + default: + return fmt.Errorf("wrong type for int64 field: %d", maj) + } + + t.TicketEpoch = abi.ChainEpoch(extraI) + } // t.PreCommitMessage (cid.Cid) (struct) case "PreCommitMessage": @@ -784,15 +815,49 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { } } - // t.Seed (api.SealSeed) (struct) - case "Seed": + // t.SeedValue (abi.InteractiveSealRandomness) (slice) + case "SeedValue": + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + + if extra > cbg.ByteArrayMaxLen { + return fmt.Errorf("t.SeedValue: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.SeedValue = make([]byte, extra) + if _, err := io.ReadFull(br, t.SeedValue); err != nil { + return err + } + // t.SeedEpoch (abi.ChainEpoch) (int64) + case "SeedEpoch": { - - if err := t.Seed.UnmarshalCBOR(br); err != nil { - return xerrors.Errorf("unmarshaling t.Seed: %w", err) + maj, extra, err := cbg.CborReadHeader(br) + var extraI int64 + if err != nil { + return err + } + switch maj { + case cbg.MajUnsignedInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 positive overflow") + } + case cbg.MajNegativeInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 negative oveflow") + } + extraI = -1 - extraI + default: + return fmt.Errorf("wrong type for int64 field: %d", maj) } + t.SeedEpoch = abi.ChainEpoch(extraI) } // t.CommitMessage (cid.Cid) (struct) case "CommitMessage": @@ -818,21 +883,6 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { t.CommitMessage = &c } - } - // t.InvalidProofs (uint64) (uint64) - case "InvalidProofs": - - { - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.InvalidProofs = uint64(extra) - } // t.FaultReportMsg (cid.Cid) (struct) case "FaultReportMsg": diff --git a/checks.go b/checks.go index cc0619e43..2721c8333 100644 --- a/checks.go +++ b/checks.go @@ -1,25 +1,18 @@ package sealing import ( - "bytes" "context" - "github.com/ipfs/go-cid" - cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/sector-storage/ffiwrapper" + "github.com/filecoin-project/sector-storage/zerocomm" "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/specs-actors/actors/builtin" - "github.com/filecoin-project/specs-actors/actors/builtin/market" "github.com/filecoin-project/specs-actors/actors/builtin/miner" "github.com/filecoin-project/specs-actors/actors/crypto" - - "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/chain/actors" - "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/sector-storage/zerocomm" + log "github.com/mgutz/logxi/v1" ) // TODO: For now we handle this by halting state execution, when we get jsonrpc reconnecting @@ -41,8 +34,8 @@ type ErrInvalidProof struct{ error } // - Piece commitments match with on chain deals // - Piece sizes match // - Deals aren't expired -func checkPieces(ctx context.Context, si SectorInfo, api sealingApi) error { - head, err := api.ChainHead(ctx) +func checkPieces(ctx context.Context, si SectorInfo, api SealingAPI) error { + tok, height, err := api.ChainHead(ctx) if err != nil { return &ErrApi{xerrors.Errorf("getting chain head: %w", err)} } @@ -55,21 +48,21 @@ func checkPieces(ctx context.Context, si SectorInfo, api sealingApi) error { } continue } - deal, err := api.StateMarketStorageDeal(ctx, *piece.DealID, types.EmptyTSK) + proposal, _, err := api.StateMarketStorageDeal(ctx, *piece.DealID, tok) if err != nil { return &ErrApi{xerrors.Errorf("getting deal %d for piece %d: %w", piece.DealID, i, err)} } - if deal.Proposal.PieceCID != piece.CommP { - return &ErrInvalidDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers deal %d with wrong CommP: %x != %x", i, len(si.Pieces), si.SectorID, piece.DealID, piece.CommP, deal.Proposal.PieceCID)} + if proposal.PieceCID != piece.CommP { + return &ErrInvalidDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers deal %d with wrong CommP: %x != %x", i, len(si.Pieces), si.SectorID, piece.DealID, piece.CommP, proposal.PieceCID)} } - if piece.Size != deal.Proposal.PieceSize.Unpadded() { - return &ErrInvalidDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers deal %d with different size: %d != %d", i, len(si.Pieces), si.SectorID, piece.DealID, piece.Size, deal.Proposal.PieceSize)} + if piece.Size != proposal.PieceSize.Unpadded() { + return &ErrInvalidDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers deal %d with different size: %d != %d", i, len(si.Pieces), si.SectorID, piece.DealID, piece.Size, proposal.PieceSize)} } - if head.Height() >= deal.Proposal.StartEpoch { - return &ErrExpiredDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers expired deal %d - should start at %d, head %d", i, len(si.Pieces), si.SectorID, piece.DealID, deal.Proposal.StartEpoch, head.Height())} + if height >= proposal.StartEpoch { + return &ErrExpiredDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers expired deal %d - should start at %d, head %d", i, len(si.Pieces), si.SectorID, piece.DealID, proposal.StartEpoch, height)} } } @@ -78,55 +71,30 @@ func checkPieces(ctx context.Context, si SectorInfo, api sealingApi) error { // checkPrecommit checks that data commitment generated in the sealing process // matches pieces, and that the seal ticket isn't expired -func checkPrecommit(ctx context.Context, maddr address.Address, si SectorInfo, api sealingApi) (err error) { - head, err := api.ChainHead(ctx) +func checkPrecommit(ctx context.Context, maddr address.Address, si SectorInfo, api SealingAPI) (err error) { + tok, height, err := api.ChainHead(ctx) if err != nil { return &ErrApi{xerrors.Errorf("getting chain head: %w", err)} } - ccparams, err := actors.SerializeParams(&market.ComputeDataCommitmentParams{ - DealIDs: si.deals(), - SectorType: si.SectorType, - }) + commD, err := api.StateComputeDataCommitment(ctx, maddr, si.SectorType, si.deals(), tok) if err != nil { - return xerrors.Errorf("computing params for ComputeDataCommitment: %w", err) + return &ErrApi{xerrors.Errorf("calling StateComputeDataCommitment: %w", err)} } - ccmt := &types.Message{ - To: builtin.StorageMarketActorAddr, - From: maddr, - Value: types.NewInt(0), - GasPrice: types.NewInt(0), - GasLimit: 9999999999, - Method: builtin.MethodsMarket.ComputeDataCommitment, - Params: ccparams, - } - r, err := api.StateCall(ctx, ccmt, types.EmptyTSK) - if err != nil { - return &ErrApi{xerrors.Errorf("calling ComputeDataCommitment: %w", err)} - } - if r.MsgRct.ExitCode != 0 { - return &ErrBadCommD{xerrors.Errorf("receipt for ComputeDataCommitment had exit code %d", r.MsgRct.ExitCode)} + if !commD.Equals(*si.CommD) { + return &ErrBadCommD{xerrors.Errorf("on chain CommD differs from sector: %s != %s", commD, si.CommD)} } - var c cbg.CborCid - if err := c.UnmarshalCBOR(bytes.NewReader(r.MsgRct.Return)); err != nil { - return err - } - - if cid.Cid(c) != *si.CommD { - return &ErrBadCommD{xerrors.Errorf("on chain CommD differs from sector: %s != %s", cid.Cid(c), si.CommD)} - } - - if int64(head.Height())-int64(si.Ticket.Epoch+build.SealRandomnessLookback) > build.SealRandomnessLookbackLimit { - return &ErrExpiredTicket{xerrors.Errorf("ticket expired: seal height: %d, head: %d", si.Ticket.Epoch+build.SealRandomnessLookback, head.Height())} + if int64(height)-int64(si.TicketEpoch+SealRandomnessLookback) > SealRandomnessLookbackLimit { + return &ErrExpiredTicket{xerrors.Errorf("ticket expired: seal height: %d, head: %d", si.TicketEpoch+SealRandomnessLookback, height)} } return nil } func (m *Sealing) checkCommit(ctx context.Context, si SectorInfo, proof []byte) (err error) { - head, err := m.api.ChainHead(ctx) + tok, height, err := m.api.ChainHead(ctx) if err != nil { return &ErrApi{xerrors.Errorf("getting chain head: %w", err)} } diff --git a/constants.go b/constants.go new file mode 100644 index 000000000..b898443e6 --- /dev/null +++ b/constants.go @@ -0,0 +1,13 @@ +package sealing + +// Epochs +const Finality = 500 + +// Epochs +const SealRandomnessLookback = Finality + +// Epochs +const SealRandomnessLookbackLimit = SealRandomnessLookback + 2000 + +// Epochs +const InteractivePoRepConfidence = 6 diff --git a/events.go b/events.go new file mode 100644 index 000000000..ba6d2a860 --- /dev/null +++ b/events.go @@ -0,0 +1,15 @@ +package sealing + +import ( + "context" + + "github.com/filecoin-project/specs-actors/actors/abi" +) + +// `curH`-`ts.Height` = `confidence` +type HeightHandler func(ctx context.Context, tok TipSetToken, curH abi.ChainEpoch) error +type RevertHandler func(ctx context.Context, tok TipSetToken) error + +type Events interface { + ChainAt(hnd HeightHandler, rev RevertHandler, confidence int, h abi.ChainEpoch) error +} diff --git a/fsm.go b/fsm.go index 2d1691678..88be53eff 100644 --- a/fsm.go +++ b/fsm.go @@ -1,6 +1,7 @@ package sealing import ( + "bytes" "context" "encoding/json" "fmt" @@ -9,10 +10,10 @@ import ( "golang.org/x/xerrors" - "github.com/filecoin-project/go-statemachine" - "github.com/filecoin-project/specs-actors/actors/abi" - + statemachine "github.com/filecoin-project/go-statemachine" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/prometheus/common/log" ) func (m *Sealing) Plan(events []statemachine.Event, user interface{}) (interface{}, uint64, error) { @@ -54,19 +55,19 @@ var fsmPlanners = map[api.SectorState]func(events []statemachine.Event, state *S on(SectorSeedReady{}, api.Committing), on(SectorChainPreCommitFailed{}, api.PreCommitFailed), ), - api.Committing: planCommitting, - api.CommitWait: planOne( - on(SectorProving{}, api.FinalizeSector), - on(SectorCommitFailed{}, api.CommitFailed), + Committing: planCommitting, + CommitWait: planOne( + on(SectorProving{}, FinalizeSector), + on(SectorCommitFailed{}, CommitFailed), ), - api.FinalizeSector: planOne( - on(SectorFinalized{}, api.Proving), + FinalizeSector: planOne( + on(SectorFinalized{}, Proving), ), - api.Proving: planOne( - on(SectorFaultReported{}, api.FaultReported), - on(SectorFaulty{}, api.Faulty), + Proving: planOne( + on(SectorFaultReported{}, FaultReported), + on(SectorFaulty{}, Faulty), ), api.SealFailed: planOne( @@ -87,10 +88,10 @@ var fsmPlanners = map[api.SectorState]func(events []statemachine.Event, state *S on(SectorRetryInvalidProof{}, api.Committing), ), - api.Faulty: planOne( - on(SectorFaultReported{}, api.FaultReported), + Faulty: planOne( + on(SectorFaultReported{}, FaultReported), ), - api.FaultedFinal: final, + FaultedFinal: final, } func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(statemachine.Context, SectorInfo) error, error) { @@ -170,7 +171,7 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta switch state.State { // Happy path - case api.Packing: + case Packing: return m.handlePacking, nil case api.PreCommit1: return m.handlePreCommit1, nil @@ -178,22 +179,22 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta return m.handlePreCommit2, nil case api.PreCommitting: return m.handlePreCommitting, nil - case api.WaitSeed: + case WaitSeed: return m.handleWaitSeed, nil - case api.Committing: + case Committing: return m.handleCommitting, nil - case api.CommitWait: + case CommitWait: return m.handleCommitWait, nil - case api.FinalizeSector: + case FinalizeSector: return m.handleFinalizeSector, nil - case api.Proving: + case Proving: // TODO: track sector health / expiration log.Infof("Proving sector %d", state.SectorID) // Handled failure modes - case api.SealFailed: + case SealFailed: return m.handleSealFailed, nil - case api.PreCommitFailed: + case PreCommitFailed: return m.handlePreCommitFailed, nil case api.ComputeProofFailed: return m.handleComputeProofFailed, nil @@ -201,15 +202,15 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta return m.handleCommitFailed, nil // Faults - case api.Faulty: + case Faulty: return m.handleFaulty, nil - case api.FaultReported: + case FaultReported: return m.handleFaultReported, nil // Fatal errors - case api.UndefinedSectorState: + case UndefinedSectorState: log.Error("sector update with undefined state!") - case api.FailedUnrecoverable: + case FailedUnrecoverable: log.Errorf("sector %d failed unrecoverably", state.SectorID) default: log.Errorf("unexpected sector update state: %d", state.State) @@ -227,22 +228,22 @@ func planCommitting(events []statemachine.Event, state *SectorInfo) error { } case SectorCommitted: // the normal case e.apply(state) - state.State = api.CommitWait + state.State = CommitWait case SectorSeedReady: // seed changed :/ - if e.Seed.Equals(&state.Seed) { + if e.SeedEpoch == state.SeedEpoch && bytes.Equal(e.SeedValue, state.SeedValue) { log.Warnf("planCommitting: got SectorSeedReady, but the seed didn't change") continue // or it didn't! } log.Warnf("planCommitting: commit Seed changed") e.apply(state) - state.State = api.Committing + state.State = Committing return nil case SectorComputeProofFailed: state.State = api.ComputeProofFailed case SectorSealPreCommitFailed: state.State = api.CommitFailed case SectorCommitFailed: - state.State = api.CommitFailed + state.State = CommitFailed default: return xerrors.Errorf("planCommitting got event of unknown type %T, events: %+v", event.User, events) } @@ -267,7 +268,7 @@ func (m *Sealing) restartSectors(ctx context.Context) error { return nil } -func (m *Sealing) ForceSectorState(ctx context.Context, id abi.SectorNumber, state api.SectorState) error { +func (m *Sealing) ForceSectorState(ctx context.Context, id abi.SectorNumber, state SectorState) error { return m.sectors.Send(id, SectorForceState{state}) } @@ -275,13 +276,13 @@ func final(events []statemachine.Event, state *SectorInfo) error { return xerrors.Errorf("didn't expect any events in state %s, got %+v", state.State, events) } -func on(mut mutator, next api.SectorState) func() (mutator, api.SectorState) { - return func() (mutator, api.SectorState) { +func on(mut mutator, next SectorState) func() (mutator, SectorState) { + return func() (mutator, SectorState) { return mut, next } } -func planOne(ts ...func() (mut mutator, next api.SectorState)) func(events []statemachine.Event, state *SectorInfo) error { +func planOne(ts ...func() (mut mutator, next SectorState)) func(events []statemachine.Event, state *SectorInfo) error { return func(events []statemachine.Event, state *SectorInfo) error { if len(events) != 1 { for _, event := range events { diff --git a/fsm_events.go b/fsm_events.go index 83d0a5c24..40388ad70 100644 --- a/fsm_events.go +++ b/fsm_events.go @@ -4,9 +4,10 @@ import ( "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-storage/storage" "github.com/ipfs/go-cid" + "github.com/prometheus/common/log" "golang.org/x/xerrors" - "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/specs-actors/actors/abi" ) type mutator interface { @@ -39,7 +40,7 @@ func (evt SectorFatalError) applyGlobal(state *SectorInfo) bool { } type SectorForceState struct { - State api.SectorState + State SectorState } func (evt SectorForceState) applyGlobal(state *SectorInfo) bool { @@ -73,12 +74,14 @@ func (evt SectorPackingFailed) apply(*SectorInfo) {} type SectorPreCommit1 struct { PreCommit1Out storage.PreCommit1Out - Ticket api.SealTicket + TicketValue abi.SealRandomness + TicketEpoch abi.ChainEpoch } func (evt SectorPreCommit1) apply(state *SectorInfo) { state.PreCommit1Out = evt.PreCommit1Out - state.Ticket = evt.Ticket + state.TicketEpoch = evt.TicketEpoch + state.TicketValue = evt.TicketValue } type SectorPreCommit2 struct { @@ -114,11 +117,13 @@ func (evt SectorPreCommitted) apply(state *SectorInfo) { } type SectorSeedReady struct { - Seed api.SealSeed + SeedValue abi.InteractiveSealRandomness + SeedEpoch abi.ChainEpoch } func (evt SectorSeedReady) apply(state *SectorInfo) { - state.Seed = evt.Seed + state.SeedEpoch = evt.SeedEpoch + state.SeedValue = evt.SeedValue } type SectorComputeProofFailed struct{ error } diff --git a/fsm_test.go b/fsm_test.go index 5014f46e9..69c2a99fb 100644 --- a/fsm_test.go +++ b/fsm_test.go @@ -7,7 +7,6 @@ import ( "github.com/stretchr/testify/require" "github.com/filecoin-project/go-statemachine" - "github.com/filecoin-project/lotus/api" ) @@ -32,7 +31,7 @@ func TestHappyPath(t *testing.T) { m := test{ s: &Sealing{}, t: t, - state: &SectorInfo{State: api.Packing}, + state: &SectorInfo{State: Packing}, } m.planSingle(SectorPacked{}) @@ -45,26 +44,26 @@ func TestHappyPath(t *testing.T) { require.Equal(m.t, m.state.State, api.PreCommitting) m.planSingle(SectorPreCommitted{}) - require.Equal(m.t, m.state.State, api.WaitSeed) + require.Equal(m.t, m.state.State, WaitSeed) m.planSingle(SectorSeedReady{}) - require.Equal(m.t, m.state.State, api.Committing) + require.Equal(m.t, m.state.State, Committing) m.planSingle(SectorCommitted{}) - require.Equal(m.t, m.state.State, api.CommitWait) + require.Equal(m.t, m.state.State, CommitWait) m.planSingle(SectorProving{}) - require.Equal(m.t, m.state.State, api.FinalizeSector) + require.Equal(m.t, m.state.State, FinalizeSector) m.planSingle(SectorFinalized{}) - require.Equal(m.t, m.state.State, api.Proving) + require.Equal(m.t, m.state.State, Proving) } func TestSeedRevert(t *testing.T) { m := test{ s: &Sealing{}, t: t, - state: &SectorInfo{State: api.Packing}, + state: &SectorInfo{State: Packing}, } m.planSingle(SectorPacked{}) @@ -77,31 +76,31 @@ func TestSeedRevert(t *testing.T) { require.Equal(m.t, m.state.State, api.PreCommitting) m.planSingle(SectorPreCommitted{}) - require.Equal(m.t, m.state.State, api.WaitSeed) + require.Equal(m.t, m.state.State, WaitSeed) m.planSingle(SectorSeedReady{}) - require.Equal(m.t, m.state.State, api.Committing) + require.Equal(m.t, m.state.State, Committing) - _, err := m.s.plan([]statemachine.Event{{SectorSeedReady{Seed: api.SealSeed{Epoch: 5}}}, {SectorCommitted{}}}, m.state) + _, err := m.s.plan([]statemachine.Event{{SectorSeedReady{Seed: SealSeed{Epoch: 5}}}, {SectorCommitted{}}}, m.state) require.NoError(t, err) - require.Equal(m.t, m.state.State, api.Committing) + require.Equal(m.t, m.state.State, Committing) // not changing the seed this time - _, err = m.s.plan([]statemachine.Event{{SectorSeedReady{Seed: api.SealSeed{Epoch: 5}}}, {SectorCommitted{}}}, m.state) - require.Equal(m.t, m.state.State, api.CommitWait) + _, err = m.s.plan([]statemachine.Event{{SectorSeedReady{Seed: SealSeed{Epoch: 5}}}, {SectorCommitted{}}}, m.state) + require.Equal(m.t, m.state.State, CommitWait) m.planSingle(SectorProving{}) - require.Equal(m.t, m.state.State, api.FinalizeSector) + require.Equal(m.t, m.state.State, FinalizeSector) m.planSingle(SectorFinalized{}) - require.Equal(m.t, m.state.State, api.Proving) + require.Equal(m.t, m.state.State, Proving) } func TestPlanCommittingHandlesSectorCommitFailed(t *testing.T) { m := test{ s: &Sealing{}, t: t, - state: &SectorInfo{State: api.Committing}, + state: &SectorInfo{State: Committing}, } events := []statemachine.Event{{SectorCommitFailed{}}} diff --git a/garbage.go b/garbage.go index fcc3505c7..7f367d448 100644 --- a/garbage.go +++ b/garbage.go @@ -2,11 +2,11 @@ package sealing import ( "context" - "github.com/filecoin-project/sector-storage/ffiwrapper" "io" "golang.org/x/xerrors" + "github.com/filecoin-project/sector-storage/ffiwrapper" "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/lotus/lib/nullreader" diff --git a/sealing.go b/sealing.go index b6fe1edb1..a843650b4 100644 --- a/sealing.go +++ b/sealing.go @@ -1,72 +1,76 @@ package sealing import ( + "bytes" "context" - "github.com/filecoin-project/sector-storage/ffiwrapper" "io" - "github.com/filecoin-project/go-address" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/namespace" logging "github.com/ipfs/go-log/v2" "golang.org/x/xerrors" - "github.com/filecoin-project/go-padreader" - "github.com/filecoin-project/go-statemachine" + "github.com/filecoin-project/go-address" + padreader "github.com/filecoin-project/go-padreader" + statemachine "github.com/filecoin-project/go-statemachine" + sectorstorage "github.com/filecoin-project/sector-storage" + "github.com/filecoin-project/sector-storage/ffiwrapper" "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/abi/big" + "github.com/filecoin-project/specs-actors/actors/builtin/market" "github.com/filecoin-project/specs-actors/actors/builtin/miner" "github.com/filecoin-project/specs-actors/actors/crypto" - - "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/chain/events" - "github.com/filecoin-project/lotus/chain/store" - "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/sector-storage" + "github.com/filecoin-project/specs-actors/actors/runtime/exitcode" ) const SectorStorePrefix = "/sectors" var log = logging.Logger("sectors") -type TicketFn func(context.Context) (*api.SealTicket, error) +type TicketFn func(context.Context) (abi.SealRandomness, abi.ChainEpoch, error) type SectorIDCounter interface { Next() (abi.SectorNumber, error) } -type sealingApi interface { // TODO: trim down - // Call a read only method on actors (no interaction with the chain required) - StateCall(context.Context, *types.Message, types.TipSetKey) (*api.InvocResult, error) - StateMinerWorker(context.Context, address.Address, types.TipSetKey) (address.Address, error) - StateMinerPostState(ctx context.Context, actor address.Address, ts types.TipSetKey) (*miner.PoStState, error) - StateMinerSectors(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) - StateMinerProvingSet(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) - StateMinerSectorSize(context.Context, address.Address, types.TipSetKey) (abi.SectorSize, error) - StateSectorPreCommitInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) - StateWaitMsg(context.Context, cid.Cid) (*api.MsgLookup, error) // TODO: removeme eventually - StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error) - StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) - StateMarketStorageDeal(context.Context, abi.DealID, types.TipSetKey) (*api.MarketDeal, error) +type TipSetToken []byte - MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error) +type MsgLookup struct { + Receipt MessageReceipt + TipSetTok TipSetToken + Height abi.ChainEpoch +} - ChainHead(context.Context) (*types.TipSet, error) - ChainNotify(context.Context) (<-chan []*store.HeadChange, error) - ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) - ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error) - ChainGetBlockMessages(context.Context, cid.Cid) (*api.BlockMessages, error) +type MessageReceipt struct { + ExitCode exitcode.ExitCode + Return []byte + GasUsed int64 +} + +func (mr *MessageReceipt) Equals(o *MessageReceipt) bool { + return mr.ExitCode == o.ExitCode && bytes.Equal(mr.Return, o.Return) && mr.GasUsed == o.GasUsed +} + +type MarketDeal struct { + Proposal market.DealProposal + State market.DealState +} + +type SealingAPI interface { + StateWaitMsg(context.Context, cid.Cid) (MsgLookup, error) + StateComputeDataCommitment(ctx context.Context, maddr address.Address, sectorType abi.RegisteredProof, deals []abi.DealID, tok TipSetToken) (cid.Cid, error) + StateGetSectorPreCommitOnChainInfo(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok TipSetToken) (*miner.SectorPreCommitOnChainInfo, error) + StateMarketStorageDeal(context.Context, abi.DealID, TipSetToken) (market.DealProposal, market.DealState, error) + SendMsg(ctx context.Context, from, to address.Address, method abi.MethodNum, value, gasPrice big.Int, gasLimit int64, params []byte) (cid.Cid, error) + ChainHead(ctx context.Context) (TipSetToken, abi.ChainEpoch, error) + ChainGetRandomness(ctx context.Context, tok TipSetToken, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) ChainReadObj(context.Context, cid.Cid) ([]byte, error) - ChainHasObj(context.Context, cid.Cid) (bool, error) - - WalletSign(context.Context, address.Address, []byte) (*crypto.Signature, error) - WalletBalance(context.Context, address.Address) (types.BigInt, error) - WalletHas(context.Context, address.Address) (bool, error) } type Sealing struct { - api sealingApi - events *events.Events + api SealingAPI + events Events maddr address.Address worker address.Address @@ -78,7 +82,7 @@ type Sealing struct { tktFn TicketFn } -func New(api sealingApi, events *events.Events, maddr address.Address, worker address.Address, ds datastore.Batching, sealer sectorstorage.SectorManager, sc SectorIDCounter, verif ffiwrapper.Verifier, tktFn TicketFn) *Sealing { +func New(api SealingAPI, events Events, maddr address.Address, worker address.Address, ds datastore.Batching, sealer sectorstorage.SectorManager, sc SectorIDCounter, verif ffiwrapper.Verifier, tktFn TicketFn) *Sealing { s := &Sealing{ api: api, events: events, diff --git a/sector_state.go b/sector_state.go new file mode 100644 index 000000000..5477edff8 --- /dev/null +++ b/sector_state.go @@ -0,0 +1,74 @@ +package sealing + +// alias because cbor-gen doesn't like non-alias types +type SectorState = uint64 + +const ( + UndefinedSectorState SectorState = iota + + // happy path + Empty + Packing // sector not in sealStore, and not on chain + + Unsealed // sealing / queued + PreCommitting // on chain pre-commit + WaitSeed // waiting for seed + Committing + CommitWait // waiting for message to land on chain + FinalizeSector + Proving + _ // reserved + _ + _ + + // recovery handling + // Reseal + _ + _ + _ + _ + _ + _ + _ + + // error modes + FailedUnrecoverable + + SealFailed + PreCommitFailed + SealCommitFailed + CommitFailed + PackingFailed + _ + _ + _ + + Faulty // sector is corrupted or gone for some reason + FaultReported // sector has been declared as a fault on chain + FaultedFinal // fault declared on chain +) + +var SectorStates = []string{ + UndefinedSectorState: "UndefinedSectorState", + Empty: "Empty", + Packing: "Packing", + Unsealed: "Unsealed", + PreCommitting: "PreCommitting", + WaitSeed: "WaitSeed", + Committing: "Committing", + CommitWait: "CommitWait", + FinalizeSector: "FinalizeSector", + Proving: "Proving", + + SealFailed: "SealFailed", + PreCommitFailed: "PreCommitFailed", + SealCommitFailed: "SealCommitFailed", + CommitFailed: "CommitFailed", + PackingFailed: "PackingFailed", + + FailedUnrecoverable: "FailedUnrecoverable", + + Faulty: "Faulty", + FaultReported: "FaultReported", + FaultedFinal: "FaultedFinal", +} diff --git a/states.go b/states.go index 072fc4ed8..0bd4f767d 100644 --- a/states.go +++ b/states.go @@ -1,21 +1,19 @@ package sealing import ( + "bytes" "context" - "github.com/filecoin-project/specs-storage/storage" - "github.com/filecoin-project/specs-actors/actors/crypto" - - "github.com/filecoin-project/go-statemachine" - "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/specs-actors/actors/builtin" - "github.com/filecoin-project/specs-actors/actors/builtin/miner" "golang.org/x/xerrors" - "github.com/filecoin-project/lotus/api" + statemachine "github.com/filecoin-project/go-statemachine" "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/chain/actors" - "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/abi/big" + "github.com/filecoin-project/specs-actors/actors/builtin" + "github.com/filecoin-project/specs-actors/actors/builtin/miner" + "github.com/filecoin-project/specs-actors/actors/crypto" + "github.com/filecoin-project/specs-storage/storage" ) func (m *Sealing) handlePacking(ctx statemachine.Context, sector SectorInfo) error { @@ -65,19 +63,20 @@ func (m *Sealing) handlePreCommit1(ctx statemachine.Context, sector SectorInfo) } log.Infow("performing sector replication...", "sector", sector.SectorID) - ticket, err := m.tktFn(ctx.Context()) + ticketValue, ticketEpoch, err := m.tktFn(ctx.Context()) if err != nil { return ctx.Send(SectorSealPreCommitFailed{xerrors.Errorf("getting ticket failed: %w", err)}) } - pc1o, err := m.sealer.SealPreCommit1(ctx.Context(), m.minerSector(sector.SectorID), ticket.Value, sector.pieceInfos()) + pc1o, err := m.sealer.SealPreCommit1(ctx.Context(), m.minerSector(sector.SectorID), ticketValue, sector.pieceInfos()) if err != nil { return ctx.Send(SectorSealPreCommitFailed{xerrors.Errorf("seal pre commit(1) failed: %w", err)}) } return ctx.Send(SectorPreCommit1{ PreCommit1Out: pc1o, - Ticket: *ticket, + TicketValue: ticketValue, + TicketEpoch: ticketEpoch, }) } @@ -94,7 +93,7 @@ func (m *Sealing) handlePreCommit2(ctx statemachine.Context, sector SectorInfo) } func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInfo) error { - if err := checkPrecommit(ctx.Context(), m.maddr, sector, m.api); err != nil { + if err := checkPrecommit(ctx.Context(), m.Address(), sector, m.api); err != nil { switch err.(type) { case *ErrApi: log.Errorf("handlePreCommitting: api error, not proceeding: %+v", err) @@ -114,31 +113,22 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf RegisteredProof: sector.SectorType, SealedCID: *sector.CommR, - SealRandEpoch: sector.Ticket.Epoch, + SealRandEpoch: sector.TicketEpoch, DealIDs: sector.deals(), } - enc, aerr := actors.SerializeParams(params) - if aerr != nil { - return ctx.Send(SectorChainPreCommitFailed{xerrors.Errorf("could not serialize commit sector parameters: %w", aerr)}) - } - msg := &types.Message{ - To: m.maddr, - From: m.worker, - Method: builtin.MethodsMiner.PreCommitSector, - Params: enc, - Value: types.NewInt(0), // TODO: need to ensure sufficient collateral - GasLimit: 1000000, /* i dont know help */ - GasPrice: types.NewInt(1), + enc := new(bytes.Buffer) + if err := params.MarshalCBOR(enc); err != nil { + return ctx.Send(SectorChainPreCommitFailed{xerrors.Errorf("could not serialize pre-commit sector parameters: %w", err)}) } log.Info("submitting precommit for sector: ", sector.SectorID) - smsg, err := m.api.MpoolPushMessage(ctx.Context(), msg) + mcid, err := m.api.SendMsg(ctx.Context(), m.worker, m.maddr, builtin.MethodsMiner.PreCommitSector, big.NewInt(0), big.NewInt(1), 1000000, enc.Bytes()) if err != nil { return ctx.Send(SectorChainPreCommitFailed{xerrors.Errorf("pushing message to mpool: %w", err)}) } - return ctx.Send(SectorPreCommitted{Message: smsg.Cid()}) + return ctx.Send(SectorPreCommitted{Message: mcid}) } func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) error { @@ -162,10 +152,9 @@ func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) er } randHeight := pci.PreCommitEpoch + miner.PreCommitChallengeDelay - log.Infof("precommit for sector %d made it on chain, will start proof computation at height %d", sector.SectorID, randHeight) - err = m.events.ChainAt(func(ectx context.Context, ts *types.TipSet, curH abi.ChainEpoch) error { - rand, err := m.api.ChainGetRandomness(ectx, ts.Key(), crypto.DomainSeparationTag_InteractiveSealChallengeSeed, randHeight, nil) + err = m.events.ChainAt(func(ectx context.Context, tok TipSetToken, curH abi.ChainEpoch) error { + rand, err := m.api.ChainGetRandomness(ectx, tok, crypto.DomainSeparationTag_InteractiveSealChallengeSeed, randHeight, nil) if err != nil { err = xerrors.Errorf("failed to get randomness for computing seal proof: %w", err) @@ -173,13 +162,10 @@ func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) er return err } - ctx.Send(SectorSeedReady{Seed: api.SealSeed{ - Epoch: randHeight, - Value: abi.InteractiveSealRandomness(rand), - }}) + ctx.Send(SectorSeedReady{SeedValue: abi.InteractiveSealRandomness(rand), SeedEpoch: randHeight}) return nil - }, func(ctx context.Context, ts *types.TipSet) error { + }, func(ctx context.Context, ts TipSetToken) error { log.Warn("revert in interactive commit sector step") // TODO: need to cancel running process and restart... return nil @@ -194,13 +180,13 @@ func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) er func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) error { log.Info("scheduling seal proof computation...") - log.Infof("KOMIT %d %x(%d); %x(%d); %v; r:%x; d:%x", sector.SectorID, sector.Ticket.Value, sector.Ticket.Epoch, sector.Seed.Value, sector.Seed.Epoch, sector.pieceInfos(), sector.CommR, sector.CommD) + log.Infof("KOMIT %d %x(%d); %x(%d); %v; r:%x; d:%x", sector.SectorID, sector.TicketValue, sector.TicketEpoch, sector.SeedValue, sector.SeedEpoch, sector.pieceInfos(), sector.CommR, sector.CommD) cids := storage.SectorCids{ Unsealed: *sector.CommD, Sealed: *sector.CommR, } - c2in, err := m.sealer.SealCommit1(ctx.Context(), m.minerSector(sector.SectorID), sector.Ticket.Value, sector.Seed.Value, sector.pieceInfos(), cids) + c2in, err := m.sealer.SealCommit1(ctx.Context(), m.minerSector(sector.SectorID), sector.TicketValue, sector.SeedValue, sector.pieceInfos(), cids) if err != nil { return ctx.Send(SectorComputeProofFailed{xerrors.Errorf("computing seal proof failed: %w", err)}) } @@ -221,31 +207,20 @@ func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) Proof: proof, } - enc, aerr := actors.SerializeParams(params) - if aerr != nil { - return ctx.Send(SectorCommitFailed{xerrors.Errorf("could not serialize commit sector parameters: %w", aerr)}) - } - - msg := &types.Message{ - To: m.maddr, - From: m.worker, - Method: builtin.MethodsMiner.ProveCommitSector, - Params: enc, - Value: types.NewInt(0), // TODO: need to ensure sufficient collateral - GasLimit: 1000000, /* i dont know help */ - GasPrice: types.NewInt(1), + enc := new(bytes.Buffer) + if err := params.MarshalCBOR(enc); err != nil { + return ctx.Send(SectorCommitFailed{xerrors.Errorf("could not serialize commit sector parameters: %w", err)}) } // TODO: check seed / ticket are up to date - - smsg, err := m.api.MpoolPushMessage(ctx.Context(), msg) + mcid, err := m.api.SendMsg(ctx.Context(), m.worker, m.maddr, builtin.MethodsMiner.ProveCommitSector, big.NewInt(0), big.NewInt(1), 1000000, enc.Bytes()) if err != nil { return ctx.Send(SectorCommitFailed{xerrors.Errorf("pushing message to mpool: %w", err)}) } return ctx.Send(SectorCommitted{ Proof: proof, - Message: smsg.Cid(), + Message: mcid, }) } @@ -261,7 +236,7 @@ func (m *Sealing) handleCommitWait(ctx statemachine.Context, sector SectorInfo) } if mw.Receipt.ExitCode != 0 { - return ctx.Send(SectorCommitFailed{xerrors.Errorf("submitting sector proof failed (exit=%d, msg=%s) (t:%x; s:%x(%d); p:%x)", mw.Receipt.ExitCode, sector.CommitMessage, sector.Ticket.Value, sector.Seed.Value, sector.Seed.Epoch, sector.Proof)}) + return ctx.Send(SectorCommitFailed{xerrors.Errorf("submitting sector proof failed (exit=%d, msg=%s) (t:%x; s:%x(%d); p:%x)", mw.Receipt.ExitCode, sector.CommitMessage, sector.TicketValue, sector.SeedValue, sector.SeedEpoch, sector.Proof)}) } return ctx.Send(SectorProving{}) @@ -284,30 +259,22 @@ func (m *Sealing) handleFaulty(ctx statemachine.Context, sector SectorInfo) erro bf := abi.NewBitField() bf.Set(uint64(sector.SectorID)) - enc, aerr := actors.SerializeParams(&miner.DeclareTemporaryFaultsParams{ + params := &miner.DeclareTemporaryFaultsParams{ SectorNumbers: bf, Duration: 99999999, // TODO: This is very unlikely to be the correct number - }) - if aerr != nil { - return xerrors.Errorf("failed to serialize declare fault params: %w", aerr) } - msg := &types.Message{ - To: m.maddr, - From: m.worker, - Method: builtin.MethodsMiner.DeclareTemporaryFaults, - Params: enc, - Value: types.NewInt(0), // TODO: need to ensure sufficient collateral - GasLimit: 1000000, /* i dont know help */ - GasPrice: types.NewInt(1), + enc := new(bytes.Buffer) + if err := params.MarshalCBOR(enc); err != nil { + return ctx.Send(SectorCommitFailed{xerrors.Errorf("failed to serialize declare fault params: %w", err)}) } - smsg, err := m.api.MpoolPushMessage(ctx.Context(), msg) + mcid, err := m.api.SendMsg(ctx.Context(), m.worker, m.maddr, builtin.MethodsMiner.DeclareTemporaryFaults, big.NewInt(0), big.NewInt(1), 1000000, enc.Bytes()) if err != nil { return xerrors.Errorf("failed to push declare faults message to network: %w", err) } - return ctx.Send(SectorFaultReported{reportMsg: smsg.Cid()}) + return ctx.Send(SectorFaultReported{reportMsg: mcid}) } func (m *Sealing) handleFaultReported(ctx statemachine.Context, sector SectorInfo) error { diff --git a/states_failed.go b/states_failed.go index c7b563923..4879b52fd 100644 --- a/states_failed.go +++ b/states_failed.go @@ -1,17 +1,12 @@ package sealing import ( - "bytes" "time" + "golang.org/x/xerrors" + "github.com/filecoin-project/go-statemachine" "github.com/filecoin-project/specs-actors/actors/builtin/miner" - "github.com/filecoin-project/specs-actors/actors/util/adt" - "golang.org/x/xerrors" - - "github.com/filecoin-project/lotus/api/apibstore" - "github.com/filecoin-project/lotus/chain/store" - "github.com/filecoin-project/lotus/chain/types" ) const minRetryTime = 1 * time.Minute @@ -33,36 +28,22 @@ func failedCooldown(ctx statemachine.Context, sector SectorInfo) error { } func (m *Sealing) checkPreCommitted(ctx statemachine.Context, sector SectorInfo) (*miner.SectorPreCommitOnChainInfo, bool) { - act, err := m.api.StateGetActor(ctx.Context(), m.maddr, types.EmptyTSK) + tok, _, err := m.api.ChainHead(ctx.Context()) if err != nil { log.Errorf("handleSealFailed(%d): temp error: %+v", sector.SectorID, err) return nil, true } - st, err := m.api.ChainReadObj(ctx.Context(), act.Head) + info, err := m.api.StateGetSectorPreCommitOnChainInfo(ctx.Context(), m.maddr, sector.SectorID, tok) if err != nil { log.Errorf("handleSealFailed(%d): temp error: %+v", sector.SectorID, err) return nil, true } - var state miner.State - if err := state.UnmarshalCBOR(bytes.NewReader(st)); err != nil { - log.Errorf("handleSealFailed(%d): temp error: unmarshaling miner state: %+v", sector.SectorID, err) - return nil, true - } - - var pci miner.SectorPreCommitOnChainInfo - precommits := adt.AsMap(store.ActorStore(ctx.Context(), apibstore.NewAPIBlockstore(m.api)), state.PreCommittedSectors) - if _, err := precommits.Get(adt.UIntKey(uint64(sector.SectorID)), &pci); err != nil { - log.Error(err) - return nil, true - } - - return &pci, false + return info, false } func (m *Sealing) handleSealFailed(ctx statemachine.Context, sector SectorInfo) error { - if _, is := m.checkPreCommitted(ctx, sector); is { // TODO: Remove this after we can re-precommit return nil // noop, for now @@ -76,7 +57,7 @@ func (m *Sealing) handleSealFailed(ctx statemachine.Context, sector SectorInfo) } func (m *Sealing) handlePreCommitFailed(ctx statemachine.Context, sector SectorInfo) error { - if err := checkPrecommit(ctx.Context(), m.maddr, sector, m.api); err != nil { + if err := checkPrecommit(ctx.Context(), m.Address(), sector, m.api); err != nil { switch err.(type) { case *ErrApi: log.Errorf("handlePreCommitFailed: api error, not proceeding: %+v", err) diff --git a/types.go b/types.go index 294802ef0..4b2a6396a 100644 --- a/types.go +++ b/types.go @@ -5,7 +5,7 @@ import ( "github.com/filecoin-project/specs-storage/storage" "github.com/ipfs/go-cid" - "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/specs-actors/actors/abi" ) type Piece struct { @@ -26,9 +26,9 @@ type Log struct { } type SectorInfo struct { - State api.SectorState - SectorID abi.SectorNumber - Nonce uint64 // TODO: remove + State SectorState + SectorID abi.SectorNumber // TODO: this field's name should be changed to SectorNumber + Nonce uint64 // TODO: remove SectorType abi.RegisteredProof @@ -37,7 +37,8 @@ type SectorInfo struct { Pieces []Piece // PreCommit1 - Ticket api.SealTicket + TicketValue abi.SealRandomness + TicketEpoch abi.ChainEpoch PreCommit1Out storage.PreCommit1Out // PreCommit2 @@ -48,7 +49,8 @@ type SectorInfo struct { PreCommitMessage *cid.Cid // WaitSeed - Seed api.SealSeed + SeedValue abi.InteractiveSealRandomness + SeedEpoch abi.ChainEpoch // Committing CommitMessage *cid.Cid diff --git a/types_test.go b/types_test.go index 93bffc20c..7270c49a7 100644 --- a/types_test.go +++ b/types_test.go @@ -4,12 +4,11 @@ import ( "bytes" "testing" - "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/specs-actors/actors/builtin" "gotest.tools/assert" cborutil "github.com/filecoin-project/go-cbor-util" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin" ) func TestSectorInfoSelialization(t *testing.T) { @@ -26,15 +25,14 @@ func TestSectorInfoSelialization(t *testing.T) { Size: 5, CommP: dummyCid, }}, - CommD: &dummyCid, - CommR: nil, - Proof: nil, - Ticket: api.SealTicket{ - Epoch: 345, - Value: []byte{87, 78, 7, 87}, - }, + CommD: &dummyCid, + CommR: nil, + Proof: nil, + TicketValue: []byte{87, 78, 7, 87}, + TicketEpoch: 345, PreCommitMessage: nil, - Seed: api.SealSeed{}, + SeedValue: []byte{}, + SeedEpoch: 0, CommitMessage: nil, FaultReportMsg: nil, LastErr: "hi", @@ -56,7 +54,8 @@ func TestSectorInfoSelialization(t *testing.T) { assert.Equal(t, si.Pieces, si2.Pieces) assert.Equal(t, si.CommD, si2.CommD) - assert.Equal(t, si.Ticket, si2.Ticket) + assert.Equal(t, si.TicketValue, si2.TicketValue) + assert.Equal(t, si.TicketEpoch, si2.TicketEpoch) assert.Equal(t, si, si2) diff --git a/utils.go b/utils.go index cfc17734c..b507907fb 100644 --- a/utils.go +++ b/utils.go @@ -1,8 +1,9 @@ package sealing import ( - "github.com/filecoin-project/specs-actors/actors/abi" "math/bits" + + "github.com/filecoin-project/specs-actors/actors/abi" ) func fillersFromRem(in abi.UnpaddedPieceSize) ([]abi.UnpaddedPieceSize, error) { From 70615df273a62ae27a2d197571097d5faa6586fd Mon Sep 17 00:00:00 2001 From: laser Date: Mon, 6 Apr 2020 13:23:37 -0700 Subject: [PATCH 118/126] miscellaneous fixes post-rebase --- cbor_gen.go | 1114 +---------------------------------------------- checks.go | 26 +- fsm.go | 78 ++-- fsm_events.go | 3 - fsm_test.go | 19 +- sealing.go | 32 +- sector_state.go | 87 +--- states.go | 11 +- types.go | 38 +- 9 files changed, 127 insertions(+), 1281 deletions(-) diff --git a/cbor_gen.go b/cbor_gen.go index d97cebd74..410936f50 100644 --- a/cbor_gen.go +++ b/cbor_gen.go @@ -3,1137 +3,35 @@ package sealing import ( - "fmt" "io" - "github.com/filecoin-project/specs-actors/actors/abi" - cbg "github.com/whyrusleeping/cbor-gen" xerrors "golang.org/x/xerrors" ) var _ = xerrors.Errorf func (t *Piece) MarshalCBOR(w io.Writer) error { - if t == nil { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{163}); err != nil { - return err - } - - // t.DealID (abi.DealID) (uint64) - if len("DealID") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"DealID\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("DealID")))); err != nil { - return err - } - if _, err := w.Write([]byte("DealID")); err != nil { - return err - } - - if t.DealID == nil { - if _, err := w.Write(cbg.CborNull); err != nil { - return err - } - } else { - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(*t.DealID))); err != nil { - return err - } - } - - // t.Size (abi.UnpaddedPieceSize) (uint64) - if len("Size") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"Size\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Size")))); err != nil { - return err - } - if _, err := w.Write([]byte("Size")); err != nil { - return err - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Size))); err != nil { - return err - } - - // t.CommP (cid.Cid) (struct) - if len("CommP") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"CommP\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("CommP")))); err != nil { - return err - } - if _, err := w.Write([]byte("CommP")); err != nil { - return err - } - - if err := cbg.WriteCid(w, t.CommP); err != nil { - return xerrors.Errorf("failed to write cid field t.CommP: %w", err) - } - return nil + } func (t *Piece) UnmarshalCBOR(r io.Reader) error { - br := cbg.GetPeeker(r) - - maj, extra, err := cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajMap { - return fmt.Errorf("cbor input should be of type map") - } - - if extra > cbg.MaxLength { - return fmt.Errorf("Piece: map struct too large (%d)", extra) - } - - var name string - n := extra - - for i := uint64(0); i < n; i++ { - - { - sval, err := cbg.ReadString(br) - if err != nil { - return err - } - - name = string(sval) - } - - switch name { - // t.DealID (abi.DealID) (uint64) - case "DealID": - - { - - 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 { - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - typed := abi.DealID(extra) - t.DealID = &typed - } - - } - // t.Size (abi.UnpaddedPieceSize) (uint64) - case "Size": - - { - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.Size = abi.UnpaddedPieceSize(extra) - - } - // t.CommP (cid.Cid) (struct) - case "CommP": - - { - - c, err := cbg.ReadCid(br) - if err != nil { - return xerrors.Errorf("failed to read cid field t.CommP: %w", err) - } - - t.CommP = c - - } - - default: - return fmt.Errorf("unknown struct field %d: '%s'", i, name) - } - } - return nil + } func (t *SectorInfo) MarshalCBOR(w io.Writer) error { - if t == nil { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{177}); err != nil { - return err - } - - // t.State (uint64) (uint64) - if len("State") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"State\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("State")))); err != nil { - return err - } - if _, err := w.Write([]byte("State")); err != nil { - return err - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.State))); err != nil { - return err - } - - // t.SectorID (abi.SectorNumber) (uint64) - if len("SectorID") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"SectorID\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("SectorID")))); err != nil { - return err - } - if _, err := w.Write([]byte("SectorID")); err != nil { - return err - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SectorID))); err != nil { - return err - } - - // t.Nonce (uint64) (uint64) - if len("Nonce") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"Nonce\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Nonce")))); err != nil { - return err - } - if _, err := w.Write([]byte("Nonce")); err != nil { - return err - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Nonce))); err != nil { - return err - } - - // t.SectorType (abi.RegisteredProof) (int64) - if len("SectorType") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"SectorType\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("SectorType")))); err != nil { - return err - } - if _, err := w.Write([]byte("SectorType")); err != nil { - return err - } - - if t.SectorType >= 0 { - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SectorType))); err != nil { - return err - } - } else { - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajNegativeInt, uint64(-t.SectorType)-1)); err != nil { - return err - } - } - - // t.Pieces ([]sealing.Piece) (slice) - if len("Pieces") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"Pieces\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Pieces")))); err != nil { - return err - } - if _, err := w.Write([]byte("Pieces")); err != nil { - return err - } - - if len(t.Pieces) > cbg.MaxLength { - return xerrors.Errorf("Slice value in field t.Pieces was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Pieces)))); err != nil { - return err - } - for _, v := range t.Pieces { - if err := v.MarshalCBOR(w); err != nil { - return err - } - } - - // t.CommD (cid.Cid) (struct) - if len("CommD") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"CommD\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("CommD")))); err != nil { - return err - } - if _, err := w.Write([]byte("CommD")); err != nil { - return err - } - - if t.CommD == nil { - if _, err := w.Write(cbg.CborNull); err != nil { - return err - } - } else { - if err := cbg.WriteCid(w, *t.CommD); err != nil { - return xerrors.Errorf("failed to write cid field t.CommD: %w", err) - } - } - - // t.CommR (cid.Cid) (struct) - if len("CommR") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"CommR\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("CommR")))); err != nil { - return err - } - if _, err := w.Write([]byte("CommR")); err != nil { - return err - } - - if t.CommR == nil { - if _, err := w.Write(cbg.CborNull); err != nil { - return err - } - } else { - if err := cbg.WriteCid(w, *t.CommR); err != nil { - return xerrors.Errorf("failed to write cid field t.CommR: %w", err) - } - } - - // t.Proof ([]uint8) (slice) - if len("Proof") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"Proof\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Proof")))); err != nil { - return err - } - if _, err := w.Write([]byte("Proof")); err != nil { - return err - } - - if len(t.Proof) > cbg.ByteArrayMaxLen { - return xerrors.Errorf("Byte array in field t.Proof was too long") - } - - 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.TicketValue (abi.SealRandomness) (slice) - if len("TicketValue") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"TicketValue\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("TicketValue")))); err != nil { - return err - } - if _, err := w.Write([]byte("TicketValue")); err != nil { - return err - } - - if len(t.TicketValue) > cbg.ByteArrayMaxLen { - return xerrors.Errorf("Byte array in field t.TicketValue was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.TicketValue)))); err != nil { - return err - } - if _, err := w.Write(t.TicketValue); err != nil { - return err - } - - // t.TicketEpoch (abi.ChainEpoch) (int64) - if len("TicketEpoch") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"TicketEpoch\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("TicketEpoch")))); err != nil { - return err - } - if _, err := w.Write([]byte("TicketEpoch")); err != nil { - return err - } - - if t.TicketEpoch >= 0 { - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.TicketEpoch))); err != nil { - return err - } - } else { - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajNegativeInt, uint64(-t.TicketEpoch)-1)); err != nil { - return err - } - } - - // t.PreCommitMessage (cid.Cid) (struct) - if len("PreCommitMessage") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"PreCommitMessage\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("PreCommitMessage")))); err != nil { - return err - } - if _, err := w.Write([]byte("PreCommitMessage")); err != nil { - return err - } - - if t.PreCommitMessage == nil { - if _, err := w.Write(cbg.CborNull); err != nil { - return err - } - } else { - if err := cbg.WriteCid(w, *t.PreCommitMessage); err != nil { - return xerrors.Errorf("failed to write cid field t.PreCommitMessage: %w", err) - } - } - - // t.SeedValue (abi.InteractiveSealRandomness) (slice) - if len("SeedValue") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"SeedValue\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("SeedValue")))); err != nil { - return err - } - if _, err := w.Write([]byte("SeedValue")); err != nil { - return err - } - - if len(t.SeedValue) > cbg.ByteArrayMaxLen { - return xerrors.Errorf("Byte array in field t.SeedValue was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.SeedValue)))); err != nil { - return err - } - if _, err := w.Write(t.SeedValue); err != nil { - return err - } - - // t.SeedEpoch (abi.ChainEpoch) (int64) - if len("SeedEpoch") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"SeedEpoch\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("SeedEpoch")))); err != nil { - return err - } - if _, err := w.Write([]byte("SeedEpoch")); err != nil { - return err - } - - if t.SeedEpoch >= 0 { - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SeedEpoch))); err != nil { - return err - } - } else { - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajNegativeInt, uint64(-t.SeedEpoch)-1)); err != nil { - return err - } - } - - // t.CommitMessage (cid.Cid) (struct) - if len("CommitMessage") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"CommitMessage\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("CommitMessage")))); err != nil { - return err - } - if _, err := w.Write([]byte("CommitMessage")); err != nil { - return err - } - - if t.CommitMessage == nil { - if _, err := w.Write(cbg.CborNull); err != nil { - return err - } - } else { - if err := cbg.WriteCid(w, *t.CommitMessage); err != nil { - return xerrors.Errorf("failed to write cid field t.CommitMessage: %w", err) - } - } - - // t.FaultReportMsg (cid.Cid) (struct) - if len("FaultReportMsg") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"FaultReportMsg\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("FaultReportMsg")))); err != nil { - return err - } - if _, err := w.Write([]byte("FaultReportMsg")); err != nil { - return err - } - - if t.FaultReportMsg == nil { - if _, err := w.Write(cbg.CborNull); err != nil { - return err - } - } else { - if err := cbg.WriteCid(w, *t.FaultReportMsg); err != nil { - return xerrors.Errorf("failed to write cid field t.FaultReportMsg: %w", err) - } - } - - // t.LastErr (string) (string) - if len("LastErr") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"LastErr\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("LastErr")))); err != nil { - return err - } - if _, err := w.Write([]byte("LastErr")); err != nil { - return err - } - - if len(t.LastErr) > cbg.MaxLength { - return xerrors.Errorf("Value in field t.LastErr was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.LastErr)))); err != nil { - return err - } - if _, err := w.Write([]byte(t.LastErr)); err != nil { - return err - } - - // t.Log ([]sealing.Log) (slice) - if len("Log") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"Log\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Log")))); err != nil { - return err - } - if _, err := w.Write([]byte("Log")); err != nil { - return err - } - - if len(t.Log) > cbg.MaxLength { - return xerrors.Errorf("Slice value in field t.Log was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Log)))); err != nil { - return err - } - for _, v := range t.Log { - if err := v.MarshalCBOR(w); err != nil { - return err - } - } return nil + } - -func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { - br := cbg.GetPeeker(r) - - maj, extra, err := cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajMap { - return fmt.Errorf("cbor input should be of type map") - } - - if extra > cbg.MaxLength { - return fmt.Errorf("SectorInfo: map struct too large (%d)", extra) - } - - var name string - n := extra - - for i := uint64(0); i < n; i++ { - - { - sval, err := cbg.ReadString(br) - if err != nil { - return err - } - - name = string(sval) - } - - switch name { - // t.State (uint64) (uint64) - case "State": - - { - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.State = uint64(extra) - - } - // t.SectorID (abi.SectorNumber) (uint64) - case "SectorID": - - { - - 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 = abi.SectorNumber(extra) - - } - // t.Nonce (uint64) (uint64) - case "Nonce": - - { - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.Nonce = uint64(extra) - - } - // t.SectorType (abi.RegisteredProof) (int64) - case "SectorType": - { - maj, extra, err := cbg.CborReadHeader(br) - var extraI int64 - if err != nil { - return err - } - switch maj { - case cbg.MajUnsignedInt: - extraI = int64(extra) - if extraI < 0 { - return fmt.Errorf("int64 positive overflow") - } - case cbg.MajNegativeInt: - extraI = int64(extra) - if extraI < 0 { - return fmt.Errorf("int64 negative oveflow") - } - extraI = -1 - extraI - default: - return fmt.Errorf("wrong type for int64 field: %d", maj) - } - - t.SectorType = abi.RegisteredProof(extraI) - } - // t.Pieces ([]sealing.Piece) (slice) - case "Pieces": - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.MaxLength { - return fmt.Errorf("t.Pieces: array too large (%d)", extra) - } - - if maj != cbg.MajArray { - return fmt.Errorf("expected cbor array") - } - if extra > 0 { - t.Pieces = make([]Piece, extra) - } - for i := 0; i < int(extra); i++ { - - var v Piece - if err := v.UnmarshalCBOR(br); err != nil { - return err - } - - t.Pieces[i] = v - } - - // t.CommD (cid.Cid) (struct) - case "CommD": - - { - - 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 { - - c, err := cbg.ReadCid(br) - if err != nil { - return xerrors.Errorf("failed to read cid field t.CommD: %w", err) - } - - t.CommD = &c - } - - } - // t.CommR (cid.Cid) (struct) - case "CommR": - - { - - 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 { - - c, err := cbg.ReadCid(br) - if err != nil { - return xerrors.Errorf("failed to read cid field t.CommR: %w", err) - } - - t.CommR = &c - } - - } - // t.Proof ([]uint8) (slice) - case "Proof": - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.ByteArrayMaxLen { - return fmt.Errorf("t.Proof: byte 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.TicketValue (abi.SealRandomness) (slice) - case "TicketValue": - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.ByteArrayMaxLen { - return fmt.Errorf("t.TicketValue: byte array too large (%d)", extra) - } - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") - } - t.TicketValue = make([]byte, extra) - if _, err := io.ReadFull(br, t.TicketValue); err != nil { - return err - } - // t.TicketEpoch (abi.ChainEpoch) (int64) - case "TicketEpoch": - { - maj, extra, err := cbg.CborReadHeader(br) - var extraI int64 - if err != nil { - return err - } - switch maj { - case cbg.MajUnsignedInt: - extraI = int64(extra) - if extraI < 0 { - return fmt.Errorf("int64 positive overflow") - } - case cbg.MajNegativeInt: - extraI = int64(extra) - if extraI < 0 { - return fmt.Errorf("int64 negative oveflow") - } - extraI = -1 - extraI - default: - return fmt.Errorf("wrong type for int64 field: %d", maj) - } - - t.TicketEpoch = abi.ChainEpoch(extraI) - } - // t.PreCommitMessage (cid.Cid) (struct) - case "PreCommitMessage": - - { - - 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 { - - c, err := cbg.ReadCid(br) - if err != nil { - return xerrors.Errorf("failed to read cid field t.PreCommitMessage: %w", err) - } - - t.PreCommitMessage = &c - } - - } - // t.SeedValue (abi.InteractiveSealRandomness) (slice) - case "SeedValue": - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.ByteArrayMaxLen { - return fmt.Errorf("t.SeedValue: byte array too large (%d)", extra) - } - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") - } - t.SeedValue = make([]byte, extra) - if _, err := io.ReadFull(br, t.SeedValue); err != nil { - return err - } - // t.SeedEpoch (abi.ChainEpoch) (int64) - case "SeedEpoch": - { - maj, extra, err := cbg.CborReadHeader(br) - var extraI int64 - if err != nil { - return err - } - switch maj { - case cbg.MajUnsignedInt: - extraI = int64(extra) - if extraI < 0 { - return fmt.Errorf("int64 positive overflow") - } - case cbg.MajNegativeInt: - extraI = int64(extra) - if extraI < 0 { - return fmt.Errorf("int64 negative oveflow") - } - extraI = -1 - extraI - default: - return fmt.Errorf("wrong type for int64 field: %d", maj) - } - - t.SeedEpoch = abi.ChainEpoch(extraI) - } - // t.CommitMessage (cid.Cid) (struct) - case "CommitMessage": - - { - - 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 { - - c, err := cbg.ReadCid(br) - if err != nil { - return xerrors.Errorf("failed to read cid field t.CommitMessage: %w", err) - } - - t.CommitMessage = &c - } - - } - // t.FaultReportMsg (cid.Cid) (struct) - case "FaultReportMsg": - - { - - 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 { - - c, err := cbg.ReadCid(br) - if err != nil { - return xerrors.Errorf("failed to read cid field t.FaultReportMsg: %w", err) - } - - t.FaultReportMsg = &c - } - - } - // t.LastErr (string) (string) - case "LastErr": - - { - sval, err := cbg.ReadString(br) - if err != nil { - return err - } - - t.LastErr = string(sval) - } - // t.Log ([]sealing.Log) (slice) - case "Log": - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - - if extra > cbg.MaxLength { - return fmt.Errorf("t.Log: array too large (%d)", extra) - } - - if maj != cbg.MajArray { - return fmt.Errorf("expected cbor array") - } - if extra > 0 { - t.Log = make([]Log, extra) - } - for i := 0; i < int(extra); i++ { - - var v Log - if err := v.UnmarshalCBOR(br); err != nil { - return err - } - - t.Log[i] = v - } - - default: - return fmt.Errorf("unknown struct field %d: '%s'", i, name) - } - } - +func (t *SectorInfo) UnmarshalCBOR(w io.Reader) error { return nil + } func (t *Log) MarshalCBOR(w io.Writer) error { - if t == nil { - _, err := w.Write(cbg.CborNull) - return err - } - if _, err := w.Write([]byte{164}); err != nil { - return err - } - - // t.Timestamp (uint64) (uint64) - if len("Timestamp") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"Timestamp\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Timestamp")))); err != nil { - return err - } - if _, err := w.Write([]byte("Timestamp")); err != nil { - return err - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Timestamp))); err != nil { - return err - } - - // t.Trace (string) (string) - if len("Trace") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"Trace\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Trace")))); err != nil { - return err - } - if _, err := w.Write([]byte("Trace")); err != nil { - return err - } - - if len(t.Trace) > cbg.MaxLength { - return xerrors.Errorf("Value in field t.Trace was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.Trace)))); err != nil { - return err - } - if _, err := w.Write([]byte(t.Trace)); err != nil { - return err - } - - // t.Message (string) (string) - if len("Message") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"Message\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Message")))); err != nil { - return err - } - if _, err := w.Write([]byte("Message")); err != nil { - return err - } - - if len(t.Message) > cbg.MaxLength { - return xerrors.Errorf("Value in field t.Message was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.Message)))); err != nil { - return err - } - if _, err := w.Write([]byte(t.Message)); err != nil { - return err - } - - // t.Kind (string) (string) - if len("Kind") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"Kind\" was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Kind")))); err != nil { - return err - } - if _, err := w.Write([]byte("Kind")); err != nil { - return err - } - - if len(t.Kind) > cbg.MaxLength { - return xerrors.Errorf("Value in field t.Kind was too long") - } - - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.Kind)))); err != nil { - return err - } - if _, err := w.Write([]byte(t.Kind)); err != nil { - return err - } return nil } func (t *Log) UnmarshalCBOR(r io.Reader) error { - br := cbg.GetPeeker(r) - - maj, extra, err := cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajMap { - return fmt.Errorf("cbor input should be of type map") - } - - if extra > cbg.MaxLength { - return fmt.Errorf("Log: map struct too large (%d)", extra) - } - - var name string - n := extra - - for i := uint64(0); i < n; i++ { - - { - sval, err := cbg.ReadString(br) - if err != nil { - return err - } - - name = string(sval) - } - - switch name { - // t.Timestamp (uint64) (uint64) - case "Timestamp": - - { - - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") - } - t.Timestamp = uint64(extra) - - } - // t.Trace (string) (string) - case "Trace": - - { - sval, err := cbg.ReadString(br) - if err != nil { - return err - } - - t.Trace = string(sval) - } - // t.Message (string) (string) - case "Message": - - { - sval, err := cbg.ReadString(br) - if err != nil { - return err - } - - t.Message = string(sval) - } - // t.Kind (string) (string) - case "Kind": - - { - sval, err := cbg.ReadString(br) - if err != nil { - return err - } - - t.Kind = string(sval) - } - - default: - return fmt.Errorf("unknown struct field %d: '%s'", i, name) - } - } - return nil + } diff --git a/checks.go b/checks.go index 2721c8333..ff1572cf2 100644 --- a/checks.go +++ b/checks.go @@ -6,13 +6,11 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/go-address" - "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/sector-storage/ffiwrapper" "github.com/filecoin-project/sector-storage/zerocomm" "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/builtin/miner" "github.com/filecoin-project/specs-actors/actors/crypto" - log "github.com/mgutz/logxi/v1" ) // TODO: For now we handle this by halting state execution, when we get jsonrpc reconnecting @@ -94,34 +92,34 @@ func checkPrecommit(ctx context.Context, maddr address.Address, si SectorInfo, a } func (m *Sealing) checkCommit(ctx context.Context, si SectorInfo, proof []byte) (err error) { - tok, height, err := m.api.ChainHead(ctx) + tok, _, err := m.api.ChainHead(ctx) if err != nil { return &ErrApi{xerrors.Errorf("getting chain head: %w", err)} } - if si.Seed.Epoch == 0 { + if si.SeedEpoch == 0 { return &ErrBadSeed{xerrors.Errorf("seed epoch was not set")} } - pci, err := m.api.StateSectorPreCommitInfo(ctx, m.maddr, si.SectorID, types.EmptyTSK) + pci, err := m.api.StateGetSectorPreCommitOnChainInfo(ctx, m.maddr, si.SectorID, tok) if err != nil { return xerrors.Errorf("getting precommit info: %w", err) } - if pci.PreCommitEpoch+miner.PreCommitChallengeDelay != si.Seed.Epoch { - return &ErrBadSeed{xerrors.Errorf("seed epoch doesn't match on chain info: %d != %d", pci.PreCommitEpoch+miner.PreCommitChallengeDelay, si.Seed.Epoch)} + if pci.PreCommitEpoch+miner.PreCommitChallengeDelay != si.SeedEpoch { + return &ErrBadSeed{xerrors.Errorf("seed epoch doesn't match on chain info: %d != %d", pci.PreCommitEpoch+miner.PreCommitChallengeDelay, si.SeedEpoch)} } - seed, err := m.api.ChainGetRandomness(ctx, head.Key(), crypto.DomainSeparationTag_InteractiveSealChallengeSeed, si.Seed.Epoch, nil) + seed, err := m.api.ChainGetRandomness(ctx, tok, crypto.DomainSeparationTag_InteractiveSealChallengeSeed, si.SeedEpoch, nil) if err != nil { return &ErrApi{xerrors.Errorf("failed to get randomness for computing seal proof: %w", err)} } - if string(seed) != string(si.Seed.Value) { + if string(seed) != string(si.SeedValue) { return &ErrBadSeed{xerrors.Errorf("seed has changed")} } - ss, err := m.api.StateMinerSectorSize(ctx, m.maddr, head.Key()) + ss, err := m.api.StateMinerSectorSize(ctx, m.maddr, tok) if err != nil { return &ErrApi{err} } @@ -138,14 +136,14 @@ func (m *Sealing) checkCommit(ctx context.Context, si SectorInfo, proof []byte) SectorID: m.minerSector(si.SectorID), OnChain: abi.OnChainSealVerifyInfo{ SealedCID: pci.Info.SealedCID, - InteractiveEpoch: si.Seed.Epoch, + InteractiveEpoch: si.SeedEpoch, RegisteredProof: spt, Proof: proof, SectorNumber: si.SectorID, - SealRandEpoch: si.Ticket.Epoch, + SealRandEpoch: si.TicketEpoch, }, - Randomness: si.Ticket.Value, - InteractiveRandomness: si.Seed.Value, + Randomness: si.TicketValue, + InteractiveRandomness: si.SeedValue, UnsealedCID: *si.CommD, }) if err != nil { diff --git a/fsm.go b/fsm.go index 88be53eff..e03ab7bd8 100644 --- a/fsm.go +++ b/fsm.go @@ -11,9 +11,7 @@ import ( "golang.org/x/xerrors" statemachine "github.com/filecoin-project/go-statemachine" - "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/prometheus/common/log" ) func (m *Sealing) Plan(events []statemachine.Event, user interface{}) (interface{}, uint64, error) { @@ -33,27 +31,27 @@ func (m *Sealing) Plan(events []statemachine.Event, user interface{}) (interface }, uint64(len(events)), nil // TODO: This processed event count is not very correct } -var fsmPlanners = map[api.SectorState]func(events []statemachine.Event, state *SectorInfo) error{ - api.UndefinedSectorState: planOne(on(SectorStart{}, api.Packing)), - api.Packing: planOne(on(SectorPacked{}, api.PreCommit1)), - api.PreCommit1: planOne( - on(SectorPreCommit1{}, api.PreCommit2), - on(SectorSealPreCommitFailed{}, api.SealFailed), - on(SectorPackingFailed{}, api.PackingFailed), +var fsmPlanners = map[SectorState]func(events []statemachine.Event, state *SectorInfo) error{ + UndefinedSectorState: planOne(on(SectorStart{}, Packing)), + Packing: planOne(on(SectorPacked{}, PreCommit1)), + PreCommit1: planOne( + on(SectorPreCommit1{}, PreCommit2), + on(SectorSealPreCommitFailed{}, SealFailed), + on(SectorPackingFailed{}, PackingFailed), ), - api.PreCommit2: planOne( - on(SectorPreCommit2{}, api.PreCommitting), - on(SectorSealPreCommitFailed{}, api.SealFailed), - on(SectorPackingFailed{}, api.PackingFailed), + PreCommit2: planOne( + on(SectorPreCommit2{}, PreCommitting), + on(SectorSealPreCommitFailed{}, SealFailed), + on(SectorPackingFailed{}, PackingFailed), ), - api.PreCommitting: planOne( - on(SectorSealPreCommitFailed{}, api.SealFailed), - on(SectorPreCommitted{}, api.WaitSeed), - on(SectorChainPreCommitFailed{}, api.PreCommitFailed), + PreCommitting: planOne( + on(SectorSealPreCommitFailed{}, SealFailed), + on(SectorPreCommitted{}, WaitSeed), + on(SectorChainPreCommitFailed{}, PreCommitFailed), ), - api.WaitSeed: planOne( - on(SectorSeedReady{}, api.Committing), - on(SectorChainPreCommitFailed{}, api.PreCommitFailed), + WaitSeed: planOne( + on(SectorSeedReady{}, Committing), + on(SectorChainPreCommitFailed{}, PreCommitFailed), ), Committing: planCommitting, CommitWait: planOne( @@ -70,22 +68,22 @@ var fsmPlanners = map[api.SectorState]func(events []statemachine.Event, state *S on(SectorFaulty{}, Faulty), ), - api.SealFailed: planOne( - on(SectorRetrySeal{}, api.PreCommit1), + SealFailed: planOne( + on(SectorRetrySeal{}, PreCommit1), ), - api.PreCommitFailed: planOne( - on(SectorRetryPreCommit{}, api.PreCommitting), - on(SectorRetryWaitSeed{}, api.WaitSeed), - on(SectorSealPreCommitFailed{}, api.SealFailed), + PreCommitFailed: planOne( + on(SectorRetryPreCommit{}, PreCommitting), + on(SectorRetryWaitSeed{}, WaitSeed), + on(SectorSealPreCommitFailed{}, SealFailed), ), - api.ComputeProofFailed: planOne( - on(SectorRetryComputeProof{}, api.Committing), + ComputeProofFailed: planOne( + on(SectorRetryComputeProof{}, Committing), ), - api.CommitFailed: planOne( - on(SectorSealPreCommitFailed{}, api.SealFailed), - on(SectorRetryWaitSeed{}, api.WaitSeed), - on(SectorRetryComputeProof{}, api.Committing), - on(SectorRetryInvalidProof{}, api.Committing), + CommitFailed: planOne( + on(SectorSealPreCommitFailed{}, SealFailed), + on(SectorRetryWaitSeed{}, WaitSeed), + on(SectorRetryComputeProof{}, Committing), + on(SectorRetryInvalidProof{}, Committing), ), Faulty: planOne( @@ -173,11 +171,11 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta // Happy path case Packing: return m.handlePacking, nil - case api.PreCommit1: + case PreCommit1: return m.handlePreCommit1, nil - case api.PreCommit2: + case PreCommit2: return m.handlePreCommit2, nil - case api.PreCommitting: + case PreCommitting: return m.handlePreCommitting, nil case WaitSeed: return m.handleWaitSeed, nil @@ -196,9 +194,9 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta return m.handleSealFailed, nil case PreCommitFailed: return m.handlePreCommitFailed, nil - case api.ComputeProofFailed: + case ComputeProofFailed: return m.handleComputeProofFailed, nil - case api.CommitFailed: + case CommitFailed: return m.handleCommitFailed, nil // Faults @@ -239,9 +237,9 @@ func planCommitting(events []statemachine.Event, state *SectorInfo) error { state.State = Committing return nil case SectorComputeProofFailed: - state.State = api.ComputeProofFailed + state.State = ComputeProofFailed case SectorSealPreCommitFailed: - state.State = api.CommitFailed + state.State = CommitFailed case SectorCommitFailed: state.State = CommitFailed default: diff --git a/fsm_events.go b/fsm_events.go index 40388ad70..2dee984d5 100644 --- a/fsm_events.go +++ b/fsm_events.go @@ -4,10 +4,7 @@ import ( "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-storage/storage" "github.com/ipfs/go-cid" - "github.com/prometheus/common/log" "golang.org/x/xerrors" - - "github.com/filecoin-project/specs-actors/actors/abi" ) type mutator interface { diff --git a/fsm_test.go b/fsm_test.go index 69c2a99fb..8738d1c59 100644 --- a/fsm_test.go +++ b/fsm_test.go @@ -7,7 +7,6 @@ import ( "github.com/stretchr/testify/require" "github.com/filecoin-project/go-statemachine" - "github.com/filecoin-project/lotus/api" ) func init() { @@ -35,13 +34,13 @@ func TestHappyPath(t *testing.T) { } m.planSingle(SectorPacked{}) - require.Equal(m.t, m.state.State, api.PreCommit1) + require.Equal(m.t, m.state.State, PreCommit1) m.planSingle(SectorPreCommit1{}) - require.Equal(m.t, m.state.State, api.PreCommit2) + require.Equal(m.t, m.state.State, PreCommit2) m.planSingle(SectorPreCommit2{}) - require.Equal(m.t, m.state.State, api.PreCommitting) + require.Equal(m.t, m.state.State, PreCommitting) m.planSingle(SectorPreCommitted{}) require.Equal(m.t, m.state.State, WaitSeed) @@ -67,13 +66,13 @@ func TestSeedRevert(t *testing.T) { } m.planSingle(SectorPacked{}) - require.Equal(m.t, m.state.State, api.PreCommit1) + require.Equal(m.t, m.state.State, PreCommit1) m.planSingle(SectorPreCommit1{}) - require.Equal(m.t, m.state.State, api.PreCommit2) + require.Equal(m.t, m.state.State, PreCommit2) m.planSingle(SectorPreCommit2{}) - require.Equal(m.t, m.state.State, api.PreCommitting) + require.Equal(m.t, m.state.State, PreCommitting) m.planSingle(SectorPreCommitted{}) require.Equal(m.t, m.state.State, WaitSeed) @@ -81,12 +80,12 @@ func TestSeedRevert(t *testing.T) { m.planSingle(SectorSeedReady{}) require.Equal(m.t, m.state.State, Committing) - _, err := m.s.plan([]statemachine.Event{{SectorSeedReady{Seed: SealSeed{Epoch: 5}}}, {SectorCommitted{}}}, m.state) + _, err := m.s.plan([]statemachine.Event{{SectorSeedReady{SeedValue: nil, SeedEpoch: 5}}, {SectorCommitted{}}}, m.state) require.NoError(t, err) require.Equal(m.t, m.state.State, Committing) // not changing the seed this time - _, err = m.s.plan([]statemachine.Event{{SectorSeedReady{Seed: SealSeed{Epoch: 5}}}, {SectorCommitted{}}}, m.state) + _, err = m.s.plan([]statemachine.Event{{SectorSeedReady{SeedValue: nil, SeedEpoch: 5}}, {SectorCommitted{}}}, m.state) require.Equal(m.t, m.state.State, CommitWait) m.planSingle(SectorProving{}) @@ -107,5 +106,5 @@ func TestPlanCommittingHandlesSectorCommitFailed(t *testing.T) { require.NoError(t, planCommitting(events, m.state)) - require.Equal(t, api.CommitFailed, m.state.State) + require.Equal(t, CommitFailed, m.state.State) } diff --git a/sealing.go b/sealing.go index a843650b4..d79ebfc84 100644 --- a/sealing.go +++ b/sealing.go @@ -1,7 +1,6 @@ package sealing import ( - "bytes" "context" "io" @@ -21,46 +20,17 @@ import ( "github.com/filecoin-project/specs-actors/actors/builtin/market" "github.com/filecoin-project/specs-actors/actors/builtin/miner" "github.com/filecoin-project/specs-actors/actors/crypto" - "github.com/filecoin-project/specs-actors/actors/runtime/exitcode" ) const SectorStorePrefix = "/sectors" var log = logging.Logger("sectors") -type TicketFn func(context.Context) (abi.SealRandomness, abi.ChainEpoch, error) - -type SectorIDCounter interface { - Next() (abi.SectorNumber, error) -} - -type TipSetToken []byte - -type MsgLookup struct { - Receipt MessageReceipt - TipSetTok TipSetToken - Height abi.ChainEpoch -} - -type MessageReceipt struct { - ExitCode exitcode.ExitCode - Return []byte - GasUsed int64 -} - -func (mr *MessageReceipt) Equals(o *MessageReceipt) bool { - return mr.ExitCode == o.ExitCode && bytes.Equal(mr.Return, o.Return) && mr.GasUsed == o.GasUsed -} - -type MarketDeal struct { - Proposal market.DealProposal - State market.DealState -} - type SealingAPI interface { StateWaitMsg(context.Context, cid.Cid) (MsgLookup, error) StateComputeDataCommitment(ctx context.Context, maddr address.Address, sectorType abi.RegisteredProof, deals []abi.DealID, tok TipSetToken) (cid.Cid, error) StateGetSectorPreCommitOnChainInfo(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok TipSetToken) (*miner.SectorPreCommitOnChainInfo, error) + StateMinerSectorSize(context.Context, address.Address, TipSetToken) (abi.SectorSize, error) StateMarketStorageDeal(context.Context, abi.DealID, TipSetToken) (market.DealProposal, market.DealState, error) SendMsg(ctx context.Context, from, to address.Address, method abi.MethodNum, value, gasPrice big.Int, gasLimit int64, params []byte) (cid.Cid, error) ChainHead(ctx context.Context) (TipSetToken, abi.ChainEpoch, error) diff --git a/sector_state.go b/sector_state.go index 5477edff8..f2a95ed5a 100644 --- a/sector_state.go +++ b/sector_state.go @@ -1,74 +1,29 @@ package sealing -// alias because cbor-gen doesn't like non-alias types -type SectorState = uint64 +type SectorState string const ( - UndefinedSectorState SectorState = iota + UndefinedSectorState SectorState = "" // happy path - Empty - Packing // sector not in sealStore, and not on chain - - Unsealed // sealing / queued - PreCommitting // on chain pre-commit - WaitSeed // waiting for seed - Committing - CommitWait // waiting for message to land on chain - FinalizeSector - Proving - _ // reserved - _ - _ - - // recovery handling - // Reseal - _ - _ - _ - _ - _ - _ - _ - + Empty SectorState = "Empty" + Packing SectorState = "Packing" // sector not in sealStore, and not on chain + PreCommit1 SectorState = "PreCommit1" // do PreCommit1 + PreCommit2 SectorState = "PreCommit2" // do PreCommit1 + PreCommitting SectorState = "PreCommitting" // on chain pre-commit + WaitSeed SectorState = "WaitSeed" // waiting for seed + Committing SectorState = "Committing" + CommitWait SectorState = "CommitWait" // waiting for message to land on chain + FinalizeSector SectorState = "FinalizeSector" + Proving SectorState = "Proving" // error modes - FailedUnrecoverable - - SealFailed - PreCommitFailed - SealCommitFailed - CommitFailed - PackingFailed - _ - _ - _ - - Faulty // sector is corrupted or gone for some reason - FaultReported // sector has been declared as a fault on chain - FaultedFinal // fault declared on chain + FailedUnrecoverable SectorState = "FailedUnrecoverable" + SealFailed SectorState = "SealFailed" + PreCommitFailed SectorState = "PreCommitFailed" + ComputeProofFailed SectorState = "ComputeProofFailed" + CommitFailed SectorState = "CommitFailed" + PackingFailed SectorState = "PackingFailed" + Faulty SectorState = "Faulty" // sector is corrupted or gone for some reason + FaultReported SectorState = "FaultReported" // sector has been declared as a fault on chain + FaultedFinal SectorState = "FaultedFinal" // fault declared on chain ) - -var SectorStates = []string{ - UndefinedSectorState: "UndefinedSectorState", - Empty: "Empty", - Packing: "Packing", - Unsealed: "Unsealed", - PreCommitting: "PreCommitting", - WaitSeed: "WaitSeed", - Committing: "Committing", - CommitWait: "CommitWait", - FinalizeSector: "FinalizeSector", - Proving: "Proving", - - SealFailed: "SealFailed", - PreCommitFailed: "PreCommitFailed", - SealCommitFailed: "SealCommitFailed", - CommitFailed: "CommitFailed", - PackingFailed: "PackingFailed", - - FailedUnrecoverable: "FailedUnrecoverable", - - Faulty: "Faulty", - FaultReported: "FaultReported", - FaultedFinal: "FaultedFinal", -} diff --git a/states.go b/states.go index 0bd4f767d..907ead6b3 100644 --- a/states.go +++ b/states.go @@ -6,8 +6,7 @@ import ( "golang.org/x/xerrors" - statemachine "github.com/filecoin-project/go-statemachine" - "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/go-statemachine" "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/abi/big" "github.com/filecoin-project/specs-actors/actors/builtin" @@ -146,7 +145,7 @@ func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) er } log.Info("precommit message landed on chain: ", sector.SectorID) - pci, err := m.api.StateSectorPreCommitInfo(ctx.Context(), m.maddr, sector.SectorID, mw.TipSet.Key()) + pci, err := m.api.StateGetSectorPreCommitOnChainInfo(ctx.Context(), m.maddr, sector.SectorID, mw.TipSetTok) if err != nil { return xerrors.Errorf("getting precommit info: %w", err) } @@ -158,18 +157,18 @@ func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) er if err != nil { err = xerrors.Errorf("failed to get randomness for computing seal proof: %w", err) - ctx.Send(SectorFatalError{error: err}) + _ = ctx.Send(SectorFatalError{error: err}) return err } - ctx.Send(SectorSeedReady{SeedValue: abi.InteractiveSealRandomness(rand), SeedEpoch: randHeight}) + _ = ctx.Send(SectorSeedReady{SeedValue: abi.InteractiveSealRandomness(rand), SeedEpoch: randHeight}) return nil }, func(ctx context.Context, ts TipSetToken) error { log.Warn("revert in interactive commit sector step") // TODO: need to cancel running process and restart... return nil - }, build.InteractivePoRepConfidence, randHeight) + }, InteractivePoRepConfidence, randHeight) if err != nil { log.Warn("waitForPreCommitMessage ChainAt errored: ", err) } diff --git a/types.go b/types.go index 4b2a6396a..7edbe7145 100644 --- a/types.go +++ b/types.go @@ -1,11 +1,14 @@ package sealing import ( - "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/specs-storage/storage" - "github.com/ipfs/go-cid" + "bytes" + "context" "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/filecoin-project/specs-actors/actors/builtin/market" + "github.com/filecoin-project/specs-actors/actors/runtime/exitcode" + "github.com/filecoin-project/specs-storage/storage" + "github.com/ipfs/go-cid" ) type Piece struct { @@ -94,3 +97,32 @@ func (t *SectorInfo) existingPieces() []abi.UnpaddedPieceSize { } return out } + +type TicketFn func(context.Context) (abi.SealRandomness, abi.ChainEpoch, error) + +type SectorIDCounter interface { + Next() (abi.SectorNumber, error) +} + +type TipSetToken []byte + +type MsgLookup struct { + Receipt MessageReceipt + TipSetTok TipSetToken + Height abi.ChainEpoch +} + +type MessageReceipt struct { + ExitCode exitcode.ExitCode + Return []byte + GasUsed int64 +} + +func (mr *MessageReceipt) Equals(o *MessageReceipt) bool { + return mr.ExitCode == o.ExitCode && bytes.Equal(mr.Return, o.Return) && mr.GasUsed == o.GasUsed +} + +type MarketDeal struct { + Proposal market.DealProposal + State market.DealState +} From f2cce143907750694ed0583452ecf22b9aa98bed Mon Sep 17 00:00:00 2001 From: laser Date: Mon, 6 Apr 2020 13:27:14 -0700 Subject: [PATCH 119/126] reorder imports --- types.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/types.go b/types.go index 7edbe7145..85525e9b4 100644 --- a/types.go +++ b/types.go @@ -4,11 +4,12 @@ import ( "bytes" "context" + "github.com/ipfs/go-cid" + "github.com/filecoin-project/specs-actors/actors/abi" "github.com/filecoin-project/specs-actors/actors/builtin/market" "github.com/filecoin-project/specs-actors/actors/runtime/exitcode" "github.com/filecoin-project/specs-storage/storage" - "github.com/ipfs/go-cid" ) type Piece struct { From b592a678928618839eaad681868a72e44186d034 Mon Sep 17 00:00:00 2001 From: laser Date: Mon, 6 Apr 2020 13:31:49 -0700 Subject: [PATCH 120/126] move to types --- types.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/types.go b/types.go index 85525e9b4..d452cb507 100644 --- a/types.go +++ b/types.go @@ -7,7 +7,6 @@ import ( "github.com/ipfs/go-cid" "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/specs-actors/actors/builtin/market" "github.com/filecoin-project/specs-actors/actors/runtime/exitcode" "github.com/filecoin-project/specs-storage/storage" ) @@ -122,8 +121,3 @@ type MessageReceipt struct { func (mr *MessageReceipt) Equals(o *MessageReceipt) bool { return mr.ExitCode == o.ExitCode && bytes.Equal(mr.Return, o.Return) && mr.GasUsed == o.GasUsed } - -type MarketDeal struct { - Proposal market.DealProposal - State market.DealState -} From 0fc5ebf5b1d927fe4b6005341abe70775181145b Mon Sep 17 00:00:00 2001 From: laser Date: Mon, 6 Apr 2020 13:35:29 -0700 Subject: [PATCH 121/126] update CBOR encoders/decoders --- cbor_gen.go | 1189 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 1183 insertions(+), 6 deletions(-) diff --git a/cbor_gen.go b/cbor_gen.go index 410936f50..96d3bb483 100644 --- a/cbor_gen.go +++ b/cbor_gen.go @@ -3,35 +3,1212 @@ package sealing import ( + "fmt" "io" + "github.com/filecoin-project/specs-actors/actors/abi" + cbg "github.com/whyrusleeping/cbor-gen" xerrors "golang.org/x/xerrors" ) var _ = xerrors.Errorf func (t *Piece) MarshalCBOR(w io.Writer) error { - return nil + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write([]byte{163}); err != nil { + return err + } + // t.DealID (abi.DealID) (uint64) + if len("DealID") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"DealID\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("DealID")))); err != nil { + return err + } + if _, err := w.Write([]byte("DealID")); err != nil { + return err + } + + if t.DealID == nil { + if _, err := w.Write(cbg.CborNull); err != nil { + return err + } + } else { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(*t.DealID))); err != nil { + return err + } + } + + // t.Size (abi.UnpaddedPieceSize) (uint64) + if len("Size") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"Size\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Size")))); err != nil { + return err + } + if _, err := w.Write([]byte("Size")); err != nil { + return err + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Size))); err != nil { + return err + } + + // t.CommP (cid.Cid) (struct) + if len("CommP") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"CommP\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("CommP")))); err != nil { + return err + } + if _, err := w.Write([]byte("CommP")); err != nil { + return err + } + + if err := cbg.WriteCid(w, t.CommP); err != nil { + return xerrors.Errorf("failed to write cid field t.CommP: %w", err) + } + + return nil } func (t *Piece) UnmarshalCBOR(r io.Reader) error { - return nil + br := cbg.GetPeeker(r) + maj, extra, err := cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("Piece: map struct too large (%d)", extra) + } + + var name string + n := extra + + for i := uint64(0); i < n; i++ { + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + name = string(sval) + } + + switch name { + // t.DealID (abi.DealID) (uint64) + case "DealID": + + { + + 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 { + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + typed := abi.DealID(extra) + t.DealID = &typed + } + + } + // t.Size (abi.UnpaddedPieceSize) (uint64) + case "Size": + + { + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Size = abi.UnpaddedPieceSize(extra) + + } + // t.CommP (cid.Cid) (struct) + case "CommP": + + { + + c, err := cbg.ReadCid(br) + if err != nil { + return xerrors.Errorf("failed to read cid field t.CommP: %w", err) + } + + t.CommP = c + + } + + default: + return fmt.Errorf("unknown struct field %d: '%s'", i, name) + } + } + + return nil } func (t *SectorInfo) MarshalCBOR(w io.Writer) error { - return nil + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write([]byte{179}); err != nil { + return err + } + // t.State (sealing.SectorState) (string) + if len("State") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"State\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("State")))); err != nil { + return err + } + if _, err := w.Write([]byte("State")); err != nil { + return err + } + + if len(t.State) > cbg.MaxLength { + return xerrors.Errorf("Value in field t.State was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.State)))); err != nil { + return err + } + if _, err := w.Write([]byte(t.State)); err != nil { + return err + } + + // t.SectorID (abi.SectorNumber) (uint64) + if len("SectorID") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"SectorID\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("SectorID")))); err != nil { + return err + } + if _, err := w.Write([]byte("SectorID")); err != nil { + return err + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SectorID))); err != nil { + return err + } + + // t.Nonce (uint64) (uint64) + if len("Nonce") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"Nonce\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Nonce")))); err != nil { + return err + } + if _, err := w.Write([]byte("Nonce")); err != nil { + return err + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Nonce))); err != nil { + return err + } + + // t.SectorType (abi.RegisteredProof) (int64) + if len("SectorType") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"SectorType\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("SectorType")))); err != nil { + return err + } + if _, err := w.Write([]byte("SectorType")); err != nil { + return err + } + + if t.SectorType >= 0 { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SectorType))); err != nil { + return err + } + } else { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajNegativeInt, uint64(-t.SectorType)-1)); err != nil { + return err + } + } + + // t.Pieces ([]sealing.Piece) (slice) + if len("Pieces") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"Pieces\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Pieces")))); err != nil { + return err + } + if _, err := w.Write([]byte("Pieces")); err != nil { + return err + } + + if len(t.Pieces) > cbg.MaxLength { + return xerrors.Errorf("Slice value in field t.Pieces was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Pieces)))); err != nil { + return err + } + for _, v := range t.Pieces { + if err := v.MarshalCBOR(w); err != nil { + return err + } + } + + // t.TicketValue (abi.SealRandomness) (slice) + if len("TicketValue") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"TicketValue\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("TicketValue")))); err != nil { + return err + } + if _, err := w.Write([]byte("TicketValue")); err != nil { + return err + } + + if len(t.TicketValue) > cbg.ByteArrayMaxLen { + return xerrors.Errorf("Byte array in field t.TicketValue was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.TicketValue)))); err != nil { + return err + } + if _, err := w.Write(t.TicketValue); err != nil { + return err + } + + // t.TicketEpoch (abi.ChainEpoch) (int64) + if len("TicketEpoch") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"TicketEpoch\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("TicketEpoch")))); err != nil { + return err + } + if _, err := w.Write([]byte("TicketEpoch")); err != nil { + return err + } + + if t.TicketEpoch >= 0 { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.TicketEpoch))); err != nil { + return err + } + } else { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajNegativeInt, uint64(-t.TicketEpoch)-1)); err != nil { + return err + } + } + + // t.PreCommit1Out (storage.PreCommit1Out) (slice) + if len("PreCommit1Out") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"PreCommit1Out\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("PreCommit1Out")))); err != nil { + return err + } + if _, err := w.Write([]byte("PreCommit1Out")); err != nil { + return err + } + + if len(t.PreCommit1Out) > cbg.ByteArrayMaxLen { + return xerrors.Errorf("Byte array in field t.PreCommit1Out was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.PreCommit1Out)))); err != nil { + return err + } + if _, err := w.Write(t.PreCommit1Out); err != nil { + return err + } + + // t.CommD (cid.Cid) (struct) + if len("CommD") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"CommD\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("CommD")))); err != nil { + return err + } + if _, err := w.Write([]byte("CommD")); err != nil { + return err + } + + if t.CommD == nil { + if _, err := w.Write(cbg.CborNull); err != nil { + return err + } + } else { + if err := cbg.WriteCid(w, *t.CommD); err != nil { + return xerrors.Errorf("failed to write cid field t.CommD: %w", err) + } + } + + // t.CommR (cid.Cid) (struct) + if len("CommR") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"CommR\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("CommR")))); err != nil { + return err + } + if _, err := w.Write([]byte("CommR")); err != nil { + return err + } + + if t.CommR == nil { + if _, err := w.Write(cbg.CborNull); err != nil { + return err + } + } else { + if err := cbg.WriteCid(w, *t.CommR); err != nil { + return xerrors.Errorf("failed to write cid field t.CommR: %w", err) + } + } + + // t.Proof ([]uint8) (slice) + if len("Proof") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"Proof\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Proof")))); err != nil { + return err + } + if _, err := w.Write([]byte("Proof")); err != nil { + return err + } + + if len(t.Proof) > cbg.ByteArrayMaxLen { + return xerrors.Errorf("Byte array in field t.Proof was too long") + } + + 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.PreCommitMessage (cid.Cid) (struct) + if len("PreCommitMessage") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"PreCommitMessage\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("PreCommitMessage")))); err != nil { + return err + } + if _, err := w.Write([]byte("PreCommitMessage")); err != nil { + return err + } + + if t.PreCommitMessage == nil { + if _, err := w.Write(cbg.CborNull); err != nil { + return err + } + } else { + if err := cbg.WriteCid(w, *t.PreCommitMessage); err != nil { + return xerrors.Errorf("failed to write cid field t.PreCommitMessage: %w", err) + } + } + + // t.SeedValue (abi.InteractiveSealRandomness) (slice) + if len("SeedValue") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"SeedValue\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("SeedValue")))); err != nil { + return err + } + if _, err := w.Write([]byte("SeedValue")); err != nil { + return err + } + + if len(t.SeedValue) > cbg.ByteArrayMaxLen { + return xerrors.Errorf("Byte array in field t.SeedValue was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.SeedValue)))); err != nil { + return err + } + if _, err := w.Write(t.SeedValue); err != nil { + return err + } + + // t.SeedEpoch (abi.ChainEpoch) (int64) + if len("SeedEpoch") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"SeedEpoch\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("SeedEpoch")))); err != nil { + return err + } + if _, err := w.Write([]byte("SeedEpoch")); err != nil { + return err + } + + if t.SeedEpoch >= 0 { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SeedEpoch))); err != nil { + return err + } + } else { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajNegativeInt, uint64(-t.SeedEpoch)-1)); err != nil { + return err + } + } + + // t.CommitMessage (cid.Cid) (struct) + if len("CommitMessage") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"CommitMessage\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("CommitMessage")))); err != nil { + return err + } + if _, err := w.Write([]byte("CommitMessage")); err != nil { + return err + } + + if t.CommitMessage == nil { + if _, err := w.Write(cbg.CborNull); err != nil { + return err + } + } else { + if err := cbg.WriteCid(w, *t.CommitMessage); err != nil { + return xerrors.Errorf("failed to write cid field t.CommitMessage: %w", err) + } + } + + // t.InvalidProofs (uint64) (uint64) + if len("InvalidProofs") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"InvalidProofs\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("InvalidProofs")))); err != nil { + return err + } + if _, err := w.Write([]byte("InvalidProofs")); err != nil { + return err + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.InvalidProofs))); err != nil { + return err + } + + // t.FaultReportMsg (cid.Cid) (struct) + if len("FaultReportMsg") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"FaultReportMsg\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("FaultReportMsg")))); err != nil { + return err + } + if _, err := w.Write([]byte("FaultReportMsg")); err != nil { + return err + } + + if t.FaultReportMsg == nil { + if _, err := w.Write(cbg.CborNull); err != nil { + return err + } + } else { + if err := cbg.WriteCid(w, *t.FaultReportMsg); err != nil { + return xerrors.Errorf("failed to write cid field t.FaultReportMsg: %w", err) + } + } + + // t.LastErr (string) (string) + if len("LastErr") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"LastErr\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("LastErr")))); err != nil { + return err + } + if _, err := w.Write([]byte("LastErr")); err != nil { + return err + } + + if len(t.LastErr) > cbg.MaxLength { + return xerrors.Errorf("Value in field t.LastErr was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.LastErr)))); err != nil { + return err + } + if _, err := w.Write([]byte(t.LastErr)); err != nil { + return err + } + + // t.Log ([]sealing.Log) (slice) + if len("Log") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"Log\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Log")))); err != nil { + return err + } + if _, err := w.Write([]byte("Log")); err != nil { + return err + } + + if len(t.Log) > cbg.MaxLength { + return xerrors.Errorf("Slice value in field t.Log was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Log)))); err != nil { + return err + } + for _, v := range t.Log { + if err := v.MarshalCBOR(w); err != nil { + return err + } + } + return nil } -func (t *SectorInfo) UnmarshalCBOR(w io.Reader) error { - return nil +func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { + br := cbg.GetPeeker(r) + + maj, extra, err := cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("SectorInfo: map struct too large (%d)", extra) + } + + var name string + n := extra + + for i := uint64(0); i < n; i++ { + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + name = string(sval) + } + + switch name { + // t.State (sealing.SectorState) (string) + case "State": + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + t.State = SectorState(sval) + } + // t.SectorID (abi.SectorNumber) (uint64) + case "SectorID": + + { + + 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 = abi.SectorNumber(extra) + + } + // t.Nonce (uint64) (uint64) + case "Nonce": + + { + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Nonce = uint64(extra) + + } + // t.SectorType (abi.RegisteredProof) (int64) + case "SectorType": + { + maj, extra, err := cbg.CborReadHeader(br) + var extraI int64 + if err != nil { + return err + } + switch maj { + case cbg.MajUnsignedInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 positive overflow") + } + case cbg.MajNegativeInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 negative oveflow") + } + extraI = -1 - extraI + default: + return fmt.Errorf("wrong type for int64 field: %d", maj) + } + + t.SectorType = abi.RegisteredProof(extraI) + } + // t.Pieces ([]sealing.Piece) (slice) + case "Pieces": + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + + if extra > cbg.MaxLength { + return fmt.Errorf("t.Pieces: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + if extra > 0 { + t.Pieces = make([]Piece, extra) + } + for i := 0; i < int(extra); i++ { + + var v Piece + if err := v.UnmarshalCBOR(br); err != nil { + return err + } + + t.Pieces[i] = v + } + + // t.TicketValue (abi.SealRandomness) (slice) + case "TicketValue": + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + + if extra > cbg.ByteArrayMaxLen { + return fmt.Errorf("t.TicketValue: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.TicketValue = make([]byte, extra) + if _, err := io.ReadFull(br, t.TicketValue); err != nil { + return err + } + // t.TicketEpoch (abi.ChainEpoch) (int64) + case "TicketEpoch": + { + maj, extra, err := cbg.CborReadHeader(br) + var extraI int64 + if err != nil { + return err + } + switch maj { + case cbg.MajUnsignedInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 positive overflow") + } + case cbg.MajNegativeInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 negative oveflow") + } + extraI = -1 - extraI + default: + return fmt.Errorf("wrong type for int64 field: %d", maj) + } + + t.TicketEpoch = abi.ChainEpoch(extraI) + } + // t.PreCommit1Out (storage.PreCommit1Out) (slice) + case "PreCommit1Out": + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + + if extra > cbg.ByteArrayMaxLen { + return fmt.Errorf("t.PreCommit1Out: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.PreCommit1Out = make([]byte, extra) + if _, err := io.ReadFull(br, t.PreCommit1Out); err != nil { + return err + } + // t.CommD (cid.Cid) (struct) + case "CommD": + + { + + 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 { + + c, err := cbg.ReadCid(br) + if err != nil { + return xerrors.Errorf("failed to read cid field t.CommD: %w", err) + } + + t.CommD = &c + } + + } + // t.CommR (cid.Cid) (struct) + case "CommR": + + { + + 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 { + + c, err := cbg.ReadCid(br) + if err != nil { + return xerrors.Errorf("failed to read cid field t.CommR: %w", err) + } + + t.CommR = &c + } + + } + // t.Proof ([]uint8) (slice) + case "Proof": + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + + if extra > cbg.ByteArrayMaxLen { + return fmt.Errorf("t.Proof: byte 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.PreCommitMessage (cid.Cid) (struct) + case "PreCommitMessage": + + { + + 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 { + + c, err := cbg.ReadCid(br) + if err != nil { + return xerrors.Errorf("failed to read cid field t.PreCommitMessage: %w", err) + } + + t.PreCommitMessage = &c + } + + } + // t.SeedValue (abi.InteractiveSealRandomness) (slice) + case "SeedValue": + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + + if extra > cbg.ByteArrayMaxLen { + return fmt.Errorf("t.SeedValue: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.SeedValue = make([]byte, extra) + if _, err := io.ReadFull(br, t.SeedValue); err != nil { + return err + } + // t.SeedEpoch (abi.ChainEpoch) (int64) + case "SeedEpoch": + { + maj, extra, err := cbg.CborReadHeader(br) + var extraI int64 + if err != nil { + return err + } + switch maj { + case cbg.MajUnsignedInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 positive overflow") + } + case cbg.MajNegativeInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 negative oveflow") + } + extraI = -1 - extraI + default: + return fmt.Errorf("wrong type for int64 field: %d", maj) + } + + t.SeedEpoch = abi.ChainEpoch(extraI) + } + // t.CommitMessage (cid.Cid) (struct) + case "CommitMessage": + + { + + 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 { + + c, err := cbg.ReadCid(br) + if err != nil { + return xerrors.Errorf("failed to read cid field t.CommitMessage: %w", err) + } + + t.CommitMessage = &c + } + + } + // t.InvalidProofs (uint64) (uint64) + case "InvalidProofs": + + { + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.InvalidProofs = uint64(extra) + + } + // t.FaultReportMsg (cid.Cid) (struct) + case "FaultReportMsg": + + { + + 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 { + + c, err := cbg.ReadCid(br) + if err != nil { + return xerrors.Errorf("failed to read cid field t.FaultReportMsg: %w", err) + } + + t.FaultReportMsg = &c + } + + } + // t.LastErr (string) (string) + case "LastErr": + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + t.LastErr = string(sval) + } + // t.Log ([]sealing.Log) (slice) + case "Log": + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + + if extra > cbg.MaxLength { + return fmt.Errorf("t.Log: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + if extra > 0 { + t.Log = make([]Log, extra) + } + for i := 0; i < int(extra); i++ { + + var v Log + if err := v.UnmarshalCBOR(br); err != nil { + return err + } + + t.Log[i] = v + } + + default: + return fmt.Errorf("unknown struct field %d: '%s'", i, name) + } + } + + return nil } func (t *Log) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write([]byte{164}); err != nil { + return err + } + + // t.Timestamp (uint64) (uint64) + if len("Timestamp") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"Timestamp\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Timestamp")))); err != nil { + return err + } + if _, err := w.Write([]byte("Timestamp")); err != nil { + return err + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Timestamp))); err != nil { + return err + } + + // t.Trace (string) (string) + if len("Trace") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"Trace\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Trace")))); err != nil { + return err + } + if _, err := w.Write([]byte("Trace")); err != nil { + return err + } + + if len(t.Trace) > cbg.MaxLength { + return xerrors.Errorf("Value in field t.Trace was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.Trace)))); err != nil { + return err + } + if _, err := w.Write([]byte(t.Trace)); err != nil { + return err + } + + // t.Message (string) (string) + if len("Message") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"Message\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Message")))); err != nil { + return err + } + if _, err := w.Write([]byte("Message")); err != nil { + return err + } + + if len(t.Message) > cbg.MaxLength { + return xerrors.Errorf("Value in field t.Message was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.Message)))); err != nil { + return err + } + if _, err := w.Write([]byte(t.Message)); err != nil { + return err + } + + // t.Kind (string) (string) + if len("Kind") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"Kind\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Kind")))); err != nil { + return err + } + if _, err := w.Write([]byte("Kind")); err != nil { + return err + } + + if len(t.Kind) > cbg.MaxLength { + return xerrors.Errorf("Value in field t.Kind was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.Kind)))); err != nil { + return err + } + if _, err := w.Write([]byte(t.Kind)); err != nil { + return err + } return nil } func (t *Log) UnmarshalCBOR(r io.Reader) error { - return nil + br := cbg.GetPeeker(r) + maj, extra, err := cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("Log: map struct too large (%d)", extra) + } + + var name string + n := extra + + for i := uint64(0); i < n; i++ { + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + name = string(sval) + } + + switch name { + // t.Timestamp (uint64) (uint64) + case "Timestamp": + + { + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Timestamp = uint64(extra) + + } + // t.Trace (string) (string) + case "Trace": + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + t.Trace = string(sval) + } + // t.Message (string) (string) + case "Message": + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + t.Message = string(sval) + } + // t.Kind (string) (string) + case "Kind": + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + t.Kind = string(sval) + } + + default: + return fmt.Errorf("unknown struct field %d: '%s'", i, name) + } + } + + return nil } From b7be24d775484fd88c0a85b2a3547afc6b1a5b43 Mon Sep 17 00:00:00 2001 From: laser Date: Mon, 6 Apr 2020 14:03:47 -0700 Subject: [PATCH 122/126] revert name change --- checks.go | 2 +- sealing.go | 2 +- states.go | 2 +- states_failed.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/checks.go b/checks.go index ff1572cf2..1538cc8d5 100644 --- a/checks.go +++ b/checks.go @@ -101,7 +101,7 @@ func (m *Sealing) checkCommit(ctx context.Context, si SectorInfo, proof []byte) return &ErrBadSeed{xerrors.Errorf("seed epoch was not set")} } - pci, err := m.api.StateGetSectorPreCommitOnChainInfo(ctx, m.maddr, si.SectorID, tok) + pci, err := m.api.StateSectorPreCommitInfo(ctx, m.maddr, si.SectorID, tok) if err != nil { return xerrors.Errorf("getting precommit info: %w", err) } diff --git a/sealing.go b/sealing.go index d79ebfc84..24d43c1b1 100644 --- a/sealing.go +++ b/sealing.go @@ -29,7 +29,7 @@ var log = logging.Logger("sectors") type SealingAPI interface { StateWaitMsg(context.Context, cid.Cid) (MsgLookup, error) StateComputeDataCommitment(ctx context.Context, maddr address.Address, sectorType abi.RegisteredProof, deals []abi.DealID, tok TipSetToken) (cid.Cid, error) - StateGetSectorPreCommitOnChainInfo(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok TipSetToken) (*miner.SectorPreCommitOnChainInfo, error) + StateSectorPreCommitInfo(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok TipSetToken) (*miner.SectorPreCommitOnChainInfo, error) StateMinerSectorSize(context.Context, address.Address, TipSetToken) (abi.SectorSize, error) StateMarketStorageDeal(context.Context, abi.DealID, TipSetToken) (market.DealProposal, market.DealState, error) SendMsg(ctx context.Context, from, to address.Address, method abi.MethodNum, value, gasPrice big.Int, gasLimit int64, params []byte) (cid.Cid, error) diff --git a/states.go b/states.go index 907ead6b3..a2c56e072 100644 --- a/states.go +++ b/states.go @@ -145,7 +145,7 @@ func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) er } log.Info("precommit message landed on chain: ", sector.SectorID) - pci, err := m.api.StateGetSectorPreCommitOnChainInfo(ctx.Context(), m.maddr, sector.SectorID, mw.TipSetTok) + pci, err := m.api.StateSectorPreCommitInfo(ctx.Context(), m.maddr, sector.SectorID, mw.TipSetTok) if err != nil { return xerrors.Errorf("getting precommit info: %w", err) } diff --git a/states_failed.go b/states_failed.go index 4879b52fd..ac4306f95 100644 --- a/states_failed.go +++ b/states_failed.go @@ -34,7 +34,7 @@ func (m *Sealing) checkPreCommitted(ctx statemachine.Context, sector SectorInfo) return nil, true } - info, err := m.api.StateGetSectorPreCommitOnChainInfo(ctx.Context(), m.maddr, sector.SectorID, tok) + info, err := m.api.StateSectorPreCommitInfo(ctx.Context(), m.maddr, sector.SectorID, tok) if err != nil { log.Errorf("handleSealFailed(%d): temp error: %+v", sector.SectorID, err) return nil, true From 8006f12deaf2def393dd297794beb05c803877b2 Mon Sep 17 00:00:00 2001 From: laser Date: Mon, 6 Apr 2020 15:31:33 -0700 Subject: [PATCH 123/126] SectorID -> SectorNumber --- cbor_gen.go | 18 +++++++++--------- checks.go | 12 ++++++------ fsm.go | 12 ++++++------ fsm_events.go | 4 ++-- states.go | 38 +++++++++++++++++++------------------- states_failed.go | 12 ++++++------ types.go | 6 +++--- types_test.go | 8 ++++---- 8 files changed, 55 insertions(+), 55 deletions(-) diff --git a/cbor_gen.go b/cbor_gen.go index 96d3bb483..08ba98546 100644 --- a/cbor_gen.go +++ b/cbor_gen.go @@ -204,19 +204,19 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error { return err } - // t.SectorID (abi.SectorNumber) (uint64) - if len("SectorID") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"SectorID\" was too long") + // t.SectorNumber (abi.SectorNumber) (uint64) + if len("SectorNumber") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"SectorNumber\" was too long") } - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("SectorID")))); err != nil { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("SectorNumber")))); err != nil { return err } - if _, err := w.Write([]byte("SectorID")); err != nil { + if _, err := w.Write([]byte("SectorNumber")); err != nil { return err } - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SectorID))); err != nil { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SectorNumber))); err != nil { return err } @@ -636,8 +636,8 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { t.State = SectorState(sval) } - // t.SectorID (abi.SectorNumber) (uint64) - case "SectorID": + // t.SectorNumber (abi.SectorNumber) (uint64) + case "SectorNumber": { @@ -648,7 +648,7 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error { if maj != cbg.MajUnsignedInt { return fmt.Errorf("wrong type for uint64 field") } - t.SectorID = abi.SectorNumber(extra) + t.SectorNumber = abi.SectorNumber(extra) } // t.Nonce (uint64) (uint64) diff --git a/checks.go b/checks.go index 1538cc8d5..3c18f9f34 100644 --- a/checks.go +++ b/checks.go @@ -52,15 +52,15 @@ func checkPieces(ctx context.Context, si SectorInfo, api SealingAPI) error { } if proposal.PieceCID != piece.CommP { - return &ErrInvalidDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers deal %d with wrong CommP: %x != %x", i, len(si.Pieces), si.SectorID, piece.DealID, piece.CommP, proposal.PieceCID)} + return &ErrInvalidDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers deal %d with wrong CommP: %x != %x", i, len(si.Pieces), si.SectorNumber, piece.DealID, piece.CommP, proposal.PieceCID)} } if piece.Size != proposal.PieceSize.Unpadded() { - return &ErrInvalidDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers deal %d with different size: %d != %d", i, len(si.Pieces), si.SectorID, piece.DealID, piece.Size, proposal.PieceSize)} + return &ErrInvalidDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers deal %d with different size: %d != %d", i, len(si.Pieces), si.SectorNumber, piece.DealID, piece.Size, proposal.PieceSize)} } if height >= proposal.StartEpoch { - return &ErrExpiredDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers expired deal %d - should start at %d, head %d", i, len(si.Pieces), si.SectorID, piece.DealID, proposal.StartEpoch, height)} + return &ErrExpiredDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers expired deal %d - should start at %d, head %d", i, len(si.Pieces), si.SectorNumber, piece.DealID, proposal.StartEpoch, height)} } } @@ -101,7 +101,7 @@ func (m *Sealing) checkCommit(ctx context.Context, si SectorInfo, proof []byte) return &ErrBadSeed{xerrors.Errorf("seed epoch was not set")} } - pci, err := m.api.StateSectorPreCommitInfo(ctx, m.maddr, si.SectorID, tok) + pci, err := m.api.StateSectorPreCommitInfo(ctx, m.maddr, si.SectorNumber, tok) if err != nil { return xerrors.Errorf("getting precommit info: %w", err) } @@ -133,13 +133,13 @@ func (m *Sealing) checkCommit(ctx context.Context, si SectorInfo, proof []byte) } ok, err := m.verif.VerifySeal(abi.SealVerifyInfo{ - SectorID: m.minerSector(si.SectorID), + SectorID: m.minerSector(si.SectorNumber), OnChain: abi.OnChainSealVerifyInfo{ SealedCID: pci.Info.SealedCID, InteractiveEpoch: si.SeedEpoch, RegisteredProof: spt, Proof: proof, - SectorNumber: si.SectorID, + SectorNumber: si.SectorNumber, SealRandEpoch: si.TicketEpoch, }, Randomness: si.TicketValue, diff --git a/fsm.go b/fsm.go index e03ab7bd8..91fbaf172 100644 --- a/fsm.go +++ b/fsm.go @@ -23,7 +23,7 @@ func (m *Sealing) Plan(events []statemachine.Event, user interface{}) (interface return func(ctx statemachine.Context, si SectorInfo) error { err := next(ctx, si) if err != nil { - log.Errorf("unhandled sector error (%d): %+v", si.SectorID, err) + log.Errorf("unhandled sector error (%d): %+v", si.SectorNumber, err) return nil } @@ -187,7 +187,7 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta return m.handleFinalizeSector, nil case Proving: // TODO: track sector health / expiration - log.Infof("Proving sector %d", state.SectorID) + log.Infof("Proving sector %d", state.SectorNumber) // Handled failure modes case SealFailed: @@ -209,7 +209,7 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta case UndefinedSectorState: log.Error("sector update with undefined state!") case FailedUnrecoverable: - log.Errorf("sector %d failed unrecoverably", state.SectorID) + log.Errorf("sector %d failed unrecoverably", state.SectorNumber) default: log.Errorf("unexpected sector update state: %d", state.State) } @@ -256,8 +256,8 @@ func (m *Sealing) restartSectors(ctx context.Context) error { } for _, sector := range trackedSectors { - if err := m.sectors.Send(uint64(sector.SectorID), SectorRestart{}); err != nil { - log.Errorf("restarting sector %d: %+v", sector.SectorID, err) + if err := m.sectors.Send(uint64(sector.SectorNumber), SectorRestart{}); err != nil { + log.Errorf("restarting sector %d: %+v", sector.SectorNumber, err) } } @@ -305,7 +305,7 @@ func planOne(ts ...func() (mut mutator, next SectorState)) func(events []statema } if err, iserr := events[0].User.(error); iserr { - log.Warnf("sector %d got error event %T: %+v", state.SectorID, events[0].User, err) + log.Warnf("sector %d got error event %T: %+v", state.SectorNumber, events[0].User, err) } events[0].User.(mutator).apply(state) diff --git a/fsm_events.go b/fsm_events.go index 2dee984d5..7316d16a1 100644 --- a/fsm_events.go +++ b/fsm_events.go @@ -29,7 +29,7 @@ type SectorFatalError struct{ error } func (evt SectorFatalError) FormatError(xerrors.Printer) (next error) { return evt.error } func (evt SectorFatalError) applyGlobal(state *SectorInfo) bool { - log.Errorf("Fatal error on sector %d: %+v", state.SectorID, evt.error) + log.Errorf("Fatal error on sector %d: %+v", state.SectorNumber, evt.error) // TODO: Do we want to mark the state as unrecoverable? // I feel like this should be a softer error, where the user would // be able to send a retry event of some kind @@ -54,7 +54,7 @@ type SectorStart struct { } func (evt SectorStart) apply(state *SectorInfo) { - state.SectorID = evt.ID + state.SectorNumber = evt.ID state.Pieces = evt.Pieces state.SectorType = evt.SectorType } diff --git a/states.go b/states.go index a2c56e072..39d277e2a 100644 --- a/states.go +++ b/states.go @@ -16,7 +16,7 @@ import ( ) func (m *Sealing) handlePacking(ctx statemachine.Context, sector SectorInfo) error { - log.Infow("performing filling up rest of the sector...", "sector", sector.SectorID) + log.Infow("performing filling up rest of the sector...", "sector", sector.SectorNumber) var allocated abi.UnpaddedPieceSize for _, piece := range sector.Pieces { @@ -35,10 +35,10 @@ func (m *Sealing) handlePacking(ctx statemachine.Context, sector SectorInfo) err } if len(fillerSizes) > 0 { - log.Warnf("Creating %d filler pieces for sector %d", len(fillerSizes), sector.SectorID) + log.Warnf("Creating %d filler pieces for sector %d", len(fillerSizes), sector.SectorNumber) } - pieces, err := m.pledgeSector(ctx.Context(), m.minerSector(sector.SectorID), sector.existingPieces(), fillerSizes...) + pieces, err := m.pledgeSector(ctx.Context(), m.minerSector(sector.SectorNumber), sector.existingPieces(), fillerSizes...) if err != nil { return xerrors.Errorf("filling up the sector (%v): %w", fillerSizes, err) } @@ -61,13 +61,13 @@ func (m *Sealing) handlePreCommit1(ctx statemachine.Context, sector SectorInfo) } } - log.Infow("performing sector replication...", "sector", sector.SectorID) + log.Infow("performing sector replication...", "sector", sector.SectorNumber) ticketValue, ticketEpoch, err := m.tktFn(ctx.Context()) if err != nil { return ctx.Send(SectorSealPreCommitFailed{xerrors.Errorf("getting ticket failed: %w", err)}) } - pc1o, err := m.sealer.SealPreCommit1(ctx.Context(), m.minerSector(sector.SectorID), ticketValue, sector.pieceInfos()) + pc1o, err := m.sealer.SealPreCommit1(ctx.Context(), m.minerSector(sector.SectorNumber), ticketValue, sector.pieceInfos()) if err != nil { return ctx.Send(SectorSealPreCommitFailed{xerrors.Errorf("seal pre commit(1) failed: %w", err)}) } @@ -80,7 +80,7 @@ func (m *Sealing) handlePreCommit1(ctx statemachine.Context, sector SectorInfo) } func (m *Sealing) handlePreCommit2(ctx statemachine.Context, sector SectorInfo) error { - cids, err := m.sealer.SealPreCommit2(ctx.Context(), m.minerSector(sector.SectorID), sector.PreCommit1Out) + cids, err := m.sealer.SealPreCommit2(ctx.Context(), m.minerSector(sector.SectorNumber), sector.PreCommit1Out) if err != nil { return ctx.Send(SectorSealPreCommitFailed{xerrors.Errorf("seal pre commit(2) failed: %w", err)}) } @@ -108,7 +108,7 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf params := &miner.SectorPreCommitInfo{ Expiration: 10000000, // TODO: implement - SectorNumber: sector.SectorID, + SectorNumber: sector.SectorNumber, RegisteredProof: sector.SectorType, SealedCID: *sector.CommR, @@ -121,7 +121,7 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf return ctx.Send(SectorChainPreCommitFailed{xerrors.Errorf("could not serialize pre-commit sector parameters: %w", err)}) } - log.Info("submitting precommit for sector: ", sector.SectorID) + log.Info("submitting precommit for sector: ", sector.SectorNumber) mcid, err := m.api.SendMsg(ctx.Context(), m.worker, m.maddr, builtin.MethodsMiner.PreCommitSector, big.NewInt(0), big.NewInt(1), 1000000, enc.Bytes()) if err != nil { return ctx.Send(SectorChainPreCommitFailed{xerrors.Errorf("pushing message to mpool: %w", err)}) @@ -132,7 +132,7 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) error { // would be ideal to just use the events.Called handler, but it wouldnt be able to handle individual message timeouts - log.Info("Sector precommitted: ", sector.SectorID) + log.Info("Sector precommitted: ", sector.SectorNumber) mw, err := m.api.StateWaitMsg(ctx.Context(), *sector.PreCommitMessage) if err != nil { return ctx.Send(SectorChainPreCommitFailed{err}) @@ -143,9 +143,9 @@ func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) er err := xerrors.Errorf("sector precommit failed: %d", mw.Receipt.ExitCode) return ctx.Send(SectorChainPreCommitFailed{err}) } - log.Info("precommit message landed on chain: ", sector.SectorID) + log.Info("precommit message landed on chain: ", sector.SectorNumber) - pci, err := m.api.StateSectorPreCommitInfo(ctx.Context(), m.maddr, sector.SectorID, mw.TipSetTok) + pci, err := m.api.StateSectorPreCommitInfo(ctx.Context(), m.maddr, sector.SectorNumber, mw.TipSetTok) if err != nil { return xerrors.Errorf("getting precommit info: %w", err) } @@ -179,18 +179,18 @@ func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) er func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) error { log.Info("scheduling seal proof computation...") - log.Infof("KOMIT %d %x(%d); %x(%d); %v; r:%x; d:%x", sector.SectorID, sector.TicketValue, sector.TicketEpoch, sector.SeedValue, sector.SeedEpoch, sector.pieceInfos(), sector.CommR, sector.CommD) + log.Infof("KOMIT %d %x(%d); %x(%d); %v; r:%x; d:%x", sector.SectorNumber, sector.TicketValue, sector.TicketEpoch, sector.SeedValue, sector.SeedEpoch, sector.pieceInfos(), sector.CommR, sector.CommD) cids := storage.SectorCids{ Unsealed: *sector.CommD, Sealed: *sector.CommR, } - c2in, err := m.sealer.SealCommit1(ctx.Context(), m.minerSector(sector.SectorID), sector.TicketValue, sector.SeedValue, sector.pieceInfos(), cids) + c2in, err := m.sealer.SealCommit1(ctx.Context(), m.minerSector(sector.SectorNumber), sector.TicketValue, sector.SeedValue, sector.pieceInfos(), cids) if err != nil { return ctx.Send(SectorComputeProofFailed{xerrors.Errorf("computing seal proof failed: %w", err)}) } - proof, err := m.sealer.SealCommit2(ctx.Context(), m.minerSector(sector.SectorID), c2in) + proof, err := m.sealer.SealCommit2(ctx.Context(), m.minerSector(sector.SectorNumber), c2in) if err != nil { return ctx.Send(SectorComputeProofFailed{xerrors.Errorf("computing seal proof failed: %w", err)}) } @@ -202,7 +202,7 @@ func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) // TODO: Consider splitting states and persist proof for faster recovery params := &miner.ProveCommitSectorParams{ - SectorNumber: sector.SectorID, + SectorNumber: sector.SectorNumber, Proof: proof, } @@ -225,7 +225,7 @@ func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) func (m *Sealing) handleCommitWait(ctx statemachine.Context, sector SectorInfo) error { if sector.CommitMessage == nil { - log.Errorf("sector %d entered commit wait state without a message cid", sector.SectorID) + log.Errorf("sector %d entered commit wait state without a message cid", sector.SectorNumber) return ctx.Send(SectorCommitFailed{xerrors.Errorf("entered commit wait with no commit cid")}) } @@ -244,7 +244,7 @@ func (m *Sealing) handleCommitWait(ctx statemachine.Context, sector SectorInfo) func (m *Sealing) handleFinalizeSector(ctx statemachine.Context, sector SectorInfo) error { // TODO: Maybe wait for some finality - if err := m.sealer.FinalizeSector(ctx.Context(), m.minerSector(sector.SectorID)); err != nil { + if err := m.sealer.FinalizeSector(ctx.Context(), m.minerSector(sector.SectorNumber)); err != nil { return ctx.Send(SectorFinalizeFailed{xerrors.Errorf("finalize sector: %w", err)}) } @@ -256,7 +256,7 @@ func (m *Sealing) handleFaulty(ctx statemachine.Context, sector SectorInfo) erro // TODO: coalesce faulty sector reporting bf := abi.NewBitField() - bf.Set(uint64(sector.SectorID)) + bf.Set(uint64(sector.SectorNumber)) params := &miner.DeclareTemporaryFaultsParams{ SectorNumbers: bf, @@ -287,7 +287,7 @@ func (m *Sealing) handleFaultReported(ctx statemachine.Context, sector SectorInf } if mw.Receipt.ExitCode != 0 { - log.Errorf("UNHANDLED: declaring sector fault failed (exit=%d, msg=%s) (id: %d)", mw.Receipt.ExitCode, *sector.FaultReportMsg, sector.SectorID) + log.Errorf("UNHANDLED: declaring sector fault failed (exit=%d, msg=%s) (id: %d)", mw.Receipt.ExitCode, *sector.FaultReportMsg, sector.SectorNumber) return xerrors.Errorf("UNHANDLED: submitting fault declaration failed (exit %d)", mw.Receipt.ExitCode) } diff --git a/states_failed.go b/states_failed.go index ac4306f95..700a04af2 100644 --- a/states_failed.go +++ b/states_failed.go @@ -16,7 +16,7 @@ func failedCooldown(ctx statemachine.Context, sector SectorInfo) error { retryStart := time.Unix(int64(sector.Log[len(sector.Log)-1].Timestamp), 0).Add(minRetryTime) if len(sector.Log) > 0 && !time.Now().After(retryStart) { - log.Infof("%s(%d), waiting %s before retrying", sector.State, sector.SectorID, time.Until(retryStart)) + log.Infof("%s(%d), waiting %s before retrying", sector.State, sector.SectorNumber, time.Until(retryStart)) select { case <-time.After(time.Until(retryStart)): case <-ctx.Context().Done(): @@ -30,13 +30,13 @@ func failedCooldown(ctx statemachine.Context, sector SectorInfo) error { func (m *Sealing) checkPreCommitted(ctx statemachine.Context, sector SectorInfo) (*miner.SectorPreCommitOnChainInfo, bool) { tok, _, err := m.api.ChainHead(ctx.Context()) if err != nil { - log.Errorf("handleSealFailed(%d): temp error: %+v", sector.SectorID, err) + log.Errorf("handleSealFailed(%d): temp error: %+v", sector.SectorNumber, err) return nil, true } - info, err := m.api.StateSectorPreCommitInfo(ctx.Context(), m.maddr, sector.SectorID, tok) + info, err := m.api.StateSectorPreCommitInfo(ctx.Context(), m.maddr, sector.SectorNumber, tok) if err != nil { - log.Errorf("handleSealFailed(%d): temp error: %+v", sector.SectorID, err) + log.Errorf("handleSealFailed(%d): temp error: %+v", sector.SectorNumber, err) return nil, true } @@ -73,12 +73,12 @@ func (m *Sealing) handlePreCommitFailed(ctx statemachine.Context, sector SectorI if pci, is := m.checkPreCommitted(ctx, sector); is && pci != nil { if sector.PreCommitMessage != nil { - log.Warn("sector %d is precommitted on chain, but we don't have precommit message", sector.SectorID) + log.Warn("sector %d is precommitted on chain, but we don't have precommit message", sector.SectorNumber) return nil // TODO: SeedWait needs this currently } if pci.Info.SealedCID != *sector.CommR { - log.Warn("sector %d is precommitted on chain, with different CommR: %x != %x", sector.SectorID, pci.Info.SealedCID, sector.CommR) + log.Warn("sector %d is precommitted on chain, with different CommR: %x != %x", sector.SectorNumber, pci.Info.SealedCID, sector.CommR) return nil // TODO: remove when the actor allows re-precommit } diff --git a/types.go b/types.go index d452cb507..3094a3e85 100644 --- a/types.go +++ b/types.go @@ -29,9 +29,9 @@ type Log struct { } type SectorInfo struct { - State SectorState - SectorID abi.SectorNumber // TODO: this field's name should be changed to SectorNumber - Nonce uint64 // TODO: remove + State SectorState + SectorNumber abi.SectorNumber // TODO: this field's name should be changed to SectorNumber + Nonce uint64 // TODO: remove SectorType abi.RegisteredProof diff --git a/types_test.go b/types_test.go index 7270c49a7..7dc8ddcca 100644 --- a/types_test.go +++ b/types_test.go @@ -17,9 +17,9 @@ func TestSectorInfoSelialization(t *testing.T) { dummyCid := builtin.AccountActorCodeID si := &SectorInfo{ - State: "stateful", - SectorID: 234, - Nonce: 345, + State: "stateful", + SectorNumber: 234, + Nonce: 345, Pieces: []Piece{{ DealID: &d, Size: 5, @@ -50,7 +50,7 @@ func TestSectorInfoSelialization(t *testing.T) { assert.Equal(t, si.State, si2.State) assert.Equal(t, si.Nonce, si2.Nonce) - assert.Equal(t, si.SectorID, si2.SectorID) + assert.Equal(t, si.SectorNumber, si2.SectorNumber) assert.Equal(t, si.Pieces, si2.Pieces) assert.Equal(t, si.CommD, si2.CommD) From 8f682303ca63738367c0d182ce5a99955cecf018 Mon Sep 17 00:00:00 2001 From: laser Date: Mon, 6 Apr 2020 17:29:52 -0700 Subject: [PATCH 124/126] configure CI, move types around, prepare for consumption by lotus --- .circleci/config.yml | 79 ++++ .gitignore | 9 + .gitmodules | 4 + Makefile | 59 +++ README.md | 1 + build/.keep | 0 extern/filecoin-ffi | 1 + fsm_test.go | 11 +- garbage.go | 4 +- gen/main.go | 22 + go.mod | 34 ++ go.sum | 837 +++++++++++++++++++++++++++++++++++ lib/nullreader/nullreader.go | 11 + 13 files changed, 1064 insertions(+), 8 deletions(-) create mode 100644 .circleci/config.yml create mode 100644 .gitmodules create mode 100644 Makefile create mode 100644 build/.keep create mode 160000 extern/filecoin-ffi create mode 100644 gen/main.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 lib/nullreader/nullreader.go diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 000000000..a7cb9a24b --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,79 @@ +version: 2.1 +orbs: + go: gotest/tools@0.0.9 +executors: + golang: + docker: + - image: circleci/golang:1.13 + resource_class: 2xlarge +commands: + prepare-git-checkout: + steps: + - checkout + - run: git submodule sync + - run: git submodule update --init --recursive + install-build-dependencies: + steps: + - run: sudo apt-get update + - run: sudo apt-get install -y jq ocl-icd-opencl-dev + - run: ./extern/filecoin-ffi/install-filcrypto + download-groth-params-and-verifying-keys: + steps: + - restore_cache: + name: Restore parameters cache + keys: + - 'v24-2k-lotus-params' + paths: + - /var/tmp/filecoin-proof-parameters/ + - run: | + DIR=$(pwd) + cd $(mktemp -d) + go get github.com/filecoin-project/go-paramfetch/paramfetch + go build -o go-paramfetch github.com/filecoin-project/go-paramfetch/paramfetch + ./go-paramfetch 2048 "${DIR}/parameters.json" + - save_cache: + name: Save parameters cache + key: 'v24-2k-lotus-params' + paths: + - /var/tmp/filecoin-proof-parameters/ +jobs: + test: + executor: golang + environment: + RUST_LOG: info + steps: + - prepare-git-checkout + - install-build-dependencies + - download-groth-params-and-verifying-keys + - run: go test -v -timeout 10m ./... + mod-tidy-check: + executor: golang + steps: + - prepare-git-checkout + - go/mod-download + - go/mod-tidy-check + gofmt-check: + executor: golang + steps: + - prepare-git-checkout + - go/mod-download + - run: "! go fmt ./... 2>&1 | read" + lint-check: + executor: golang + steps: + - prepare-git-checkout + - install-build-dependencies + - go/mod-download + - go/install-golangci-lint: + gobin: $HOME/.local/bin + version: 1.23.8 + - run: + command: $HOME/.local/bin/golangci-lint run -v --concurrency 2 +workflows: + version: 2.1 + build_and_test: + jobs: + - mod-tidy-check + - lint-check + - gofmt-check + - test diff --git a/.gitignore b/.gitignore index 66fd13c90..72fda5716 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,12 @@ # Dependency directories (remove the comment below to include it) # vendor/ + +# filecoin-ffi assets +*.a +*.h +*.pc + +# build artifacts +build/.filecoin-ffi-install +build/.update-submodules diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..c50b68575 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "extern/filecoin-ffi"] + path = extern/filecoin-ffi + url = git@github.com:filecoin-project/filecoin-ffi + branch = master diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..d22fa2636 --- /dev/null +++ b/Makefile @@ -0,0 +1,59 @@ +SHELL=/usr/bin/env bash + +all: build +.PHONY: all + +# git submodules that need to be loaded +SUBMODULES:= + +# things to clean up, e.g. libfilecoin.a +CLEAN:= + +FFI_PATH:=extern/filecoin-ffi/ +FFI_DEPS:=libfilcrypto.a filcrypto.pc filcrypto.h +FFI_DEPS:=$(addprefix $(FFI_PATH),$(FFI_DEPS)) + +$(FFI_DEPS): build/.filecoin-ffi-install ; + +# dummy file that marks the last time the filecoin-ffi project was built +build/.filecoin-ffi-install: $(FFI_PATH) + $(MAKE) -C $(FFI_PATH) $(FFI_DEPS:$(FFI_PATH)%=%) + @touch $@ + +SUBMODULES+=$(FFI_PATH) +BUILD_DEPS+=build/.filecoin-ffi-install +CLEAN+=build/.filecoin-ffi-install + +$(SUBMODULES): build/.update-submodules ; + +# dummy file that marks the last time submodules were updated +build/.update-submodules: + git submodule update --init --recursive + touch $@ + +CLEAN+=build/.update-submodules + +# build and install any upstream dependencies, e.g. filecoin-ffi +deps: $(BUILD_DEPS) +.PHONY: deps + +test: $(BUILD_DEPS) + RUST_LOG=info go test -race -count 1 -v -timeout 120m ./... +.PHONY: test + +lint: $(BUILD_DEPS) + golangci-lint run -v --concurrency 2 --new-from-rev origin/master +.PHONY: lint + +build: $(BUILD_DEPS) + go build -v $(GOFLAGS) ./... +.PHONY: build + +clean: + rm -rf $(CLEAN) + -$(MAKE) -C $(FFI_PATH) clean +.PHONY: clean + +type-gen: + go run ./gen/main.go +.PHONY: type-gen diff --git a/README.md b/README.md index 525c06d95..b09741e9c 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ # storage-fsm + A finite state machine used for sector storage diff --git a/build/.keep b/build/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/extern/filecoin-ffi b/extern/filecoin-ffi new file mode 160000 index 000000000..355e5e514 --- /dev/null +++ b/extern/filecoin-ffi @@ -0,0 +1 @@ +Subproject commit 355e5e514ee07e946bd2c84ca4883150769dfec3 diff --git a/fsm_test.go b/fsm_test.go index 8738d1c59..5a04b2d7d 100644 --- a/fsm_test.go +++ b/fsm_test.go @@ -14,7 +14,7 @@ func init() { } func (t *test) planSingle(evt interface{}) { - _, err := t.s.plan([]statemachine.Event{{evt}}, t.state) + _, err := t.s.plan([]statemachine.Event{{User: evt}}, t.state) require.NoError(t.t, err) } @@ -22,8 +22,6 @@ type test struct { s *Sealing t *testing.T state *SectorInfo - - next func(statemachine.Context, SectorInfo) error } func TestHappyPath(t *testing.T) { @@ -80,12 +78,13 @@ func TestSeedRevert(t *testing.T) { m.planSingle(SectorSeedReady{}) require.Equal(m.t, m.state.State, Committing) - _, err := m.s.plan([]statemachine.Event{{SectorSeedReady{SeedValue: nil, SeedEpoch: 5}}, {SectorCommitted{}}}, m.state) + _, err := m.s.plan([]statemachine.Event{{User: SectorSeedReady{SeedValue: nil, SeedEpoch: 5}}, {User: SectorCommitted{}}}, m.state) require.NoError(t, err) require.Equal(m.t, m.state.State, Committing) // not changing the seed this time - _, err = m.s.plan([]statemachine.Event{{SectorSeedReady{SeedValue: nil, SeedEpoch: 5}}, {SectorCommitted{}}}, m.state) + _, err = m.s.plan([]statemachine.Event{{User: SectorSeedReady{SeedValue: nil, SeedEpoch: 5}}, {User: SectorCommitted{}}}, m.state) + require.NoError(t, err) require.Equal(m.t, m.state.State, CommitWait) m.planSingle(SectorProving{}) @@ -102,7 +101,7 @@ func TestPlanCommittingHandlesSectorCommitFailed(t *testing.T) { state: &SectorInfo{State: Committing}, } - events := []statemachine.Event{{SectorCommitFailed{}}} + events := []statemachine.Event{{User: SectorCommitFailed{}}} require.NoError(t, planCommitting(events, m.state)) diff --git a/garbage.go b/garbage.go index 7f367d448..e65d9419a 100644 --- a/garbage.go +++ b/garbage.go @@ -9,11 +9,11 @@ import ( "github.com/filecoin-project/sector-storage/ffiwrapper" "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/lotus/lib/nullreader" + nr "github.com/filecoin-project/storage-fsm/lib/nullreader" ) func (m *Sealing) pledgeReader(size abi.UnpaddedPieceSize) io.Reader { - return io.LimitReader(&nullreader.Reader{}, int64(size)) + return io.LimitReader(&nr.Reader{}, int64(size)) } func (m *Sealing) pledgeSector(ctx context.Context, sectorID abi.SectorID, existingPieceSizes []abi.UnpaddedPieceSize, sizes ...abi.UnpaddedPieceSize) ([]Piece, error) { diff --git a/gen/main.go b/gen/main.go new file mode 100644 index 000000000..7b9ade11f --- /dev/null +++ b/gen/main.go @@ -0,0 +1,22 @@ +package main + +import ( + "fmt" + "os" + + gen "github.com/whyrusleeping/cbor-gen" + + sealing "github.com/filecoin-project/storage-fsm" +) + +func main() { + err := gen.WriteMapEncodersToFile("./cbor_gen.go", "sealing", + sealing.Piece{}, + sealing.SectorInfo{}, + sealing.Log{}, + ) + if err != nil { + fmt.Println(err) + os.Exit(1) + } +} diff --git a/go.mod b/go.mod new file mode 100644 index 000000000..5ccc6b09a --- /dev/null +++ b/go.mod @@ -0,0 +1,34 @@ +module github.com/filecoin-project/storage-fsm + +go 1.13 + +require ( + github.com/filecoin-project/go-address v0.0.2-0.20200218010043-eb9bb40ed5be + github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 + github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6 + github.com/filecoin-project/go-paramfetch v0.0.2-0.20200218225740-47c639bab663 // indirect + github.com/filecoin-project/go-statemachine v0.0.0-20200226041606-2074af6d51d9 + github.com/filecoin-project/sector-storage v0.0.0-20200406195014-a6d093838576 + github.com/filecoin-project/specs-actors v0.0.0-20200324235424-aef9b20a9fb1 + github.com/filecoin-project/specs-storage v0.0.0-20200317225704-7420bc655c38 + github.com/ipfs/go-cid v0.0.5 + github.com/ipfs/go-datastore v0.4.4 + github.com/ipfs/go-hamt-ipld v0.0.15-0.20200204200533-99b8553ef242 // indirect + github.com/ipfs/go-ipld-cbor v0.0.5-0.20200204214505-252690b78669 // indirect + github.com/ipfs/go-log/v2 v2.0.3 + github.com/libp2p/go-libp2p-core v0.5.0 // indirect + github.com/stretchr/testify v1.4.0 + github.com/whyrusleeping/cbor-gen v0.0.0-20200321164527-9340289d0ca7 + go.uber.org/zap v1.14.1 // indirect + golang.org/x/crypto v0.0.0-20200317142112-1b76d66859c6 // indirect + golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect + golang.org/x/sys v0.0.0-20200317113312-5766fd39f98d // indirect + golang.org/x/tools v0.0.0-20200318150045-ba25ddc85566 // indirect + golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 + gotest.tools v2.2.0+incompatible + honnef.co/go/tools v0.0.1-2020.1.3 // indirect +) + +replace github.com/golangci/golangci-lint => github.com/golangci/golangci-lint v1.18.0 + +replace github.com/filecoin-project/filecoin-ffi => ./extern/filecoin-ffi diff --git a/go.sum b/go.sum new file mode 100644 index 000000000..2e1530db6 --- /dev/null +++ b/go.sum @@ -0,0 +1,837 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +contrib.go.opencensus.io/exporter/jaeger v0.1.0/go.mod h1:VYianECmuFPwU37O699Vc1GOcy+y8kOsfaxHRImmjbA= +contrib.go.opencensus.io/exporter/prometheus v0.1.0/go.mod h1:cGFniUXGZlKRjzOyuZJ6mgB+PgBcCIa79kEKR8YCW+A= +github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= +github.com/GeertJohan/go.rice v1.0.0 h1:KkI6O9uMaQU3VEKaj01ulavtF7o1fWT7+pk/4voiMLQ= +github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= +github.com/Gurpartap/async v0.0.0-20180927173644-4f7f499dd9ee/go.mod h1:W0GbEAA4uFNYOGG2cJpmFJ04E6SD1NLELPYZB57/7AY= +github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk= +github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/Stebalien/go-bitfield v0.0.1/go.mod h1:GNjFpasyUVkHMsfEOk8EFLJ9syQ6SI+XWrX9Wf2XH0s= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +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-20190629003639-c26ffa870fd8/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= +github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= +github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= +github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= +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= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.2.1-0.20180108230905-e214231b295a/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 h1:HVTnpeuvF6Owjd5mniCL8DEXo7uYXdQEmOP4FJbV5tg= +github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE= +github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= +github.com/daaku/go.zipexe v1.0.0 h1:VSOgZtH418pH9L16hC/JrgSNJbbAL26pj7lmD1+CGdY= +github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= +github.com/dgraph-io/badger v1.6.0-rc1/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= +github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= +github.com/dgraph-io/badger/v2 v2.0.1-rc1.0.20200120142413-c3333a5a830e/go.mod h1:3KY8+bsP8wI0OEnQJAKpd4wIJW/Mm32yw2j/9FUVnIM= +github.com/dgraph-io/ristretto v0.0.2-0.20200115201040-8f368f2f2ab3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= +github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/elastic/go-sysinfo v1.3.0 h1:eb2XFGTMlSwG/yyU9Y8jVAYLIzU2sFzWXwo2gmetyrE= +github.com/elastic/go-sysinfo v1.3.0/go.mod h1:i1ZYdU10oLNfRzq4vq62BEwD2fH8KaWh6eh0ikPT9F0= +github.com/elastic/go-windows v1.0.0 h1:qLURgZFkkrYyTTkvYpsZIgf83AUsdIHfvlJaqaZ7aSY= +github.com/elastic/go-windows v1.0.0/go.mod h1:TsU0Nrp7/y3+VwE82FoZF8gC/XFg/Elz6CcloAxnPgU= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.8.0 h1:5bzFgL+oy7JITMTxUPJ00n7VxmYd/PdMp5mHFX40/RY= +github.com/fatih/color v1.8.0/go.mod h1:3l45GVGkyrnYNl9HoIjnp2NnNWvh6hLAqD8yTfGjnw8= +github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E= +github.com/filecoin-project/chain-validation v0.0.3/go.mod h1:NCEGFjcWRjb8akWFSOXvU6n2efkWIqAeOKU6o5WBGQw= +github.com/filecoin-project/go-address v0.0.0-20191219011437-af739c490b4f/go.mod h1:rCbpXPva2NKF9/J4X6sr7hbKBgQCxyFtRj7KOZqoIms= +github.com/filecoin-project/go-address v0.0.0-20200107215422-da8eea2842b5/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0= +github.com/filecoin-project/go-address v0.0.2-0.20200218010043-eb9bb40ed5be h1:TooKBwR/g8jG0hZ3lqe9S5sy2vTUcLOZLlz3M5wGn2E= +github.com/filecoin-project/go-address v0.0.2-0.20200218010043-eb9bb40ed5be/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0= +github.com/filecoin-project/go-amt-ipld v0.0.0-20191205011053-79efc22d6cdc h1:cODZD2YzpTUtrOSxbEnWFcQHidNRZiRdvLxySjGvG/M= +github.com/filecoin-project/go-amt-ipld v0.0.0-20191205011053-79efc22d6cdc/go.mod h1:KsFPWjF+UUYl6n9A+qbg4bjFgAOneicFZtDH/LQEX2U= +github.com/filecoin-project/go-amt-ipld/v2 v2.0.0/go.mod h1:PAZ5tvSfMfWE327osqFXKm7cBpCpBk2Nh0qKsJUmjjk= +github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200131012142-05d80eeccc5e h1:IOoff6yAZSJ5zHCPY2jzGNwQYQU6ygsRVe/cSnJrY+o= +github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200131012142-05d80eeccc5e/go.mod h1:boRtQhzmxNocrMxOXo1NYn4oUc1NGvR8tEa79wApNXg= +github.com/filecoin-project/go-bitfield v0.0.0-20200309034705-8c7ac40bd550 h1:aockulLU8Qjkdj4FQz53WQpNosAIYk8DxRediRLkE5c= +github.com/filecoin-project/go-bitfield v0.0.0-20200309034705-8c7ac40bd550/go.mod h1:iodsLxOFZnqKtjj2zkgqzoGNrv6vUqj69AT/J8DKXEw= +github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 h1:av5fw6wmm58FYMgJeoB/lK9XXrgdugYiTqkdxjTy9k8= +github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2/go.mod h1:pqTiPHobNkOVM5thSRsHYjyQfq7O5QSCMhvuu9JoDlg= +github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 h1:2pMXdBnCiXjfCYx/hLqFxccPoqsSveQFxVLvNxy9bus= +github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03/go.mod h1:+viYnvGtUTgJRdy6oaeF4MTFKAfatX071MPDPBL11EQ= +github.com/filecoin-project/go-data-transfer v0.0.0-20191219005021-4accf56bd2ce/go.mod h1:b14UWxhxVCAjrQUYvVGrQRRsjAh79wXYejw9RbUcAww= +github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5 h1:yvQJCW9mmi9zy+51xA01Ea2X7/dL7r8eKDPuGUjRmbo= +github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5/go.mod h1:JbkIgFF/Z9BDlvrJO1FuKkaWsH673/UdFaiVS6uIHlA= +github.com/filecoin-project/go-fil-markets v0.0.0-20200114015428-74d100f305f8/go.mod h1:c8NTjvFVy1Ud02mmGDjOiMeawY2t6ALfrrdvAB01FQc= +github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6 h1:92PET+sx1Hb4W/8CgFwGuxaKbttwY+UNspYZTvXY0vs= +github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6/go.mod h1:0HgYnrkeSU4lu1p+LEOeDpFsNBssa0OGGriWdA4hvaE= +github.com/filecoin-project/go-paramfetch v0.0.0-20200102181131-b20d579f2878/go.mod h1:40kI2Gv16mwcRsHptI3OAV4nlOEU7wVDc4RgMylNFjU= +github.com/filecoin-project/go-paramfetch v0.0.1/go.mod h1:fZzmf4tftbwf9S37XRifoJlz7nCjRdIrMGLR07dKLCc= +github.com/filecoin-project/go-paramfetch v0.0.2-0.20200218225740-47c639bab663 h1:eYxi6vI5CyeXD15X1bB3bledDXbqKxqf0wQzTLgwYwA= +github.com/filecoin-project/go-paramfetch v0.0.2-0.20200218225740-47c639bab663/go.mod h1:fZzmf4tftbwf9S37XRifoJlz7nCjRdIrMGLR07dKLCc= +github.com/filecoin-project/go-sectorbuilder v0.0.1/go.mod h1:3OZ4E3B2OuwhJjtxR4r7hPU9bCfB+A+hm4alLEsaeDc= +github.com/filecoin-project/go-sectorbuilder v0.0.2-0.20200203173614-42d67726bb62/go.mod h1:jNGVCDihkMFnraYVLH1xl4ceZQVxx/u4dOORrTKeRi0= +github.com/filecoin-project/go-statemachine v0.0.0-20200226041606-2074af6d51d9 h1:k9qVR9ItcziSB2rxtlkN/MDWNlbsI6yzec+zjUatLW0= +github.com/filecoin-project/go-statemachine v0.0.0-20200226041606-2074af6d51d9/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= +github.com/filecoin-project/go-statestore v0.1.0 h1:t56reH59843TwXHkMcwyuayStBIiWBRilQjQ+5IiwdQ= +github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZOinUJB4WARkRfNl10O7kTnI= +github.com/filecoin-project/lotus v0.2.10 h1:ijrj/nYdKu5GiMo9r1+Zcp2A4jKHSOMZ2WNy2K/mtOE= +github.com/filecoin-project/lotus v0.2.10/go.mod h1:om5PQA9ZT0lf16qI7Fz/ZGLn4LDCMqPC8ntZA9uncRE= +github.com/filecoin-project/sector-storage v0.0.0-20200406195014-a6d093838576 h1:MzBqbddYp/vdFOC3WNu3tSWfLFwHUP8Orcx2CxjRPyo= +github.com/filecoin-project/sector-storage v0.0.0-20200406195014-a6d093838576/go.mod h1:yT100eeKHGO9xU3rfkeM2/8NcBktxe2nBkDT4WmD1lA= +github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= +github.com/filecoin-project/specs-actors v0.0.0-20200226200336-94c9b92b2775/go.mod h1:0HAWYrvajFHDgRaKbF0rl+IybVLZL5z4gQ8koCMPhoU= +github.com/filecoin-project/specs-actors v0.0.0-20200302223606-0eaf97b10aaf/go.mod h1:0HAWYrvajFHDgRaKbF0rl+IybVLZL5z4gQ8koCMPhoU= +github.com/filecoin-project/specs-actors v0.0.0-20200324235424-aef9b20a9fb1 h1:IL6A1yAamz0HtLQEdZS57hnRZHPL11VIrQxMZ1Nn5hI= +github.com/filecoin-project/specs-actors v0.0.0-20200324235424-aef9b20a9fb1/go.mod h1:5WngRgTN5Eo4+0SjCBqLzEr2l6Mj45DrP2606gBhqI0= +github.com/filecoin-project/specs-storage v0.0.0-20200317225704-7420bc655c38 h1:ky+rfX3bG1TjOBLn14V674q+iwZpalyKzZxGRNzA11I= +github.com/filecoin-project/specs-storage v0.0.0-20200317225704-7420bc655c38/go.mod h1:dUmzHS7izOD6HW3/JpzFrjxnptxbsHXBlO8puK2UzBk= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1/go.mod h1:0eHX/BVySxPc6SE2mZRoppGq7qcEagxdmQnA3dzork8= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= +github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/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/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f h1:KMlcu9X58lhTA/KrfX8Bi1LQSO4pzoVjTiL3h4Jk+Zk= +github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc= +github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +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= +github.com/hannahhoward/cbor-gen-for v0.0.0-20191216214420-3e450425c40c/go.mod h1:WVPCl0HO/0RAL5+vBH2GMxBomlxBF70MAS78+Lu1//k= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huin/goupnp v0.0.0-20180415215157-1395d1447324/go.mod h1:MZ2ZmwcBpvOoJ22IJsc7va19ZwoheaBk43rKg12SKag= +github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= +github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/influxdata/influxdb1-client v0.0.0-20190809212627-fc22c7df067e/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/ipfs/bbloom v0.0.1/go.mod h1:oqo8CVWsJFMOZqTglBG4wydCE4IQA/G2/SEofB0rjUI= +github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= +github.com/ipfs/go-bitswap v0.0.9/go.mod h1:kAPf5qgn2W2DrgAcscZ3HrM9qh4pH+X8Fkk3UPrwvis= +github.com/ipfs/go-bitswap v0.1.0/go.mod h1:FFJEf18E9izuCqUtHxbWEvq+reg7o4CW5wSAE1wsxj0= +github.com/ipfs/go-bitswap v0.1.2/go.mod h1:qxSWS4NXGs7jQ6zQvoPY3+NmOfHHG47mhkiLzBpJQIs= +github.com/ipfs/go-bitswap v0.1.3/go.mod h1:YEQlFy0kkxops5Vy+OxWdRSEZIoS7I7KDIwoa5Chkps= +github.com/ipfs/go-bitswap v0.1.8/go.mod h1:TOWoxllhccevbWFUR2N7B1MTSVVge1s6XSMiCSA4MzM= +github.com/ipfs/go-block-format v0.0.1/go.mod h1:DK/YYcsSUIVAFNwo/KZCdIIbpN0ROH/baNLgayt4pFc= +github.com/ipfs/go-block-format v0.0.2 h1:qPDvcP19izTjU8rgo6p7gTXZlkMkF5bz5G3fqIsSCPE= +github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= +github.com/ipfs/go-blockservice v0.0.7/go.mod h1:EOfb9k/Y878ZTRY/CH0x5+ATtaipfbRhbvNSdgc/7So= +github.com/ipfs/go-blockservice v0.1.0/go.mod h1:hzmMScl1kXHg3M2BjTymbVPjv627N7sYcvYaKbop39M= +github.com/ipfs/go-blockservice v0.1.3-0.20190908200855-f22eea50656c/go.mod h1:t+411r7psEUhLueM8C7aPA7cxCclv4O3VsUVxt9kz2I= +github.com/ipfs/go-car v0.0.3-0.20191203022317-23b0a85fd1b1/go.mod h1:rmd887mJxQRDfndfDEY3Liyx8gQVyfFFRSHdsnDSAlk= +github.com/ipfs/go-car v0.0.3-0.20200121013634-f188c0e24291/go.mod h1:AG6sBpd2PWMccpAG7XLFBBQ/4rfBEtzUNeO2GSMesYk= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.4-0.20191112011718-79e75dffeb10/go.mod h1:/BYOuUoxkE+0f6tGzlzMvycuN+5l35VOR4Bpg2sCmds= +github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= +github.com/ipfs/go-cid v0.0.5 h1:o0Ix8e/ql7Zb5UVUJEUfjsWCIY8t48++9lR8qi6oiJU= +github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= +github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-datastore v0.0.5/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-datastore v0.1.0/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-datastore v0.1.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw= +github.com/ipfs/go-datastore v0.3.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw= +github.com/ipfs/go-datastore v0.4.4 h1:rjvQ9+muFaJ+QZ7dN5B1MSDNQ0JVZKkkES/rMZmA8X8= +github.com/ipfs/go-datastore v0.4.4/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= +github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= +github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= +github.com/ipfs/go-ds-badger v0.0.5/go.mod h1:g5AuuCGmr7efyzQhLL8MzwqcauPojGPUaHzfGTzuE3s= +github.com/ipfs/go-ds-badger v0.0.7/go.mod h1:qt0/fWzZDoPW6jpQeqUjR5kBfhDNB65jd9YlmAvpQBk= +github.com/ipfs/go-ds-badger2 v0.0.0-20200123200730-d75eb2678a5d/go.mod h1:sTQFaWUoW0OvhXzfHnQ9j39L6fdlqDkptDYcpC1XrYE= +github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= +github.com/ipfs/go-ds-leveldb v0.1.0/go.mod h1:hqAW8y4bwX5LWcCtku2rFNX3vjDZCy5LZCg+cSZvYb8= +github.com/ipfs/go-filestore v0.0.2/go.mod h1:KnZ41qJsCt2OX2mxZS0xsK3Psr0/oB93HMMssLujjVc= +github.com/ipfs/go-fs-lock v0.0.1/go.mod h1:DNBekbboPKcxs1aukPSaOtFA3QfSdi5C855v0i9XJ8Y= +github.com/ipfs/go-graphsync v0.0.4/go.mod h1:6UACBjfOXEa8rQL3Q/JpZpWS0nZDCLx134WUkjrmFpQ= +github.com/ipfs/go-hamt-ipld v0.0.14-0.20191218031521-b2c774a54db1/go.mod h1:8yRx0xLUps1Xq8ZDnIwIVdQRp7JjA55gGvCiRHT91Vk= +github.com/ipfs/go-hamt-ipld v0.0.15-0.20200131012125-dd88a59d3f2e/go.mod h1:9aQJu/i/TaRDW6jqB5U217dLIDopn50wxLdHXM2CTfE= +github.com/ipfs/go-hamt-ipld v0.0.15-0.20200204200533-99b8553ef242 h1:OYVGeYkGSRZdBJ35JHPXQ9deQxlLtJ3Ln0FuaJOu6x8= +github.com/ipfs/go-hamt-ipld v0.0.15-0.20200204200533-99b8553ef242/go.mod h1:kq3Pi+UP3oHhAdKexE+kHHYRKMoFNuGero0R7q3hWGg= +github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= +github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw= +github.com/ipfs/go-ipfs-blockstore v0.1.1/go.mod h1:8gZOgIN5e+Xdg2YSGdwTTRbguSVjYyosIDRQCY8E9QM= +github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= +github.com/ipfs/go-ipfs-chunker v0.0.1/go.mod h1:tWewYK0we3+rMbOh7pPFGDyypCtvGcBFymgY4rSDLAw= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-ds-help v0.0.1/go.mod h1:gtP9xRaZXqIQRh1HRpp595KbBEdgqWFxefeVKOV8sxo= +github.com/ipfs/go-ipfs-exchange-interface v0.0.1/go.mod h1:c8MwfHjtQjPoDyiy9cFquVtVHkO9b9Ob3FG91qJnWCM= +github.com/ipfs/go-ipfs-exchange-offline v0.0.1/go.mod h1:WhHSFCVYX36H/anEKQboAzpUws3x7UeEGkzQc3iNkM0= +github.com/ipfs/go-ipfs-files v0.0.3/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4= +github.com/ipfs/go-ipfs-files v0.0.4/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4= +github.com/ipfs/go-ipfs-files v0.0.7 h1:s5BRD12ndahqYifeH1S8Z73zqZhR+3IdKYAG9PiETs0= +github.com/ipfs/go-ipfs-files v0.0.7/go.mod h1:wiN/jSG8FKyk7N0WyctKSvq3ljIa2NNTiZB55kpTdOs= +github.com/ipfs/go-ipfs-flags v0.0.1/go.mod h1:RnXBb9WV53GSfTrSDVK61NLTFKvWc60n+K9EgCDh+rA= +github.com/ipfs/go-ipfs-posinfo v0.0.1/go.mod h1:SwyeVP+jCwiDu0C313l/8jg6ZxM0qqtlt2a0vILTc1A= +github.com/ipfs/go-ipfs-pq v0.0.1/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= +github.com/ipfs/go-ipfs-routing v0.0.1/go.mod h1:k76lf20iKFxQTjcJokbPM9iBXVXVZhcOwc360N4nuKs= +github.com/ipfs/go-ipfs-routing v0.1.0/go.mod h1:hYoUkJLyAUKhF58tysKpids8RNDPO42BVMgK5dNsoqY= +github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/ipfs/go-ipld-cbor v0.0.2/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA0AQFOn7Nc= +github.com/ipfs/go-ipld-cbor v0.0.3/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA0AQFOn7Nc= +github.com/ipfs/go-ipld-cbor v0.0.4/go.mod h1:BkCduEx3XBCO6t2Sfo5BaHzuok7hbhdMm9Oh8B2Ftq4= +github.com/ipfs/go-ipld-cbor v0.0.5-0.20200204214505-252690b78669 h1:jIVle1vGSzxyUhseYNEqd7qcDVRrIbJ7UxGwao70cF0= +github.com/ipfs/go-ipld-cbor v0.0.5-0.20200204214505-252690b78669/go.mod h1:BkCduEx3XBCO6t2Sfo5BaHzuok7hbhdMm9Oh8B2Ftq4= +github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= +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 v1.0.0/go.mod h1:JO7RzlMK6rA+CIxFMLOuB6Wf5b81GDiKElL7UPSIKjA= +github.com/ipfs/go-log v1.0.1/go.mod h1:HuWlQttfN6FWNHRhlY5yMk/lW7evQC0HHGOxEwMRR8I= +github.com/ipfs/go-log v1.0.3 h1:Gg7SUYSZ7BrqaKMwM+hRgcAkKv4QLfzP4XPQt5Sx/OI= +github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= +github.com/ipfs/go-log/v2 v2.0.1/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= +github.com/ipfs/go-log/v2 v2.0.2/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= +github.com/ipfs/go-log/v2 v2.0.3 h1:Q2gXcBoCALyLN/pUQlz1qgu0x3uFV6FzP9oXhpfyJpc= +github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= +github.com/ipfs/go-merkledag v0.0.6/go.mod h1:QYPdnlvkOg7GnQRofu9XZimC5ZW5Wi3bKys/4GQQfto= +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/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB3ClKnBAlk= +github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= +github.com/ipfs/go-path v0.0.7/go.mod h1:6KTKmeRnBXgqrTvzFrPV3CamxcgvXX/4z79tfAd2Sno= +github.com/ipfs/go-peertaskqueue v0.0.4/go.mod h1:03H8fhyeMfKNFWqzYEVyMbcPUeYrqP1MX6Kd+aN+rMQ= +github.com/ipfs/go-peertaskqueue v0.1.0/go.mod h1:Jmk3IyCcfl1W3jTW3YpghSwSEC6IJ3Vzz/jUmWw8Z0U= +github.com/ipfs/go-peertaskqueue v0.1.1/go.mod h1:Jmk3IyCcfl1W3jTW3YpghSwSEC6IJ3Vzz/jUmWw8Z0U= +github.com/ipfs/go-todocounter v0.0.1/go.mod h1:l5aErvQc8qKE2r7NDMjmq5UNAvuZy0rC8BHOplkWvZ4= +github.com/ipfs/go-unixfs v0.2.2-0.20190827150610-868af2e9e5cb/go.mod h1:IwAAgul1UQIcNZzKPYZWOCijryFBeCV79cNubPzol+k= +github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= +github.com/ipld/go-ipld-prime v0.0.1/go.mod h1:bDDSvVz7vaK12FNvMeRYnpRFkSUPNQOiCYQezMD/P3w= +github.com/ipld/go-ipld-prime v0.0.2-0.20191108012745-28a82f04c785/go.mod h1:bDDSvVz7vaK12FNvMeRYnpRFkSUPNQOiCYQezMD/P3w= +github.com/ipld/go-ipld-prime-proto v0.0.0-20191113031812-e32bd156a1e5/go.mod h1:gcvzoEDBjwycpXt3LBE061wT9f46szXGHAmj9uoP6fU= +github.com/ipsn/go-secp256k1 v0.0.0-20180726113642-9d62b9f0bc52 h1:QG4CGBqCeuBo6aZlGAamSkxWdgWfZGeE49eUOWJPA4c= +github.com/ipsn/go-secp256k1 v0.0.0-20180726113642-9d62b9f0bc52/go.mod h1:fdg+/X9Gg4AsAIzWpEHwnqd+QY3b7lajxyjE1m4hkq4= +github.com/jackpal/gateway v1.0.4/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= +github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= +github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs= +github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= +github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c/go.mod h1:sdx1xVM9UuLw1tXnhJWN3piypTUO3vCIHYmG15KE/dU= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jbenet/goprocess v0.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr10= +github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 h1:rp+c0RAYOWj8l6qbCUTSiRLG/iKnW3K3/QfPPuSsBt4= +github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +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= +github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= +github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= +github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= +github.com/libp2p/go-conn-security v0.0.1/go.mod h1:bGmu51N0KU9IEjX7kl2PQjgZa40JQWnayTvNMgD/vyk= +github.com/libp2p/go-conn-security-multistream v0.0.2/go.mod h1:nc9vud7inQ+d6SO0I/6dSWrdMnHnzZNHeyUQqrAJulE= +github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= +github.com/libp2p/go-eventbus v0.0.2/go.mod h1:Hr/yGlwxA/stuLnpMiu82lpNKpvRy3EaJxPu40XYOwk= +github.com/libp2p/go-eventbus v0.0.3/go.mod h1:Hr/yGlwxA/stuLnpMiu82lpNKpvRy3EaJxPu40XYOwk= +github.com/libp2p/go-eventbus v0.1.0/go.mod h1:vROgu5cs5T7cv7POWlWxBaVLxfSegC5UGQf8A2eEmx4= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= +github.com/libp2p/go-libp2p v0.0.30/go.mod h1:XWT8FGHlhptAv1+3V/+J5mEpzyui/5bvFsNuWYs611A= +github.com/libp2p/go-libp2p v0.1.0/go.mod h1:6D/2OBauqLUoqcADOJpn9WbKqvaM07tDw68qHM0BxUM= +github.com/libp2p/go-libp2p v0.1.1/go.mod h1:I00BRo1UuUSdpuc8Q2mN7yDF/oTUTRAX6JWpTiK9Rp8= +github.com/libp2p/go-libp2p v0.2.1/go.mod h1:HZbtEOrgZN4F1fGZVvkV+930Wx3DkqlpBlO8dIoZWds= +github.com/libp2p/go-libp2p v0.3.0/go.mod h1:J7DPB1+zB5VLc8v/kKSD8+u2cbyIGI0Dh/Pf3Wprt+0= +github.com/libp2p/go-libp2p v0.4.2/go.mod h1:MNmgUxUw5pMsdOzMlT0EE7oKjRasl+WyVwM0IBlpKgQ= +github.com/libp2p/go-libp2p-autonat v0.0.6/go.mod h1:uZneLdOkZHro35xIhpbtTzLlgYturpu4J5+0cZK3MqE= +github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= +github.com/libp2p/go-libp2p-autonat v0.1.1/go.mod h1:OXqkeGOY2xJVWKAGV2inNF5aKN/djNA3fdpCWloIudE= +github.com/libp2p/go-libp2p-blankhost v0.0.1/go.mod h1:Ibpbw/7cPPYwFb7PACIWdvxxv0t0XCCI10t7czjAjTc= +github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro= +github.com/libp2p/go-libp2p-blankhost v0.1.3/go.mod h1:KML1//wiKR8vuuJO0y3LUd1uLv+tlkGTAr3jC0S5cLg= +github.com/libp2p/go-libp2p-blankhost v0.1.4/go.mod h1:oJF0saYsAXQCSfDq254GMNmLNz6ZTHTOvtF4ZydUvwU= +github.com/libp2p/go-libp2p-circuit v0.0.9/go.mod h1:uU+IBvEQzCu953/ps7bYzC/D/R0Ho2A9LfKVVCatlqU= +github.com/libp2p/go-libp2p-circuit v0.1.0/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8= +github.com/libp2p/go-libp2p-circuit v0.1.1/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8= +github.com/libp2p/go-libp2p-circuit v0.1.4/go.mod h1:CY67BrEjKNDhdTk8UgBX1Y/H5c3xkAcs3gnksxY7osU= +github.com/libp2p/go-libp2p-connmgr v0.1.0/go.mod h1:wZxh8veAmU5qdrfJ0ZBLcU8oJe9L82ciVP/fl1VHjXk= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-core v0.0.2/go.mod h1:9dAcntw/n46XycV4RnlBq3BpgrmyUi9LuoTNdPrbUco= +github.com/libp2p/go-libp2p-core v0.0.3/go.mod h1:j+YQMNz9WNSkNezXOsahp9kwZBKBvxLpKD316QWSJXE= +github.com/libp2p/go-libp2p-core v0.0.4/go.mod h1:jyuCQP356gzfCFtRKyvAbNkyeuxb7OlyhWZ3nls5d2I= +github.com/libp2p/go-libp2p-core v0.0.6/go.mod h1:0d9xmaYAVY5qmbp/fcgxHT3ZJsLjYeYPMJAUKpaCHrE= +github.com/libp2p/go-libp2p-core v0.0.9/go.mod h1:0d9xmaYAVY5qmbp/fcgxHT3ZJsLjYeYPMJAUKpaCHrE= +github.com/libp2p/go-libp2p-core v0.2.0/go.mod h1:X0eyB0Gy93v0DZtSYbEM7RnMChm9Uv3j7yRXjO77xSI= +github.com/libp2p/go-libp2p-core v0.2.2/go.mod h1:8fcwTbsG2B+lTgRJ1ICZtiM5GWCWZVoVrLaDRvIRng0= +github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= +github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= +github.com/libp2p/go-libp2p-core v0.5.0 h1:FBQ1fpq2Fo/ClyjojVJ5AKXlKhvNc/B6U0O+7AN1ffE= +github.com/libp2p/go-libp2p-core v0.5.0/go.mod h1:49XGI+kc38oGVwqSBhDEwytaAxgZasHhFfQKibzTls0= +github.com/libp2p/go-libp2p-crypto v0.0.1/go.mod h1:yJkNyDmO341d5wwXxDUGO0LykUVT72ImHNUqh5D/dBE= +github.com/libp2p/go-libp2p-crypto v0.0.2/go.mod h1:eETI5OUfBnvARGOHrJz2eWNyTUxEGZnBxMcbUjfIj4I= +github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= +github.com/libp2p/go-libp2p-discovery v0.0.5/go.mod h1:YtF20GUxjgoKZ4zmXj8j3Nb2TUSBHFlOCetzYdbZL5I= +github.com/libp2p/go-libp2p-discovery v0.1.0/go.mod h1:4F/x+aldVHjHDHuX85x1zWoFTGElt8HnoDzwkFZm29g= +github.com/libp2p/go-libp2p-discovery v0.2.0/go.mod h1:s4VGaxYMbw4+4+tsoQTqh7wfxg97AEdo4GYBt6BadWg= +github.com/libp2p/go-libp2p-host v0.0.1/go.mod h1:qWd+H1yuU0m5CwzAkvbSjqKairayEHdR5MMl7Cwa7Go= +github.com/libp2p/go-libp2p-host v0.0.3/go.mod h1:Y/qPyA6C8j2coYyos1dfRm0I8+nvd4TGrDGt4tA7JR8= +github.com/libp2p/go-libp2p-interface-connmgr v0.0.1/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= +github.com/libp2p/go-libp2p-interface-connmgr v0.0.4/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= +github.com/libp2p/go-libp2p-interface-connmgr v0.0.5/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= +github.com/libp2p/go-libp2p-interface-pnet v0.0.1/go.mod h1:el9jHpQAXK5dnTpKA4yfCNBZXvrzdOU75zz+C6ryp3k= +github.com/libp2p/go-libp2p-kad-dht v0.1.1/go.mod h1:1kj2Rk5pX3/0RwqMm9AMNCT7DzcMHYhgDN5VTi+cY0M= +github.com/libp2p/go-libp2p-kbucket v0.2.0/go.mod h1:JNymBToym3QXKBMKGy3m29+xprg0EVr/GJFHxFEdgh8= +github.com/libp2p/go-libp2p-loggables v0.0.1/go.mod h1:lDipDlBNYbpyqyPX/KcoO+eq0sJYEVR2JgOexcivchg= +github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= +github.com/libp2p/go-libp2p-metrics v0.0.1/go.mod h1:jQJ95SXXA/K1VZi13h52WZMa9ja78zjyy5rspMsC/08= +github.com/libp2p/go-libp2p-mplex v0.1.1/go.mod h1:KUQWpGkCzfV7UIpi8SKsAVxyBgz1c9R5EvxgnwLsb/I= +github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3g+OtR+EMMODbKo= +github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= +github.com/libp2p/go-libp2p-nat v0.0.4/go.mod h1:N9Js/zVtAXqaeT99cXgTV9e75KpnWCvVOiGzlcHmBbY= +github.com/libp2p/go-libp2p-nat v0.0.5/go.mod h1:1qubaE5bTZMJE+E/uu2URroMbzdubFz1ChgiN79yKPE= +github.com/libp2p/go-libp2p-net v0.0.1/go.mod h1:Yt3zgmlsHOgUWSXmt5V/Jpz9upuJBE8EgNU9DrCcR8c= +github.com/libp2p/go-libp2p-net v0.0.2/go.mod h1:Yt3zgmlsHOgUWSXmt5V/Jpz9upuJBE8EgNU9DrCcR8c= +github.com/libp2p/go-libp2p-netutil v0.0.1/go.mod h1:GdusFvujWZI9Vt0X5BKqwWWmZFxecf9Gt03cKxm2f/Q= +github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU= +github.com/libp2p/go-libp2p-peer v0.0.1/go.mod h1:nXQvOBbwVqoP+T5Y5nCjeH4sP9IX/J0AMzcDUVruVoo= +github.com/libp2p/go-libp2p-peer v0.1.1/go.mod h1:jkF12jGB4Gk/IOo+yomm+7oLWxF278F7UnrYUQ1Q8es= +github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= +github.com/libp2p/go-libp2p-peerstore v0.0.1/go.mod h1:RabLyPVJLuNQ+GFyoEkfi8H4Ti6k/HtZJ7YKgtSq+20= +github.com/libp2p/go-libp2p-peerstore v0.0.6/go.mod h1:RabLyPVJLuNQ+GFyoEkfi8H4Ti6k/HtZJ7YKgtSq+20= +github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY= +github.com/libp2p/go-libp2p-peerstore v0.1.2/go.mod h1:BJ9sHlm59/80oSkpWgr1MyY1ciXAXV397W6h1GH/uKI= +github.com/libp2p/go-libp2p-peerstore v0.1.3/go.mod h1:BJ9sHlm59/80oSkpWgr1MyY1ciXAXV397W6h1GH/uKI= +github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs= +github.com/libp2p/go-libp2p-protocol v0.0.1/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1VZNHYcK8cLgFJLZ4s= +github.com/libp2p/go-libp2p-protocol v0.1.0/go.mod h1:KQPHpAabB57XQxGrXCNvbL6UEXfQqUgC/1adR2Xtflk= +github.com/libp2p/go-libp2p-pubsub v0.2.6/go.mod h1:5jEp7R3ItQ0pgcEMrPZYE9DQTg/H3CTc7Mu1j2G4Y5o= +github.com/libp2p/go-libp2p-quic-transport v0.1.1/go.mod h1:wqG/jzhF3Pu2NrhJEvE+IE0NTHNXslOPn9JQzyCAxzU= +github.com/libp2p/go-libp2p-record v0.0.1/go.mod h1:grzqg263Rug/sRex85QrDOLntdFAymLDLm7lxMgU79Q= +github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= +github.com/libp2p/go-libp2p-record v0.1.1/go.mod h1:VRgKajOyMVgP/F0L5g3kH7SVskp17vFi2xheb5uMJtg= +github.com/libp2p/go-libp2p-routing v0.0.1/go.mod h1:N51q3yTr4Zdr7V8Jt2JIktVU+3xBBylx1MZeVA6t1Ys= +github.com/libp2p/go-libp2p-routing v0.1.0/go.mod h1:zfLhI1RI8RLEzmEaaPwzonRvXeeSHddONWkcTcB54nE= +github.com/libp2p/go-libp2p-routing-helpers v0.1.0/go.mod h1:oUs0h39vNwYtYXnQWOTU5BaafbedSyWCCal3gqHuoOQ= +github.com/libp2p/go-libp2p-secio v0.0.3/go.mod h1:hS7HQ00MgLhRO/Wyu1bTX6ctJKhVpm+j2/S2A5UqYb0= +github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= +github.com/libp2p/go-libp2p-secio v0.1.1/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= +github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g= +github.com/libp2p/go-libp2p-secio v0.2.1/go.mod h1:cWtZpILJqkqrSkiYcDBh5lA3wbT2Q+hz3rJQq3iftD8= +github.com/libp2p/go-libp2p-swarm v0.0.6/go.mod h1:s5GZvzg9xXe8sbeESuFpjt8CJPTCa8mhEusweJqyFy8= +github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4= +github.com/libp2p/go-libp2p-swarm v0.1.1/go.mod h1:4NVJaLwq/dr5kEq79Jo6pMin7ZFwLx73ln1FTefR91Q= +github.com/libp2p/go-libp2p-swarm v0.2.0/go.mod h1:x07b4zkMFo2EvgPV2bMTlNmdQc8i+74Jjio7xGvsTgU= +github.com/libp2p/go-libp2p-swarm v0.2.2/go.mod h1:fvmtQ0T1nErXym1/aa1uJEyN7JzaTNyBcHImCxRpPKU= +github.com/libp2p/go-libp2p-testing v0.0.1/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.4/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.1.0/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0= +github.com/libp2p/go-libp2p-tls v0.1.0/go.mod h1:VZdoSWQDeNpIIAFJFv+6uqTqpnIIDHcqZQSTC/A1TT0= +github.com/libp2p/go-libp2p-transport v0.0.1/go.mod h1:UzbUs9X+PHOSw7S3ZmeOxfnwaQY5vGDzZmKPod3N3tk= +github.com/libp2p/go-libp2p-transport v0.0.4/go.mod h1:StoY3sx6IqsP6XKoabsPnHCwqKXWUMWU7Rfcsubee/A= +github.com/libp2p/go-libp2p-transport v0.0.5/go.mod h1:StoY3sx6IqsP6XKoabsPnHCwqKXWUMWU7Rfcsubee/A= +github.com/libp2p/go-libp2p-transport-upgrader v0.0.4/go.mod h1:RGq+tupk+oj7PzL2kn/m1w6YXxcIAYJYeI90h6BGgUc= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= +github.com/libp2p/go-libp2p-yamux v0.1.2/go.mod h1:xUoV/RmYkg6BW/qGxA9XJyg+HzXFYkeXbnhjmnYzKp8= +github.com/libp2p/go-libp2p-yamux v0.1.3/go.mod h1:VGSQVrqkh6y4nm0189qqxMtvyBft44MOYYPpYKXiVt4= +github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= +github.com/libp2p/go-libp2p-yamux v0.2.1/go.mod h1:1FBXiHDk1VyRM1C0aez2bCfHQ4vMZKkAQzZbkSQt5fI= +github.com/libp2p/go-maddr-filter v0.0.1/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= +github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= +github.com/libp2p/go-maddr-filter v0.0.5/go.mod h1:Jk+36PMfIqCJhAnaASRH83bdAvfDRp/w6ENFaC9bG+M= +github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= +github.com/libp2p/go-mplex v0.0.4/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= +github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= +github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-msgio v0.0.3/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-nat v0.0.3/go.mod h1:88nUEt0k0JD45Bk93NIwDqjlhiOwOoV36GchpcVc1yI= +github.com/libp2p/go-nat v0.0.4/go.mod h1:Nmw50VAvKuk38jUBcmNh6p9lUJLoODbJRvYAa/+KSDo= +github.com/libp2p/go-openssl v0.0.2/go.mod h1:v8Zw2ijCSWBQi8Pq5GAixw6DbFfa9u6VIYDXnvOXkc0= +github.com/libp2p/go-openssl v0.0.3/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= +github.com/libp2p/go-openssl v0.0.4 h1:d27YZvLoTyMhIN4njrkr8zMDOM4lfpHIp6A+TK9fovg= +github.com/libp2p/go-openssl v0.0.4/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= +github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= +github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= +github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= +github.com/libp2p/go-stream-muxer v0.1.0/go.mod h1:8JAVsjeRBCWwPoZeH0W1imLOcriqXJyFvB0mR4A04sQ= +github.com/libp2p/go-stream-muxer-multistream v0.1.1/go.mod h1:zmGdfkQ1AzOECIAcccoL8L//laqawOsO03zX8Sa+eGw= +github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc= +github.com/libp2p/go-tcp-transport v0.0.4/go.mod h1:+E8HvC8ezEVOxIo3V5vCK9l1y/19K427vCzQ+xHKH/o= +github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc= +github.com/libp2p/go-tcp-transport v0.1.1/go.mod h1:3HzGvLbx6etZjnFlERyakbaYPdfjg2pWP97dFZworkY= +github.com/libp2p/go-testutil v0.0.1/go.mod h1:iAcJc/DKJQanJ5ws2V+u5ywdL2n12X1WbbEG+Jjy69I= +github.com/libp2p/go-testutil v0.1.0/go.mod h1:81b2n5HypcVyrCg/MJx4Wgfp/VHojytjVe/gLzZ2Ehc= +github.com/libp2p/go-ws-transport v0.0.5/go.mod h1:Qbl4BxPfXXhhd/o0wcrgoaItHqA9tnZjoFZnxykuaXU= +github.com/libp2p/go-ws-transport v0.1.0/go.mod h1:rjw1MG1LU9YDC6gzmwObkPd/Sqwhw7yT74kj3raBFuo= +github.com/libp2p/go-ws-transport v0.1.2/go.mod h1:dsh2Ld8F+XNmzpkaAijmg5Is+e9l6/1tK/6VFOdN69Y= +github.com/libp2p/go-yamux v1.2.1/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/libp2p/go-yamux v1.2.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/lucas-clemente/quic-go v0.11.2/go.mod h1:PpMmPfPKO9nKJ/psF49ESTAGQSdfXxlg1otPbEB2nOw= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +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/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.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54= +github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= +github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/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= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/mr-tron/base58 v1.1.3 h1:v+sk57XuaCKGXpWtVBX8YJzO7hMGx4Aajh4TQbdEFdc= +github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.4/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/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= +github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= +github.com/multiformats/go-multiaddr v0.2.1 h1:SgG/cw5vqyB5QQe5FPe2TqggU9WtrA9X4nZw7LlVqOI= +github.com/multiformats/go-multiaddr v0.2.1/go.mod h1:s/Apk6IyxfvMjDafnhJgJ3/46z7tZ04iMk5wP4QMGGE= +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/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/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q= +github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= +github.com/multiformats/go-multiaddr-net v0.1.0/go.mod h1:5JNbcfBOP4dnhoZOv10JJVkJO0pCCEf8mTnipAo2UZQ= +github.com/multiformats/go-multiaddr-net v0.1.1/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.6/go.mod h1:XuKXPp8VHcTygube3OWZC+aZrA+H1IhmjoCDtJc7PXM= +github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= +github.com/multiformats/go-multihash v0.0.9/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= +github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= +github.com/multiformats/go-multihash v0.0.13 h1:06x+mk/zj1FoMsgNejLpy6QTvJqlSt/BhLEy87zidlc= +github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= +github.com/multiformats/go-multistream v0.0.1/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/multiformats/go-multistream v0.0.4/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/multiformats/go-multistream v0.1.1/go.mod h1:KmHZ40hzVxiaiwlj3MEbYgK9JFk2/9UktWZAF54Du38= +github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/multiformats/go-varint v0.0.2/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/multiformats/go-varint v0.0.5 h1:XVZwSo04Cs3j/jS0uAEPpT3JY6DzMcVLLoWOSnCxOjg= +github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.9.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.6.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/otiai10/copy v1.0.2/go.mod h1:c7RpqBkwMom4bYTSkLSym4VSJz/XtncWRAj/J4PEIMY= +github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= +github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= +github.com/polydawn/refmt v0.0.0-20190408063855-01bf1e26dd14/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= +github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= +github.com/polydawn/refmt v0.0.0-20190809202753-05966cbd336a h1:hjZfReYVLbqFkAtr2us7vdy04YWz3LVAirzP7reh8+M= +github.com/polydawn/refmt v0.0.0-20190809202753-05966cbd336a/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190425082905-87a4384529e0 h1:c8R11WC8m7KNMkTv/0+Be8vvwo4I3/Ut9AC2FW8fX3U= +github.com/prometheus/procfs v0.0.0-20190425082905-87a4384529e0/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/shirou/gopsutil v2.18.12+incompatible h1:1eaJvGomDnH74/5cF4CTmTbLHAriGFsTZppLXDX93OM= +github.com/shirou/gopsutil v2.18.12+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= +github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w= +github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= +github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa/go.mod h1:2RVY1rIf+2J2o/IM9+vPq9RzmHDSseB7FoXiSNIUsoU= +github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smartystreets/goconvey v0.0.0-20190710185942-9d28bd7c0945/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8= +github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/R4aaNBc= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +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/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli/v2 v2.0.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= +github.com/warpfork/go-wish v0.0.0-20190328234359-8b3e70f8e830 h1:8kxMKmKzXXL4Ru1nyhvdms/JjWt+3YLpvRb/bAjO/y0= +github.com/warpfork/go-wish v0.0.0-20190328234359-8b3e70f8e830/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= +github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= +github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba h1:X4n8JG2e2biEZZXdBKt9HX7DN3bYGFUqljqqy0DqgnY= +github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba/go.mod h1:CHQnYnQUEPydYCwuy8lmTHfGmdw9TKrhWV0xLx8l0oM= +github.com/whyrusleeping/cbor-gen v0.0.0-20190910031516-c1cbffdb01bb/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY= +github.com/whyrusleeping/cbor-gen v0.0.0-20190917003517-d78d67427694/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY= +github.com/whyrusleeping/cbor-gen v0.0.0-20191116002219-891f55cd449d/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY= +github.com/whyrusleeping/cbor-gen v0.0.0-20191212224538-d370462a7e8a/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY= +github.com/whyrusleeping/cbor-gen v0.0.0-20191216205031-b047b6acb3c0/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY= +github.com/whyrusleeping/cbor-gen v0.0.0-20200121162646-b63bacf5eaf8/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY= +github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= +github.com/whyrusleeping/cbor-gen v0.0.0-20200206220010-03c9665e2a66/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= +github.com/whyrusleeping/cbor-gen v0.0.0-20200321164527-9340289d0ca7 h1:SVU2yhhHHamTPIMT9kk28KSYdO3ykTZeIp5p+6G9qNk= +github.com/whyrusleeping/cbor-gen v0.0.0-20200321164527-9340289d0ca7/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= +github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f/go.mod h1:cZNvX9cFybI01GriPRMXDtczuvUhgbcYr9iCGaNlRv8= +github.com/whyrusleeping/go-smux-multiplex v3.0.16+incompatible/go.mod h1:34LEDbeKFZInPUrAG+bjuJmUXONGdEFW7XL0SpTY1y4= +github.com/whyrusleeping/go-smux-multistream v2.0.2+incompatible/go.mod h1:dRWHHvc4HDQSHh9gbKEBbUZ+f2Q8iZTPG3UOGYODxSQ= +github.com/whyrusleeping/go-smux-yamux v2.0.8+incompatible/go.mod h1:6qHUzBXUbB9MXmw3AUdB52L8sEb/hScCqOdW2kj/wuI= +github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= +github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= +github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= +github.com/whyrusleeping/pubsub v0.0.0-20131020042734-02de8aa2db3d/go.mod h1:g7ckxrjiFh8mi1AY7ox23PZD0g6QU/TxW3U3unX7I3A= +github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee/go.mod h1:m2aV4LZI4Aez7dP5PMyVKEHhUyEJ/RjmPEDOpDvudHg= +github.com/whyrusleeping/yamux v1.1.5/go.mod h1:E8LnQQ8HKx5KD29HZFUwM1PxCOdPRzGwur1mcYhXcD8= +github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +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/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.5.1/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/dig v1.7.0/go.mod h1:z+dSd2TP9Usi48jL8M3v63iSBVkiwtVyMKxMZYYauPg= +go.uber.org/fx v1.9.0/go.mod h1:mFdUyAUuJ3w4jAckiKSKbldsxy1ojpAMJ+dVZg5Y0Aw= +go.uber.org/goleak v0.10.0/go.mod h1:VCZuO8V8mFPlL0F5J5GK1rtHV3DrFcQ1R8ryq7FK0aI= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.14.1 h1:nYDKopTbvAPq/NrUVZwT15y2lpROBiLLyoRTbXOYWOo= +go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= +go4.org v0.0.0-20190218023631-ce4c26f7be8e/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= +go4.org v0.0.0-20190313082347-94abd6928b1d/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200317142112-1b76d66859c6 h1:TjszyFsQsyZNHwdVdZ5m7bjmreu0znc2kRYsEml9/Ww= +golang.org/x/crypto v0.0.0-20200317142112-1b76d66859c6/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +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= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180524181706-dfa909b99c79/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-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-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/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/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/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180202135801-37707fdb30a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190302025703-b6889370fb10/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190524122548-abf6ff778158/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190524152521-dbbf3f1254d4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190526052359-791d8a0f4d09/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/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/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200317113312-5766fd39f98d h1:62ap6LNOjDU6uGmKXHJbSfciMoV+FeI1sRXx/pLDL44= +golang.org/x/sys v0.0.0-20200317113312-5766fd39f98d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +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= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200108195415-316d2f248479/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200318150045-ba25ddc85566 h1:OXjomkWHhzUx4+HldlJ2TsMxJdWgEo5CTtspD1wdhdk= +golang.org/x/tools v0.0.0-20200318150045-ba25ddc85566/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/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/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +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/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= +gopkg.in/cheggaaa/pb.v1 v1.0.28 h1:n1tBJnnK2r7g9OW2btFH91V92STTUevLXYFb8gy9EMk= +gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8= +gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +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/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= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +howett.net/plist v0.0.0-20181124034731-591f970eefbb h1:jhnBjNi9UFpfpl8YZhA9CrOqpnJdvzuiHsl/dnxl11M= +howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= +launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM= diff --git a/lib/nullreader/nullreader.go b/lib/nullreader/nullreader.go new file mode 100644 index 000000000..dc3537ad7 --- /dev/null +++ b/lib/nullreader/nullreader.go @@ -0,0 +1,11 @@ +package nullreader + +// TODO: extract this to someplace where it can be shared with lotus +type Reader struct{} + +func (Reader) Read(out []byte) (int, error) { + for i := range out { + out[i] = 0 + } + return len(out), nil +} From d4d58047b0d0a99c4f94589690083f454f36de39 Mon Sep 17 00:00:00 2001 From: laser Date: Mon, 6 Apr 2020 17:38:48 -0700 Subject: [PATCH 125/126] add licenses and basic readme scaffolding --- LICENSE | 201 ------------------------------------------------- LICENSE-APACHE | 5 ++ LICENSE-MIT | 19 +++++ README.md | 13 +++- 4 files changed, 36 insertions(+), 202 deletions(-) delete mode 100644 LICENSE create mode 100644 LICENSE-APACHE create mode 100644 LICENSE-MIT diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 261eeb9e9..000000000 --- a/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/LICENSE-APACHE b/LICENSE-APACHE new file mode 100644 index 000000000..14478a3b6 --- /dev/null +++ b/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/LICENSE-MIT b/LICENSE-MIT new file mode 100644 index 000000000..72dc60d84 --- /dev/null +++ b/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md index b09741e9c..cee2eb0cc 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,14 @@ # storage-fsm -A finite state machine used for sector storage +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![CircleCI](https://circleci.com/gh/filecoin-project/storage-fsm.svg?style=svg)](https://circleci.com/gh/filecoin-project/storage-fsm) +[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) + +> A finite state machine used for sector storage + +## License + +The Filecoin Project is dual-licensed under Apache 2.0 and MIT terms: + +- Apache License, Version 2.0, ([LICENSE-APACHE](https://github.com/filecoin-project/storage-fsm/blob/master/LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) +- MIT license ([LICENSE-MIT](https://github.com/filecoin-project/storage-fsm/blob/master/LICENSE-MIT) or http://opensource.org/licenses/MIT) From 32cf7ec677e66d1a8b903104afb3c51f82ad393b Mon Sep 17 00:00:00 2001 From: laser Date: Mon, 6 Apr 2020 17:40:12 -0700 Subject: [PATCH 126/126] need parameters.json for vk and groth parameter downloading (circleci) --- parameters.json | 82 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 parameters.json diff --git a/parameters.json b/parameters.json new file mode 100644 index 000000000..8591c1218 --- /dev/null +++ b/parameters.json @@ -0,0 +1,82 @@ +{ + "v24-proof-of-spacetime-election-PoseidonHasher-0b0b9781bcb153efbb3cab4be3a792c4f555d4ab6f8dd62b27e1dcad08a34f22.params": { + "cid": "QmUonpeUaLD6G4byFdZAMzwXorD4Qs1XDjmdXFbWYCgvjW", + "digest": "19e50903e53c826ff66f360283f324c1", + "sector_size": 34359738368 + }, + "v24-proof-of-spacetime-election-PoseidonHasher-0b0b9781bcb153efbb3cab4be3a792c4f555d4ab6f8dd62b27e1dcad08a34f22.vk": { + "cid": "QmVXv4Q1T3FbiY5AUgWER11Lsrby9aUVJy2mgWDWrndFbq", + "digest": "223dd87c6161c45daf448ca9eda28298", + "sector_size": 34359738368 + }, + "v24-proof-of-spacetime-election-PoseidonHasher-0b499a953f1a9dcab420b3ba1e6b1f3952dc7f17cf67ed10406ae9a43e2b8ec5.params": { + "cid": "Qmea7VsrYnkrpdMnutkGKppX5finoDwCA2fP5Zg5bDuBQw", + "digest": "3de5b8738a2cd933c214fa2023e30909", + "sector_size": 8388608 + }, + "v24-proof-of-spacetime-election-PoseidonHasher-0b499a953f1a9dcab420b3ba1e6b1f3952dc7f17cf67ed10406ae9a43e2b8ec5.vk": { + "cid": "QmavFXmf3jeacHKB6HoJH3gUqzmKnsDn5F5HSYfwPbDHRu", + "digest": "485b7eab4f70031fdda4eaeccfe4f26e", + "sector_size": 8388608 + }, + "v24-proof-of-spacetime-election-PoseidonHasher-27a7fc680a47e4821f40cf1676fb80b9888820ef6867a71a175b4c9ae068ad3f.params": { + "cid": "QmQrUjB9NSMuThe1JHoHfC7u1xdoLS6WLu15waWcnZ3tQT", + "digest": "7e6adc7cbf73db8c95a54e3c23bea1ae", + "sector_size": 536870912 + }, + "v24-proof-of-spacetime-election-PoseidonHasher-27a7fc680a47e4821f40cf1676fb80b9888820ef6867a71a175b4c9ae068ad3f.vk": { + "cid": "QmVPPk4fBcEero2GHsYuBoh97yhugTBWUp9yWSPPWjRWQ7", + "digest": "952b352d694d650e912b3b92ad63f7c9", + "sector_size": 536870912 + }, + "v24-proof-of-spacetime-election-PoseidonHasher-5916054ae98e28fc2f0470d1fb58eb875a6865be86f0b8c4e302d55f13217fef.params": { + "cid": "QmSXMF85mdGLQfAY98zVL4dUBpGPFFUPDmFzdc1NZrVFdh", + "digest": "a93de0f8cfb04af5d21f66ef48ee59a8", + "sector_size": 2048 + }, + "v24-proof-of-spacetime-election-PoseidonHasher-5916054ae98e28fc2f0470d1fb58eb875a6865be86f0b8c4e302d55f13217fef.vk": { + "cid": "QmaTsAmbdnQtJoSpkWsXmvHPpMJinzFYTe6t5LLm7w5RtQ", + "digest": "e4d0575f119e3e7b42bc3e5b6bb35a0b", + "sector_size": 2048 + }, + "v24-stacked-proof-of-replication-PoseidonHasher-Sha256Hasher-49442c8ce7545579cbd689d578301d0cc1e46e94e2499a0ec36de7ff4f4694a2.params": { + "cid": "QmYCFrU4G2LakPngFXayX7afyondQbB9hfnVRz1ffWD9MS", + "digest": "d64e5d1bbb9120bea4c0cd8cdcdfb834", + "sector_size": 8388608 + }, + "v24-stacked-proof-of-replication-PoseidonHasher-Sha256Hasher-49442c8ce7545579cbd689d578301d0cc1e46e94e2499a0ec36de7ff4f4694a2.vk": { + "cid": "QmfXAPtHKU2MJVJDwLTUCM4W2tYQ8biGq9cZaAnjtaZidZ", + "digest": "572536e8684454a5cd80361e5c952b38", + "sector_size": 8388608 + }, + "v24-stacked-proof-of-replication-PoseidonHasher-Sha256Hasher-d84aa4581c74190f845596893ebe5b71da32ecf16e1d151b9fff74ee8f94d77c.params": { + "cid": "QmdXtQsLbBFmVxrd6kWKr2FYbQfhEdR6PinwrGBXhHmLdT", + "digest": "77cfafee088bd59411d766621df6de42", + "sector_size": 536870912 + }, + "v24-stacked-proof-of-replication-PoseidonHasher-Sha256Hasher-d84aa4581c74190f845596893ebe5b71da32ecf16e1d151b9fff74ee8f94d77c.vk": { + "cid": "QmdE8oZJofaenThLi2TWXJPk9cExZgTA36TjrHeAC65BGA", + "digest": "30586a2396ef6b60b122ac5a2ba87681", + "sector_size": 536870912 + }, + "v24-stacked-proof-of-replication-PoseidonHasher-Sha256Hasher-fc32be6028c2398175466f36fa36810842ae8948fae15c84454af5b61ca99e15.params": { + "cid": "QmNqcqGxf7pJjipHNwcH44D5KgiTUNo3mK5HiSxBwYcjkx", + "digest": "25ea39db2a003c817113f6f2ea936b3d", + "sector_size": 34359738368 + }, + "v24-stacked-proof-of-replication-PoseidonHasher-Sha256Hasher-fc32be6028c2398175466f36fa36810842ae8948fae15c84454af5b61ca99e15.vk": { + "cid": "QmWiaqy8hWshv2FsLDoZAtpJKZng5QN3x2X5C7xsPvSbFb", + "digest": "ab1239c802c480cf12f63d13fb2f620a", + "sector_size": 34359738368 + }, + "v24-stacked-proof-of-replication-PoseidonHasher-Sha256Hasher-fe437922fe766f61b112750506d6be0e4ad5daa85ff9ce96549d99253ba61cbe.params": { + "cid": "QmbPk3fKKLjkm6pD1CzwGyTnMwNSSZVxVSMWEceqSv6LDW", + "digest": "76bd3702312cfe0d69bb5e0891c52615", + "sector_size": 2048 + }, + "v24-stacked-proof-of-replication-PoseidonHasher-Sha256Hasher-fe437922fe766f61b112750506d6be0e4ad5daa85ff9ce96549d99253ba61cbe.vk": { + "cid": "QmPZ9bGSVs5GHQRRAtC1qv9eQ7GPoH8FWukjxAXtXXcTxg", + "digest": "4edb21b7b6d5787b646f3e336e06303e", + "sector_size": 2048 + } +}