func TestClientFindProviders(t *testing.T) { pi := testutil.RandIdentityOrFatal(t) rs := NewServer() client := rs.Client(pi) k := cid.NewCidV0(u.Hash([]byte("hello"))) err := client.Provide(context.Background(), k) if err != nil { t.Fatal(err) } // This is bad... but simulating networks is hard time.Sleep(time.Millisecond * 300) max := 100 providersFromClient := client.FindProvidersAsync(context.Background(), k, max) isInClient := false for pi := range providersFromClient { if pi.ID == pi.ID { isInClient = true } } if !isInClient { t.Fatal("Despite client providing key, client didn't receive peer when finding providers") } }
func TestClientOverMax(t *testing.T) { rs := NewServer() k := cid.NewCidV0(u.Hash([]byte("hello"))) numProvidersForHelloKey := 100 for i := 0; i < numProvidersForHelloKey; i++ { pi := testutil.RandIdentityOrFatal(t) err := rs.Client(pi).Provide(context.Background(), k) if err != nil { t.Fatal(err) } } max := 10 pi := testutil.RandIdentityOrFatal(t) client := rs.Client(pi) providersFromClient := client.FindProvidersAsync(context.Background(), k, max) i := 0 for _ = range providersFromClient { i++ } if i != max { t.Fatal("Too many providers returned") } }
func TestValidAfter(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() pi := testutil.RandIdentityOrFatal(t) key := cid.NewCidV0(u.Hash([]byte("mock key"))) conf := DelayConfig{ ValueVisibility: delay.Fixed(1 * time.Hour), Query: delay.Fixed(0), } rs := NewServerWithDelay(conf) rs.Client(pi).Provide(ctx, key) var providers []pstore.PeerInfo providers, err := rs.Client(pi).FindProviders(ctx, key) if err != nil { t.Fatal(err) } if len(providers) > 0 { t.Fail() } conf.ValueVisibility.Set(0) providers, err = rs.Client(pi).FindProviders(ctx, key) if err != nil { t.Fatal(err) } t.Log("providers", providers) if len(providers) != 1 { t.Fail() } }
func TestBlockReturnsErr(t *testing.T) { off := Exchange(bstore()) c := cid.NewCidV0(u.Hash([]byte("foo"))) _, err := off.GetBlock(context.Background(), c) if err != nil { return // as desired } t.Fail() }
// TODO does dht ensure won't receive self as a provider? probably not. func TestCanceledContext(t *testing.T) { rs := NewServer() k := cid.NewCidV0(u.Hash([]byte("hello"))) // avoid leaking goroutine, without using the context to signal // (we want the goroutine to keep trying to publish on a // cancelled context until we've tested it doesnt do anything.) done := make(chan struct{}) defer func() { done <- struct{}{} }() t.Log("async'ly announce infinite stream of providers for key") i := 0 go func() { // infinite stream for { select { case <-done: t.Log("exiting async worker") return default: } pi, err := testutil.RandIdentity() if err != nil { t.Error(err) } err = rs.Client(pi).Provide(context.Background(), k) if err != nil { t.Error(err) } i++ } }() local := testutil.RandIdentityOrFatal(t) client := rs.Client(local) t.Log("warning: max is finite so this test is non-deterministic") t.Log("context cancellation could simply take lower priority") t.Log("and result in receiving the max number of results") max := 1000 t.Log("cancel the context before consuming") ctx, cancelFunc := context.WithCancel(context.Background()) cancelFunc() providers := client.FindProvidersAsync(ctx, k, max) numProvidersReturned := 0 for _ = range providers { numProvidersReturned++ } t.Log(numProvidersReturned) if numProvidersReturned == max { t.Fatal("Context cancel had no effect") } }
func TestKeyNotFound(t *testing.T) { var pi = testutil.RandIdentityOrFatal(t) var key = cid.NewCidV0(u.Hash([]byte("mock key"))) var ctx = context.Background() rs := NewServer() providers := rs.Client(pi).FindProvidersAsync(ctx, key, 10) _, ok := <-providers if ok { t.Fatal("should be closed") } }
// FWIW: At the time of this commit, including a timestamp in task increases // time cost of Push by 3%. func BenchmarkTaskQueuePush(b *testing.B) { q := newPRQ() peers := []peer.ID{ testutil.RandPeerIDFatal(b), testutil.RandPeerIDFatal(b), testutil.RandPeerIDFatal(b), } b.ResetTimer() for i := 0; i < b.N; i++ { c := cid.NewCidV0(u.Hash([]byte(fmt.Sprint(i)))) q.Push(&wantlist.Entry{Cid: c, Priority: math.MaxInt32}, peers[i%len(peers)]) } }
// EncodeProtobuf returns the encoded raw data version of a Node instance. // It may use a cached encoded version, unless the force flag is given. func (n *ProtoNode) EncodeProtobuf(force bool) ([]byte, error) { sort.Stable(LinkSlice(n.links)) // keep links sorted if n.encoded == nil || force { n.cached = nil var err error n.encoded, err = n.Marshal() if err != nil { return nil, err } } if n.cached == nil { n.cached = cid.NewCidV0(u.Hash(n.encoded)) } return n.encoded, nil }
func TestManualHash(t *testing.T) { oldDebugState := u.Debug defer (func() { u.Debug = oldDebugState })() data := []byte("I can't figure out more names .. data") hash, err := mh.Sum(data, mh.SHA2_256, -1) if err != nil { t.Fatal(err) } c := cid.NewCidV0(hash) u.Debug = false block, err := NewBlockWithCid(data, c) if err != nil { t.Fatal(err) } if !bytes.Equal(block.Multihash(), hash) { t.Error("wrong multihash") } data[5] = byte((uint32(data[5]) + 5) % 256) // Transfrom hash to be different block, err = NewBlockWithCid(data, c) if err != nil { t.Fatal(err) } if !bytes.Equal(block.Multihash(), hash) { t.Error("wrong multihash") } u.Debug = true block, err = NewBlockWithCid(data, c) if err != ErrWrongHash { t.Fatal(err) } }
func TestBlocks(t *testing.T) { bstore := blockstore.NewBlockstore(dssync.MutexWrap(ds.NewMapDatastore())) bs := New(bstore, offline.Exchange(bstore)) defer bs.Close() o := newObject([]byte("beep boop")) h := cid.NewCidV0(u.Hash([]byte("beep boop"))) if !o.Cid().Equals(h) { t.Error("Block key and data multihash key not equal") } k, err := bs.AddBlock(o) if err != nil { t.Error("failed to add block to BlockService", err) return } if !k.Equals(o.Cid()) { t.Error("returned key is not equal to block key", err) } ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) defer cancel() b2, err := bs.GetBlock(ctx, o.Cid()) if err != nil { t.Error("failed to retrieve block from BlockService", err) return } if !o.Cid().Equals(b2.Cid()) { t.Error("Block keys not equal.") } if !bytes.Equal(o.RawData(), b2.RawData()) { t.Error("Block data is not equal.") } }
func (n *ProtoNode) Cid() *cid.Cid { h := n.Multihash() return cid.NewCidV0(h) }
// NewBlock creates a Block object from opaque data. It will hash the data. func NewBlock(data []byte) *BasicBlock { // TODO: fix assumptions return &BasicBlock{data: data, cid: cid.NewCidV0(u.Hash(data))} }
// resolveOnce implements resolver. Uses the IPFS routing system to // resolve SFS-like names. func (r *routingResolver) resolveOnce(ctx context.Context, name string) (path.Path, error) { log.Debugf("RoutingResolve: '%s'", name) cached, ok := r.cacheGet(name) if ok { return cached, nil } name = strings.TrimPrefix(name, "/ipns/") hash, err := mh.FromB58String(name) if err != nil { // name should be a multihash. if it isn't, error out here. log.Warningf("RoutingResolve: bad input hash: [%s]\n", name) return "", err } // use the routing system to get the name. // /ipns/<name> h := []byte("/ipns/" + string(hash)) var entry *pb.IpnsEntry var pubkey ci.PubKey resp := make(chan error, 2) go func() { ipnsKey := string(h) val, err := r.routing.GetValue(ctx, ipnsKey) if err != nil { log.Warning("RoutingResolve get failed.") resp <- err return } entry = new(pb.IpnsEntry) err = proto.Unmarshal(val, entry) if err != nil { resp <- err return } resp <- nil }() go func() { // name should be a public key retrievable from ipfs pubk, err := routing.GetPublicKey(r.routing, ctx, hash) if err != nil { resp <- err return } pubkey = pubk resp <- nil }() for i := 0; i < 2; i++ { err = <-resp if err != nil { return "", err } } hsh, _ := pubkey.Hash() log.Debugf("pk hash = %s", key.Key(hsh)) // check sig with pk if ok, err := pubkey.Verify(ipnsEntryDataForSig(entry), entry.GetSignature()); err != nil || !ok { return "", fmt.Errorf("Invalid value. Not signed by PrivateKey corresponding to %v", pubkey) } // ok sig checks out. this is a valid name. // check for old style record: valh, err := mh.Cast(entry.GetValue()) if err != nil { // Not a multihash, probably a new record p, err := path.ParsePath(string(entry.GetValue())) if err != nil { return "", err } r.cacheSet(name, p, entry) return p, nil } else { // Its an old style multihash record log.Warning("Detected old style multihash record") p := path.FromCid(cid.NewCidV0(valh)) r.cacheSet(name, p, entry) return p, nil } }
func TestBitswapWithoutRouting(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() const numPeers = 4 // create network mn := mocknet.New(ctx) var nodes []*core.IpfsNode for i := 0; i < numPeers; i++ { n, err := core.NewNode(ctx, &core.BuildCfg{ Online: true, Host: coremock.MockHostOption(mn), Routing: core.NilRouterOption, // no routing }) if err != nil { t.Fatal(err) } defer n.Close() nodes = append(nodes, n) } mn.LinkAll() // connect them for _, n1 := range nodes { for _, n2 := range nodes { if n1 == n2 { continue } log.Debug("connecting to other hosts") p2 := n2.PeerHost.Peerstore().PeerInfo(n2.PeerHost.ID()) if err := n1.PeerHost.Connect(ctx, p2); err != nil { t.Fatal(err) } } } // add blocks to each before log.Debug("adding block.") block0 := blocks.NewBlock([]byte("block0")) block1 := blocks.NewBlock([]byte("block1")) // put 1 before if err := nodes[0].Blockstore.Put(block0); err != nil { t.Fatal(err) } // get it out. for i, n := range nodes { // skip first because block not in its exchange. will hang. if i == 0 { continue } log.Debugf("%d %s get block.", i, n.Identity) b, err := n.Blocks.GetBlock(ctx, cid.NewCidV0(block0.Multihash())) if err != nil { t.Error(err) } else if !bytes.Equal(b.RawData(), block0.RawData()) { t.Error("byte comparison fail") } else { log.Debug("got block: %s", b.Cid()) } } // put 1 after if err := nodes[1].Blockstore.Put(block1); err != nil { t.Fatal(err) } // get it out. for _, n := range nodes { b, err := n.Blocks.GetBlock(ctx, cid.NewCidV0(block1.Multihash())) if err != nil { t.Error(err) } else if !bytes.Equal(b.RawData(), block1.RawData()) { t.Error("byte comparison fail") } else { log.Debug("got block: %s", b.Cid()) } } }