Skip to content

Commit

Permalink
feat(ipld): wrap bindnode with panic protection (#368)
Browse files Browse the repository at this point in the history
* feat(ipld): wrap bindnode with panic protection

* fix(src): fiximports
  • Loading branch information
rvagg committed Mar 29, 2022
1 parent ed48027 commit 3674b42
Show file tree
Hide file tree
Showing 16 changed files with 107 additions and 44 deletions.
2 changes: 1 addition & 1 deletion message/ipldbind/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
39 changes: 39 additions & 0 deletions message/ipldbind/util.go
Original file line number Diff line number Diff line change
@@ -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
}
5 changes: 4 additions & 1 deletion message/v1/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 10 additions & 6 deletions message/v1/metadata/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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())
}
3 changes: 2 additions & 1 deletion message/v1/metadata/metadata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
9 changes: 5 additions & 4 deletions message/v1/pb_roundtrip_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
18 changes: 10 additions & 8 deletions message/v2/ipld_roundtrip_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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)
Expand All @@ -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()
Expand Down
13 changes: 9 additions & 4 deletions message/v2/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion requestmanager/reconciledloader/injest.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 3 additions & 2 deletions requestmanager/reconciledloader/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion requestmanager/reconciledloader/pathtracker.go
Original file line number Diff line number Diff line change
@@ -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
Expand Down
7 changes: 4 additions & 3 deletions requestmanager/reconciledloader/reconciledloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
13 changes: 7 additions & 6 deletions requestmanager/reconciledloader/reconciledloader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
3 changes: 2 additions & 1 deletion requestmanager/reconciledloader/remotequeue.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down

0 comments on commit 3674b42

Please sign in to comment.