diff --git a/exchange/bitswap/message/message.go b/exchange/bitswap/message/message.go
index 32109b8f00ac0b057cc189f973bd6997e2afdcae..22258e17fe9c1a9f40d516b233488b96d1ef40a0 100644
--- a/exchange/bitswap/message/message.go
+++ b/exchange/bitswap/message/message.go
@@ -1,11 +1,9 @@
 package message
 
 import (
-	"errors"
-
-	netmsg "github.com/jbenet/go-ipfs/net/message"
-
+	proto "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
 	blocks "github.com/jbenet/go-ipfs/blocks"
+	netmsg "github.com/jbenet/go-ipfs/net/message"
 	nm "github.com/jbenet/go-ipfs/net/message"
 	peer "github.com/jbenet/go-ipfs/peer"
 	u "github.com/jbenet/go-ipfs/util"
@@ -68,7 +66,15 @@ func (m *message) AppendBlock(b blocks.Block) {
 }
 
 func FromNet(nmsg netmsg.NetMessage) (BitSwapMessage, error) {
-	return nil, errors.New("TODO implement")
+	pb := new(PBMessage)
+	if err := proto.Unmarshal(nmsg.Data(), pb); err != nil {
+		return nil, err
+	}
+	m, err := newMessageFromProto(*pb)
+	if err != nil {
+		return nil, err
+	}
+	return m, nil
 }
 
 func (m *message) ToProto() *PBMessage {
diff --git a/exchange/bitswap/message/message_test.go b/exchange/bitswap/message/message_test.go
index e4b9e123f6f71177edd91fd6e32ca6cd606e93e3..9590f1ff1a3115bbf059ba6e3f7db7d053bb500c 100644
--- a/exchange/bitswap/message/message_test.go
+++ b/exchange/bitswap/message/message_test.go
@@ -4,6 +4,7 @@ import (
 	"bytes"
 	"testing"
 
+	peer "github.com/jbenet/go-ipfs/peer"
 	u "github.com/jbenet/go-ipfs/util"
 	testutil "github.com/jbenet/go-ipfs/util/testutil"
 )
@@ -88,6 +89,79 @@ func TestCopyProtoByValue(t *testing.T) {
 	}
 }
 
+func TestToNetMethodSetsPeer(t *testing.T) {
+	m := New()
+	p := &peer.Peer{ID: []byte("X")}
+	netmsg, err := m.ToNet(p)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !(netmsg.Peer().Key() == p.Key()) {
+		t.Fatal("Peer key is different")
+	}
+}
+
+func TestToNetFromNetPreservesWantList(t *testing.T) {
+	original := New()
+	original.AppendWanted(u.Key("M"))
+	original.AppendWanted(u.Key("B"))
+	original.AppendWanted(u.Key("D"))
+	original.AppendWanted(u.Key("T"))
+	original.AppendWanted(u.Key("F"))
+
+	netmsg, err := original.ToNet(&peer.Peer{ID: []byte("X")})
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	copied, err := FromNet(netmsg)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	keys := make(map[u.Key]bool)
+	for _, k := range copied.Wantlist() {
+		keys[k] = true
+	}
+
+	for _, k := range original.Wantlist() {
+		if _, ok := keys[k]; !ok {
+			t.Fatalf("Key Missing: \"%v\"", k)
+		}
+	}
+}
+
+func TestToAndFromNetMessage(t *testing.T) {
+
+	original := New()
+	original.AppendBlock(testutil.NewBlockOrFail(t, "W"))
+	original.AppendBlock(testutil.NewBlockOrFail(t, "E"))
+	original.AppendBlock(testutil.NewBlockOrFail(t, "F"))
+	original.AppendBlock(testutil.NewBlockOrFail(t, "M"))
+
+	p := &peer.Peer{ID: []byte("X")}
+	netmsg, err := original.ToNet(p)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	m2, err := FromNet(netmsg)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	keys := make(map[u.Key]bool)
+	for _, b := range m2.Blocks() {
+		keys[b.Key()] = true
+	}
+
+	for _, b := range original.Blocks() {
+		if _, ok := keys[b.Key()]; !ok {
+			t.Fail()
+		}
+	}
+}
+
 func contains(s []string, x string) bool {
 	for _, a := range s {
 		if a == x {