left-icon

The Kademlia Protocol Succinctly®
by Marc Clifton

Previous
Chapter

of
A
A
A

CHAPTER 11

Persisting the DHT

Persisting the DHT


The bucket lists and contacts in each bucket need to be persisted so the last known state of the DHT can be restored. This is baked into the Dht implementation, serializing the data in a JSON file. The persistence of key-values is handled separately, and is defined by the specific implementation needs. Note that the VirtualStorage class provided in the baseline code does not persist its data. Internally, various properties are decorated with the JsonIgnore attribute to prevent circular serialization, and some classes have parameter-less public constructors for deserialization.

Serializing

This is straightforward—the only trick is enabling the type name handling in Newtonsoft.Json so that properties with abstract and interface types also serialize their concrete type.

Code Listing 85: Save the DHT

/// <summary>

/// Returns a JSON string of the serialized DHT.

/// </summary>

public string Save()

{

  var settings = new JsonSerializerSettings();

  settings.TypeNameHandling = TypeNameHandling.Auto;

  string json = JsonConvert.SerializeObject(this, Formatting.Indented, settings);

  return json;

}

Deserializing

The deserializer is equally simple, however note the call to DeserializationFixups. This reduces the size of the JSON by not serializing certain properties that can be obtained from other properties. As a result, some minor fixups are necessary.

Code Listing 86: Load the DHT

public static Dht Load(string json)

{

  var settings = new JsonSerializerSettings();

  settings.TypeNameHandling = TypeNameHandling.Auto;

  Dht dht = JsonConvert.DeserializeObject<Dht>(json, settings);

  dht.DeserializationFixups();

  dht.SetupTimers();

  return dht;

}

protected void DeserializationFixups()

{

  ID = ourContact.ID;

  protocol = ourContact.Protocol;

  node = router.Node;

  node.OurContact = ourContact;

  node.BucketList.OurID = ID;

  node.BucketList.OurContact = ourContact;

  router.Dht = this;

  node.Dht = this;

}

DHT serialization unit test

The unit test is a simple test that a contact in a bucket gets persisted and restored correctly.

Code Listing 87: DhtSerializationTest

[TestMethod]

public void DhtSerializationTest()

{

  TcpSubnetProtocol p1 = new TcpSubnetProtocol(“http://127.0.0.1”, 2720, 1);

  TcpSubnetProtocol p2 = new TcpSubnetProtocol(“http://127.0.0.1”, 2720, 2);

  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, p1, new Router(), store1, store1, new VirtualStorage());

  ID contactID = ID.Mid;      // a closer contact.

  Contact otherContact = new Contact(p2, contactID);

  Node otherNode = new Node(otherContact, store2);

  // Add this other contact to our peer list.

  dht.Node.BucketList.AddContact(otherContact);

  string json = dht.Save();

  Dht newDht = Dht.Load(json);

  Assert.IsTrue(newDht.Node.BucketList.Buckets.Sum(b => b.Contacts.Count) == 1,
    "Expected our node to have 1 contact.");

  Assert.IsTrue(newDht.Node.BucketList.ContactExists(otherContact),
    "Expected our contact to have the other contact.");

  Assert.IsTrue(newDht.Router.Node == newDht.Node,
    "Router node not initialized.");

}

When you look at the JSON, you suddenly realize that shared objects, particularly contacts, are deserialized into separate instances. Because there are assumptions in the code regarding “same instance,” and also as a way of ensuring that we’re comparing contacts correctly (using their IDs), the Contact class implements IComparable and operator == and operator != overloads.

Scroll To Top
Disclaimer

DISCLAIMER: Web reader is currently in beta. Please report any issues through our support system. PDF and Kindle format files are also available for download.

Previous

Next



You are one step away from downloading ebooks from the Succinctly® series premier collection!
A confirmation has been sent to your email address. Please check and confirm your email subscription to complete the download.