diff --git a/message/ipldbind/message.go b/message/ipldbind/message.go index d167450f..f0e65f65 100644 --- a/message/ipldbind/message.go +++ b/message/ipldbind/message.go @@ -2,10 +2,10 @@ package ipldbind import ( cid "github.com/ipfs/go-cid" - "github.com/ipfs/go-graphsync/message" "github.com/ipld/go-ipld-prime/datamodel" "github.com/ipfs/go-graphsync" + "github.com/ipfs/go-graphsync/message" ) // GraphSyncExtensions is a container for representing extension data for diff --git a/message/ipldbind/util.go b/message/ipldbind/util.go new file mode 100644 index 00000000..26f7fb50 --- /dev/null +++ b/message/ipldbind/util.go @@ -0,0 +1,39 @@ +package ipldbind + +import ( + "fmt" + + "github.com/ipld/go-ipld-prime/datamodel" + "github.com/ipld/go-ipld-prime/node/bindnode" + "github.com/ipld/go-ipld-prime/schema" +) + +func SafeUnwrap(node datamodel.Node) (_ interface{}, err error) { + defer func() { + if r := recover(); r != nil { + if rerr, ok := r.(error); ok { + err = rerr + } else { + err = fmt.Errorf("%v", r) + } + } + }() + + ptr := bindnode.Unwrap(node) + return ptr, err +} + +func SafeWrap(ptr interface{}, typ schema.Type) (_ schema.TypedNode, err error) { + defer func() { + if r := recover(); r != nil { + if rerr, ok := r.(error); ok { + err = rerr + } else { + err = fmt.Errorf("%v", r) + } + } + }() + + node := bindnode.Wrap(ptr, typ) + return node, err +} diff --git a/message/v1/message.go b/message/v1/message.go index 0554c355..23d3ae89 100644 --- a/message/v1/message.go +++ b/message/v1/message.go @@ -275,7 +275,10 @@ func toEncodedExtensions(part message.MessagePartWithExtensions, linkMetadata gr linkMetadata.Iterate(func(c cid.Cid, la graphsync.LinkAction) { md = append(md, metadata.Item{Link: c, BlockPresent: la == graphsync.LinkActionPresent}) }) - mdNode := metadata.EncodeMetadata(md) + mdNode, err := metadata.EncodeMetadata(md) + if err != nil { + return nil, err + } mdByts, err := ipldutil.EncodeNode(mdNode) if err != nil { return nil, err diff --git a/message/v1/metadata/metadata.go b/message/v1/metadata/metadata.go index 2e0bf487..a0debefb 100644 --- a/message/v1/metadata/metadata.go +++ b/message/v1/metadata/metadata.go @@ -2,10 +2,11 @@ package metadata import ( "github.com/ipfs/go-cid" + "github.com/ipld/go-ipld-prime/datamodel" + "github.com/ipfs/go-graphsync" "github.com/ipfs/go-graphsync/message" - "github.com/ipld/go-ipld-prime/datamodel" - "github.com/ipld/go-ipld-prime/node/bindnode" + "github.com/ipfs/go-graphsync/message/ipldbind" ) // Item is a single link traversed in a repsonse @@ -44,11 +45,14 @@ func DecodeMetadata(data datamodel.Node) (Metadata, error) { if err != nil { return nil, err } - metadata := bindnode.Unwrap(builder.Build()).(*Metadata) - return *metadata, nil + metadata, err := ipldbind.SafeUnwrap(builder.Build()) + if err != nil { + return nil, err + } + return *(metadata.(*Metadata)), nil } // EncodeMetadata encodes metadata to an IPLD node then serializes to raw bytes -func EncodeMetadata(entries Metadata) datamodel.Node { - return bindnode.Wrap(&entries, Prototype.Metadata.Type()) +func EncodeMetadata(entries Metadata) (datamodel.Node, error) { + return ipldbind.SafeWrap(&entries, Prototype.Metadata.Type()) } diff --git a/message/v1/metadata/metadata_test.go b/message/v1/metadata/metadata_test.go index 6a7abb38..6691354d 100644 --- a/message/v1/metadata/metadata_test.go +++ b/message/v1/metadata/metadata_test.go @@ -27,7 +27,8 @@ func TestDecodeEncodeMetadata(t *testing.T) { }) // verify metadata matches - encoded := EncodeMetadata(initialMetadata) + encoded, err := EncodeMetadata(initialMetadata) + require.NoError(t, err, "encode errored") decodedMetadata, err := DecodeMetadata(encoded) require.NoError(t, err, "decode errored") diff --git a/message/v1/pb_roundtrip_test.go b/message/v1/pb_roundtrip_test.go index c38224e2..5b963af3 100644 --- a/message/v1/pb_roundtrip_test.go +++ b/message/v1/pb_roundtrip_test.go @@ -5,16 +5,17 @@ import ( blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" - "github.com/ipfs/go-graphsync" - "github.com/ipfs/go-graphsync/message" - pb "github.com/ipfs/go-graphsync/message/pb" - "github.com/ipfs/go-graphsync/testutil" "github.com/ipld/go-ipld-prime/datamodel" "github.com/ipld/go-ipld-prime/node/basicnode" selectorparse "github.com/ipld/go-ipld-prime/traversal/selector/parse" "github.com/libp2p/go-libp2p-core/peer" "github.com/stretchr/testify/require" "google.golang.org/protobuf/proto" + + "github.com/ipfs/go-graphsync" + "github.com/ipfs/go-graphsync/message" + pb "github.com/ipfs/go-graphsync/message/pb" + "github.com/ipfs/go-graphsync/testutil" ) func TestIPLDRoundTrip(t *testing.T) { diff --git a/message/v2/ipld_roundtrip_test.go b/message/v2/ipld_roundtrip_test.go index 9d1aaad7..168c3704 100644 --- a/message/v2/ipld_roundtrip_test.go +++ b/message/v2/ipld_roundtrip_test.go @@ -6,16 +6,16 @@ import ( blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" - "github.com/ipfs/go-graphsync" - "github.com/ipfs/go-graphsync/message" - "github.com/ipfs/go-graphsync/message/ipldbind" - "github.com/ipfs/go-graphsync/testutil" "github.com/ipld/go-ipld-prime/codec/dagcbor" "github.com/ipld/go-ipld-prime/datamodel" "github.com/ipld/go-ipld-prime/node/basicnode" - "github.com/ipld/go-ipld-prime/node/bindnode" selectorparse "github.com/ipld/go-ipld-prime/traversal/selector/parse" "github.com/stretchr/testify/require" + + "github.com/ipfs/go-graphsync" + "github.com/ipfs/go-graphsync/message" + "github.com/ipfs/go-graphsync/message/ipldbind" + "github.com/ipfs/go-graphsync/testutil" ) func TestIPLDRoundTrip(t *testing.T) { @@ -65,7 +65,8 @@ func TestIPLDRoundTrip(t *testing.T) { // ipld TypedNode format var buf bytes.Buffer - node := bindnode.Wrap(igsm, ipldbind.Prototype.Message.Type()) + node, err := ipldbind.SafeWrap(igsm, ipldbind.Prototype.Message.Type()) + require.NoError(t, err) // dag-cbor binary format err = dagcbor.Encode(node.Representation(), &buf) @@ -76,10 +77,11 @@ func TestIPLDRoundTrip(t *testing.T) { err = dagcbor.Decode(builder, &buf) require.NoError(t, err) rtnode := builder.Build() - rtigsm := bindnode.Unwrap(rtnode).(*ipldbind.GraphSyncMessageRoot) + rtigsm, err := ipldbind.SafeUnwrap(rtnode) + require.NoError(t, err) // back to message format - rtgsm, err := NewMessageHandler().fromIPLD(rtigsm) + rtgsm, err := NewMessageHandler().fromIPLD(rtigsm.(*ipldbind.GraphSyncMessageRoot)) require.NoError(t, err) rtreq := rtgsm.Requests() diff --git a/message/v2/message.go b/message/v2/message.go index 8b47efb3..1b26ab9d 100644 --- a/message/v2/message.go +++ b/message/v2/message.go @@ -10,7 +10,6 @@ import ( "github.com/ipfs/go-cid" "github.com/ipld/go-ipld-prime/codec/dagcbor" "github.com/ipld/go-ipld-prime/datamodel" - "github.com/ipld/go-ipld-prime/node/bindnode" "github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-msgio" @@ -49,8 +48,11 @@ func (mh *MessageHandler) FromMsgReader(_ peer.ID, r msgio.Reader) (message.Grap return message.GraphSyncMessage{}, err } node := builder.Build() - ipldGSM := bindnode.Unwrap(node).(*ipldbind.GraphSyncMessageRoot) - return mh.fromIPLD(ipldGSM) + ipldGSM, err := ipldbind.SafeUnwrap(node) + if err != nil { + return message.GraphSyncMessage{}, err + } + return mh.fromIPLD(ipldGSM.(*ipldbind.GraphSyncMessageRoot)) } // ToProto converts a GraphSyncMessage to its ipldbind.GraphSyncMessageRoot equivalent @@ -138,7 +140,10 @@ func (mh *MessageHandler) ToNet(_ peer.ID, gsm message.GraphSyncMessage, w io.Wr buf := new(bytes.Buffer) buf.Write(lbuf) - node := bindnode.Wrap(msg, ipldbind.Prototype.Message.Type()) + node, err := ipldbind.SafeWrap(msg, ipldbind.Prototype.Message.Type()) + if err != nil { + return err + } err = dagcbor.Encode(node.Representation(), buf) if err != nil { return err diff --git a/requestmanager/reconciledloader/injest.go b/requestmanager/reconciledloader/injest.go index 2150a0e7..d2533378 100644 --- a/requestmanager/reconciledloader/injest.go +++ b/requestmanager/reconciledloader/injest.go @@ -2,8 +2,9 @@ package reconciledloader import ( "github.com/ipfs/go-cid" - "github.com/ipfs/go-graphsync" "go.opentelemetry.io/otel/trace" + + "github.com/ipfs/go-graphsync" ) // IngestResponse ingests new remote items into the reconciled loader diff --git a/requestmanager/reconciledloader/load.go b/requestmanager/reconciledloader/load.go index 0f31f216..5215b857 100644 --- a/requestmanager/reconciledloader/load.go +++ b/requestmanager/reconciledloader/load.go @@ -4,14 +4,15 @@ import ( "context" "io/ioutil" - "github.com/ipfs/go-graphsync" - "github.com/ipfs/go-graphsync/requestmanager/types" "github.com/ipld/go-ipld-prime/datamodel" "github.com/ipld/go-ipld-prime/linking" cidlink "github.com/ipld/go-ipld-prime/linking/cid" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" + + "github.com/ipfs/go-graphsync" + "github.com/ipfs/go-graphsync/requestmanager/types" ) // BlockReadOpener synchronously loads the next block result diff --git a/requestmanager/reconciledloader/pathtracker.go b/requestmanager/reconciledloader/pathtracker.go index 07e88a21..0d2cd3d7 100644 --- a/requestmanager/reconciledloader/pathtracker.go +++ b/requestmanager/reconciledloader/pathtracker.go @@ -1,8 +1,9 @@ package reconciledloader import ( - "github.com/ipfs/go-graphsync" "github.com/ipld/go-ipld-prime/datamodel" + + "github.com/ipfs/go-graphsync" ) // pathTracker is just a simple utility to track whether we're on a missing diff --git a/requestmanager/reconciledloader/reconciledloader.go b/requestmanager/reconciledloader/reconciledloader.go index e74d3ee9..b41f0811 100644 --- a/requestmanager/reconciledloader/reconciledloader.go +++ b/requestmanager/reconciledloader/reconciledloader.go @@ -27,12 +27,13 @@ import ( "errors" "sync" - "github.com/ipfs/go-graphsync" - "github.com/ipfs/go-graphsync/requestmanager/reconciledloader/traversalrecord" - "github.com/ipfs/go-graphsync/requestmanager/types" logging "github.com/ipfs/go-log/v2" "github.com/ipld/go-ipld-prime/datamodel" "github.com/ipld/go-ipld-prime/linking" + + "github.com/ipfs/go-graphsync" + "github.com/ipfs/go-graphsync/requestmanager/reconciledloader/traversalrecord" + "github.com/ipfs/go-graphsync/requestmanager/types" ) var log = logging.Logger("gs-reconciledlaoder") diff --git a/requestmanager/reconciledloader/reconciledloader_test.go b/requestmanager/reconciledloader/reconciledloader_test.go index a2800666..a63d0db6 100644 --- a/requestmanager/reconciledloader/reconciledloader_test.go +++ b/requestmanager/reconciledloader/reconciledloader_test.go @@ -8,18 +8,19 @@ import ( blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" - "github.com/ipfs/go-graphsync" - "github.com/ipfs/go-graphsync/ipldutil" - "github.com/ipfs/go-graphsync/message" - "github.com/ipfs/go-graphsync/requestmanager/reconciledloader" - "github.com/ipfs/go-graphsync/requestmanager/types" - "github.com/ipfs/go-graphsync/testutil" "github.com/ipld/go-ipld-prime" "github.com/ipld/go-ipld-prime/datamodel" cidlink "github.com/ipld/go-ipld-prime/linking/cid" selectorparse "github.com/ipld/go-ipld-prime/traversal/selector/parse" "github.com/stretchr/testify/require" "go.opentelemetry.io/otel/trace" + + "github.com/ipfs/go-graphsync" + "github.com/ipfs/go-graphsync/ipldutil" + "github.com/ipfs/go-graphsync/message" + "github.com/ipfs/go-graphsync/requestmanager/reconciledloader" + "github.com/ipfs/go-graphsync/requestmanager/types" + "github.com/ipfs/go-graphsync/testutil" ) func TestReconciledLoader(t *testing.T) { diff --git a/requestmanager/reconciledloader/remotequeue.go b/requestmanager/reconciledloader/remotequeue.go index 8cf31f8b..18c59854 100644 --- a/requestmanager/reconciledloader/remotequeue.go +++ b/requestmanager/reconciledloader/remotequeue.go @@ -4,8 +4,9 @@ import ( "sync" "github.com/ipfs/go-cid" - "github.com/ipfs/go-graphsync" "go.opentelemetry.io/otel/trace" + + "github.com/ipfs/go-graphsync" ) var linkedRemoteItemPool = sync.Pool{ diff --git a/requestmanager/reconciledloader/traversalrecord/traversalrecord.go b/requestmanager/reconciledloader/traversalrecord/traversalrecord.go index 9caba96f..3035c501 100644 --- a/requestmanager/reconciledloader/traversalrecord/traversalrecord.go +++ b/requestmanager/reconciledloader/traversalrecord/traversalrecord.go @@ -4,9 +4,10 @@ import ( "errors" "github.com/ipfs/go-cid" - "github.com/ipfs/go-graphsync" "github.com/ipld/go-ipld-prime/datamodel" cidlink "github.com/ipld/go-ipld-prime/linking/cid" + + "github.com/ipfs/go-graphsync" ) // TraversalRecord records the links traversed by a selector and their paths in a space efficient manner diff --git a/requestmanager/reconciledloader/traversalrecord/traversalrecord_test.go b/requestmanager/reconciledloader/traversalrecord/traversalrecord_test.go index 28453c44..4b283fcd 100644 --- a/requestmanager/reconciledloader/traversalrecord/traversalrecord_test.go +++ b/requestmanager/reconciledloader/traversalrecord/traversalrecord_test.go @@ -7,16 +7,17 @@ import ( "testing" "github.com/ipfs/go-cid" - "github.com/ipfs/go-graphsync" - "github.com/ipfs/go-graphsync/ipldutil" - "github.com/ipfs/go-graphsync/requestmanager/reconciledloader/traversalrecord" - "github.com/ipfs/go-graphsync/testutil" "github.com/ipld/go-ipld-prime" "github.com/ipld/go-ipld-prime/datamodel" cidlink "github.com/ipld/go-ipld-prime/linking/cid" "github.com/ipld/go-ipld-prime/traversal" selectorparse "github.com/ipld/go-ipld-prime/traversal/selector/parse" "github.com/stretchr/testify/require" + + "github.com/ipfs/go-graphsync" + "github.com/ipfs/go-graphsync/ipldutil" + "github.com/ipfs/go-graphsync/requestmanager/reconciledloader/traversalrecord" + "github.com/ipfs/go-graphsync/testutil" ) func TestTraversalRecord(t *testing.T) {