diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..485dee6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea diff --git a/capabilities/access/cbor_gen.go b/capabilities/access/cbor_gen.go index 644c288..faf7e5d 100644 --- a/capabilities/access/cbor_gen.go +++ b/capabilities/access/cbor_gen.go @@ -930,3 +930,188 @@ func (t *DelegateArguments) UnmarshalCBOR(r io.Reader) (err error) { return nil } +func (t *GrantArguments) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + fieldCount := 2 + + if t.Cause == nil { + fieldCount-- + } + + if _, err := cw.Write(cbg.CborEncodeMajorType(cbg.MajMap, uint64(fieldCount))); err != nil { + return err + } + + // t.Attenuations ([]access.CapabilityRequest) (slice) + if len("att") > 8192 { + return xerrors.Errorf("Value in field \"att\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("att"))); err != nil { + return err + } + if _, err := cw.WriteString(string("att")); err != nil { + return err + } + + if len(t.Attenuations) > 8192 { + return xerrors.Errorf("Slice value in field t.Attenuations was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.Attenuations))); err != nil { + return err + } + for _, v := range t.Attenuations { + if err := v.MarshalCBOR(cw); err != nil { + return err + } + + } + + // t.Cause (cid.Cid) (struct) + if t.Cause != nil { + + if len("cause") > 8192 { + return xerrors.Errorf("Value in field \"cause\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("cause"))); err != nil { + return err + } + if _, err := cw.WriteString(string("cause")); err != nil { + return err + } + + if t.Cause == nil { + if _, err := cw.Write(cbg.CborNull); err != nil { + return err + } + } else { + if err := cbg.WriteCid(cw, *t.Cause); err != nil { + return xerrors.Errorf("failed to write cid field t.Cause: %w", err) + } + } + + } + return nil +} + +func (t *GrantArguments) UnmarshalCBOR(r io.Reader) (err error) { + *t = GrantArguments{} + + 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.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("GrantArguments: map struct too large (%d)", extra) + } + + n := extra + + nameBuf := make([]byte, 5) + for i := uint64(0); i < n; i++ { + nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 8192) + if err != nil { + return err + } + + if !ok { + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil { + return err + } + continue + } + + switch string(nameBuf[:nameLen]) { + // t.Attenuations ([]access.CapabilityRequest) (slice) + case "att": + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > 8192 { + return fmt.Errorf("t.Attenuations: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + + if extra > 0 { + t.Attenuations = make([]CapabilityRequest, extra) + } + + for i := 0; i < int(extra); i++ { + { + var maj byte + var extra uint64 + var err error + _ = maj + _ = extra + _ = err + + { + + if err := t.Attenuations[i].UnmarshalCBOR(cr); err != nil { + return xerrors.Errorf("unmarshaling t.Attenuations[i]: %w", err) + } + + } + + } + } + // t.Cause (cid.Cid) (struct) + case "cause": + + { + + b, err := cr.ReadByte() + if err != nil { + return err + } + if b != cbg.CborNull[0] { + if err := cr.UnreadByte(); err != nil { + return err + } + + c, err := cbg.ReadCid(cr) + if err != nil { + return xerrors.Errorf("failed to read cid field t.Cause: %w", err) + } + + t.Cause = &c + } + + } + + default: + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil { + return err + } + } + } + + return nil +} diff --git a/capabilities/access/gen/main.go b/capabilities/access/gen/main.go index 914b147..b39bed9 100644 --- a/capabilities/access/gen/main.go +++ b/capabilities/access/gen/main.go @@ -30,6 +30,7 @@ func main() { access.ClaimOK{}, access.ConfirmArguments{}, access.DelegateArguments{}, + access.GrantArguments{}, } const ( cborFile = "../cbor_gen.go" diff --git a/capabilities/access/grant.go b/capabilities/access/grant.go new file mode 100644 index 0000000..bf30eb7 --- /dev/null +++ b/capabilities/access/grant.go @@ -0,0 +1,35 @@ +//go:build !codegen + +package access + +import ( + "github.com/fil-forge/libforge/capabilities" + "github.com/fil-forge/ucantone/errors" +) + +const GrantCommand = "/access/grant" + +// GrantOK mirrors ClaimOK / ConfirmOK: a successful grant resolves into a +// bundle of delegation CIDs. The actual delegation envelopes ride in the +// receipt response container as metadata. +type GrantOK = ClaimOK + +// Grant can be invoked by an agent to request that a set of capabilities be +// granted directly. Unlike Request -> Confirm, Grant is one-shot: the +// executor decides immediately whether to issue the delegation. +var Grant = capabilities.MustNew[*GrantArguments](GrantCommand) + +const ( + UnknownAbilityErrorName = "UnknownAbility" + MissingCapabilityErrorName = "MissingCapability" + UnknownCauseErrorName = "UnknownCause" + MissingCauseErrorName = "MissingCause" + InvalidCauseErrorName = "InvalidCause" + UnauthorizedCauseErrorName = "UnauthorizedCause" +) + +var ( + ErrMissingCapability = errors.New(MissingCapabilityErrorName, "grant requires one or more capabilities") + ErrMissingCause = errors.New(MissingCauseErrorName, "grant requires a supporting contextual invocation") + ErrUnknownCause = errors.New(UnknownCauseErrorName, "unknown cause invocation") +) diff --git a/capabilities/access/json_gen.go b/capabilities/access/json_gen.go index 0215a19..12f7185 100644 --- a/capabilities/access/json_gen.go +++ b/capabilities/access/json_gen.go @@ -985,3 +985,192 @@ func (t *DelegateArguments) UnmarshalDagJSON(r io.Reader) (err error) { return nil } +func (t *GrantArguments) MarshalDagJSON(w io.Writer) error { + jw := jsg.NewDagJsonWriter(w) + if t == nil { + err := jw.WriteNull() + return err + } + if err := jw.WriteObjectOpen(); err != nil { + return err + } + written := 0 + + // t.Attenuations ([]access.CapabilityRequest) (slice) + if len("att") > 8192 { + return fmt.Errorf("string in field \"att\" was too long") + } + if err := jw.WriteString(string("att")); err != nil { + return fmt.Errorf("writing string for field \"att\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if len(t.Attenuations) > 8192 { + return fmt.Errorf("slice value in field t.Attenuations was too long") + } + + if err := jw.WriteArrayOpen(); err != nil { + return fmt.Errorf("writing array open for field t.Attenuations: %w", err) + } + for i, v := range t.Attenuations { + if i > 0 { + if err := jw.WriteComma(); err != nil { + return fmt.Errorf("writing comma for field t.Attenuations: %w", err) + } + } + if err := v.MarshalDagJSON(jw); err != nil { + return fmt.Errorf("marshaling field v: %w", err) + } + } + if err := jw.WriteArrayClose(); err != nil { + return fmt.Errorf("writing array close for field t.Attenuations: %w", err) + } + + written++ + if t.Cause != nil { + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + } + + // t.Cause (cid.Cid) (struct) + if t.Cause != nil { + if len("cause") > 8192 { + return fmt.Errorf("string in field \"cause\" was too long") + } + if err := jw.WriteString(string("cause")); err != nil { + return fmt.Errorf("writing string for field \"cause\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + + if t.Cause == nil { + if err := jw.WriteNull(); err != nil { + return fmt.Errorf("writing null for field t.Cause: %w", err) + } + } else { + if err := jw.WriteCid(*t.Cause); err != nil { + return fmt.Errorf("writing CID for field t.Cause: %w", err) + } + } + + written++ + } + if err := jw.WriteObjectClose(); err != nil { + return err + } + return nil +} +func (t *GrantArguments) UnmarshalDagJSON(r io.Reader) (err error) { + *t = GrantArguments{} + + jr := jsg.NewDagJsonReader(r) + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + if err := jr.ReadObjectOpen(); err != nil { + return fmt.Errorf("reading object open for GrantArguments: %w", err) + } + close, err := jr.PeekObjectClose() + if err != nil { + return fmt.Errorf("peeking object close for GrantArguments: %w", err) + } + if close { + if err := jr.ReadObjectClose(); err != nil { + return fmt.Errorf("reading object close for GrantArguments: %w", err) + } + } else { + for i := uint64(0); i < 8192; i++ { + name, err := jr.ReadString(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string for field GrantArguments: string too large") + } + return fmt.Errorf("reading string for field GrantArguments: %w", err) + } + if err := jr.ReadObjectColon(); err != nil { + return fmt.Errorf("reading object colon for field GrantArguments: %w", err) + } + switch name { + + // t.Attenuations ([]access.CapabilityRequest) (slice) + case "att": + { + + if err := jr.ReadArrayOpen(); err != nil { + return fmt.Errorf("reading array open for field t.Attenuations: %w", err) + } + + close, err := jr.PeekArrayClose() + if err != nil { + return fmt.Errorf("peeking array close for field t.Attenuations: %w", err) + } + if close { + if err := jr.ReadArrayClose(); err != nil { + return fmt.Errorf("reading array close for field t.Attenuations: %w", err) + } + + } else { + for i := 0; i < 8192; i++ { + item := make([]CapabilityRequest, 1) + + if err := item[0].UnmarshalDagJSON(jr); err != nil { + return fmt.Errorf("unmarshaling item[0]: %w", err) + } + + t.Attenuations = append(t.Attenuations, item[0]) + + close, err := jr.ReadArrayCloseOrComma() + if err != nil { + return fmt.Errorf("reading array close or comma for field t.Attenuations: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("reading array for field t.Attenuations: slice too large") + } + } + } + + } + + // t.Cause (cid.Cid) (struct) + case "cause": + { + + c, err := jr.ReadCidOrNull() + if err != nil { + return fmt.Errorf("reading CID or null for field t.Cause: %w", err) + } + t.Cause = c + + } + default: + // Field doesn't exist on this type, so ignore it + if err := jr.DiscardType(); err != nil { + return fmt.Errorf("ignoring field %s for GrantArguments: %w", name, err) + } + } + + close, err := jr.ReadObjectCloseOrComma() + if err != nil { + return fmt.Errorf("reading object close or comma for field GrantArguments: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("map too large for GrantArguments") + } + } + } + + return nil +} diff --git a/capabilities/access/types.go b/capabilities/access/types.go index 07d0599..a7e78f3 100644 --- a/capabilities/access/types.go +++ b/capabilities/access/types.go @@ -43,3 +43,12 @@ type DelegateArguments struct { // The delegations to store. Delegations []cid.Cid `cborgen:"delegations" dagjsongen:"delegations"` } + +type GrantArguments struct { + // Attenuations are the capabilities the agent wishes to be granted. + Attenuations []CapabilityRequest `cborgen:"att" dagjsongen:"att"` + // Cause optionally links to a UCAN invocation that contextualizes the + // grant request. Leave nil when no cause is needed; otherwise the + // linked invocation MUST be present in the request container. + Cause *cid.Cid `cborgen:"cause,omitempty" dagjsongen:"cause,omitempty"` +} diff --git a/capabilities/pdp/accept.go b/capabilities/pdp/accept.go new file mode 100644 index 0000000..1d4ea00 --- /dev/null +++ b/capabilities/pdp/accept.go @@ -0,0 +1,9 @@ +//go:build !codegen + +package pdp + +import "github.com/fil-forge/libforge/capabilities" + +const AcceptCommand = "/pdp/accept" + +var Accept = capabilities.MustNew[*AcceptArguments](AcceptCommand) diff --git a/capabilities/pdp/cbor_gen.go b/capabilities/pdp/cbor_gen.go new file mode 100644 index 0000000..1146d33 --- /dev/null +++ b/capabilities/pdp/cbor_gen.go @@ -0,0 +1,679 @@ +//go:build !codegen + +// Code generated by github.com/whyrusleeping/cbor-gen. DO NOT EDIT. + +package pdp + +import ( + "fmt" + "io" + "math" + "sort" + + cid "github.com/ipfs/go-cid" + cbg "github.com/whyrusleeping/cbor-gen" + xerrors "golang.org/x/xerrors" +) + +var _ = xerrors.Errorf +var _ = cid.Undef +var _ = math.E +var _ = sort.Sort + +func (t *AcceptArguments) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + + if _, err := cw.Write([]byte{161}); err != nil { + return err + } + + // t.Blob (multihash.Multihash) (slice) + if len("blob") > 8192 { + return xerrors.Errorf("Value in field \"blob\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("blob"))); err != nil { + return err + } + if _, err := cw.WriteString(string("blob")); err != nil { + return err + } + + if len(t.Blob) > 2097152 { + return xerrors.Errorf("Byte array in field t.Blob was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajByteString, uint64(len(t.Blob))); err != nil { + return err + } + + if _, err := cw.Write(t.Blob); err != nil { + return err + } + + return nil +} + +func (t *AcceptArguments) UnmarshalCBOR(r io.Reader) (err error) { + *t = AcceptArguments{} + + 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.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("AcceptArguments: map struct too large (%d)", extra) + } + + n := extra + + nameBuf := make([]byte, 4) + for i := uint64(0); i < n; i++ { + nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 8192) + if err != nil { + return err + } + + if !ok { + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil { + return err + } + continue + } + + switch string(nameBuf[:nameLen]) { + // t.Blob (multihash.Multihash) (slice) + case "blob": + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > 2097152 { + return fmt.Errorf("t.Blob: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + + if extra > 0 { + t.Blob = make([]uint8, extra) + } + + if _, err := io.ReadFull(cr, t.Blob); err != nil { + return err + } + + default: + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil { + return err + } + } + } + + return nil +} +func (t *AcceptOK) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + + if _, err := cw.Write([]byte{163}); err != nil { + return err + } + + // t.Piece (cid.Cid) (struct) + if len("piece") > 8192 { + return xerrors.Errorf("Value in field \"piece\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("piece"))); err != nil { + return err + } + if _, err := cw.WriteString(string("piece")); err != nil { + return err + } + + if err := cbg.WriteCid(cw, t.Piece); err != nil { + return xerrors.Errorf("failed to write cid field t.Piece: %w", err) + } + + // t.Aggregate (cid.Cid) (struct) + if len("aggregate") > 8192 { + return xerrors.Errorf("Value in field \"aggregate\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("aggregate"))); err != nil { + return err + } + if _, err := cw.WriteString(string("aggregate")); err != nil { + return err + } + + if err := cbg.WriteCid(cw, t.Aggregate); err != nil { + return xerrors.Errorf("failed to write cid field t.Aggregate: %w", err) + } + + // t.InclusionProof (merkletree.ProofData) (struct) + if len("inclusionProof") > 8192 { + return xerrors.Errorf("Value in field \"inclusionProof\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("inclusionProof"))); err != nil { + return err + } + if _, err := cw.WriteString(string("inclusionProof")); err != nil { + return err + } + + if err := t.InclusionProof.MarshalCBOR(cw); err != nil { + return err + } + return nil +} + +func (t *AcceptOK) UnmarshalCBOR(r io.Reader) (err error) { + *t = AcceptOK{} + + 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.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("AcceptOK: map struct too large (%d)", extra) + } + + n := extra + + nameBuf := make([]byte, 14) + for i := uint64(0); i < n; i++ { + nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 8192) + if err != nil { + return err + } + + if !ok { + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil { + return err + } + continue + } + + switch string(nameBuf[:nameLen]) { + // t.Piece (cid.Cid) (struct) + case "piece": + + { + + c, err := cbg.ReadCid(cr) + if err != nil { + return xerrors.Errorf("failed to read cid field t.Piece: %w", err) + } + + t.Piece = c + + } + // t.Aggregate (cid.Cid) (struct) + case "aggregate": + + { + + c, err := cbg.ReadCid(cr) + if err != nil { + return xerrors.Errorf("failed to read cid field t.Aggregate: %w", err) + } + + t.Aggregate = c + + } + // t.InclusionProof (merkletree.ProofData) (struct) + case "inclusionProof": + + { + + if err := t.InclusionProof.UnmarshalCBOR(cr); err != nil { + return xerrors.Errorf("unmarshaling t.InclusionProof: %w", err) + } + + } + + default: + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil { + return err + } + } + } + + return nil +} +func (t *InfoArguments) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + + if _, err := cw.Write([]byte{161}); err != nil { + return err + } + + // t.Blob (multihash.Multihash) (slice) + if len("blob") > 8192 { + return xerrors.Errorf("Value in field \"blob\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("blob"))); err != nil { + return err + } + if _, err := cw.WriteString(string("blob")); err != nil { + return err + } + + if len(t.Blob) > 2097152 { + return xerrors.Errorf("Byte array in field t.Blob was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajByteString, uint64(len(t.Blob))); err != nil { + return err + } + + if _, err := cw.Write(t.Blob); err != nil { + return err + } + + return nil +} + +func (t *InfoArguments) UnmarshalCBOR(r io.Reader) (err error) { + *t = InfoArguments{} + + 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.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("InfoArguments: map struct too large (%d)", extra) + } + + n := extra + + nameBuf := make([]byte, 4) + for i := uint64(0); i < n; i++ { + nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 8192) + if err != nil { + return err + } + + if !ok { + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil { + return err + } + continue + } + + switch string(nameBuf[:nameLen]) { + // t.Blob (multihash.Multihash) (slice) + case "blob": + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > 2097152 { + return fmt.Errorf("t.Blob: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + + if extra > 0 { + t.Blob = make([]uint8, extra) + } + + if _, err := io.ReadFull(cr, t.Blob); err != nil { + return err + } + + default: + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil { + return err + } + } + } + + return nil +} +func (t *InfoAcceptedAggregate) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + + if _, err := cw.Write([]byte{162}); err != nil { + return err + } + + // t.Aggregate (cid.Cid) (struct) + if len("aggregate") > 8192 { + return xerrors.Errorf("Value in field \"aggregate\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("aggregate"))); err != nil { + return err + } + if _, err := cw.WriteString(string("aggregate")); err != nil { + return err + } + + if err := cbg.WriteCid(cw, t.Aggregate); err != nil { + return xerrors.Errorf("failed to write cid field t.Aggregate: %w", err) + } + + // t.InclusionProof (merkletree.ProofData) (struct) + if len("inclusionProof") > 8192 { + return xerrors.Errorf("Value in field \"inclusionProof\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("inclusionProof"))); err != nil { + return err + } + if _, err := cw.WriteString(string("inclusionProof")); err != nil { + return err + } + + if err := t.InclusionProof.MarshalCBOR(cw); err != nil { + return err + } + return nil +} + +func (t *InfoAcceptedAggregate) UnmarshalCBOR(r io.Reader) (err error) { + *t = InfoAcceptedAggregate{} + + 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.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("InfoAcceptedAggregate: map struct too large (%d)", extra) + } + + n := extra + + nameBuf := make([]byte, 14) + for i := uint64(0); i < n; i++ { + nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 8192) + if err != nil { + return err + } + + if !ok { + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil { + return err + } + continue + } + + switch string(nameBuf[:nameLen]) { + // t.Aggregate (cid.Cid) (struct) + case "aggregate": + + { + + c, err := cbg.ReadCid(cr) + if err != nil { + return xerrors.Errorf("failed to read cid field t.Aggregate: %w", err) + } + + t.Aggregate = c + + } + // t.InclusionProof (merkletree.ProofData) (struct) + case "inclusionProof": + + { + + if err := t.InclusionProof.UnmarshalCBOR(cr); err != nil { + return xerrors.Errorf("unmarshaling t.InclusionProof: %w", err) + } + + } + + default: + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil { + return err + } + } + } + + return nil +} +func (t *InfoOK) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + + if _, err := cw.Write([]byte{162}); err != nil { + return err + } + + // t.Piece (cid.Cid) (struct) + if len("piece") > 8192 { + return xerrors.Errorf("Value in field \"piece\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("piece"))); err != nil { + return err + } + if _, err := cw.WriteString(string("piece")); err != nil { + return err + } + + if err := cbg.WriteCid(cw, t.Piece); err != nil { + return xerrors.Errorf("failed to write cid field t.Piece: %w", err) + } + + // t.Aggregates ([]pdp.InfoAcceptedAggregate) (slice) + if len("aggregates") > 8192 { + return xerrors.Errorf("Value in field \"aggregates\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("aggregates"))); err != nil { + return err + } + if _, err := cw.WriteString(string("aggregates")); err != nil { + return err + } + + if len(t.Aggregates) > 8192 { + return xerrors.Errorf("Slice value in field t.Aggregates was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.Aggregates))); err != nil { + return err + } + for _, v := range t.Aggregates { + if err := v.MarshalCBOR(cw); err != nil { + return err + } + + } + return nil +} + +func (t *InfoOK) UnmarshalCBOR(r io.Reader) (err error) { + *t = InfoOK{} + + 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.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("InfoOK: map struct too large (%d)", extra) + } + + n := extra + + nameBuf := make([]byte, 10) + for i := uint64(0); i < n; i++ { + nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 8192) + if err != nil { + return err + } + + if !ok { + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil { + return err + } + continue + } + + switch string(nameBuf[:nameLen]) { + // t.Piece (cid.Cid) (struct) + case "piece": + + { + + c, err := cbg.ReadCid(cr) + if err != nil { + return xerrors.Errorf("failed to read cid field t.Piece: %w", err) + } + + t.Piece = c + + } + // t.Aggregates ([]pdp.InfoAcceptedAggregate) (slice) + case "aggregates": + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > 8192 { + return fmt.Errorf("t.Aggregates: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + + if extra > 0 { + t.Aggregates = make([]InfoAcceptedAggregate, extra) + } + + for i := 0; i < int(extra); i++ { + { + var maj byte + var extra uint64 + var err error + _ = maj + _ = extra + _ = err + + { + + if err := t.Aggregates[i].UnmarshalCBOR(cr); err != nil { + return xerrors.Errorf("unmarshaling t.Aggregates[i]: %w", err) + } + + } + + } + } + + default: + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil { + return err + } + } + } + + return nil +} diff --git a/capabilities/pdp/gen/main.go b/capabilities/pdp/gen/main.go new file mode 100644 index 0000000..bfe9662 --- /dev/null +++ b/capabilities/pdp/gen/main.go @@ -0,0 +1,45 @@ +//go:generate go run -tags codegen . + +package main + +import ( + "os" + + jsg "github.com/alanshaw/dag-json-gen" + "github.com/fil-forge/libforge/capabilities/pdp" + cbg "github.com/whyrusleeping/cbor-gen" +) + +const buildTag = "//go:build !codegen\n\n" + +func tag(path string) { + data, err := os.ReadFile(path) + if err != nil { + panic(err) + } + if err := os.WriteFile(path, append([]byte(buildTag), data...), 0644); err != nil { + panic(err) + } +} + +func main() { + models := []any{ + pdp.AcceptArguments{}, + pdp.AcceptOK{}, + pdp.InfoArguments{}, + pdp.InfoAcceptedAggregate{}, + pdp.InfoOK{}, + } + const ( + cborFile = "../cbor_gen.go" + jsonFile = "../json_gen.go" + ) + if err := cbg.WriteMapEncodersToFile(cborFile, "pdp", models...); err != nil { + panic(err) + } + if err := jsg.WriteMapEncodersToFile(jsonFile, "pdp", models...); err != nil { + panic(err) + } + tag(cborFile) + tag(jsonFile) +} diff --git a/capabilities/pdp/info.go b/capabilities/pdp/info.go new file mode 100644 index 0000000..922ae67 --- /dev/null +++ b/capabilities/pdp/info.go @@ -0,0 +1,9 @@ +//go:build !codegen + +package pdp + +import "github.com/fil-forge/libforge/capabilities" + +const InfoCommand = "/pdp/info" + +var Info = capabilities.MustNew[*InfoArguments](InfoCommand) diff --git a/capabilities/pdp/json_gen.go b/capabilities/pdp/json_gen.go new file mode 100644 index 0000000..9ff1b2d --- /dev/null +++ b/capabilities/pdp/json_gen.go @@ -0,0 +1,698 @@ +//go:build !codegen + +// Code generated by github.com/alanshaw/dag-json-gen. DO NOT EDIT. + +package pdp + +import ( + "errors" + "fmt" + "io" + "math" + "sort" + + jsg "github.com/alanshaw/dag-json-gen" + cid "github.com/ipfs/go-cid" +) + +var _ = cid.Undef +var _ = math.E +var _ = sort.Sort +var _ = errors.Is + +func (t *AcceptArguments) MarshalDagJSON(w io.Writer) error { + jw := jsg.NewDagJsonWriter(w) + if t == nil { + err := jw.WriteNull() + return err + } + if err := jw.WriteObjectOpen(); err != nil { + return err + } + + // t.Blob (multihash.Multihash) (slice) + if len("blob") > 8192 { + return fmt.Errorf("string in field \"blob\" was too long") + } + if err := jw.WriteString(string("blob")); err != nil { + return fmt.Errorf("writing string for field \"blob\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if len(t.Blob) > 2097152 { + return fmt.Errorf("byte array in field t.Blob was too long") + } + + if err := jw.WriteBytes(t.Blob); err != nil { + return fmt.Errorf("writing bytes for field t.Blob: %w", err) + } + + if err := jw.WriteObjectClose(); err != nil { + return err + } + return nil +} +func (t *AcceptArguments) UnmarshalDagJSON(r io.Reader) (err error) { + *t = AcceptArguments{} + + jr := jsg.NewDagJsonReader(r) + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + if err := jr.ReadObjectOpen(); err != nil { + return fmt.Errorf("reading object open for AcceptArguments: %w", err) + } + close, err := jr.PeekObjectClose() + if err != nil { + return fmt.Errorf("peeking object close for AcceptArguments: %w", err) + } + if close { + if err := jr.ReadObjectClose(); err != nil { + return fmt.Errorf("reading object close for AcceptArguments: %w", err) + } + } else { + for i := uint64(0); i < 8192; i++ { + name, err := jr.ReadString(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string for field AcceptArguments: string too large") + } + return fmt.Errorf("reading string for field AcceptArguments: %w", err) + } + if err := jr.ReadObjectColon(); err != nil { + return fmt.Errorf("reading object colon for field AcceptArguments: %w", err) + } + switch name { + + // t.Blob (multihash.Multihash) (slice) + case "blob": + + { + bval, err := jr.ReadBytes(2097152) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading bytes for field t.Blob: byte array too large") + } + return fmt.Errorf("reading bytes for field t.Blob: %w", err) + } + if len(bval) > 0 { + t.Blob = []uint8(bval) + } + } + + default: + // Field doesn't exist on this type, so ignore it + if err := jr.DiscardType(); err != nil { + return fmt.Errorf("ignoring field %s for AcceptArguments: %w", name, err) + } + } + + close, err := jr.ReadObjectCloseOrComma() + if err != nil { + return fmt.Errorf("reading object close or comma for field AcceptArguments: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("map too large for AcceptArguments") + } + } + } + + return nil +} +func (t *AcceptOK) MarshalDagJSON(w io.Writer) error { + jw := jsg.NewDagJsonWriter(w) + if t == nil { + err := jw.WriteNull() + return err + } + if err := jw.WriteObjectOpen(); err != nil { + return err + } + written := 0 + + // t.Aggregate (cid.Cid) (struct) + if len("aggregate") > 8192 { + return fmt.Errorf("string in field \"aggregate\" was too long") + } + if err := jw.WriteString(string("aggregate")); err != nil { + return fmt.Errorf("writing string for field \"aggregate\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + + if err := jw.WriteCid(t.Aggregate); err != nil { + return fmt.Errorf("writing CID for field t.Aggregate: %w", err) + } + + written++ + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + + // t.InclusionProof (merkletree.ProofData) (struct) + if len("inclusionProof") > 8192 { + return fmt.Errorf("string in field \"inclusionProof\" was too long") + } + if err := jw.WriteString(string("inclusionProof")); err != nil { + return fmt.Errorf("writing string for field \"inclusionProof\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if err := t.InclusionProof.MarshalDagJSON(jw); err != nil { + return fmt.Errorf("marshaling field t.InclusionProof: %w", err) + } + written++ + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + + // t.Piece (cid.Cid) (struct) + if len("piece") > 8192 { + return fmt.Errorf("string in field \"piece\" was too long") + } + if err := jw.WriteString(string("piece")); err != nil { + return fmt.Errorf("writing string for field \"piece\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + + if err := jw.WriteCid(t.Piece); err != nil { + return fmt.Errorf("writing CID for field t.Piece: %w", err) + } + + written++ + if err := jw.WriteObjectClose(); err != nil { + return err + } + return nil +} +func (t *AcceptOK) UnmarshalDagJSON(r io.Reader) (err error) { + *t = AcceptOK{} + + jr := jsg.NewDagJsonReader(r) + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + if err := jr.ReadObjectOpen(); err != nil { + return fmt.Errorf("reading object open for AcceptOK: %w", err) + } + close, err := jr.PeekObjectClose() + if err != nil { + return fmt.Errorf("peeking object close for AcceptOK: %w", err) + } + if close { + if err := jr.ReadObjectClose(); err != nil { + return fmt.Errorf("reading object close for AcceptOK: %w", err) + } + } else { + for i := uint64(0); i < 8192; i++ { + name, err := jr.ReadString(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string for field AcceptOK: string too large") + } + return fmt.Errorf("reading string for field AcceptOK: %w", err) + } + if err := jr.ReadObjectColon(); err != nil { + return fmt.Errorf("reading object colon for field AcceptOK: %w", err) + } + switch name { + + // t.Aggregate (cid.Cid) (struct) + case "aggregate": + { + + c, err := jr.ReadCid() + if err != nil { + return fmt.Errorf("reading CID for field t.Aggregate: %w", err) + } + t.Aggregate = c + + } + + // t.InclusionProof (merkletree.ProofData) (struct) + case "inclusionProof": + + if err := t.InclusionProof.UnmarshalDagJSON(jr); err != nil { + return fmt.Errorf("unmarshaling t.InclusionProof: %w", err) + } + + // t.Piece (cid.Cid) (struct) + case "piece": + { + + c, err := jr.ReadCid() + if err != nil { + return fmt.Errorf("reading CID for field t.Piece: %w", err) + } + t.Piece = c + + } + default: + // Field doesn't exist on this type, so ignore it + if err := jr.DiscardType(); err != nil { + return fmt.Errorf("ignoring field %s for AcceptOK: %w", name, err) + } + } + + close, err := jr.ReadObjectCloseOrComma() + if err != nil { + return fmt.Errorf("reading object close or comma for field AcceptOK: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("map too large for AcceptOK") + } + } + } + + return nil +} +func (t *InfoArguments) MarshalDagJSON(w io.Writer) error { + jw := jsg.NewDagJsonWriter(w) + if t == nil { + err := jw.WriteNull() + return err + } + if err := jw.WriteObjectOpen(); err != nil { + return err + } + + // t.Blob (multihash.Multihash) (slice) + if len("blob") > 8192 { + return fmt.Errorf("string in field \"blob\" was too long") + } + if err := jw.WriteString(string("blob")); err != nil { + return fmt.Errorf("writing string for field \"blob\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if len(t.Blob) > 2097152 { + return fmt.Errorf("byte array in field t.Blob was too long") + } + + if err := jw.WriteBytes(t.Blob); err != nil { + return fmt.Errorf("writing bytes for field t.Blob: %w", err) + } + + if err := jw.WriteObjectClose(); err != nil { + return err + } + return nil +} +func (t *InfoArguments) UnmarshalDagJSON(r io.Reader) (err error) { + *t = InfoArguments{} + + jr := jsg.NewDagJsonReader(r) + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + if err := jr.ReadObjectOpen(); err != nil { + return fmt.Errorf("reading object open for InfoArguments: %w", err) + } + close, err := jr.PeekObjectClose() + if err != nil { + return fmt.Errorf("peeking object close for InfoArguments: %w", err) + } + if close { + if err := jr.ReadObjectClose(); err != nil { + return fmt.Errorf("reading object close for InfoArguments: %w", err) + } + } else { + for i := uint64(0); i < 8192; i++ { + name, err := jr.ReadString(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string for field InfoArguments: string too large") + } + return fmt.Errorf("reading string for field InfoArguments: %w", err) + } + if err := jr.ReadObjectColon(); err != nil { + return fmt.Errorf("reading object colon for field InfoArguments: %w", err) + } + switch name { + + // t.Blob (multihash.Multihash) (slice) + case "blob": + + { + bval, err := jr.ReadBytes(2097152) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading bytes for field t.Blob: byte array too large") + } + return fmt.Errorf("reading bytes for field t.Blob: %w", err) + } + if len(bval) > 0 { + t.Blob = []uint8(bval) + } + } + + default: + // Field doesn't exist on this type, so ignore it + if err := jr.DiscardType(); err != nil { + return fmt.Errorf("ignoring field %s for InfoArguments: %w", name, err) + } + } + + close, err := jr.ReadObjectCloseOrComma() + if err != nil { + return fmt.Errorf("reading object close or comma for field InfoArguments: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("map too large for InfoArguments") + } + } + } + + return nil +} +func (t *InfoAcceptedAggregate) MarshalDagJSON(w io.Writer) error { + jw := jsg.NewDagJsonWriter(w) + if t == nil { + err := jw.WriteNull() + return err + } + if err := jw.WriteObjectOpen(); err != nil { + return err + } + written := 0 + + // t.Aggregate (cid.Cid) (struct) + if len("aggregate") > 8192 { + return fmt.Errorf("string in field \"aggregate\" was too long") + } + if err := jw.WriteString(string("aggregate")); err != nil { + return fmt.Errorf("writing string for field \"aggregate\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + + if err := jw.WriteCid(t.Aggregate); err != nil { + return fmt.Errorf("writing CID for field t.Aggregate: %w", err) + } + + written++ + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + + // t.InclusionProof (merkletree.ProofData) (struct) + if len("inclusionProof") > 8192 { + return fmt.Errorf("string in field \"inclusionProof\" was too long") + } + if err := jw.WriteString(string("inclusionProof")); err != nil { + return fmt.Errorf("writing string for field \"inclusionProof\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if err := t.InclusionProof.MarshalDagJSON(jw); err != nil { + return fmt.Errorf("marshaling field t.InclusionProof: %w", err) + } + written++ + if err := jw.WriteObjectClose(); err != nil { + return err + } + return nil +} +func (t *InfoAcceptedAggregate) UnmarshalDagJSON(r io.Reader) (err error) { + *t = InfoAcceptedAggregate{} + + jr := jsg.NewDagJsonReader(r) + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + if err := jr.ReadObjectOpen(); err != nil { + return fmt.Errorf("reading object open for InfoAcceptedAggregate: %w", err) + } + close, err := jr.PeekObjectClose() + if err != nil { + return fmt.Errorf("peeking object close for InfoAcceptedAggregate: %w", err) + } + if close { + if err := jr.ReadObjectClose(); err != nil { + return fmt.Errorf("reading object close for InfoAcceptedAggregate: %w", err) + } + } else { + for i := uint64(0); i < 8192; i++ { + name, err := jr.ReadString(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string for field InfoAcceptedAggregate: string too large") + } + return fmt.Errorf("reading string for field InfoAcceptedAggregate: %w", err) + } + if err := jr.ReadObjectColon(); err != nil { + return fmt.Errorf("reading object colon for field InfoAcceptedAggregate: %w", err) + } + switch name { + + // t.Aggregate (cid.Cid) (struct) + case "aggregate": + { + + c, err := jr.ReadCid() + if err != nil { + return fmt.Errorf("reading CID for field t.Aggregate: %w", err) + } + t.Aggregate = c + + } + + // t.InclusionProof (merkletree.ProofData) (struct) + case "inclusionProof": + + if err := t.InclusionProof.UnmarshalDagJSON(jr); err != nil { + return fmt.Errorf("unmarshaling t.InclusionProof: %w", err) + } + + default: + // Field doesn't exist on this type, so ignore it + if err := jr.DiscardType(); err != nil { + return fmt.Errorf("ignoring field %s for InfoAcceptedAggregate: %w", name, err) + } + } + + close, err := jr.ReadObjectCloseOrComma() + if err != nil { + return fmt.Errorf("reading object close or comma for field InfoAcceptedAggregate: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("map too large for InfoAcceptedAggregate") + } + } + } + + return nil +} +func (t *InfoOK) MarshalDagJSON(w io.Writer) error { + jw := jsg.NewDagJsonWriter(w) + if t == nil { + err := jw.WriteNull() + return err + } + if err := jw.WriteObjectOpen(); err != nil { + return err + } + written := 0 + + // t.Aggregates ([]pdp.InfoAcceptedAggregate) (slice) + if len("aggregates") > 8192 { + return fmt.Errorf("string in field \"aggregates\" was too long") + } + if err := jw.WriteString(string("aggregates")); err != nil { + return fmt.Errorf("writing string for field \"aggregates\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if len(t.Aggregates) > 8192 { + return fmt.Errorf("slice value in field t.Aggregates was too long") + } + + if err := jw.WriteArrayOpen(); err != nil { + return fmt.Errorf("writing array open for field t.Aggregates: %w", err) + } + for i, v := range t.Aggregates { + if i > 0 { + if err := jw.WriteComma(); err != nil { + return fmt.Errorf("writing comma for field t.Aggregates: %w", err) + } + } + if err := v.MarshalDagJSON(jw); err != nil { + return fmt.Errorf("marshaling field v: %w", err) + } + } + if err := jw.WriteArrayClose(); err != nil { + return fmt.Errorf("writing array close for field t.Aggregates: %w", err) + } + + written++ + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + + // t.Piece (cid.Cid) (struct) + if len("piece") > 8192 { + return fmt.Errorf("string in field \"piece\" was too long") + } + if err := jw.WriteString(string("piece")); err != nil { + return fmt.Errorf("writing string for field \"piece\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + + if err := jw.WriteCid(t.Piece); err != nil { + return fmt.Errorf("writing CID for field t.Piece: %w", err) + } + + written++ + if err := jw.WriteObjectClose(); err != nil { + return err + } + return nil +} +func (t *InfoOK) UnmarshalDagJSON(r io.Reader) (err error) { + *t = InfoOK{} + + jr := jsg.NewDagJsonReader(r) + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + if err := jr.ReadObjectOpen(); err != nil { + return fmt.Errorf("reading object open for InfoOK: %w", err) + } + close, err := jr.PeekObjectClose() + if err != nil { + return fmt.Errorf("peeking object close for InfoOK: %w", err) + } + if close { + if err := jr.ReadObjectClose(); err != nil { + return fmt.Errorf("reading object close for InfoOK: %w", err) + } + } else { + for i := uint64(0); i < 8192; i++ { + name, err := jr.ReadString(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string for field InfoOK: string too large") + } + return fmt.Errorf("reading string for field InfoOK: %w", err) + } + if err := jr.ReadObjectColon(); err != nil { + return fmt.Errorf("reading object colon for field InfoOK: %w", err) + } + switch name { + + // t.Aggregates ([]pdp.InfoAcceptedAggregate) (slice) + case "aggregates": + { + + if err := jr.ReadArrayOpen(); err != nil { + return fmt.Errorf("reading array open for field t.Aggregates: %w", err) + } + + close, err := jr.PeekArrayClose() + if err != nil { + return fmt.Errorf("peeking array close for field t.Aggregates: %w", err) + } + if close { + if err := jr.ReadArrayClose(); err != nil { + return fmt.Errorf("reading array close for field t.Aggregates: %w", err) + } + + } else { + for i := 0; i < 8192; i++ { + item := make([]InfoAcceptedAggregate, 1) + + if err := item[0].UnmarshalDagJSON(jr); err != nil { + return fmt.Errorf("unmarshaling item[0]: %w", err) + } + + t.Aggregates = append(t.Aggregates, item[0]) + + close, err := jr.ReadArrayCloseOrComma() + if err != nil { + return fmt.Errorf("reading array close or comma for field t.Aggregates: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("reading array for field t.Aggregates: slice too large") + } + } + } + + } + + // t.Piece (cid.Cid) (struct) + case "piece": + { + + c, err := jr.ReadCid() + if err != nil { + return fmt.Errorf("reading CID for field t.Piece: %w", err) + } + t.Piece = c + + } + default: + // Field doesn't exist on this type, so ignore it + if err := jr.DiscardType(); err != nil { + return fmt.Errorf("ignoring field %s for InfoOK: %w", name, err) + } + } + + close, err := jr.ReadObjectCloseOrComma() + if err != nil { + return fmt.Errorf("reading object close or comma for field InfoOK: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("map too large for InfoOK") + } + } + } + + return nil +} diff --git a/capabilities/pdp/sign/cbor_gen.go b/capabilities/pdp/sign/cbor_gen.go new file mode 100644 index 0000000..9921ed1 --- /dev/null +++ b/capabilities/pdp/sign/cbor_gen.go @@ -0,0 +1,1712 @@ +//go:build !codegen + +// Code generated by github.com/whyrusleeping/cbor-gen. DO NOT EDIT. + +package sign + +import ( + "fmt" + "io" + "math" + "sort" + + cid "github.com/ipfs/go-cid" + cbg "github.com/whyrusleeping/cbor-gen" + xerrors "golang.org/x/xerrors" + big "math/big" +) + +var _ = xerrors.Errorf +var _ = cid.Undef +var _ = math.E +var _ = sort.Sort + +func (t *AuthSignature) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + + if _, err := cw.Write([]byte{166}); err != nil { + return err + } + + // t.R ([]uint8) (slice) + if len("r") > 8192 { + return xerrors.Errorf("Value in field \"r\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("r"))); err != nil { + return err + } + if _, err := cw.WriteString(string("r")); err != nil { + return err + } + + if len(t.R) > 2097152 { + return xerrors.Errorf("Byte array in field t.R was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajByteString, uint64(len(t.R))); err != nil { + return err + } + + if _, err := cw.Write(t.R); err != nil { + return err + } + + // t.S ([]uint8) (slice) + if len("s") > 8192 { + return xerrors.Errorf("Value in field \"s\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("s"))); err != nil { + return err + } + if _, err := cw.WriteString(string("s")); err != nil { + return err + } + + if len(t.S) > 2097152 { + return xerrors.Errorf("Byte array in field t.S was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajByteString, uint64(len(t.S))); err != nil { + return err + } + + if _, err := cw.Write(t.S); err != nil { + return err + } + + // t.V (uint8) (uint8) + if len("v") > 8192 { + return xerrors.Errorf("Value in field \"v\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("v"))); err != nil { + return err + } + if _, err := cw.WriteString(string("v")); err != nil { + return err + } + + if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.V)); err != nil { + return err + } + + // t.Signer ([]uint8) (slice) + if len("signer") > 8192 { + return xerrors.Errorf("Value in field \"signer\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("signer"))); err != nil { + return err + } + if _, err := cw.WriteString(string("signer")); err != nil { + return err + } + + if len(t.Signer) > 2097152 { + return xerrors.Errorf("Byte array in field t.Signer was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajByteString, uint64(len(t.Signer))); err != nil { + return err + } + + if _, err := cw.Write(t.Signer); err != nil { + return err + } + + // t.Signature ([]uint8) (slice) + if len("signature") > 8192 { + return xerrors.Errorf("Value in field \"signature\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("signature"))); err != nil { + return err + } + if _, err := cw.WriteString(string("signature")); err != nil { + return err + } + + if len(t.Signature) > 2097152 { + return xerrors.Errorf("Byte array in field t.Signature was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajByteString, uint64(len(t.Signature))); err != nil { + return err + } + + if _, err := cw.Write(t.Signature); err != nil { + return err + } + + // t.SignedData ([]uint8) (slice) + if len("signedData") > 8192 { + return xerrors.Errorf("Value in field \"signedData\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("signedData"))); err != nil { + return err + } + if _, err := cw.WriteString(string("signedData")); err != nil { + return err + } + + if len(t.SignedData) > 2097152 { + return xerrors.Errorf("Byte array in field t.SignedData was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajByteString, uint64(len(t.SignedData))); err != nil { + return err + } + + if _, err := cw.Write(t.SignedData); err != nil { + return err + } + + return nil +} + +func (t *AuthSignature) UnmarshalCBOR(r io.Reader) (err error) { + *t = AuthSignature{} + + 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.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("AuthSignature: map struct too large (%d)", extra) + } + + n := extra + + nameBuf := make([]byte, 10) + for i := uint64(0); i < n; i++ { + nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 8192) + if err != nil { + return err + } + + if !ok { + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil { + return err + } + continue + } + + switch string(nameBuf[:nameLen]) { + // t.R ([]uint8) (slice) + case "r": + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > 2097152 { + return fmt.Errorf("t.R: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + + if extra > 0 { + t.R = make([]uint8, extra) + } + + if _, err := io.ReadFull(cr, t.R); err != nil { + return err + } + + // t.S ([]uint8) (slice) + case "s": + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > 2097152 { + return fmt.Errorf("t.S: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + + if extra > 0 { + t.S = make([]uint8, extra) + } + + if _, err := io.ReadFull(cr, t.S); err != nil { + return err + } + + // t.V (uint8) (uint8) + case "v": + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint8 field") + } + if extra > math.MaxUint8 { + return fmt.Errorf("integer in input was too large for uint8 field") + } + t.V = uint8(extra) + // t.Signer ([]uint8) (slice) + case "signer": + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > 2097152 { + return fmt.Errorf("t.Signer: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + + if extra > 0 { + t.Signer = make([]uint8, extra) + } + + if _, err := io.ReadFull(cr, t.Signer); err != nil { + return err + } + + // t.Signature ([]uint8) (slice) + case "signature": + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > 2097152 { + return fmt.Errorf("t.Signature: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + + if extra > 0 { + t.Signature = make([]uint8, extra) + } + + if _, err := io.ReadFull(cr, t.Signature); err != nil { + return err + } + + // t.SignedData ([]uint8) (slice) + case "signedData": + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > 2097152 { + return fmt.Errorf("t.SignedData: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + + if extra > 0 { + t.SignedData = make([]uint8, extra) + } + + if _, err := io.ReadFull(cr, t.SignedData); err != nil { + return err + } + + default: + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil { + return err + } + } + } + + return nil +} +func (t *Metadata) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + + if _, err := cw.Write([]byte{162}); err != nil { + return err + } + + // t.Keys ([]string) (slice) + if len("keys") > 8192 { + return xerrors.Errorf("Value in field \"keys\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("keys"))); err != nil { + return err + } + if _, err := cw.WriteString(string("keys")); err != nil { + return err + } + + if len(t.Keys) > 8192 { + return xerrors.Errorf("Slice value in field t.Keys was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.Keys))); err != nil { + return err + } + for _, v := range t.Keys { + if len(v) > 8192 { + return xerrors.Errorf("Value in field v was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(v))); err != nil { + return err + } + if _, err := cw.WriteString(string(v)); err != nil { + return err + } + + } + + // t.Values (map[string]string) (map) + if len("values") > 8192 { + return xerrors.Errorf("Value in field \"values\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("values"))); err != nil { + return err + } + if _, err := cw.WriteString(string("values")); err != nil { + return err + } + + { + if len(t.Values) > 4096 { + return xerrors.Errorf("cannot marshal t.Values map too large") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajMap, uint64(len(t.Values))); err != nil { + return err + } + + keys := make([]string, 0, len(t.Values)) + for k := range t.Values { + keys = append(keys, k) + } + sort.Strings(keys) + for _, k := range keys { + v := t.Values[k] + + if len(k) > 8192 { + return xerrors.Errorf("Value in field k was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(k))); err != nil { + return err + } + if _, err := cw.WriteString(string(k)); err != nil { + return err + } + + if len(v) > 8192 { + return xerrors.Errorf("Value in field v was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(v))); err != nil { + return err + } + if _, err := cw.WriteString(string(v)); err != nil { + return err + } + + } + } + return nil +} + +func (t *Metadata) UnmarshalCBOR(r io.Reader) (err error) { + *t = Metadata{} + + 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.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("Metadata: map struct too large (%d)", extra) + } + + n := extra + + nameBuf := make([]byte, 6) + for i := uint64(0); i < n; i++ { + nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 8192) + if err != nil { + return err + } + + if !ok { + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil { + return err + } + continue + } + + switch string(nameBuf[:nameLen]) { + // t.Keys ([]string) (slice) + case "keys": + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > 8192 { + return fmt.Errorf("t.Keys: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + + if extra > 0 { + t.Keys = make([]string, extra) + } + + for i := 0; i < int(extra); i++ { + { + var maj byte + var extra uint64 + var err error + _ = maj + _ = extra + _ = err + + { + sval, err := cbg.ReadStringWithMax(cr, 8192) + if err != nil { + return err + } + + t.Keys[i] = string(sval) + } + + } + } + // t.Values (map[string]string) (map) + case "values": + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + if maj != cbg.MajMap { + return fmt.Errorf("expected a map (major type 5)") + } + if extra > 4096 { + return fmt.Errorf("t.Values: map too large") + } + + t.Values = make(map[string]string, extra) + + for i, l := 0, int(extra); i < l; i++ { + + var k string + + { + sval, err := cbg.ReadStringWithMax(cr, 8192) + if err != nil { + return err + } + + k = string(sval) + } + + var v string + + { + sval, err := cbg.ReadStringWithMax(cr, 8192) + if err != nil { + return err + } + + v = string(sval) + } + + t.Values[k] = v + + } + + default: + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil { + return err + } + } + } + + return nil +} +func (t *PieceProofs) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + + if _, err := cw.Write([]byte{161}); err != nil { + return err + } + + // t.Proofs ([]cid.Cid) (slice) + if len("proofs") > 8192 { + return xerrors.Errorf("Value in field \"proofs\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("proofs"))); err != nil { + return err + } + if _, err := cw.WriteString(string("proofs")); err != nil { + return err + } + + if len(t.Proofs) > 8192 { + return xerrors.Errorf("Slice value in field t.Proofs was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.Proofs))); err != nil { + return err + } + for _, v := range t.Proofs { + + if err := cbg.WriteCid(cw, v); err != nil { + return xerrors.Errorf("failed to write cid field v: %w", err) + } + + } + return nil +} + +func (t *PieceProofs) UnmarshalCBOR(r io.Reader) (err error) { + *t = PieceProofs{} + + 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.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("PieceProofs: map struct too large (%d)", extra) + } + + n := extra + + nameBuf := make([]byte, 6) + for i := uint64(0); i < n; i++ { + nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 8192) + if err != nil { + return err + } + + if !ok { + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil { + return err + } + continue + } + + switch string(nameBuf[:nameLen]) { + // t.Proofs ([]cid.Cid) (slice) + case "proofs": + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > 8192 { + return fmt.Errorf("t.Proofs: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + + if extra > 0 { + t.Proofs = make([]cid.Cid, extra) + } + + for i := 0; i < int(extra); i++ { + { + var maj byte + var extra uint64 + var err error + _ = maj + _ = extra + _ = err + + { + + c, err := cbg.ReadCid(cr) + if err != nil { + return xerrors.Errorf("failed to read cid field t.Proofs[i]: %w", err) + } + + t.Proofs[i] = c + + } + + } + } + + default: + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil { + return err + } + } + } + + return nil +} +func (t *DataSetCreateArguments) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + + if _, err := cw.Write([]byte{163}); err != nil { + return err + } + + // t.Payee ([]uint8) (slice) + if len("payee") > 8192 { + return xerrors.Errorf("Value in field \"payee\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("payee"))); err != nil { + return err + } + if _, err := cw.WriteString(string("payee")); err != nil { + return err + } + + if len(t.Payee) > 2097152 { + return xerrors.Errorf("Byte array in field t.Payee was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajByteString, uint64(len(t.Payee))); err != nil { + return err + } + + if _, err := cw.Write(t.Payee); err != nil { + return err + } + + // t.DataSet (big.Int) (struct) + if len("dataSet") > 8192 { + return xerrors.Errorf("Value in field \"dataSet\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("dataSet"))); err != nil { + return err + } + if _, err := cw.WriteString(string("dataSet")); err != nil { + return err + } + + { + if t.DataSet != nil && t.DataSet.Sign() < 0 { + return xerrors.Errorf("Value in field t.DataSet was a negative big-integer (not supported)") + } + if err := cw.CborWriteHeader(cbg.MajTag, 2); err != nil { + return err + } + var b []byte + if t.DataSet != nil { + b = t.DataSet.Bytes() + } + + if err := cw.CborWriteHeader(cbg.MajByteString, uint64(len(b))); err != nil { + return err + } + if _, err := cw.Write(b); err != nil { + return err + } + } + + // t.Metadata (sign.Metadata) (struct) + if len("metadata") > 8192 { + return xerrors.Errorf("Value in field \"metadata\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("metadata"))); err != nil { + return err + } + if _, err := cw.WriteString(string("metadata")); err != nil { + return err + } + + if err := t.Metadata.MarshalCBOR(cw); err != nil { + return err + } + return nil +} + +func (t *DataSetCreateArguments) UnmarshalCBOR(r io.Reader) (err error) { + *t = DataSetCreateArguments{} + + 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.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("DataSetCreateArguments: map struct too large (%d)", extra) + } + + n := extra + + nameBuf := make([]byte, 8) + for i := uint64(0); i < n; i++ { + nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 8192) + if err != nil { + return err + } + + if !ok { + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil { + return err + } + continue + } + + switch string(nameBuf[:nameLen]) { + // t.Payee ([]uint8) (slice) + case "payee": + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > 2097152 { + return fmt.Errorf("t.Payee: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + + if extra > 0 { + t.Payee = make([]uint8, extra) + } + + if _, err := io.ReadFull(cr, t.Payee); err != nil { + return err + } + + // t.DataSet (big.Int) (struct) + case "dataSet": + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if maj != cbg.MajTag || extra != 2 { + return fmt.Errorf("big ints should be cbor bignums") + } + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if maj != cbg.MajByteString { + return fmt.Errorf("big ints should be tagged cbor byte strings") + } + + if extra > 256 { + return fmt.Errorf("t.DataSet: cbor bignum was too large") + } + + if extra > 0 { + buf := make([]byte, extra) + if _, err := io.ReadFull(cr, buf); err != nil { + return err + } + t.DataSet = big.NewInt(0).SetBytes(buf) + } else { + t.DataSet = big.NewInt(0) + } + // t.Metadata (sign.Metadata) (struct) + case "metadata": + + { + + if err := t.Metadata.UnmarshalCBOR(cr); err != nil { + return xerrors.Errorf("unmarshaling t.Metadata: %w", err) + } + + } + + default: + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil { + return err + } + } + } + + return nil +} +func (t *DataSetDeleteArguments) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + + if _, err := cw.Write([]byte{161}); err != nil { + return err + } + + // t.DataSet (big.Int) (struct) + if len("dataSet") > 8192 { + return xerrors.Errorf("Value in field \"dataSet\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("dataSet"))); err != nil { + return err + } + if _, err := cw.WriteString(string("dataSet")); err != nil { + return err + } + + { + if t.DataSet != nil && t.DataSet.Sign() < 0 { + return xerrors.Errorf("Value in field t.DataSet was a negative big-integer (not supported)") + } + if err := cw.CborWriteHeader(cbg.MajTag, 2); err != nil { + return err + } + var b []byte + if t.DataSet != nil { + b = t.DataSet.Bytes() + } + + if err := cw.CborWriteHeader(cbg.MajByteString, uint64(len(b))); err != nil { + return err + } + if _, err := cw.Write(b); err != nil { + return err + } + } + return nil +} + +func (t *DataSetDeleteArguments) UnmarshalCBOR(r io.Reader) (err error) { + *t = DataSetDeleteArguments{} + + 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.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("DataSetDeleteArguments: map struct too large (%d)", extra) + } + + n := extra + + nameBuf := make([]byte, 7) + for i := uint64(0); i < n; i++ { + nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 8192) + if err != nil { + return err + } + + if !ok { + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil { + return err + } + continue + } + + switch string(nameBuf[:nameLen]) { + // t.DataSet (big.Int) (struct) + case "dataSet": + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if maj != cbg.MajTag || extra != 2 { + return fmt.Errorf("big ints should be cbor bignums") + } + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if maj != cbg.MajByteString { + return fmt.Errorf("big ints should be tagged cbor byte strings") + } + + if extra > 256 { + return fmt.Errorf("t.DataSet: cbor bignum was too large") + } + + if extra > 0 { + buf := make([]byte, extra) + if _, err := io.ReadFull(cr, buf); err != nil { + return err + } + t.DataSet = big.NewInt(0).SetBytes(buf) + } else { + t.DataSet = big.NewInt(0) + } + + default: + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil { + return err + } + } + } + + return nil +} +func (t *PiecesAddArguments) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + + if _, err := cw.Write([]byte{165}); err != nil { + return err + } + + // t.Nonce (big.Int) (struct) + if len("nonce") > 8192 { + return xerrors.Errorf("Value in field \"nonce\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("nonce"))); err != nil { + return err + } + if _, err := cw.WriteString(string("nonce")); err != nil { + return err + } + + { + if t.Nonce != nil && t.Nonce.Sign() < 0 { + return xerrors.Errorf("Value in field t.Nonce was a negative big-integer (not supported)") + } + if err := cw.CborWriteHeader(cbg.MajTag, 2); err != nil { + return err + } + var b []byte + if t.Nonce != nil { + b = t.Nonce.Bytes() + } + + if err := cw.CborWriteHeader(cbg.MajByteString, uint64(len(b))); err != nil { + return err + } + if _, err := cw.Write(b); err != nil { + return err + } + } + + // t.Proofs ([]sign.PieceProofs) (slice) + if len("proofs") > 8192 { + return xerrors.Errorf("Value in field \"proofs\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("proofs"))); err != nil { + return err + } + if _, err := cw.WriteString(string("proofs")); err != nil { + return err + } + + if len(t.Proofs) > 8192 { + return xerrors.Errorf("Slice value in field t.Proofs was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.Proofs))); err != nil { + return err + } + for _, v := range t.Proofs { + if err := v.MarshalCBOR(cw); err != nil { + return err + } + + } + + // t.DataSet (big.Int) (struct) + if len("dataSet") > 8192 { + return xerrors.Errorf("Value in field \"dataSet\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("dataSet"))); err != nil { + return err + } + if _, err := cw.WriteString(string("dataSet")); err != nil { + return err + } + + { + if t.DataSet != nil && t.DataSet.Sign() < 0 { + return xerrors.Errorf("Value in field t.DataSet was a negative big-integer (not supported)") + } + if err := cw.CborWriteHeader(cbg.MajTag, 2); err != nil { + return err + } + var b []byte + if t.DataSet != nil { + b = t.DataSet.Bytes() + } + + if err := cw.CborWriteHeader(cbg.MajByteString, uint64(len(b))); err != nil { + return err + } + if _, err := cw.Write(b); err != nil { + return err + } + } + + // t.Metadata ([]sign.Metadata) (slice) + if len("metadata") > 8192 { + return xerrors.Errorf("Value in field \"metadata\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("metadata"))); err != nil { + return err + } + if _, err := cw.WriteString(string("metadata")); err != nil { + return err + } + + if len(t.Metadata) > 8192 { + return xerrors.Errorf("Slice value in field t.Metadata was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.Metadata))); err != nil { + return err + } + for _, v := range t.Metadata { + if err := v.MarshalCBOR(cw); err != nil { + return err + } + + } + + // t.PieceData ([][]uint8) (slice) + if len("pieceData") > 8192 { + return xerrors.Errorf("Value in field \"pieceData\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("pieceData"))); err != nil { + return err + } + if _, err := cw.WriteString(string("pieceData")); err != nil { + return err + } + + if len(t.PieceData) > 8192 { + return xerrors.Errorf("Slice value in field t.PieceData was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.PieceData))); err != nil { + return err + } + for _, v := range t.PieceData { + 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 + } + + } + return nil +} + +func (t *PiecesAddArguments) UnmarshalCBOR(r io.Reader) (err error) { + *t = PiecesAddArguments{} + + 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.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("PiecesAddArguments: map struct too large (%d)", extra) + } + + n := extra + + nameBuf := make([]byte, 9) + for i := uint64(0); i < n; i++ { + nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 8192) + if err != nil { + return err + } + + if !ok { + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil { + return err + } + continue + } + + switch string(nameBuf[:nameLen]) { + // t.Nonce (big.Int) (struct) + case "nonce": + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if maj != cbg.MajTag || extra != 2 { + return fmt.Errorf("big ints should be cbor bignums") + } + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if maj != cbg.MajByteString { + return fmt.Errorf("big ints should be tagged cbor byte strings") + } + + if extra > 256 { + return fmt.Errorf("t.Nonce: cbor bignum was too large") + } + + if extra > 0 { + buf := make([]byte, extra) + if _, err := io.ReadFull(cr, buf); err != nil { + return err + } + t.Nonce = big.NewInt(0).SetBytes(buf) + } else { + t.Nonce = big.NewInt(0) + } + // t.Proofs ([]sign.PieceProofs) (slice) + case "proofs": + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > 8192 { + return fmt.Errorf("t.Proofs: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + + if extra > 0 { + t.Proofs = make([]PieceProofs, extra) + } + + for i := 0; i < int(extra); i++ { + { + var maj byte + var extra uint64 + var err error + _ = maj + _ = extra + _ = err + + { + + if err := t.Proofs[i].UnmarshalCBOR(cr); err != nil { + return xerrors.Errorf("unmarshaling t.Proofs[i]: %w", err) + } + + } + + } + } + // t.DataSet (big.Int) (struct) + case "dataSet": + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if maj != cbg.MajTag || extra != 2 { + return fmt.Errorf("big ints should be cbor bignums") + } + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if maj != cbg.MajByteString { + return fmt.Errorf("big ints should be tagged cbor byte strings") + } + + if extra > 256 { + return fmt.Errorf("t.DataSet: cbor bignum was too large") + } + + if extra > 0 { + buf := make([]byte, extra) + if _, err := io.ReadFull(cr, buf); err != nil { + return err + } + t.DataSet = big.NewInt(0).SetBytes(buf) + } else { + t.DataSet = big.NewInt(0) + } + // t.Metadata ([]sign.Metadata) (slice) + case "metadata": + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > 8192 { + return fmt.Errorf("t.Metadata: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + + if extra > 0 { + t.Metadata = make([]Metadata, extra) + } + + for i := 0; i < int(extra); i++ { + { + var maj byte + var extra uint64 + var err error + _ = maj + _ = extra + _ = err + + { + + if err := t.Metadata[i].UnmarshalCBOR(cr); err != nil { + return xerrors.Errorf("unmarshaling t.Metadata[i]: %w", err) + } + + } + + } + } + // t.PieceData ([][]uint8) (slice) + case "pieceData": + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > 8192 { + return fmt.Errorf("t.PieceData: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + + if extra > 0 { + t.PieceData = 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.PieceData[i]: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + + if extra > 0 { + t.PieceData[i] = make([]uint8, extra) + } + + if _, err := io.ReadFull(cr, t.PieceData[i]); err != nil { + return err + } + + } + } + + default: + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil { + return err + } + } + } + + return nil +} +func (t *PiecesRemoveScheduleArguments) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + + if _, err := cw.Write([]byte{162}); err != nil { + return err + } + + // t.Pieces ([]*big.Int) (slice) + if len("pieces") > 8192 { + return xerrors.Errorf("Value in field \"pieces\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("pieces"))); err != nil { + return err + } + if _, err := cw.WriteString(string("pieces")); err != nil { + return err + } + + if len(t.Pieces) > 8192 { + return xerrors.Errorf("Slice value in field t.Pieces was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.Pieces))); err != nil { + return err + } + for _, v := range t.Pieces { + { + if v != nil && v.Sign() < 0 { + return xerrors.Errorf("Value in field v was a negative big-integer (not supported)") + } + if err := cw.CborWriteHeader(cbg.MajTag, 2); err != nil { + return err + } + var b []byte + if v != nil { + b = v.Bytes() + } + + if err := cw.CborWriteHeader(cbg.MajByteString, uint64(len(b))); err != nil { + return err + } + if _, err := cw.Write(b); err != nil { + return err + } + } + + } + + // t.DataSet (big.Int) (struct) + if len("dataSet") > 8192 { + return xerrors.Errorf("Value in field \"dataSet\" was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("dataSet"))); err != nil { + return err + } + if _, err := cw.WriteString(string("dataSet")); err != nil { + return err + } + + { + if t.DataSet != nil && t.DataSet.Sign() < 0 { + return xerrors.Errorf("Value in field t.DataSet was a negative big-integer (not supported)") + } + if err := cw.CborWriteHeader(cbg.MajTag, 2); err != nil { + return err + } + var b []byte + if t.DataSet != nil { + b = t.DataSet.Bytes() + } + + if err := cw.CborWriteHeader(cbg.MajByteString, uint64(len(b))); err != nil { + return err + } + if _, err := cw.Write(b); err != nil { + return err + } + } + return nil +} + +func (t *PiecesRemoveScheduleArguments) UnmarshalCBOR(r io.Reader) (err error) { + *t = PiecesRemoveScheduleArguments{} + + 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.MajMap { + return fmt.Errorf("cbor input should be of type map") + } + + if extra > cbg.MaxLength { + return fmt.Errorf("PiecesRemoveScheduleArguments: map struct too large (%d)", extra) + } + + n := extra + + nameBuf := make([]byte, 7) + for i := uint64(0); i < n; i++ { + nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 8192) + if err != nil { + return err + } + + if !ok { + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil { + return err + } + continue + } + + switch string(nameBuf[:nameLen]) { + // t.Pieces ([]*big.Int) (slice) + case "pieces": + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > 8192 { + 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([]*big.Int, 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 maj != cbg.MajTag || extra != 2 { + return fmt.Errorf("big ints should be cbor bignums") + } + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if maj != cbg.MajByteString { + return fmt.Errorf("big ints should be tagged cbor byte strings") + } + + if extra > 256 { + return fmt.Errorf("t.Pieces[i]: cbor bignum was too large") + } + + if extra > 0 { + buf := make([]byte, extra) + if _, err := io.ReadFull(cr, buf); err != nil { + return err + } + t.Pieces[i] = big.NewInt(0).SetBytes(buf) + } else { + t.Pieces[i] = big.NewInt(0) + } + + } + } + // t.DataSet (big.Int) (struct) + case "dataSet": + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if maj != cbg.MajTag || extra != 2 { + return fmt.Errorf("big ints should be cbor bignums") + } + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if maj != cbg.MajByteString { + return fmt.Errorf("big ints should be tagged cbor byte strings") + } + + if extra > 256 { + return fmt.Errorf("t.DataSet: cbor bignum was too large") + } + + if extra > 0 { + buf := make([]byte, extra) + if _, err := io.ReadFull(cr, buf); err != nil { + return err + } + t.DataSet = big.NewInt(0).SetBytes(buf) + } else { + t.DataSet = big.NewInt(0) + } + + default: + // Field doesn't exist on this type, so ignore it + if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil { + return err + } + } + } + + return nil +} diff --git a/capabilities/pdp/sign/gen/main.go b/capabilities/pdp/sign/gen/main.go new file mode 100644 index 0000000..722e45c --- /dev/null +++ b/capabilities/pdp/sign/gen/main.go @@ -0,0 +1,55 @@ +//go:generate go run -tags codegen . + +package main + +import ( + "os" + + jsg "github.com/alanshaw/dag-json-gen" + sign "github.com/fil-forge/libforge/capabilities/pdp/sign" + cbg "github.com/whyrusleeping/cbor-gen" +) + +// The parent sign package has bindcap.New calls that require codec methods +// to exist on the argument types. Those codecs are what this tool +// generates. To break the bootstrap, bindings and generated codec files +// carry `//go:build !codegen`; this tool is built with `-tags codegen`, so +// the import of `sign` here only pulls in the wire types from types.go. +// +// After cbor-gen / dag-json-gen write the codec files, we re-tag them with +// the same constraint so subsequent codegen runs are stale-safe. +const buildTag = "//go:build !codegen\n\n" + +func tag(path string) { + data, err := os.ReadFile(path) + if err != nil { + panic(err) + } + if err := os.WriteFile(path, append([]byte(buildTag), data...), 0644); err != nil { + panic(err) + } +} + +func main() { + models := []any{ + sign.AuthSignature{}, + sign.Metadata{}, + sign.PieceProofs{}, + sign.DataSetCreateArguments{}, + sign.DataSetDeleteArguments{}, + sign.PiecesAddArguments{}, + sign.PiecesRemoveScheduleArguments{}, + } + const ( + cborFile = "../cbor_gen.go" + jsonFile = "../json_gen.go" + ) + if err := cbg.WriteMapEncodersToFile(cborFile, "sign", models...); err != nil { + panic(err) + } + if err := jsg.WriteMapEncodersToFile(jsonFile, "sign", models...); err != nil { + panic(err) + } + tag(cborFile) + tag(jsonFile) +} diff --git a/capabilities/pdp/sign/json_gen.go b/capabilities/pdp/sign/json_gen.go new file mode 100644 index 0000000..26305b2 --- /dev/null +++ b/capabilities/pdp/sign/json_gen.go @@ -0,0 +1,1624 @@ +//go:build !codegen + +// Code generated by github.com/alanshaw/dag-json-gen. DO NOT EDIT. + +package sign + +import ( + "errors" + "fmt" + "io" + "math" + "sort" + + jsg "github.com/alanshaw/dag-json-gen" + cid "github.com/ipfs/go-cid" + big "math/big" +) + +var _ = cid.Undef +var _ = math.E +var _ = sort.Sort +var _ = errors.Is + +func (t *AuthSignature) MarshalDagJSON(w io.Writer) error { + jw := jsg.NewDagJsonWriter(w) + if t == nil { + err := jw.WriteNull() + return err + } + if err := jw.WriteObjectOpen(); err != nil { + return err + } + written := 0 + + // t.R ([]uint8) (slice) + if len("r") > 8192 { + return fmt.Errorf("string in field \"r\" was too long") + } + if err := jw.WriteString(string("r")); err != nil { + return fmt.Errorf("writing string for field \"r\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if len(t.R) > 2097152 { + return fmt.Errorf("byte array in field t.R was too long") + } + + if err := jw.WriteBytes(t.R); err != nil { + return fmt.Errorf("writing bytes for field t.R: %w", err) + } + + written++ + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + + // t.S ([]uint8) (slice) + if len("s") > 8192 { + return fmt.Errorf("string in field \"s\" was too long") + } + if err := jw.WriteString(string("s")); err != nil { + return fmt.Errorf("writing string for field \"s\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if len(t.S) > 2097152 { + return fmt.Errorf("byte array in field t.S was too long") + } + + if err := jw.WriteBytes(t.S); err != nil { + return fmt.Errorf("writing bytes for field t.S: %w", err) + } + + written++ + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + + // t.Signature ([]uint8) (slice) + if len("signature") > 8192 { + return fmt.Errorf("string in field \"signature\" was too long") + } + if err := jw.WriteString(string("signature")); err != nil { + return fmt.Errorf("writing string for field \"signature\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if len(t.Signature) > 2097152 { + return fmt.Errorf("byte array in field t.Signature was too long") + } + + if err := jw.WriteBytes(t.Signature); err != nil { + return fmt.Errorf("writing bytes for field t.Signature: %w", err) + } + + written++ + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + + // t.SignedData ([]uint8) (slice) + if len("signedData") > 8192 { + return fmt.Errorf("string in field \"signedData\" was too long") + } + if err := jw.WriteString(string("signedData")); err != nil { + return fmt.Errorf("writing string for field \"signedData\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if len(t.SignedData) > 2097152 { + return fmt.Errorf("byte array in field t.SignedData was too long") + } + + if err := jw.WriteBytes(t.SignedData); err != nil { + return fmt.Errorf("writing bytes for field t.SignedData: %w", err) + } + + written++ + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + + // t.Signer ([]uint8) (slice) + if len("signer") > 8192 { + return fmt.Errorf("string in field \"signer\" was too long") + } + if err := jw.WriteString(string("signer")); err != nil { + return fmt.Errorf("writing string for field \"signer\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if len(t.Signer) > 2097152 { + return fmt.Errorf("byte array in field t.Signer was too long") + } + + if err := jw.WriteBytes(t.Signer); err != nil { + return fmt.Errorf("writing bytes for field t.Signer: %w", err) + } + + written++ + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + + // t.V (uint8) (uint8) + if len("v") > 8192 { + return fmt.Errorf("string in field \"v\" was too long") + } + if err := jw.WriteString(string("v")); err != nil { + return fmt.Errorf("writing string for field \"v\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if err := jw.WriteUint8(uint8(t.V)); err != nil { + return fmt.Errorf("writing uint8 for field t.V: %w", err) + } + written++ + if err := jw.WriteObjectClose(); err != nil { + return err + } + return nil +} +func (t *AuthSignature) UnmarshalDagJSON(r io.Reader) (err error) { + *t = AuthSignature{} + + jr := jsg.NewDagJsonReader(r) + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + if err := jr.ReadObjectOpen(); err != nil { + return fmt.Errorf("reading object open for AuthSignature: %w", err) + } + close, err := jr.PeekObjectClose() + if err != nil { + return fmt.Errorf("peeking object close for AuthSignature: %w", err) + } + if close { + if err := jr.ReadObjectClose(); err != nil { + return fmt.Errorf("reading object close for AuthSignature: %w", err) + } + } else { + for i := uint64(0); i < 8192; i++ { + name, err := jr.ReadString(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string for field AuthSignature: string too large") + } + return fmt.Errorf("reading string for field AuthSignature: %w", err) + } + if err := jr.ReadObjectColon(); err != nil { + return fmt.Errorf("reading object colon for field AuthSignature: %w", err) + } + switch name { + + // t.R ([]uint8) (slice) + case "r": + + { + bval, err := jr.ReadBytes(2097152) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading bytes for field t.R: byte array too large") + } + return fmt.Errorf("reading bytes for field t.R: %w", err) + } + if len(bval) > 0 { + t.R = []uint8(bval) + } + } + + // t.S ([]uint8) (slice) + case "s": + + { + bval, err := jr.ReadBytes(2097152) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading bytes for field t.S: byte array too large") + } + return fmt.Errorf("reading bytes for field t.S: %w", err) + } + if len(bval) > 0 { + t.S = []uint8(bval) + } + } + + // t.Signature ([]uint8) (slice) + case "signature": + + { + bval, err := jr.ReadBytes(2097152) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading bytes for field t.Signature: byte array too large") + } + return fmt.Errorf("reading bytes for field t.Signature: %w", err) + } + if len(bval) > 0 { + t.Signature = []uint8(bval) + } + } + + // t.SignedData ([]uint8) (slice) + case "signedData": + + { + bval, err := jr.ReadBytes(2097152) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading bytes for field t.SignedData: byte array too large") + } + return fmt.Errorf("reading bytes for field t.SignedData: %w", err) + } + if len(bval) > 0 { + t.SignedData = []uint8(bval) + } + } + + // t.Signer ([]uint8) (slice) + case "signer": + + { + bval, err := jr.ReadBytes(2097152) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading bytes for field t.Signer: byte array too large") + } + return fmt.Errorf("reading bytes for field t.Signer: %w", err) + } + if len(bval) > 0 { + t.Signer = []uint8(bval) + } + } + + // t.V (uint8) (uint8) + case "v": + { + nval, err := jr.ReadNumberAsUint8() + if err != nil { + return fmt.Errorf("reading uint8 for field t.V: %w", err) + } + t.V = uint8(nval) + } + default: + // Field doesn't exist on this type, so ignore it + if err := jr.DiscardType(); err != nil { + return fmt.Errorf("ignoring field %s for AuthSignature: %w", name, err) + } + } + + close, err := jr.ReadObjectCloseOrComma() + if err != nil { + return fmt.Errorf("reading object close or comma for field AuthSignature: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("map too large for AuthSignature") + } + } + } + + return nil +} +func (t *Metadata) MarshalDagJSON(w io.Writer) error { + jw := jsg.NewDagJsonWriter(w) + if t == nil { + err := jw.WriteNull() + return err + } + if err := jw.WriteObjectOpen(); err != nil { + return err + } + written := 0 + + // t.Keys ([]string) (slice) + if len("keys") > 8192 { + return fmt.Errorf("string in field \"keys\" was too long") + } + if err := jw.WriteString(string("keys")); err != nil { + return fmt.Errorf("writing string for field \"keys\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if len(t.Keys) > 8192 { + return fmt.Errorf("slice value in field t.Keys was too long") + } + + if err := jw.WriteArrayOpen(); err != nil { + return fmt.Errorf("writing array open for field t.Keys: %w", err) + } + for i, v := range t.Keys { + if i > 0 { + if err := jw.WriteComma(); err != nil { + return fmt.Errorf("writing comma for field t.Keys: %w", err) + } + } + if len(v) > 8192 { + return fmt.Errorf("string in field v was too long") + } + if err := jw.WriteString(string(v)); err != nil { + return fmt.Errorf("writing string for field v: %w", err) + } + } + if err := jw.WriteArrayClose(); err != nil { + return fmt.Errorf("writing array close for field t.Keys: %w", err) + } + + written++ + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + + // t.Values (map[string]string) (map) + if len("values") > 8192 { + return fmt.Errorf("string in field \"values\" was too long") + } + if err := jw.WriteString(string("values")); err != nil { + return fmt.Errorf("writing string for field \"values\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + { + if len(t.Values) > 4096 { + return fmt.Errorf("cannot marshal t.Values map too large") + } + + if err := jw.WriteObjectOpen(); err != nil { + return fmt.Errorf("writing object open for field t.Values: %w", err) + } + + keys := make([]string, 0, len(t.Values)) + for k := range t.Values { + keys = append(keys, k) + } + sort.Strings(keys) + for i, k := range keys { + if i > 0 { + if err := jw.WriteComma(); err != nil { + return fmt.Errorf("writing comma for field t.Values: %w", err) + } + } + v := t.Values[k] + if len(k) > 8192 { + return fmt.Errorf("string in field k was too long") + } + if err := jw.WriteString(string(k)); err != nil { + return fmt.Errorf("writing string for field k: %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return fmt.Errorf("writing colon for field t.Values: %w", err) + } + + if len(v) > 8192 { + return fmt.Errorf("string in field v was too long") + } + if err := jw.WriteString(string(v)); err != nil { + return fmt.Errorf("writing string for field v: %w", err) + } + } + if err := jw.WriteObjectClose(); err != nil { + return fmt.Errorf("writing object close for field t.Values: %w", err) + } + } + + written++ + if err := jw.WriteObjectClose(); err != nil { + return err + } + return nil +} +func (t *Metadata) UnmarshalDagJSON(r io.Reader) (err error) { + *t = Metadata{} + + jr := jsg.NewDagJsonReader(r) + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + if err := jr.ReadObjectOpen(); err != nil { + return fmt.Errorf("reading object open for Metadata: %w", err) + } + close, err := jr.PeekObjectClose() + if err != nil { + return fmt.Errorf("peeking object close for Metadata: %w", err) + } + if close { + if err := jr.ReadObjectClose(); err != nil { + return fmt.Errorf("reading object close for Metadata: %w", err) + } + } else { + for i := uint64(0); i < 8192; i++ { + name, err := jr.ReadString(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string for field Metadata: string too large") + } + return fmt.Errorf("reading string for field Metadata: %w", err) + } + if err := jr.ReadObjectColon(); err != nil { + return fmt.Errorf("reading object colon for field Metadata: %w", err) + } + switch name { + + // t.Keys ([]string) (slice) + case "keys": + { + + if err := jr.ReadArrayOpen(); err != nil { + return fmt.Errorf("reading array open for field t.Keys: %w", err) + } + + close, err := jr.PeekArrayClose() + if err != nil { + return fmt.Errorf("peeking array close for field t.Keys: %w", err) + } + if close { + if err := jr.ReadArrayClose(); err != nil { + return fmt.Errorf("reading array close for field t.Keys: %w", err) + } + + } else { + for i := 0; i < 8192; i++ { + item := make([]string, 1) + { + sval, err := jr.ReadString(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string for field item[0]: string too long") + } + return fmt.Errorf("reading string for field item[0]: %w", err) + } + item[0] = string(sval) + } + t.Keys = append(t.Keys, item[0]) + + close, err := jr.ReadArrayCloseOrComma() + if err != nil { + return fmt.Errorf("reading array close or comma for field t.Keys: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("reading array for field t.Keys: slice too large") + } + } + } + + } + + // t.Values (map[string]string) (map) + case "values": + if err := jr.ReadObjectOpen(); err != nil { + return fmt.Errorf("reading object open for field t.Values: %w", err) + } + + t.Values = map[string]string{} + + close, err := jr.PeekObjectClose() + if err != nil { + return fmt.Errorf("peeking object close for field t.Values: %w", err) + } + if close { + if err := jr.ReadObjectClose(); err != nil { + return fmt.Errorf("reading object close for field t.Values: %w", err) + } + } else { + for i, l := 0, 8192; i < l; i++ { + var k string + { + sval, err := jr.ReadString(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string for field k: string too long") + } + return fmt.Errorf("reading string for field k: %w", err) + } + k = string(sval) + } + if err := jr.ReadObjectColon(); err != nil { + return fmt.Errorf("reading object colon for field t.Values: %w", err) + } + var v string + { + sval, err := jr.ReadString(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string for field v: string too long") + } + return fmt.Errorf("reading string for field v: %w", err) + } + v = string(sval) + } + t.Values[k] = v + close, err := jr.ReadObjectCloseOrComma() + if err != nil { + return fmt.Errorf("reading object close or comma for field t.Values: %w", err) + } + if close { + break + } + } + } + default: + // Field doesn't exist on this type, so ignore it + if err := jr.DiscardType(); err != nil { + return fmt.Errorf("ignoring field %s for Metadata: %w", name, err) + } + } + + close, err := jr.ReadObjectCloseOrComma() + if err != nil { + return fmt.Errorf("reading object close or comma for field Metadata: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("map too large for Metadata") + } + } + } + + return nil +} +func (t *PieceProofs) MarshalDagJSON(w io.Writer) error { + jw := jsg.NewDagJsonWriter(w) + if t == nil { + err := jw.WriteNull() + return err + } + if err := jw.WriteObjectOpen(); err != nil { + return err + } + + // t.Proofs ([]cid.Cid) (slice) + if len("proofs") > 8192 { + return fmt.Errorf("string in field \"proofs\" was too long") + } + if err := jw.WriteString(string("proofs")); err != nil { + return fmt.Errorf("writing string for field \"proofs\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if len(t.Proofs) > 8192 { + return fmt.Errorf("slice value in field t.Proofs was too long") + } + + if err := jw.WriteArrayOpen(); err != nil { + return fmt.Errorf("writing array open for field t.Proofs: %w", err) + } + for i, v := range t.Proofs { + if i > 0 { + if err := jw.WriteComma(); err != nil { + return fmt.Errorf("writing comma for field t.Proofs: %w", err) + } + } + + if err := jw.WriteCid(v); err != nil { + return fmt.Errorf("writing CID for field v: %w", err) + } + + } + if err := jw.WriteArrayClose(); err != nil { + return fmt.Errorf("writing array close for field t.Proofs: %w", err) + } + + if err := jw.WriteObjectClose(); err != nil { + return err + } + return nil +} +func (t *PieceProofs) UnmarshalDagJSON(r io.Reader) (err error) { + *t = PieceProofs{} + + jr := jsg.NewDagJsonReader(r) + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + if err := jr.ReadObjectOpen(); err != nil { + return fmt.Errorf("reading object open for PieceProofs: %w", err) + } + close, err := jr.PeekObjectClose() + if err != nil { + return fmt.Errorf("peeking object close for PieceProofs: %w", err) + } + if close { + if err := jr.ReadObjectClose(); err != nil { + return fmt.Errorf("reading object close for PieceProofs: %w", err) + } + } else { + for i := uint64(0); i < 8192; i++ { + name, err := jr.ReadString(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string for field PieceProofs: string too large") + } + return fmt.Errorf("reading string for field PieceProofs: %w", err) + } + if err := jr.ReadObjectColon(); err != nil { + return fmt.Errorf("reading object colon for field PieceProofs: %w", err) + } + switch name { + + // t.Proofs ([]cid.Cid) (slice) + case "proofs": + { + + if err := jr.ReadArrayOpen(); err != nil { + return fmt.Errorf("reading array open for field t.Proofs: %w", err) + } + + close, err := jr.PeekArrayClose() + if err != nil { + return fmt.Errorf("peeking array close for field t.Proofs: %w", err) + } + if close { + if err := jr.ReadArrayClose(); err != nil { + return fmt.Errorf("reading array close for field t.Proofs: %w", err) + } + + } else { + for i := 0; i < 8192; i++ { + item := make([]cid.Cid, 1) + { + + c, err := jr.ReadCid() + if err != nil { + return fmt.Errorf("reading CID for field item[0]: %w", err) + } + item[0] = c + + } + t.Proofs = append(t.Proofs, item[0]) + + close, err := jr.ReadArrayCloseOrComma() + if err != nil { + return fmt.Errorf("reading array close or comma for field t.Proofs: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("reading array for field t.Proofs: slice too large") + } + } + } + + } + default: + // Field doesn't exist on this type, so ignore it + if err := jr.DiscardType(); err != nil { + return fmt.Errorf("ignoring field %s for PieceProofs: %w", name, err) + } + } + + close, err := jr.ReadObjectCloseOrComma() + if err != nil { + return fmt.Errorf("reading object close or comma for field PieceProofs: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("map too large for PieceProofs") + } + } + } + + return nil +} +func (t *DataSetCreateArguments) MarshalDagJSON(w io.Writer) error { + jw := jsg.NewDagJsonWriter(w) + if t == nil { + err := jw.WriteNull() + return err + } + if err := jw.WriteObjectOpen(); err != nil { + return err + } + written := 0 + + // t.DataSet (big.Int) (struct) + if len("dataSet") > 8192 { + return fmt.Errorf("string in field \"dataSet\" was too long") + } + if err := jw.WriteString(string("dataSet")); err != nil { + return fmt.Errorf("writing string for field \"dataSet\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if t.DataSet != nil && t.DataSet.Sign() < 0 { + return fmt.Errorf("value in field t.DataSet was a negative big-integer (not supported)") + } + if t.DataSet == nil { + if err := jw.WriteUint8(0); err != nil { + return fmt.Errorf("writing uint8 for field t.DataSet: %w", err) + } + } else { + if err := jw.WriteBigInt(t.DataSet); err != nil { + return fmt.Errorf("writing bigint for field t.DataSet: %w", err) + } + } + written++ + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + + // t.Metadata (sign.Metadata) (struct) + if len("metadata") > 8192 { + return fmt.Errorf("string in field \"metadata\" was too long") + } + if err := jw.WriteString(string("metadata")); err != nil { + return fmt.Errorf("writing string for field \"metadata\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if err := t.Metadata.MarshalDagJSON(jw); err != nil { + return fmt.Errorf("marshaling field t.Metadata: %w", err) + } + written++ + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + + // t.Payee ([]uint8) (slice) + if len("payee") > 8192 { + return fmt.Errorf("string in field \"payee\" was too long") + } + if err := jw.WriteString(string("payee")); err != nil { + return fmt.Errorf("writing string for field \"payee\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if len(t.Payee) > 2097152 { + return fmt.Errorf("byte array in field t.Payee was too long") + } + + if err := jw.WriteBytes(t.Payee); err != nil { + return fmt.Errorf("writing bytes for field t.Payee: %w", err) + } + + written++ + if err := jw.WriteObjectClose(); err != nil { + return err + } + return nil +} +func (t *DataSetCreateArguments) UnmarshalDagJSON(r io.Reader) (err error) { + *t = DataSetCreateArguments{} + + jr := jsg.NewDagJsonReader(r) + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + if err := jr.ReadObjectOpen(); err != nil { + return fmt.Errorf("reading object open for DataSetCreateArguments: %w", err) + } + close, err := jr.PeekObjectClose() + if err != nil { + return fmt.Errorf("peeking object close for DataSetCreateArguments: %w", err) + } + if close { + if err := jr.ReadObjectClose(); err != nil { + return fmt.Errorf("reading object close for DataSetCreateArguments: %w", err) + } + } else { + for i := uint64(0); i < 8192; i++ { + name, err := jr.ReadString(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string for field DataSetCreateArguments: string too large") + } + return fmt.Errorf("reading string for field DataSetCreateArguments: %w", err) + } + if err := jr.ReadObjectColon(); err != nil { + return fmt.Errorf("reading object colon for field DataSetCreateArguments: %w", err) + } + switch name { + + // t.DataSet (big.Int) (struct) + case "dataSet": + { + nval, err := jr.ReadNumberAsBigInt(256) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading number as bigint for field t.DataSet: number too large") + } + return fmt.Errorf("reading number as bigint for field t.DataSet: %w", err) + } + t.DataSet = nval + } + + // t.Metadata (sign.Metadata) (struct) + case "metadata": + + if err := t.Metadata.UnmarshalDagJSON(jr); err != nil { + return fmt.Errorf("unmarshaling t.Metadata: %w", err) + } + + // t.Payee ([]uint8) (slice) + case "payee": + + { + bval, err := jr.ReadBytes(2097152) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading bytes for field t.Payee: byte array too large") + } + return fmt.Errorf("reading bytes for field t.Payee: %w", err) + } + if len(bval) > 0 { + t.Payee = []uint8(bval) + } + } + + default: + // Field doesn't exist on this type, so ignore it + if err := jr.DiscardType(); err != nil { + return fmt.Errorf("ignoring field %s for DataSetCreateArguments: %w", name, err) + } + } + + close, err := jr.ReadObjectCloseOrComma() + if err != nil { + return fmt.Errorf("reading object close or comma for field DataSetCreateArguments: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("map too large for DataSetCreateArguments") + } + } + } + + return nil +} +func (t *DataSetDeleteArguments) MarshalDagJSON(w io.Writer) error { + jw := jsg.NewDagJsonWriter(w) + if t == nil { + err := jw.WriteNull() + return err + } + if err := jw.WriteObjectOpen(); err != nil { + return err + } + + // t.DataSet (big.Int) (struct) + if len("dataSet") > 8192 { + return fmt.Errorf("string in field \"dataSet\" was too long") + } + if err := jw.WriteString(string("dataSet")); err != nil { + return fmt.Errorf("writing string for field \"dataSet\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if t.DataSet != nil && t.DataSet.Sign() < 0 { + return fmt.Errorf("value in field t.DataSet was a negative big-integer (not supported)") + } + if t.DataSet == nil { + if err := jw.WriteUint8(0); err != nil { + return fmt.Errorf("writing uint8 for field t.DataSet: %w", err) + } + } else { + if err := jw.WriteBigInt(t.DataSet); err != nil { + return fmt.Errorf("writing bigint for field t.DataSet: %w", err) + } + } + if err := jw.WriteObjectClose(); err != nil { + return err + } + return nil +} +func (t *DataSetDeleteArguments) UnmarshalDagJSON(r io.Reader) (err error) { + *t = DataSetDeleteArguments{} + + jr := jsg.NewDagJsonReader(r) + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + if err := jr.ReadObjectOpen(); err != nil { + return fmt.Errorf("reading object open for DataSetDeleteArguments: %w", err) + } + close, err := jr.PeekObjectClose() + if err != nil { + return fmt.Errorf("peeking object close for DataSetDeleteArguments: %w", err) + } + if close { + if err := jr.ReadObjectClose(); err != nil { + return fmt.Errorf("reading object close for DataSetDeleteArguments: %w", err) + } + } else { + for i := uint64(0); i < 8192; i++ { + name, err := jr.ReadString(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string for field DataSetDeleteArguments: string too large") + } + return fmt.Errorf("reading string for field DataSetDeleteArguments: %w", err) + } + if err := jr.ReadObjectColon(); err != nil { + return fmt.Errorf("reading object colon for field DataSetDeleteArguments: %w", err) + } + switch name { + + // t.DataSet (big.Int) (struct) + case "dataSet": + { + nval, err := jr.ReadNumberAsBigInt(256) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading number as bigint for field t.DataSet: number too large") + } + return fmt.Errorf("reading number as bigint for field t.DataSet: %w", err) + } + t.DataSet = nval + } + default: + // Field doesn't exist on this type, so ignore it + if err := jr.DiscardType(); err != nil { + return fmt.Errorf("ignoring field %s for DataSetDeleteArguments: %w", name, err) + } + } + + close, err := jr.ReadObjectCloseOrComma() + if err != nil { + return fmt.Errorf("reading object close or comma for field DataSetDeleteArguments: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("map too large for DataSetDeleteArguments") + } + } + } + + return nil +} +func (t *PiecesAddArguments) MarshalDagJSON(w io.Writer) error { + jw := jsg.NewDagJsonWriter(w) + if t == nil { + err := jw.WriteNull() + return err + } + if err := jw.WriteObjectOpen(); err != nil { + return err + } + written := 0 + + // t.DataSet (big.Int) (struct) + if len("dataSet") > 8192 { + return fmt.Errorf("string in field \"dataSet\" was too long") + } + if err := jw.WriteString(string("dataSet")); err != nil { + return fmt.Errorf("writing string for field \"dataSet\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if t.DataSet != nil && t.DataSet.Sign() < 0 { + return fmt.Errorf("value in field t.DataSet was a negative big-integer (not supported)") + } + if t.DataSet == nil { + if err := jw.WriteUint8(0); err != nil { + return fmt.Errorf("writing uint8 for field t.DataSet: %w", err) + } + } else { + if err := jw.WriteBigInt(t.DataSet); err != nil { + return fmt.Errorf("writing bigint for field t.DataSet: %w", err) + } + } + written++ + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + + // t.Metadata ([]sign.Metadata) (slice) + if len("metadata") > 8192 { + return fmt.Errorf("string in field \"metadata\" was too long") + } + if err := jw.WriteString(string("metadata")); err != nil { + return fmt.Errorf("writing string for field \"metadata\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if len(t.Metadata) > 8192 { + return fmt.Errorf("slice value in field t.Metadata was too long") + } + + if err := jw.WriteArrayOpen(); err != nil { + return fmt.Errorf("writing array open for field t.Metadata: %w", err) + } + for i, v := range t.Metadata { + if i > 0 { + if err := jw.WriteComma(); err != nil { + return fmt.Errorf("writing comma for field t.Metadata: %w", err) + } + } + if err := v.MarshalDagJSON(jw); err != nil { + return fmt.Errorf("marshaling field v: %w", err) + } + } + if err := jw.WriteArrayClose(); err != nil { + return fmt.Errorf("writing array close for field t.Metadata: %w", err) + } + + written++ + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + + // t.Nonce (big.Int) (struct) + if len("nonce") > 8192 { + return fmt.Errorf("string in field \"nonce\" was too long") + } + if err := jw.WriteString(string("nonce")); err != nil { + return fmt.Errorf("writing string for field \"nonce\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if t.Nonce != nil && t.Nonce.Sign() < 0 { + return fmt.Errorf("value in field t.Nonce was a negative big-integer (not supported)") + } + if t.Nonce == nil { + if err := jw.WriteUint8(0); err != nil { + return fmt.Errorf("writing uint8 for field t.Nonce: %w", err) + } + } else { + if err := jw.WriteBigInt(t.Nonce); err != nil { + return fmt.Errorf("writing bigint for field t.Nonce: %w", err) + } + } + written++ + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + + // t.PieceData ([][]uint8) (slice) + if len("pieceData") > 8192 { + return fmt.Errorf("string in field \"pieceData\" was too long") + } + if err := jw.WriteString(string("pieceData")); err != nil { + return fmt.Errorf("writing string for field \"pieceData\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if len(t.PieceData) > 8192 { + return fmt.Errorf("slice value in field t.PieceData was too long") + } + + if err := jw.WriteArrayOpen(); err != nil { + return fmt.Errorf("writing array open for field t.PieceData: %w", err) + } + for i, v := range t.PieceData { + if i > 0 { + if err := jw.WriteComma(); err != nil { + return fmt.Errorf("writing comma for field t.PieceData: %w", err) + } + } + if len(v) > 2097152 { + return fmt.Errorf("byte array in field v was too long") + } + + if err := jw.WriteBytes(v); err != nil { + return fmt.Errorf("writing bytes for field v: %w", err) + } + + } + if err := jw.WriteArrayClose(); err != nil { + return fmt.Errorf("writing array close for field t.PieceData: %w", err) + } + + written++ + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + + // t.Proofs ([]sign.PieceProofs) (slice) + if len("proofs") > 8192 { + return fmt.Errorf("string in field \"proofs\" was too long") + } + if err := jw.WriteString(string("proofs")); err != nil { + return fmt.Errorf("writing string for field \"proofs\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if len(t.Proofs) > 8192 { + return fmt.Errorf("slice value in field t.Proofs was too long") + } + + if err := jw.WriteArrayOpen(); err != nil { + return fmt.Errorf("writing array open for field t.Proofs: %w", err) + } + for i, v := range t.Proofs { + if i > 0 { + if err := jw.WriteComma(); err != nil { + return fmt.Errorf("writing comma for field t.Proofs: %w", err) + } + } + if err := v.MarshalDagJSON(jw); err != nil { + return fmt.Errorf("marshaling field v: %w", err) + } + } + if err := jw.WriteArrayClose(); err != nil { + return fmt.Errorf("writing array close for field t.Proofs: %w", err) + } + + written++ + if err := jw.WriteObjectClose(); err != nil { + return err + } + return nil +} +func (t *PiecesAddArguments) UnmarshalDagJSON(r io.Reader) (err error) { + *t = PiecesAddArguments{} + + jr := jsg.NewDagJsonReader(r) + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + if err := jr.ReadObjectOpen(); err != nil { + return fmt.Errorf("reading object open for PiecesAddArguments: %w", err) + } + close, err := jr.PeekObjectClose() + if err != nil { + return fmt.Errorf("peeking object close for PiecesAddArguments: %w", err) + } + if close { + if err := jr.ReadObjectClose(); err != nil { + return fmt.Errorf("reading object close for PiecesAddArguments: %w", err) + } + } else { + for i := uint64(0); i < 8192; i++ { + name, err := jr.ReadString(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string for field PiecesAddArguments: string too large") + } + return fmt.Errorf("reading string for field PiecesAddArguments: %w", err) + } + if err := jr.ReadObjectColon(); err != nil { + return fmt.Errorf("reading object colon for field PiecesAddArguments: %w", err) + } + switch name { + + // t.DataSet (big.Int) (struct) + case "dataSet": + { + nval, err := jr.ReadNumberAsBigInt(256) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading number as bigint for field t.DataSet: number too large") + } + return fmt.Errorf("reading number as bigint for field t.DataSet: %w", err) + } + t.DataSet = nval + } + + // t.Metadata ([]sign.Metadata) (slice) + case "metadata": + { + + if err := jr.ReadArrayOpen(); err != nil { + return fmt.Errorf("reading array open for field t.Metadata: %w", err) + } + + close, err := jr.PeekArrayClose() + if err != nil { + return fmt.Errorf("peeking array close for field t.Metadata: %w", err) + } + if close { + if err := jr.ReadArrayClose(); err != nil { + return fmt.Errorf("reading array close for field t.Metadata: %w", err) + } + + } else { + for i := 0; i < 8192; i++ { + item := make([]Metadata, 1) + + if err := item[0].UnmarshalDagJSON(jr); err != nil { + return fmt.Errorf("unmarshaling item[0]: %w", err) + } + + t.Metadata = append(t.Metadata, item[0]) + + close, err := jr.ReadArrayCloseOrComma() + if err != nil { + return fmt.Errorf("reading array close or comma for field t.Metadata: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("reading array for field t.Metadata: slice too large") + } + } + } + + } + + // t.Nonce (big.Int) (struct) + case "nonce": + { + nval, err := jr.ReadNumberAsBigInt(256) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading number as bigint for field t.Nonce: number too large") + } + return fmt.Errorf("reading number as bigint for field t.Nonce: %w", err) + } + t.Nonce = nval + } + + // t.PieceData ([][]uint8) (slice) + case "pieceData": + { + + if err := jr.ReadArrayOpen(); err != nil { + return fmt.Errorf("reading array open for field t.PieceData: %w", err) + } + + close, err := jr.PeekArrayClose() + if err != nil { + return fmt.Errorf("peeking array close for field t.PieceData: %w", err) + } + if close { + if err := jr.ReadArrayClose(); err != nil { + return fmt.Errorf("reading array close for field t.PieceData: %w", err) + } + + } else { + for i := 0; i < 8192; i++ { + item := make([][]uint8, 1) + + { + bval, err := jr.ReadBytes(2097152) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading bytes for field item[0]: byte array too large") + } + return fmt.Errorf("reading bytes for field item[0]: %w", err) + } + if len(bval) > 0 { + item[0] = []uint8(bval) + } + } + + t.PieceData = append(t.PieceData, item[0]) + + close, err := jr.ReadArrayCloseOrComma() + if err != nil { + return fmt.Errorf("reading array close or comma for field t.PieceData: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("reading array for field t.PieceData: slice too large") + } + } + } + + } + + // t.Proofs ([]sign.PieceProofs) (slice) + case "proofs": + { + + if err := jr.ReadArrayOpen(); err != nil { + return fmt.Errorf("reading array open for field t.Proofs: %w", err) + } + + close, err := jr.PeekArrayClose() + if err != nil { + return fmt.Errorf("peeking array close for field t.Proofs: %w", err) + } + if close { + if err := jr.ReadArrayClose(); err != nil { + return fmt.Errorf("reading array close for field t.Proofs: %w", err) + } + + } else { + for i := 0; i < 8192; i++ { + item := make([]PieceProofs, 1) + + if err := item[0].UnmarshalDagJSON(jr); err != nil { + return fmt.Errorf("unmarshaling item[0]: %w", err) + } + + t.Proofs = append(t.Proofs, item[0]) + + close, err := jr.ReadArrayCloseOrComma() + if err != nil { + return fmt.Errorf("reading array close or comma for field t.Proofs: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("reading array for field t.Proofs: slice too large") + } + } + } + + } + default: + // Field doesn't exist on this type, so ignore it + if err := jr.DiscardType(); err != nil { + return fmt.Errorf("ignoring field %s for PiecesAddArguments: %w", name, err) + } + } + + close, err := jr.ReadObjectCloseOrComma() + if err != nil { + return fmt.Errorf("reading object close or comma for field PiecesAddArguments: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("map too large for PiecesAddArguments") + } + } + } + + return nil +} +func (t *PiecesRemoveScheduleArguments) MarshalDagJSON(w io.Writer) error { + jw := jsg.NewDagJsonWriter(w) + if t == nil { + err := jw.WriteNull() + return err + } + if err := jw.WriteObjectOpen(); err != nil { + return err + } + written := 0 + + // t.DataSet (big.Int) (struct) + if len("dataSet") > 8192 { + return fmt.Errorf("string in field \"dataSet\" was too long") + } + if err := jw.WriteString(string("dataSet")); err != nil { + return fmt.Errorf("writing string for field \"dataSet\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if t.DataSet != nil && t.DataSet.Sign() < 0 { + return fmt.Errorf("value in field t.DataSet was a negative big-integer (not supported)") + } + if t.DataSet == nil { + if err := jw.WriteUint8(0); err != nil { + return fmt.Errorf("writing uint8 for field t.DataSet: %w", err) + } + } else { + if err := jw.WriteBigInt(t.DataSet); err != nil { + return fmt.Errorf("writing bigint for field t.DataSet: %w", err) + } + } + written++ + if written > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + + // t.Pieces ([]*big.Int) (slice) + if len("pieces") > 8192 { + return fmt.Errorf("string in field \"pieces\" was too long") + } + if err := jw.WriteString(string("pieces")); err != nil { + return fmt.Errorf("writing string for field \"pieces\": %w", err) + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if len(t.Pieces) > 8192 { + return fmt.Errorf("slice value in field t.Pieces was too long") + } + + if err := jw.WriteArrayOpen(); err != nil { + return fmt.Errorf("writing array open for field t.Pieces: %w", err) + } + for i, v := range t.Pieces { + if i > 0 { + if err := jw.WriteComma(); err != nil { + return fmt.Errorf("writing comma for field t.Pieces: %w", err) + } + } + if v != nil && v.Sign() < 0 { + return fmt.Errorf("value in field v was a negative big-integer (not supported)") + } + if v == nil { + if err := jw.WriteUint8(0); err != nil { + return fmt.Errorf("writing uint8 for field v: %w", err) + } + } else { + if err := jw.WriteBigInt(v); err != nil { + return fmt.Errorf("writing bigint for field v: %w", err) + } + } + } + if err := jw.WriteArrayClose(); err != nil { + return fmt.Errorf("writing array close for field t.Pieces: %w", err) + } + + written++ + if err := jw.WriteObjectClose(); err != nil { + return err + } + return nil +} +func (t *PiecesRemoveScheduleArguments) UnmarshalDagJSON(r io.Reader) (err error) { + *t = PiecesRemoveScheduleArguments{} + + jr := jsg.NewDagJsonReader(r) + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + if err := jr.ReadObjectOpen(); err != nil { + return fmt.Errorf("reading object open for PiecesRemoveScheduleArguments: %w", err) + } + close, err := jr.PeekObjectClose() + if err != nil { + return fmt.Errorf("peeking object close for PiecesRemoveScheduleArguments: %w", err) + } + if close { + if err := jr.ReadObjectClose(); err != nil { + return fmt.Errorf("reading object close for PiecesRemoveScheduleArguments: %w", err) + } + } else { + for i := uint64(0); i < 8192; i++ { + name, err := jr.ReadString(8192) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading string for field PiecesRemoveScheduleArguments: string too large") + } + return fmt.Errorf("reading string for field PiecesRemoveScheduleArguments: %w", err) + } + if err := jr.ReadObjectColon(); err != nil { + return fmt.Errorf("reading object colon for field PiecesRemoveScheduleArguments: %w", err) + } + switch name { + + // t.DataSet (big.Int) (struct) + case "dataSet": + { + nval, err := jr.ReadNumberAsBigInt(256) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading number as bigint for field t.DataSet: number too large") + } + return fmt.Errorf("reading number as bigint for field t.DataSet: %w", err) + } + t.DataSet = nval + } + + // t.Pieces ([]*big.Int) (slice) + case "pieces": + { + + if err := jr.ReadArrayOpen(); err != nil { + return fmt.Errorf("reading array open for field t.Pieces: %w", err) + } + + close, err := jr.PeekArrayClose() + if err != nil { + return fmt.Errorf("peeking array close for field t.Pieces: %w", err) + } + if close { + if err := jr.ReadArrayClose(); err != nil { + return fmt.Errorf("reading array close for field t.Pieces: %w", err) + } + + } else { + for i := 0; i < 8192; i++ { + item := make([]*big.Int, 1) + { + nval, err := jr.ReadNumberAsBigInt(256) + if err != nil { + if errors.Is(err, jsg.ErrLimitExceeded) { + return fmt.Errorf("reading number as bigint for field item[0]: number too large") + } + return fmt.Errorf("reading number as bigint for field item[0]: %w", err) + } + item[0] = nval + } + t.Pieces = append(t.Pieces, item[0]) + + close, err := jr.ReadArrayCloseOrComma() + if err != nil { + return fmt.Errorf("reading array close or comma for field t.Pieces: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("reading array for field t.Pieces: slice too large") + } + } + } + + } + default: + // Field doesn't exist on this type, so ignore it + if err := jr.DiscardType(); err != nil { + return fmt.Errorf("ignoring field %s for PiecesRemoveScheduleArguments: %w", name, err) + } + } + + close, err := jr.ReadObjectCloseOrComma() + if err != nil { + return fmt.Errorf("reading object close or comma for field PiecesRemoveScheduleArguments: %w", err) + } + if close { + break + } + if i == 8192-1 { + return fmt.Errorf("map too large for PiecesRemoveScheduleArguments") + } + } + } + + return nil +} diff --git a/capabilities/pdp/sign/sign.go b/capabilities/pdp/sign/sign.go new file mode 100644 index 0000000..8177afb --- /dev/null +++ b/capabilities/pdp/sign/sign.go @@ -0,0 +1,28 @@ +//go:build !codegen + +package sign + +import "github.com/fil-forge/libforge/capabilities" + +const ( + DataSetCreateCommand = "/pdp/sign/dataset/create" + DataSetDeleteCommand = "/pdp/sign/dataset/delete" + PiecesAddCommand = "/pdp/sign/pieces/add" + PiecesRemoveScheduleCommand = "/pdp/sign/pieces/remove/schedule" +) + +// Every /pdp/sign/* operation returns the same shape; these per-operation +// labels exist so call sites can keep the operation name in the type. +type ( + DataSetCreateOK = AuthSignature + DataSetDeleteOK = AuthSignature + PiecesAddOK = AuthSignature + PiecesRemoveScheduleOK = AuthSignature +) + +var ( + DataSetCreate = capabilities.MustNew[*DataSetCreateArguments](DataSetCreateCommand) + DataSetDelete = capabilities.MustNew[*DataSetDeleteArguments](DataSetDeleteCommand) + PiecesAdd = capabilities.MustNew[*PiecesAddArguments](PiecesAddCommand) + PiecesRemoveSchedule = capabilities.MustNew[*PiecesRemoveScheduleArguments](PiecesRemoveScheduleCommand) +) diff --git a/capabilities/pdp/sign/types.go b/capabilities/pdp/sign/types.go new file mode 100644 index 0000000..ef5cd2a --- /dev/null +++ b/capabilities/pdp/sign/types.go @@ -0,0 +1,88 @@ +// Package sign exposes the four /pdp/sign/* UCAN capabilities used by piri +// to drive an eip712 signing service: +// +// - /pdp/sign/dataset/create +// - /pdp/sign/dataset/delete +// - /pdp/sign/pieces/add +// - /pdp/sign/pieces/remove/schedule +// +// Each returns an [AuthSignature] (an eip712-signed bytes payload). +// +// Wire-level conventions: +// +// - `*big.Int` fields (DataSet, Nonce, Pieces) are encoded as CBOR +// bignums (tag 2). cbor-gen does not support negative bignums; the +// domain (dataset IDs, nonces, piece IDs) is non-negative. +// +// - `common.Address` (20 bytes) and `common.Hash` (32 bytes) are plain +// `[]byte`; length validation is left to the caller. +package sign + +import ( + "math/big" + + "github.com/ipfs/go-cid" +) + +// AuthSignature is the eip712 auth signature returned from every +// /pdp/sign/* invocation. Field semantics mirror +// filecoin-services/go/eip712.AuthSignature. +type AuthSignature struct { + Signature []byte `cborgen:"signature" dagjsongen:"signature"` + V uint8 `cborgen:"v" dagjsongen:"v"` + R []byte `cborgen:"r" dagjsongen:"r"` + S []byte `cborgen:"s" dagjsongen:"s"` + SignedData []byte `cborgen:"signedData" dagjsongen:"signedData"` + Signer []byte `cborgen:"signer" dagjsongen:"signer"` +} + +// Metadata is the eip712 metadata bag attached to dataset & piece signing +// requests. Keys carries insertion order so the wire encoding is +// deterministic across implementations. +type Metadata struct { + Keys []string `cborgen:"keys" dagjsongen:"keys"` + Values map[string]string `cborgen:"values" dagjsongen:"values"` +} + +// PieceProofs wraps the list of `blob/accept` invocation links proving the +// sub-pieces of one piece in a /pdp/sign/pieces/add request. cborgen does +// not natively encode `[][]cid.Cid`, so this single-level wrapper turns +// the outer slice into `[]PieceProofs`. +type PieceProofs struct { + Proofs []cid.Cid `cborgen:"proofs" dagjsongen:"proofs"` +} + +// DataSetCreateArguments are the arguments for /pdp/sign/dataset/create. +type DataSetCreateArguments struct { + DataSet *big.Int `cborgen:"dataSet" dagjsongen:"dataSet"` + Payee []byte `cborgen:"payee" dagjsongen:"payee"` + Metadata Metadata `cborgen:"metadata" dagjsongen:"metadata"` +} + +// DataSetDeleteArguments are the arguments for /pdp/sign/dataset/delete. +type DataSetDeleteArguments struct { + DataSet *big.Int `cborgen:"dataSet" dagjsongen:"dataSet"` +} + +// PiecesAddArguments are the arguments for /pdp/sign/pieces/add. +// +// Each entry in PieceData has a matching Metadata entry and a matching +// Proofs entry. The Proofs[i].Proofs list links to `blob/accept` +// invocations for every sub-piece of piece i. Each `blob/accept` receipt +// MUST include the corresponding `pdp/accept` effect receipt; all receipt +// data MUST be attached to the signing invocation's container as proof +// blocks. +type PiecesAddArguments struct { + DataSet *big.Int `cborgen:"dataSet" dagjsongen:"dataSet"` + Nonce *big.Int `cborgen:"nonce" dagjsongen:"nonce"` + PieceData [][]byte `cborgen:"pieceData" dagjsongen:"pieceData"` + Metadata []Metadata `cborgen:"metadata" dagjsongen:"metadata"` + Proofs []PieceProofs `cborgen:"proofs" dagjsongen:"proofs"` +} + +// PiecesRemoveScheduleArguments are the arguments for +// /pdp/sign/pieces/remove/schedule. +type PiecesRemoveScheduleArguments struct { + DataSet *big.Int `cborgen:"dataSet" dagjsongen:"dataSet"` + Pieces []*big.Int `cborgen:"pieces" dagjsongen:"pieces"` +} diff --git a/capabilities/pdp/types.go b/capabilities/pdp/types.go new file mode 100644 index 0000000..bd16abf --- /dev/null +++ b/capabilities/pdp/types.go @@ -0,0 +1,31 @@ +package pdp + +import ( + "github.com/fil-forge/libforge/merkletree" + "github.com/ipfs/go-cid" + "github.com/multiformats/go-multihash" +) + +type AcceptArguments struct { + Blob multihash.Multihash `cborgen:"blob" dagjsongen:"blob"` +} + +type AcceptOK struct { + Aggregate cid.Cid `cborgen:"aggregate" dagjsongen:"aggregate"` + InclusionProof merkletree.ProofData `cborgen:"inclusionProof" dagjsongen:"inclusionProof"` + Piece cid.Cid `cborgen:"piece" dagjsongen:"piece"` +} + +type InfoArguments struct { + Blob multihash.Multihash `cborgen:"blob" dagjsongen:"blob"` +} + +type InfoAcceptedAggregate struct { + Aggregate cid.Cid `cborgen:"aggregate" dagjsongen:"aggregate"` + InclusionProof merkletree.ProofData `cborgen:"inclusionProof" dagjsongen:"inclusionProof"` +} + +type InfoOK struct { + Piece cid.Cid `cborgen:"piece" dagjsongen:"piece"` + Aggregates []InfoAcceptedAggregate `cborgen:"aggregates" dagjsongen:"aggregates"` +} diff --git a/go.mod b/go.mod index d65d9bb..2dfaecd 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/alanshaw/dag-json-gen v0.0.5 github.com/fil-forge/automobile v0.0.1 github.com/fil-forge/ucantone v0.0.0-20260514184915-8bebe15b0096 + github.com/filecoin-project/go-data-segment v0.0.1 github.com/gobwas/glob v0.2.3 github.com/ipfs/go-cid v0.6.1 github.com/ipfs/go-log/v2 v2.9.1 @@ -31,6 +32,7 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect golang.org/x/crypto v0.50.0 // indirect + golang.org/x/exp v0.0.0-20230418202329-0354be287a23 // indirect golang.org/x/sys v0.43.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.4.1 // indirect diff --git a/go.sum b/go.sum index 6d728cc..f857771 100644 --- a/go.sum +++ b/go.sum @@ -6,6 +6,10 @@ github.com/fil-forge/automobile v0.0.1 h1:9xB3yc4l5b9EdRJSJcNwudgBFNHoMPEAdcb7Gf github.com/fil-forge/automobile v0.0.1/go.mod h1:TsO7jlO8ykJZY5tF8j4GsUcu3F02lEzxO7ULoB61hRA= github.com/fil-forge/ucantone v0.0.0-20260514184915-8bebe15b0096 h1:T/JkfzRNu4/9OnqgggVWbn+OXs/y12xDSVEen0NS7EY= github.com/fil-forge/ucantone v0.0.0-20260514184915-8bebe15b0096/go.mod h1:vqgVEsy6LEEsY24Zyjxem0vSofj1XTIx29GbV635f+I= +github.com/filecoin-project/go-data-segment v0.0.1 h1:1wmDxOG4ubWQm3ZC1XI5nCon5qgSq7Ra3Rb6Dbu10Gs= +github.com/filecoin-project/go-data-segment v0.0.1/go.mod h1:H0/NKbsRxmRFBcLibmABv+yFNHdmtl5AyplYLnb0Zv4= +github.com/filecoin-project/go-fil-commcid v0.1.0 h1:3R4ds1A9r6cr8mvZBfMYxTS88OqLYEo6roi+GiIeOh8= +github.com/filecoin-project/go-fil-commcid v0.1.0/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/ipfs/go-cid v0.6.1 h1:T5TnNb08+ueovG76Z5gx1L4Y7QOaGTXHg1F6raWFxIc= @@ -60,6 +64,8 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q= +golang.org/x/exp v0.0.0-20230418202329-0354be287a23 h1:4NKENAGIctmZYLK9W+X1kDK8ObBFqOSCJM6WE7CvkJY= +golang.org/x/exp v0.0.0-20230418202329-0354be287a23/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= diff --git a/merkletree/proofdata.go b/merkletree/proofdata.go new file mode 100644 index 0000000..c70c2cd --- /dev/null +++ b/merkletree/proofdata.go @@ -0,0 +1,175 @@ +// Package merkletree is a thin libforge wrapper around +// go-data-segment's merkletree.ProofData that adds DagJSON codec methods. +// +// The merkletree algorithm itself is not reimplemented here; conversions +// to/from the canonical go-data-segment type are zero-cost since the +// underlying struct layout is identical. +package merkletree + +import ( + "fmt" + "io" + + jsg "github.com/alanshaw/dag-json-gen" + dsmerkle "github.com/filecoin-project/go-data-segment/merkletree" +) + +// Node is re-exported from go-data-segment for ergonomic use alongside +// the wrapped ProofData. +type Node = dsmerkle.Node + +// NodeSize matches go-data-segment's NodeSize. +const NodeSize = dsmerkle.NodeSize + +// ProofData is a merkle inclusion proof, layout-identical to +// go-data-segment's merkletree.ProofData. Use a named-type conversion to +// move between the two: +// +// libforgePD := merkletree.ProofData(dsPD) +// dsPD := dsmerkle.ProofData(libforgePD) +type ProofData dsmerkle.ProofData + +// MarshalCBOR delegates to go-data-segment's CBOR codec via a zero-cost +// named-type conversion. +func (p *ProofData) MarshalCBOR(w io.Writer) error { + pd := dsmerkle.ProofData(*p) + return pd.MarshalCBOR(w) +} + +// UnmarshalCBOR delegates to go-data-segment's CBOR codec. +func (p *ProofData) UnmarshalCBOR(r io.Reader) error { + var pd dsmerkle.ProofData + if err := pd.UnmarshalCBOR(r); err != nil { + return err + } + *p = ProofData(pd) + return nil +} + +// MarshalDagJSON writes the proof as a DagJSON map: {"path": [...], "index": N}. +// Path nodes use DagJSON's canonical bytes encoding ({"/": {"bytes": ""}}). +func (p *ProofData) MarshalDagJSON(w io.Writer) error { + jw := jsg.NewDagJsonWriter(w) + + if err := jw.WriteObjectOpen(); err != nil { + return err + } + + if err := jw.WriteString("path"); err != nil { + return err + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if err := jw.WriteArrayOpen(); err != nil { + return err + } + for i, n := range p.Path { + if i > 0 { + if err := jw.WriteComma(); err != nil { + return err + } + } + if err := jw.WriteBytes(n[:]); err != nil { + return err + } + } + if err := jw.WriteArrayClose(); err != nil { + return err + } + + if err := jw.WriteComma(); err != nil { + return err + } + + if err := jw.WriteString("index"); err != nil { + return err + } + if err := jw.WriteObjectColon(); err != nil { + return err + } + if err := jw.WriteUint64(p.Index); err != nil { + return err + } + + return jw.WriteObjectClose() +} + +// UnmarshalDagJSON reads the proof from the DagJSON form produced by MarshalDagJSON. +func (p *ProofData) UnmarshalDagJSON(r io.Reader) error { + jr := jsg.NewDagJsonReader(r) + *p = ProofData{} + + if err := jr.ReadObjectOpen(); err != nil { + return err + } + empty, err := jr.PeekObjectClose() + if err != nil { + return err + } + if empty { + return jr.ReadObjectClose() + } + for { + key, err := jr.ReadString(8192) + if err != nil { + return err + } + if err := jr.ReadObjectColon(); err != nil { + return err + } + switch key { + case "path": + if err := jr.ReadArrayOpen(); err != nil { + return err + } + emptyArr, err := jr.PeekArrayClose() + if err != nil { + return err + } + if emptyArr { + if err := jr.ReadArrayClose(); err != nil { + return err + } + } else { + for { + b, err := jr.ReadBytes(NodeSize) + if err != nil { + return fmt.Errorf("reading path node %d: %w", len(p.Path), err) + } + if len(b) != NodeSize { + return fmt.Errorf("path node %d size %d, want %d", len(p.Path), len(b), NodeSize) + } + var n Node + copy(n[:], b) + p.Path = append(p.Path, n) + + done, err := jr.ReadArrayCloseOrComma() + if err != nil { + return err + } + if done { + break + } + } + } + case "index": + n, err := jr.ReadNumberAsUint64() + if err != nil { + return err + } + p.Index = n + default: + return fmt.Errorf("unexpected field %q", key) + } + + done, err := jr.ReadObjectCloseOrComma() + if err != nil { + return err + } + if done { + break + } + } + return nil +} diff --git a/merkletree/proofdata_test.go b/merkletree/proofdata_test.go new file mode 100644 index 0000000..121802e --- /dev/null +++ b/merkletree/proofdata_test.go @@ -0,0 +1,61 @@ +package merkletree_test + +import ( + "bytes" + "testing" + + "github.com/fil-forge/libforge/merkletree" + "github.com/stretchr/testify/require" +) + +func sampleProof() merkletree.ProofData { + pd := merkletree.ProofData{Index: 7} + for i := 0; i < 4; i++ { + var n merkletree.Node + for j := range n { + n[j] = byte(i*0x10 + j) + } + pd.Path = append(pd.Path, n) + } + return pd +} + +func TestProofData_CBORRoundtrip(t *testing.T) { + in := sampleProof() + var buf bytes.Buffer + require.NoError(t, in.MarshalCBOR(&buf)) + + var out merkletree.ProofData + require.NoError(t, out.UnmarshalCBOR(&buf)) + + require.Equal(t, in, out) +} + +func TestProofData_DagJSONRoundtrip(t *testing.T) { + in := sampleProof() + var buf bytes.Buffer + require.NoError(t, in.MarshalDagJSON(&buf)) + + var out merkletree.ProofData + require.NoError(t, out.UnmarshalDagJSON(&buf)) + + require.Equal(t, in, out) +} + +func TestProofData_EmptyPathRoundtrip(t *testing.T) { + in := merkletree.ProofData{Index: 0} + + var cb bytes.Buffer + require.NoError(t, in.MarshalCBOR(&cb)) + var outCBOR merkletree.ProofData + require.NoError(t, outCBOR.UnmarshalCBOR(&cb)) + require.Equal(t, in.Index, outCBOR.Index) + require.Empty(t, outCBOR.Path) + + var jb bytes.Buffer + require.NoError(t, in.MarshalDagJSON(&jb)) + var outJSON merkletree.ProofData + require.NoError(t, outJSON.UnmarshalDagJSON(&jb)) + require.Equal(t, in.Index, outJSON.Index) + require.Empty(t, outJSON.Path) +}