From 54d57a539d6365d028180949e5c487d2b94ab755 Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Fri, 24 May 2024 14:30:43 +1000 Subject: [PATCH 1/7] feat: miner: niporep params and cbor encoding vector tests --- builtin/v14/gen/gen.go | 2 + builtin/v14/miner/cbor_gen.go | 506 ++++++++++++++++++++++++++ builtin/v14/miner/miner_types.go | 29 ++ builtin/v14/miner/miner_types_test.go | 89 +++++ 4 files changed, 626 insertions(+) create mode 100644 builtin/v14/miner/miner_types_test.go diff --git a/builtin/v14/gen/gen.go b/builtin/v14/gen/gen.go index 5b0e9f30..ea377673 100644 --- a/builtin/v14/gen/gen.go +++ b/builtin/v14/gen/gen.go @@ -218,6 +218,8 @@ func main() { miner.ReplicaUpdate2{}, miner.ExpirationExtension2{}, miner.SectorClaim{}, + miner.SectorNIActivationInfo{}, + miner.ProveCommitSectorsNIParams{}, ); err != nil { panic(err) } diff --git a/builtin/v14/miner/cbor_gen.go b/builtin/v14/miner/cbor_gen.go index 6dcaa5c9..b250ef0e 100644 --- a/builtin/v14/miner/cbor_gen.go +++ b/builtin/v14/miner/cbor_gen.go @@ -9550,3 +9550,509 @@ func (t *SectorClaim) UnmarshalCBOR(r io.Reader) (err error) { } return nil } + +var lengthBufSectorNIActivationInfo = []byte{134} + +func (t *SectorNIActivationInfo) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + + if _, err := cw.Write(lengthBufSectorNIActivationInfo); err != nil { + return err + } + + // t.SealingNumber (abi.SectorNumber) (uint64) + + if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.SealingNumber)); err != nil { + return err + } + + // t.SealerID (abi.ActorID) (uint64) + + if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.SealerID)); err != nil { + return err + } + + // t.SealedCID (cid.Cid) (struct) + + if err := cbg.WriteCid(cw, t.SealedCID); err != nil { + return xerrors.Errorf("failed to write cid field t.SealedCID: %w", err) + } + + // t.SectorNumber (abi.SectorNumber) (uint64) + + if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.SectorNumber)); err != nil { + return err + } + + // t.SealRandEpoch (abi.ChainEpoch) (int64) + if t.SealRandEpoch >= 0 { + if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.SealRandEpoch)); err != nil { + return err + } + } else { + if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.SealRandEpoch-1)); err != nil { + return err + } + } + + // t.Expiration (abi.ChainEpoch) (int64) + if t.Expiration >= 0 { + if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.Expiration)); err != nil { + return err + } + } else { + if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.Expiration-1)); err != nil { + return err + } + } + + return nil +} + +func (t *SectorNIActivationInfo) UnmarshalCBOR(r io.Reader) (err error) { + *t = SectorNIActivationInfo{} + + cr := cbg.NewCborReader(r) + + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + + if maj != cbg.MajArray { + return fmt.Errorf("cbor input should be of type array") + } + + if extra != 6 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + // t.SealingNumber (abi.SectorNumber) (uint64) + + { + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.SealingNumber = abi.SectorNumber(extra) + + } + // t.SealerID (abi.ActorID) (uint64) + + { + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.SealerID = abi.ActorID(extra) + + } + // t.SealedCID (cid.Cid) (struct) + + { + + c, err := cbg.ReadCid(cr) + if err != nil { + return xerrors.Errorf("failed to read cid field t.SealedCID: %w", err) + } + + t.SealedCID = c + + } + // t.SectorNumber (abi.SectorNumber) (uint64) + + { + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.SectorNumber = abi.SectorNumber(extra) + + } + // t.SealRandEpoch (abi.ChainEpoch) (int64) + { + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + var extraI int64 + 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 overflow") + } + extraI = -1 - extraI + default: + return fmt.Errorf("wrong type for int64 field: %d", maj) + } + + t.SealRandEpoch = abi.ChainEpoch(extraI) + } + // t.Expiration (abi.ChainEpoch) (int64) + { + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + var extraI int64 + 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 overflow") + } + extraI = -1 - extraI + default: + return fmt.Errorf("wrong type for int64 field: %d", maj) + } + + t.Expiration = abi.ChainEpoch(extraI) + } + return nil +} + +var lengthBufProveCommitSectorsNIParams = []byte{134} + +func (t *ProveCommitSectorsNIParams) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + + if _, err := cw.Write(lengthBufProveCommitSectorsNIParams); err != nil { + return err + } + + // t.Sectors ([]miner.SectorNIActivationInfo) (slice) + if len(t.Sectors) > 8192 { + return xerrors.Errorf("Slice value in field t.Sectors was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.Sectors))); err != nil { + return err + } + for _, v := range t.Sectors { + if err := v.MarshalCBOR(cw); err != nil { + return err + } + + } + + // t.SealProofType (abi.RegisteredSealProof) (int64) + if t.SealProofType >= 0 { + if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.SealProofType)); err != nil { + return err + } + } else { + if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.SealProofType-1)); err != nil { + return err + } + } + + // t.SectorProofs ([][]uint8) (slice) + if len(t.SectorProofs) > 8192 { + return xerrors.Errorf("Slice value in field t.SectorProofs was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.SectorProofs))); err != nil { + return err + } + for _, v := range t.SectorProofs { + if len(v) > 2097152 { + return xerrors.Errorf("Byte array in field v was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajByteString, uint64(len(v))); err != nil { + return err + } + + if _, err := cw.Write(v); err != nil { + return err + } + + } + + // t.AggregateProof ([]uint8) (slice) + if len(t.AggregateProof) > 2097152 { + return xerrors.Errorf("Byte array in field t.AggregateProof was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajByteString, uint64(len(t.AggregateProof))); err != nil { + return err + } + + if _, err := cw.Write(t.AggregateProof); err != nil { + return err + } + + // t.AggregateProofType (abi.RegisteredAggregationProof) (int64) + if t.AggregateProofType == nil { + if _, err := cw.Write(cbg.CborNull); err != nil { + return err + } + } else { + if *t.AggregateProofType >= 0 { + if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(*t.AggregateProofType)); err != nil { + return err + } + } else { + if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-*t.AggregateProofType-1)); err != nil { + return err + } + } + } + + // t.RequireActivationSuccess (bool) (bool) + if err := cbg.WriteBool(w, t.RequireActivationSuccess); err != nil { + return err + } + return nil +} + +func (t *ProveCommitSectorsNIParams) UnmarshalCBOR(r io.Reader) (err error) { + *t = ProveCommitSectorsNIParams{} + + cr := cbg.NewCborReader(r) + + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + + if maj != cbg.MajArray { + return fmt.Errorf("cbor input should be of type array") + } + + if extra != 6 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + // t.Sectors ([]miner.SectorNIActivationInfo) (slice) + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > 8192 { + return fmt.Errorf("t.Sectors: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + + if extra > 0 { + t.Sectors = make([]SectorNIActivationInfo, extra) + } + + for i := 0; i < int(extra); i++ { + { + var maj byte + var extra uint64 + var err error + _ = maj + _ = extra + _ = err + + { + + if err := t.Sectors[i].UnmarshalCBOR(cr); err != nil { + return xerrors.Errorf("unmarshaling t.Sectors[i]: %w", err) + } + + } + + } + } + // t.SealProofType (abi.RegisteredSealProof) (int64) + { + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + var extraI int64 + 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 overflow") + } + extraI = -1 - extraI + default: + return fmt.Errorf("wrong type for int64 field: %d", maj) + } + + t.SealProofType = abi.RegisteredSealProof(extraI) + } + // t.SectorProofs ([][]uint8) (slice) + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > 8192 { + return fmt.Errorf("t.SectorProofs: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + + if extra > 0 { + t.SectorProofs = make([][]uint8, extra) + } + + for i := 0; i < int(extra); i++ { + { + var maj byte + var extra uint64 + var err error + _ = maj + _ = extra + _ = err + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > 2097152 { + return fmt.Errorf("t.SectorProofs[i]: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + + if extra > 0 { + t.SectorProofs[i] = make([]uint8, extra) + } + + if _, err := io.ReadFull(cr, t.SectorProofs[i]); err != nil { + return err + } + + } + } + // t.AggregateProof ([]uint8) (slice) + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > 2097152 { + return fmt.Errorf("t.AggregateProof: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + + if extra > 0 { + t.AggregateProof = make([]uint8, extra) + } + + if _, err := io.ReadFull(cr, t.AggregateProof); err != nil { + return err + } + + // t.AggregateProofType (abi.RegisteredAggregationProof) (int64) + { + + b, err := cr.ReadByte() + if err != nil { + return err + } + if b != cbg.CborNull[0] { + if err := cr.UnreadByte(); err != nil { + return err + } + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + var extraI int64 + 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 overflow") + } + extraI = -1 - extraI + default: + return fmt.Errorf("wrong type for int64 field: %d", maj) + } + + t.AggregateProofType = (*abi.RegisteredAggregationProof)(&extraI) + } + } + // t.RequireActivationSuccess (bool) (bool) + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + if maj != cbg.MajOther { + return fmt.Errorf("booleans must be major type 7") + } + switch extra { + case 20: + t.RequireActivationSuccess = false + case 21: + t.RequireActivationSuccess = true + default: + return fmt.Errorf("booleans are either major type 7, value 20 or 21 (got %d)", extra) + } + return nil +} diff --git a/builtin/v14/miner/miner_types.go b/builtin/v14/miner/miner_types.go index 1570c8c1..df9d802c 100644 --- a/builtin/v14/miner/miner_types.go +++ b/builtin/v14/miner/miner_types.go @@ -496,3 +496,32 @@ type SectorReturn = []PieceReturn // PieceReturn represents a result for each piece for the sector that was notified. type PieceReturn = bool // Accepted = true + +// SectorNIActivationInfo is the information needed to activate a sector with a "zero" replica. +type SectorNIActivationInfo struct { + SealingNumber abi.SectorNumber // Sector number used to generate replica id + SealerID abi.ActorID // Must be set to ID of receiving actor for now + SealedCID cid.Cid // CommR + SectorNumber abi.SectorNumber // unique id of sector in actor state + SealRandEpoch abi.ChainEpoch + Expiration abi.ChainEpoch +} + +// ProveCommitSectorsNIParams is the parameters for non-interactive prove committing of sectors +// via the miner actor method ProveCommitSectorsNI. +type ProveCommitSectorsNIParams struct { + // Information about sealing of each sector. + Sectors []SectorNIActivationInfo + // Proof type for each seal (must be an NI-PoRep variant) + SealProofType abi.RegisteredSealProof + // Proofs for each sector, parallel to activation manifests. + // Exactly one of sector_proofs or aggregate_proof must be non-empty. + SectorProofs [][]byte + // Aggregate proof for all sectors. + // Exactly one of sector_proofs or aggregate_proof must be non-empty. + AggregateProof []byte + // Proof type for aggregation, if aggregated + AggregateProofType *abi.RegisteredAggregationProof + // Whether to abort if any sector activation fails. + RequireActivationSuccess bool +} diff --git a/builtin/v14/miner/miner_types_test.go b/builtin/v14/miner/miner_types_test.go new file mode 100644 index 00000000..e35e9686 --- /dev/null +++ b/builtin/v14/miner/miner_types_test.go @@ -0,0 +1,89 @@ +package miner + +import ( + "bytes" + "encoding/hex" + "testing" + + "github.com/filecoin-project/go-state-types/abi" + cid "github.com/ipfs/go-cid" + "github.com/stretchr/testify/require" +) + +// Tests to match with Rust fil_actor_miner::serialization + +func TestSerializationSlaimAllocationsParams(t *testing.T) { + apt := abi.RegisteredAggregationProof_SnarkPackV2 + + testCases := []struct { + params ProveCommitSectorsNIParams + hex string + }{ + { + params: ProveCommitSectorsNIParams{Sectors: nil, SealProofType: abi.RegisteredSealProof_StackedDrg32GiBV1_1}, + // [[],8,[],byte[],null,false] + hex: "8680088040f6f4", + }, + { + params: ProveCommitSectorsNIParams{ + Sectors: []SectorNIActivationInfo{{ + SealingNumber: 1, + SealerID: 2, + SealedCID: cid.MustParse("bagboea4seaaqa"), + SectorNumber: 3, + SealRandEpoch: 4, + Expiration: 5, + }}, + SealProofType: abi.RegisteredSealProof_StackedDrg32GiBV1_1_Feat_NiPoRep, + SectorProofs: nil, + AggregateProof: []byte{0xde, 0xad, 0xbe, 0xef}, + AggregateProofType: &apt, + RequireActivationSuccess: true, + }, + // [[[1,2,bagboea4seaaqa,3,4,5]],18,[],byte[deadbeef],1,true] + hex: "8681860102d82a49000182e20392200100030405128044deadbeef01f5", + }, + { + params: ProveCommitSectorsNIParams{ + Sectors: []SectorNIActivationInfo{ + { + SealingNumber: 1, + SealerID: 2, + SealedCID: cid.MustParse("bagboea4seaaqa"), + SectorNumber: 3, + SealRandEpoch: 4, + Expiration: 5, + }, + { + SealingNumber: 6, + SealerID: 7, + SealedCID: cid.MustParse("bagboea4seaaqc"), + SectorNumber: 8, + SealRandEpoch: 9, + Expiration: 10, + }, + }, + SealProofType: abi.RegisteredSealProof_StackedDrg32GiBV1_1_Feat_NiPoRep, + SectorProofs: [][]byte{[]byte{0xde, 0xad}, []byte{0xbe, 0xef}}, + AggregateProof: nil, + AggregateProofType: nil, + RequireActivationSuccess: false, + }, + // [[[1,2,bagboea4seaaqa,3,4,5],[6,7,bagboea4seaaqc,8,9,10]],18,[byte[dead],byte[beef]],byte[],null,false] + hex: "8682860102d82a49000182e20392200100030405860607d82a49000182e2039220010108090a128242dead42beef40f6f4", + }, + } + + for _, tc := range testCases { + t.Run("", func(t *testing.T) { + req := require.New(t) + + var buf bytes.Buffer + req.NoError(tc.params.MarshalCBOR(&buf)) + req.Equal(tc.hex, hex.EncodeToString(buf.Bytes())) + var rt ProveCommitSectorsNIParams + req.NoError(rt.UnmarshalCBOR(&buf)) + req.Equal(tc.params, rt) + }) + } +} From 46349ac85f2759f716451a7a3b62015528653745 Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Fri, 24 May 2024 15:40:45 +1000 Subject: [PATCH 2/7] feat: miner: add ProveCommitSectorsNI method --- builtin/methods.go | 2 ++ builtin/v14/miner/methods.go | 1 + 2 files changed, 3 insertions(+) diff --git a/builtin/methods.go b/builtin/methods.go index 8b57a498..e6cee9dd 100644 --- a/builtin/methods.go +++ b/builtin/methods.go @@ -243,6 +243,7 @@ var MethodsMiner = struct { // MovePartitionsExported abi.MethodNum ProveCommitSectors3 abi.MethodNum ProveReplicaUpdates3 abi.MethodNum + ProveCommitSectorsNI abi.MethodNum }{ MethodConstructor, 2, @@ -294,6 +295,7 @@ var MethodsMiner = struct { // MovePartitions: 33, 34, 35, + 36, } var MethodsVerifiedRegistry = struct { diff --git a/builtin/v14/miner/methods.go b/builtin/v14/miner/methods.go index d79549cf..4729cf0f 100644 --- a/builtin/v14/miner/methods.go +++ b/builtin/v14/miner/methods.go @@ -62,4 +62,5 @@ var Methods = map[abi.MethodNum]builtin.MethodMeta{ // 33 MovePartitions 34: {"ProveCommitSectors3", *new(func(*ProveCommitSectors3Params) *ProveCommitSectors3Return)}, // ProveCommitSectors3 35: {"ProveReplicaUpdates3", *new(func(*ProveReplicaUpdates3Params) *ProveReplicaUpdates3Return)}, // ProveReplicaUpdates3 + 36: {"ProveCommitSectorsNI", *new(func(*ProveCommitSectorsNIParams) *abi.EmptyValue)}, // ProveCommitSectorsNI } From 3bfff718e9cc197e050bff311161beea6cd06344 Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Fri, 24 May 2024 20:02:43 +1000 Subject: [PATCH 3/7] feat: miner: add new ni-porep constants --- builtin/v14/miner/policy.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/builtin/v14/miner/policy.go b/builtin/v14/miner/policy.go index 22390079..463ff2ff 100644 --- a/builtin/v14/miner/policy.go +++ b/builtin/v14/miner/policy.go @@ -107,6 +107,16 @@ var MaxPreCommitRandomnessLookback = builtin.EpochsInDay + ChainFinality // PARA // (2) prevents a miner attempting a long fork in the past to insert a pre-commitment after seeing the challenge. var PreCommitChallengeDelay = abi.ChainEpoch(150) // PARAM_SPEC +// The maximum number of sector commitments in a single batch for calling ProveCommitSectorsNI. +// Same as PreCommitSectorBatchMaxSize for consistency. +var ProveCommitNiSectorBatchMaxSize = 256 // PARAM_SPEC + +// Maximum number of epochs within which to fetch a valid seal randomness from the chain for +// a non-interactive PoRep proof. This balances the need to tie the seal to a particular chain with +// but makes allowance for service providers to offer pre-sealed sectors within a larger window of +// time. +var MaxProveCommitNiLookback = abi.ChainEpoch(30*builtin.EpochsInDay) + ChainFinality // PARAM_SPEC + // Lookback from the deadline's challenge window opening from which to sample chain randomness for the WindowPoSt challenge seed. // This means that deadline windows can be non-overlapping (which make the programming simpler) without requiring a // miner to wait for chain stability during the challenge window. From 2d27210dc3cdef79f45b149f615952559710c0ab Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Wed, 29 May 2024 15:25:23 +1000 Subject: [PATCH 4/7] feat: add helper methods to SealProofType --- abi/sector.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/abi/sector.go b/abi/sector.go index ecfb9ae7..c5802965 100644 --- a/abi/sector.go +++ b/abi/sector.go @@ -488,6 +488,16 @@ func (p RegisteredSealProof) ReplicaId(prover ActorID, sector SectorNumber, tick return bytesIntoFr32Safe(s.Sum(nil)), nil } +func (p RegisteredSealProof) IsSynthetic() bool { + _, ok := Synthetic[p] + return ok +} + +func (p RegisteredSealProof) IsNonInteractive() bool { + _, ok := NonInteractive[p] + return ok +} + type ProverID [32]byte // ProverID returns a 32 byte proverID used when computing ReplicaID From 19a29aa50e4ac7ad3f3ae90070fe83574602f99e Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Tue, 11 Jun 2024 20:36:34 +1000 Subject: [PATCH 5/7] fix: adapt to FIP-0092 changes --- builtin/v14/miner/cbor_gen.go | 205 +++++++++----------------- builtin/v14/miner/miner_types.go | 24 ++- builtin/v14/miner/miner_types_test.go | 37 +++-- 3 files changed, 98 insertions(+), 168 deletions(-) diff --git a/builtin/v14/miner/cbor_gen.go b/builtin/v14/miner/cbor_gen.go index b250ef0e..9d9ce934 100644 --- a/builtin/v14/miner/cbor_gen.go +++ b/builtin/v14/miner/cbor_gen.go @@ -9773,6 +9773,19 @@ func (t *ProveCommitSectorsNIParams) MarshalCBOR(w io.Writer) error { } + // t.AggregateProof ([]uint8) (slice) + if len(t.AggregateProof) > 2097152 { + return xerrors.Errorf("Byte array in field t.AggregateProof was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajByteString, uint64(len(t.AggregateProof))); err != nil { + return err + } + + if _, err := cw.Write(t.AggregateProof); err != nil { + return err + } + // t.SealProofType (abi.RegisteredSealProof) (int64) if t.SealProofType >= 0 { if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.SealProofType)); err != nil { @@ -9784,59 +9797,23 @@ func (t *ProveCommitSectorsNIParams) MarshalCBOR(w io.Writer) error { } } - // t.SectorProofs ([][]uint8) (slice) - if len(t.SectorProofs) > 8192 { - return xerrors.Errorf("Slice value in field t.SectorProofs was too long") - } - - if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.SectorProofs))); err != nil { - return err - } - for _, v := range t.SectorProofs { - if len(v) > 2097152 { - return xerrors.Errorf("Byte array in field v was too long") - } - - if err := cw.WriteMajorTypeHeader(cbg.MajByteString, uint64(len(v))); err != nil { + // t.AggregateProofType (abi.RegisteredAggregationProof) (int64) + if t.AggregateProofType >= 0 { + if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.AggregateProofType)); err != nil { return err } - - if _, err := cw.Write(v); err != nil { + } else { + if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.AggregateProofType-1)); err != nil { return err } - } - // t.AggregateProof ([]uint8) (slice) - if len(t.AggregateProof) > 2097152 { - return xerrors.Errorf("Byte array in field t.AggregateProof was too long") - } + // t.ProvingDeadline (uint64) (uint64) - if err := cw.WriteMajorTypeHeader(cbg.MajByteString, uint64(len(t.AggregateProof))); err != nil { + if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.ProvingDeadline)); err != nil { return err } - if _, err := cw.Write(t.AggregateProof); err != nil { - return err - } - - // t.AggregateProofType (abi.RegisteredAggregationProof) (int64) - if t.AggregateProofType == nil { - if _, err := cw.Write(cbg.CborNull); err != nil { - return err - } - } else { - if *t.AggregateProofType >= 0 { - if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(*t.AggregateProofType)); err != nil { - return err - } - } else { - if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-*t.AggregateProofType-1)); err != nil { - return err - } - } - } - // t.RequireActivationSuccess (bool) (bool) if err := cbg.WriteBool(w, t.RequireActivationSuccess); err != nil { return err @@ -9905,6 +9882,28 @@ func (t *ProveCommitSectorsNIParams) UnmarshalCBOR(r io.Reader) (err error) { } } + // t.AggregateProof ([]uint8) (slice) + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > 2097152 { + return fmt.Errorf("t.AggregateProof: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + + if extra > 0 { + t.AggregateProof = make([]uint8, extra) + } + + if _, err := io.ReadFull(cr, t.AggregateProof); err != nil { + return err + } + // t.SealProofType (abi.RegisteredSealProof) (int64) { maj, extra, err := cr.ReadHeader() @@ -9930,112 +9929,44 @@ func (t *ProveCommitSectorsNIParams) UnmarshalCBOR(r io.Reader) (err error) { t.SealProofType = abi.RegisteredSealProof(extraI) } - // t.SectorProofs ([][]uint8) (slice) - - maj, extra, err = cr.ReadHeader() - if err != nil { - return err - } - - if extra > 8192 { - return fmt.Errorf("t.SectorProofs: array too large (%d)", extra) - } - - if maj != cbg.MajArray { - return fmt.Errorf("expected cbor array") - } - - if extra > 0 { - t.SectorProofs = make([][]uint8, extra) - } - - for i := 0; i < int(extra); i++ { - { - var maj byte - var extra uint64 - var err error - _ = maj - _ = extra - _ = err - - maj, extra, err = cr.ReadHeader() - if err != nil { - return err - } - - if extra > 2097152 { - return fmt.Errorf("t.SectorProofs[i]: byte array too large (%d)", extra) - } - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") - } - - if extra > 0 { - t.SectorProofs[i] = make([]uint8, extra) + // t.AggregateProofType (abi.RegisteredAggregationProof) (int64) + { + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + var extraI int64 + switch maj { + case cbg.MajUnsignedInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 positive overflow") } - - if _, err := io.ReadFull(cr, t.SectorProofs[i]); err != nil { - return err + case cbg.MajNegativeInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 negative overflow") } - + extraI = -1 - extraI + default: + return fmt.Errorf("wrong type for int64 field: %d", maj) } - } - // t.AggregateProof ([]uint8) (slice) - - maj, extra, err = cr.ReadHeader() - if err != nil { - return err - } - if extra > 2097152 { - return fmt.Errorf("t.AggregateProof: byte array too large (%d)", extra) - } - if maj != cbg.MajByteString { - return fmt.Errorf("expected byte array") - } - - if extra > 0 { - t.AggregateProof = make([]uint8, extra) + t.AggregateProofType = abi.RegisteredAggregationProof(extraI) } + // t.ProvingDeadline (uint64) (uint64) - if _, err := io.ReadFull(cr, t.AggregateProof); err != nil { - return err - } - - // t.AggregateProofType (abi.RegisteredAggregationProof) (int64) { - b, err := cr.ReadByte() + maj, extra, err = cr.ReadHeader() if err != nil { return err } - if b != cbg.CborNull[0] { - if err := cr.UnreadByte(); err != nil { - return err - } - maj, extra, err := cr.ReadHeader() - if err != nil { - return err - } - var extraI int64 - 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 overflow") - } - extraI = -1 - extraI - default: - return fmt.Errorf("wrong type for int64 field: %d", maj) - } - - t.AggregateProofType = (*abi.RegisteredAggregationProof)(&extraI) + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") } + t.ProvingDeadline = uint64(extra) + } // t.RequireActivationSuccess (bool) (bool) diff --git a/builtin/v14/miner/miner_types.go b/builtin/v14/miner/miner_types.go index df9d802c..b1515451 100644 --- a/builtin/v14/miner/miner_types.go +++ b/builtin/v14/miner/miner_types.go @@ -502,7 +502,7 @@ type SectorNIActivationInfo struct { SealingNumber abi.SectorNumber // Sector number used to generate replica id SealerID abi.ActorID // Must be set to ID of receiving actor for now SealedCID cid.Cid // CommR - SectorNumber abi.SectorNumber // unique id of sector in actor state + SectorNumber abi.SectorNumber // Unique id of sector in actor state SealRandEpoch abi.ChainEpoch Expiration abi.ChainEpoch } @@ -510,18 +510,12 @@ type SectorNIActivationInfo struct { // ProveCommitSectorsNIParams is the parameters for non-interactive prove committing of sectors // via the miner actor method ProveCommitSectorsNI. type ProveCommitSectorsNIParams struct { - // Information about sealing of each sector. - Sectors []SectorNIActivationInfo - // Proof type for each seal (must be an NI-PoRep variant) - SealProofType abi.RegisteredSealProof - // Proofs for each sector, parallel to activation manifests. - // Exactly one of sector_proofs or aggregate_proof must be non-empty. - SectorProofs [][]byte - // Aggregate proof for all sectors. - // Exactly one of sector_proofs or aggregate_proof must be non-empty. - AggregateProof []byte - // Proof type for aggregation, if aggregated - AggregateProofType *abi.RegisteredAggregationProof - // Whether to abort if any sector activation fails. - RequireActivationSuccess bool + Sectors []SectorNIActivationInfo // Information about sealing of each sector + AggregateProof []byte // Aggregate proof for all sectors + SealProofType abi.RegisteredSealProof // Proof type for each seal (must be an NI-PoRep variant) + AggregateProofType abi.RegisteredAggregationProof // Proof type for aggregation + ProvingDeadline uint64 // The Window PoST deadline index at which to schedule the new sectors + RequireActivationSuccess bool // Whether to abort if any sector activation fails } + +type ProveCommitSectorsNIReturn = BatchReturn diff --git a/builtin/v14/miner/miner_types_test.go b/builtin/v14/miner/miner_types_test.go index e35e9686..4068ba27 100644 --- a/builtin/v14/miner/miner_types_test.go +++ b/builtin/v14/miner/miner_types_test.go @@ -13,16 +13,21 @@ import ( // Tests to match with Rust fil_actor_miner::serialization func TestSerializationSlaimAllocationsParams(t *testing.T) { - apt := abi.RegisteredAggregationProof_SnarkPackV2 - testCases := []struct { params ProveCommitSectorsNIParams hex string }{ { - params: ProveCommitSectorsNIParams{Sectors: nil, SealProofType: abi.RegisteredSealProof_StackedDrg32GiBV1_1}, - // [[],8,[],byte[],null,false] - hex: "8680088040f6f4", + params: ProveCommitSectorsNIParams{ + Sectors: nil, + AggregateProof: nil, + SealProofType: abi.RegisteredSealProof_StackedDrg32GiBV1_1, + AggregateProofType: abi.RegisteredAggregationProof_SnarkPackV2, + ProvingDeadline: 2, + RequireActivationSuccess: false, + }, + // [[],byte[],8,1,2,false] + hex: "868040080102f4", }, { params: ProveCommitSectorsNIParams{ @@ -34,14 +39,14 @@ func TestSerializationSlaimAllocationsParams(t *testing.T) { SealRandEpoch: 4, Expiration: 5, }}, - SealProofType: abi.RegisteredSealProof_StackedDrg32GiBV1_1_Feat_NiPoRep, - SectorProofs: nil, + SealProofType: abi.RegisteredSealProof_StackedDrg32GiBV1_2_Feat_NiPoRep, AggregateProof: []byte{0xde, 0xad, 0xbe, 0xef}, - AggregateProofType: &apt, + AggregateProofType: abi.RegisteredAggregationProof_SnarkPackV2, + ProvingDeadline: 6, RequireActivationSuccess: true, }, - // [[[1,2,bagboea4seaaqa,3,4,5]],18,[],byte[deadbeef],1,true] - hex: "8681860102d82a49000182e20392200100030405128044deadbeef01f5", + // [[[1,2,bagboea4seaaqa,3,4,5]],byte[deadbeef],18,1,6,true] + hex: "8681860102d82a49000182e2039220010003040544deadbeef120106f5", }, { params: ProveCommitSectorsNIParams{ @@ -63,14 +68,14 @@ func TestSerializationSlaimAllocationsParams(t *testing.T) { Expiration: 10, }, }, - SealProofType: abi.RegisteredSealProof_StackedDrg32GiBV1_1_Feat_NiPoRep, - SectorProofs: [][]byte{[]byte{0xde, 0xad}, []byte{0xbe, 0xef}}, - AggregateProof: nil, - AggregateProofType: nil, + SealProofType: abi.RegisteredSealProof_StackedDrg32GiBV1_2_Feat_NiPoRep, + AggregateProof: []byte{0xde, 0xad, 0xbe, 0xef}, + AggregateProofType: abi.RegisteredAggregationProof_SnarkPackV2, + ProvingDeadline: 11, RequireActivationSuccess: false, }, - // [[[1,2,bagboea4seaaqa,3,4,5],[6,7,bagboea4seaaqc,8,9,10]],18,[byte[dead],byte[beef]],byte[],null,false] - hex: "8682860102d82a49000182e20392200100030405860607d82a49000182e2039220010108090a128242dead42beef40f6f4", + // [[[1,2,bagboea4seaaqa,3,4,5],[6,7,bagboea4seaaqc,8,9,10]],byte[deadbeef],18,1,11,false] + hex: "8682860102d82a49000182e20392200100030405860607d82a49000182e2039220010108090a44deadbeef12010bf4", }, } From 7fc3b07fc93ca927c6571fa63889b1e69f2220c8 Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Tue, 11 Jun 2024 22:47:33 +1000 Subject: [PATCH 6/7] fix: miner: MaxProveCommitNiLookback should be 180 days --- builtin/v14/miner/policy.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin/v14/miner/policy.go b/builtin/v14/miner/policy.go index 463ff2ff..0fac03e8 100644 --- a/builtin/v14/miner/policy.go +++ b/builtin/v14/miner/policy.go @@ -115,7 +115,7 @@ var ProveCommitNiSectorBatchMaxSize = 256 // PARAM_SPEC // a non-interactive PoRep proof. This balances the need to tie the seal to a particular chain with // but makes allowance for service providers to offer pre-sealed sectors within a larger window of // time. -var MaxProveCommitNiLookback = abi.ChainEpoch(30*builtin.EpochsInDay) + ChainFinality // PARAM_SPEC +var MaxProveCommitNiLookback = abi.ChainEpoch(180 * builtin.EpochsInDay) // PARAM_SPEC // Lookback from the deadline's challenge window opening from which to sample chain randomness for the WindowPoSt challenge seed. // This means that deadline windows can be non-overlapping (which make the programming simpler) without requiring a From 97a904ad6ed681f89a7be751012f7fb1874f4fef Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Tue, 11 Jun 2024 22:48:43 +1000 Subject: [PATCH 7/7] fix: miner: remove unnecessary ProveCommitNiSectorBatchMaxSize --- builtin/v14/miner/policy.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/builtin/v14/miner/policy.go b/builtin/v14/miner/policy.go index 0fac03e8..ccbf7667 100644 --- a/builtin/v14/miner/policy.go +++ b/builtin/v14/miner/policy.go @@ -107,10 +107,6 @@ var MaxPreCommitRandomnessLookback = builtin.EpochsInDay + ChainFinality // PARA // (2) prevents a miner attempting a long fork in the past to insert a pre-commitment after seeing the challenge. var PreCommitChallengeDelay = abi.ChainEpoch(150) // PARAM_SPEC -// The maximum number of sector commitments in a single batch for calling ProveCommitSectorsNI. -// Same as PreCommitSectorBatchMaxSize for consistency. -var ProveCommitNiSectorBatchMaxSize = 256 // PARAM_SPEC - // Maximum number of epochs within which to fetch a valid seal randomness from the chain for // a non-interactive PoRep proof. This balances the need to tie the seal to a particular chain with // but makes allowance for service providers to offer pre-sealed sectors within a larger window of