Exemple #1
0
        public void ParallelValueStoredGetsPropagatedTest()
        {
            VirtualProtocol vp1    = new VirtualProtocol();
            VirtualProtocol vp2    = new VirtualProtocol();
            VirtualStorage  store1 = new VirtualStorage();
            VirtualStorage  store2 = new VirtualStorage();

            // Ensures that all nodes are closer, because ID.Max ^ n < ID.Max when n > 0.
            Dht dht = new Dht(ID.Max, vp1, new ParallelRouter(), store1, store1, new VirtualStorage());

            vp1.Node = dht.Router.Node;

            ID      contactID    = ID.Mid; // a closer contact.
            Contact otherContact = new Contact(vp2, contactID);
            Node    otherNode    = new Node(otherContact, store2);

            vp2.Node = otherNode;

            // Add this other contact to our peer list.
            dht.Router.Node.BucketList.AddContact(otherContact);

            // We want an integer distance, not an XOR distance.
            ID     key = ID.Zero;
            string val = "Test";

            Assert.IsFalse(store1.Contains(key), "Obviously we don't have the key-value yet.");
            Assert.IsFalse(store2.Contains(key), "And equally obvious, the other peer doesn't have the key-value yet either.");

            dht.Store(key, val);

            Assert.IsTrue(store1.Contains(key), "Expected our peer to have stored the key-value.");
            Assert.IsTrue(store2.Contains(key), "Expected the other peer to have stored the key-value.");
        }
        public void NonRespondingContactDelayedEvictionTest()
        {
            // Create a DHT so we have an eviction handler.
            Dht dht = new Dht(ID.Zero, new VirtualProtocol(), () => null, new Router());
            //Contact dummyContact = new Contact(new VirtualProtocol(), ID.Zero);
            //((VirtualProtocol)dummyContact.Protocol).Node = new Node(dummyContact, new VirtualStorage());

            IBucketList bucketList = SetupSplitFailure(dht.Node.BucketList);

            Assert.IsTrue(bucketList.Buckets.Count == 2, "Bucket split should have occurred.");
            Assert.IsTrue(bucketList.Buckets[0].Contacts.Count == 1, "Expected 1 contact in bucket 0.");
            Assert.IsTrue(bucketList.Buckets[1].Contacts.Count == 20, "Expected 20 contacts in bucket 1.");

            // The bucket is now full.  Pick the first contact, as it is last seen (they are added in chronological order.)
            Contact nonRespondingContact = bucketList.Buckets[1].Contacts[0];

            // Since the protocols are shared, we need to assign a unique protocol for this node for testing.
            VirtualProtocol vpUnresponding = new VirtualProtocol(((VirtualProtocol)nonRespondingContact.Protocol).Node, false);

            nonRespondingContact.Protocol = vpUnresponding;

            // Setup the next new contact (it can respond.)
            Contact nextNewContact = new Contact(dht.Contact.Protocol, ID.Zero.SetBit(159));

            bucketList.AddContact(nextNewContact);

            Assert.IsTrue(bucketList.Buckets[1].Contacts.Count == 20, "Expected 20 contacts in bucket 1.");

            // Verify CanSplit -> Evict happened.

            Assert.IsTrue(dht.PendingContacts.Count == 1, "Expected one pending contact.");
            Assert.IsTrue(dht.PendingContacts.Contains(nextNewContact), "Expected pending contact to be the 21st contact.");
            Assert.IsTrue(dht.EvictionCount.Count == 1, "Expected one contact to be pending eviction.");
        }
Exemple #3
0
        public void ParallelBootstrapOutsideBootstrappingBucketTest()
        {
            // We need 32 virtual protocols.  One for the bootstrap peer,
            // 20 for the nodes the bootstrap peer knows about, 10 for the nodes
            // one of those nodes knows about, and one for us to rule them all.
            VirtualProtocol[] vp = new VirtualProtocol[32];
            32.ForEach((i) => vp[i] = new VirtualProtocol());

            // Us, ID doesn't matter.
            Dht dhtUs = new Dht(ID.RandomID, vp[0], () => new VirtualStorage(), new ParallelRouter());

            vp[0].Node = dhtUs.Router.Node;

            // Our bootstrap peer
            // All ID's are < 2^159
            Dht dhtBootstrap = new Dht(ID.Zero.RandomizeBeyond(Constants.ID_LENGTH_BITS - 1), vp[1], () => new VirtualStorage(), new ParallelRouter());

            vp[1].Node = dhtBootstrap.Router.Node;
            Node n = null;

            // Our boostrapper knows 20 contacts
            20.ForEach((i) =>
            {
                ID id;

                // All ID's are < 2^159 except the last one, which is >= 2^159
                // which will force a bucket split for _us_
                if (i < 19)
                {
                    id = ID.Zero.RandomizeBeyond(Constants.ID_LENGTH_BITS - 1);
                }
                else
                {
                    id = ID.Max;
                }

                Contact c      = new Contact(vp[i + 2], id);
                n              = new Node(c, new VirtualStorage());
                vp[i + 2].Node = n;
                dhtBootstrap.Router.Node.BucketList.AddContact(c);
            });

            // One of those nodes, in this case specifically the last one we added to our bootstrapper
            // so that it isn't in the bucket of our bootstrapper, we add 10 contacts.  The ID's of
            // those contacts don't matter.
            10.ForEach((i) =>
            {
                Contact c       = new Contact(vp[i + 22], ID.RandomID);
                Node n2         = new Node(c, new VirtualStorage());
                vp[i + 22].Node = n;
                n.BucketList.AddContact(c);     // Note we're adding these contacts to the 10th node.
            });

            dhtUs.Bootstrap(dhtBootstrap.Router.Node.OurContact);

            Assert.IsTrue(dhtUs.Router.Node.BucketList.Buckets.Sum(c => c.Contacts.Count) == 31, "Expected our peer to have 31 contacts.");
        }
Exemple #4
0
        public void ParallelGetValuePropagatesToCloserNodeTest()
        {
            VirtualProtocol vp1    = new VirtualProtocol();
            VirtualProtocol vp2    = new VirtualProtocol();
            VirtualProtocol vp3    = new VirtualProtocol();
            VirtualStorage  store1 = new VirtualStorage();
            VirtualStorage  store2 = new VirtualStorage();
            VirtualStorage  store3 = new VirtualStorage();
            VirtualStorage  cache3 = new VirtualStorage();

            // Ensures that all nodes are closer, because ID.Max ^ n < ID.Max when n > 0.
            Dht dht = new Dht(ID.Max, vp1, new ParallelRouter(), store1, store1, new VirtualStorage());

            vp1.Node = dht.Router.Node;

            // Setup node 2:

            ID      contactID2    = ID.Mid; // a closer contact.
            Contact otherContact2 = new Contact(vp2, contactID2);
            Node    otherNode2    = new Node(otherContact2, store2);

            vp2.Node = otherNode2;

            // Add the second contact to our peer list.
            dht.Router.Node.BucketList.AddContact(otherContact2);

            // Node 2 has the value.
            // We want an integer distance, not an XOR distance.
            ID     key = ID.Zero;
            string val = "Test";

            otherNode2.Storage.Set(key, val);

            // Setup node 3:

            ID      contactID3    = ID.Zero.SetBit(158); // 01000.... -- a farther contact.
            Contact otherContact3 = new Contact(vp3, contactID3);
            Node    otherNode3    = new Node(otherContact3, store3, cache3);

            vp3.Node = otherNode3;

            // Add the third contact to our peer list.
            dht.Router.Node.BucketList.AddContact(otherContact3);

            Assert.IsFalse(store1.Contains(key), "Obviously we don't have the key-value yet.");
            Assert.IsFalse(store3.Contains(key), "And equally obvious, the third peer doesn't have the key-value yet either.");

            var ret = dht.FindValue(key);

            Assert.IsTrue(ret.found, "Expected value to be found.");
            Assert.IsFalse(store3.Contains(key), "Key should not be in the republish store.");
            Assert.IsTrue(cache3.Contains(key), "Key should be in the cache store.");
            Assert.IsTrue(cache3.GetExpirationTimeSec(key.Value) == Constants.EXPIRATION_TIME_SECONDS / 2, "Expected 12 hour expiration.");
        }
Exemple #5
0
        public void ParallelLocalStoreFoundValueTest()
        {
            VirtualProtocol vp  = new VirtualProtocol();
            Dht             dht = new Dht(ID.RandomID, vp, () => new VirtualStorage(), new ParallelRouter());

            vp.Node = dht.Router.Node;
            ID     key = ID.RandomID;
            string val = "Test";

            dht.Store(key, val);
            string retval = dht.FindValue(key).val;

            Assert.IsTrue(retval == val, "Expected to get back what we stored");
        }
        public void TestNewContactGetsStoredContactsTest()
        {
            // Set up a node at the midpoint.
            // The existing node has the ID 10000....
            Node   existing = new Node(new Contact(null, ID.Mid), new VirtualStorage());
            string val1     = "Value 1";
            string valMid   = "Value Mid";

            // The existing node stores two items, one with an ID "hash" of 1, the other with ID.Max
            // Simple storage, rather than executing the code for Store.
            existing.SimpleStore(ID.One, val1);
            existing.SimpleStore(ID.Mid, valMid);

            Assert.IsTrue(existing.Storage.Keys.Count == 2, "Expected the existing node to have two key-values.");

            // Create a contact in the existing node's bucket list that is closer to one of the values.
            // This contact has the prefix 010000....
            Contact otherContact = new Contact(null, ID.Zero.SetBit(158));
            Node    other        = new Node(otherContact, new VirtualStorage());

            existing.BucketList.Buckets[0].Contacts.Add(otherContact);

            // The unseen contact has a prefix 0110000....
            VirtualProtocol unseenvp      = new VirtualProtocol();
            Contact         unseenContact = new Contact(unseenvp, ID.Zero.SetBit(157));
            Node            unseen        = new Node(unseenContact, new VirtualStorage());

            unseenvp.Node = unseen;     // final fixup.

            Assert.IsTrue(unseen.Storage.Keys.Count == 0, "The unseen node shouldn't have any key-values!");

            // An unseen node pings, and we should get back valMin only, as ID.One ^ ID.Mid < ID.Max ^ ID.Mid
            existing.Ping(unseenContact);

            // Contacts             V1          V2
            // 10000000             00...0001   10...0000
            // 01000000

            // Math:
            // c1 ^ V1      c1 ^ V2      c2 ^ V1     c2 ^ V2
            // 100...001    000...000    010...001   110...000

            // c1 ^ V1 > c1 ^ V2, so v1 doesn't get sent to the unseen node.
            // c1 ^ V2 < c2 ^ V2, so it does get sent.

            Assert.IsTrue(unseen.Storage.Keys.Count == 1, "Expected 1 value stored in our new node.");
            Assert.IsTrue(unseen.Storage.Contains(ID.Mid), "Expected valMid to be stored.");
            Assert.IsTrue(unseen.Storage.Get(ID.Mid) == valMid, "Expected valMid value to match.");
        }
Exemple #7
0
        public void ParallelBootstrapWithinBootstrappingBucketTest()
        {
            // We need 22 virtual protocols.  One for the bootstrap peer,
            // 10 for the nodes the bootstrap peer knows about, and 10 for the nodes
            // one of those nodes knows about, and one for us to rule them all.
            VirtualProtocol[] vp = new VirtualProtocol[22];
            22.ForEach((i) => vp[i] = new VirtualProtocol());

            // Us
            Dht dhtUs = new Dht(ID.RandomID, vp[0], () => new VirtualStorage(), new ParallelRouter());

            vp[0].Node = dhtUs.Router.Node;

            // Our bootstrap peer
            Dht dhtBootstrap = new Dht(ID.RandomID, vp[1], () => new VirtualStorage(), new ParallelRouter());

            vp[1].Node = dhtBootstrap.Router.Node;
            Node n = null;

            // Our boostrapper knows 10 contacts
            10.ForEach((i) =>
            {
                Contact c      = new Contact(vp[i + 2], ID.RandomID);
                n              = new Node(c, new VirtualStorage());
                vp[i + 2].Node = n;
                dhtBootstrap.Router.Node.BucketList.AddContact(c);
            });

            // One of those nodes, in this case the last one we added to our bootstrapper
            // for convenience, knows about 10 other contacts.
            10.ForEach((i) =>
            {
                Contact c       = new Contact(vp[i + 12], ID.RandomID);
                Node n2         = new Node(c, new VirtualStorage());
                vp[i + 12].Node = n;
                n.BucketList.AddContact(c);     // Note we're adding these contacts to the 10th node.
            });

            dhtUs.Bootstrap(dhtBootstrap.Router.Node.OurContact);

            Assert.IsTrue(dhtUs.Router.Node.BucketList.Buckets.Sum(c => c.Contacts.Count) == 11, "Expected our peer to get 11 contacts.");
        }
Exemple #8
0
        public void ParallelValueStoredInFartherNodeTest()
        {
            VirtualProtocol vp1    = new VirtualProtocol();
            VirtualProtocol vp2    = new VirtualProtocol();
            VirtualStorage  store1 = new VirtualStorage();
            VirtualStorage  store2 = new VirtualStorage();

            // Ensures that all nodes are closer, because ID.Max ^ n < ID.Max when n > 0.
            Dht dht = new Dht(ID.Zero, vp1, new ParallelRouter(), store1, store1, new VirtualStorage());

            vp1.Node = dht.Router.Node;

            ID      contactID    = ID.Max; // a farther contact.
            Contact otherContact = new Contact(vp2, contactID);
            Node    otherNode    = new Node(otherContact, store2);

            vp2.Node = otherNode;

            // Add this other contact to our peer list.
            dht.Router.Node.BucketList.AddContact(otherContact);

            // We want an integer distance, not an XOR distance.
            ID key = ID.One;

            // Set the value in the other node, to be discovered by the lookup process.
            string val = "Test";

            otherNode.SimpleStore(key, val);

            Assert.IsFalse(store1.Contains(key), "Expected our peer to NOT have cached the key-value.");
            Assert.IsTrue(store2.Contains(key), "Expected other node to HAVE cached the key-value.");

            // Try and find the value, given our Dht knows about the other contact.
            string retval = dht.FindValue(key).val;

            Assert.IsTrue(retval == val, "Expected to get back what we stored");
        }
        public void NonRespondingContactEvictedTest()
        {
            // Create a DHT so we have an eviction handler.
            Dht dht = new Dht(ID.Zero, new VirtualProtocol(), () => null, new Router());
            //Contact dummyContact = new Contact(new VirtualProtocol(), ID.Zero);
            //((VirtualProtocol)dummyContact.Protocol).Node = new Node(dummyContact, new VirtualStorage());

            IBucketList bucketList = SetupSplitFailure(dht.Node.BucketList);

            Assert.IsTrue(bucketList.Buckets.Count == 2, "Bucket split should have occurred.");
            Assert.IsTrue(bucketList.Buckets[0].Contacts.Count == 1, "Expected 1 contact in bucket 0.");
            Assert.IsTrue(bucketList.Buckets[1].Contacts.Count == 20, "Expected 20 contacts in bucket 1.");

            // The bucket is now full.  Pick the first contact, as it is last seen (they are added in chronological order.)
            Contact nonRespondingContact = bucketList.Buckets[1].Contacts[0];

            // Since the protocols are shared, we need to assign a unique protocol for this node for testing.
            VirtualProtocol vpUnresponding = new VirtualProtocol(((VirtualProtocol)nonRespondingContact.Protocol).Node, false);

            nonRespondingContact.Protocol = vpUnresponding;

            // Setup the next new contact (it can respond.)
            Contact nextNewContact = new Contact(dht.Contact.Protocol, ID.Zero.SetBit(159));

            // Hit the non-responding contact EVICTION_LIMIT times, which will trigger the eviction algorithm.
            Constants.EVICTION_LIMIT.ForEach(() => bucketList.AddContact(nextNewContact));

            Assert.IsTrue(bucketList.Buckets[1].Contacts.Count == 20, "Expected 20 contacts in bucket 1.");

            // Verify CanSplit -> Pending eviction happened.

            Assert.IsTrue(dht.PendingContacts.Count == 0, "Pending contact list should now be empty.");
            Assert.IsFalse(bucketList.Buckets.SelectMany(b => b.Contacts).Contains(nonRespondingContact), "Expected bucket to NOT contain non-responding contact.");
            Assert.IsTrue(bucketList.Buckets.SelectMany(b => b.Contacts).Contains(nextNewContact), "Expected bucket to contain new contact.");
            Assert.IsTrue(dht.EvictionCount.Count == 0, "Expected no contacts to be pending eviction.");
        }