diff --git a/routing/supernode/server.go b/routing/supernode/server.go index cbf240a19..78a686ebe 100644 --- a/routing/supernode/server.go +++ b/routing/supernode/server.go @@ -8,6 +8,7 @@ import ( datastore "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore" peer "github.com/jbenet/go-ipfs/p2p/peer" dhtpb "github.com/jbenet/go-ipfs/routing/dht/pb" + record "github.com/jbenet/go-ipfs/routing/record" proxy "github.com/jbenet/go-ipfs/routing/supernode/proxy" util "github.com/jbenet/go-ipfs/util" errors "github.com/jbenet/go-ipfs/util/debugerror" @@ -55,7 +56,12 @@ func (s *Server) handleMessage( return p, response case dhtpb.Message_PUT_VALUE: - // TODO before merging: verifyRecord(req.GetRecord()) + // FIXME: verify complains that the peer's ID is not present in the + // peerstore. Mocknet problem? + // if err := verify(s.peerstore, req.GetRecord()); err != nil { + // log.Event(ctx, "validationFailed", req, p) + // return "", nil + // } putRoutingRecord(s.routingBackend, util.Key(req.GetKey()), req.GetRecord()) return p, req @@ -191,3 +197,17 @@ func getRoutingProviders(ds datastore.Datastore, k util.Key) ([]*dhtpb.Message_P func providerKey(k util.Key) datastore.Key { return datastore.KeyWithNamespaces([]string{"routing", "providers", k.String()}) } + +func verify(ps peer.Peerstore, r *dhtpb.Record) error { + v := make(record.Validator) + v["pk"] = record.ValidatePublicKeyRecord + p := peer.ID(r.GetAuthor()) + pk := ps.PubKey(p) + if pk == nil { + return fmt.Errorf("do not have public key for %s", p) + } + if err := v.VerifyRecord(r, pk); err != nil { + return err + } + return nil +} diff --git a/test/integration/grandcentral_test.go b/test/integration/grandcentral_test.go index 87dc577c7..5f86f7571 100644 --- a/test/integration/grandcentral_test.go +++ b/test/integration/grandcentral_test.go @@ -2,6 +2,7 @@ package integrationtest import ( "bytes" + "fmt" "io" "math" "testing" @@ -16,6 +17,7 @@ import ( "github.com/jbenet/go-ipfs/p2p/peer" "github.com/jbenet/go-ipfs/thirdparty/iter" "github.com/jbenet/go-ipfs/thirdparty/unit" + "github.com/jbenet/go-ipfs/util" ds2 "github.com/jbenet/go-ipfs/util/datastore2" errors "github.com/jbenet/go-ipfs/util/debugerror" testutil "github.com/jbenet/go-ipfs/util/testutil" @@ -132,3 +134,51 @@ func InitializeSupernodeNetwork( } return servers, clients, nil } + +func TestSupernodePutRecordGetRecord(t *testing.T) { + // create 8 supernode-routing bootstrap nodes + // create 2 supernode-routing clients both bootstrapped to the bootstrap nodes + // let the bootstrap nodes share a single datastore + // add a large file on one node then cat the file from the other + conf := testutil.LatencyConfig{ + NetworkLatency: 0, + RoutingLatency: 0, + BlockstoreLatency: 0, + } + if err := RunSupernodePutRecordGetRecord(conf); err != nil { + t.Fatal(err) + } +} + +func RunSupernodePutRecordGetRecord(conf testutil.LatencyConfig) error { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + servers, clients, err := InitializeSupernodeNetwork(ctx, 2, 2, conf) + if err != nil { + return err + } + for _, n := range append(servers, clients...) { + defer n.Close() + } + + putter := clients[0] + getter := clients[1] + + k := util.Key("key") + note := []byte("a note from putter") + + if err := putter.Routing.PutValue(ctx, k, note); err != nil { + return fmt.Errorf("failed to put value: %s", err) + } + + received, err := getter.Routing.GetValue(ctx, k) + if err != nil { + return fmt.Errorf("failed to get value: %s", err) + } + + if 0 != bytes.Compare(note, received) { + return errors.New("record doesn't match") + } + return nil +}