Finished NodeLookupOperation functionality! Finally found the bug

This commit is contained in:
Joshua Kissoon 2014-02-22 19:37:04 +05:30
parent 9eca0614f2
commit 3344511603
10 changed files with 153 additions and 57 deletions

View File

@ -16,7 +16,7 @@ public class Configuration
* If no reply received from a node in this period (in milliseconds)
* consider the node unresponsive.
* */
public static long RESPONSE_TIMEOUT = 3000;
public static long RESPONSE_TIMEOUT = 1500;
/**
* Maximum number of milliseconds for performing an operation.
@ -36,7 +36,7 @@ public class Configuration
/**
* Bucket size.
* */
public static int K = 3;
public static int K = 5;
/**
* Size of replacement cache.

View File

@ -36,6 +36,8 @@ public class KadServer
private final Timer timer; // Schedule future tasks
private final HashMap<Integer, TimerTask> tasks; // Keep track of scheduled tasks
private final Node localNode;
/* Factories */
private final MessageFactory messageFactory;
@ -47,11 +49,13 @@ public class KadServer
this.timer = new Timer(true);
}
public KadServer(int udpPort, MessageFactory mFactory) throws SocketException
public KadServer(int udpPort, MessageFactory mFactory, Node localNode) throws SocketException
{
this.udpPort = udpPort;
this.socket = new DatagramSocket(udpPort);
this.localNode = localNode;
this.messageFactory = mFactory;
/* Start listening for incoming requests in a new thread */
@ -128,7 +132,7 @@ public class KadServer
if (data.length > DATAGRAM_BUFFER_SIZE)
{
throw new IOException("MEssage is too big");
throw new IOException("Message is too big");
}
/* Everything is good, now create the packet and send it */
@ -163,9 +167,7 @@ public class KadServer
Message msg = messageFactory.createMessage(messCode, din);
din.close();
System.out.println("Message Received: " + msg);
System.out.println("Receivers: " + receivers);
System.out.println(this.localNode.getNodeId() + " Message Received: " + msg);
/* Get a receiver for this message */
Receiver receiver;

View File

@ -49,7 +49,7 @@ public class Kademlia
this.name = name;
this.localNode = new Node(defaultId, InetAddress.getLocalHost(), udpPort);
this.messageFactory = new MessageFactory(localNode);
this.server = new KadServer(udpPort, this.messageFactory);
this.server = new KadServer(udpPort, this.messageFactory, this.localNode);
this.timer = new Timer(true);
/* Schedule Recurring RestoreOperation */

View File

@ -39,7 +39,7 @@ public class NodeLookupReceiver implements Receiver
Node origin = msg.getOrigin();
System.out.println(this.localNode.getNodeId() + ": Received incoming NodeLookupMessage, sending NodeReplyMessage to: " + origin.getNodeId());
System.out.println(this.localNode.getNodeId() + ": Received NodeLookupMessage, sending NodeReplyMessage to: " + origin.getNodeId());
/* Update the local space by inserting the origin node. */
this.localNode.getRoutingTable().insert(origin);

View File

@ -117,6 +117,28 @@ public class Node implements Streamable
return this.routingTable;
}
@Override
public boolean equals(Object o)
{
if (o instanceof Node)
{
return this.getNodeId().equals(((Node) o).getNodeId());
}
return false;
}
@Override
public int hashCode()
{
return this.getNodeId().hashCode();
}
@Override
public String toString()
{
return this.getNodeId().toString();
}
/**
* A DistanceComparator is used to compare Node objects based on their closeness
* */
@ -145,23 +167,36 @@ public class Node implements Streamable
{
Node n1 = (Node) o1;
Node n2 = (Node) o2;
int index1 = nodeId.xor(n1.getNodeId()).getFirstSetBitIndex();
int index2 = nodeId.xor(n2.getNodeId()).getFirstSetBitIndex();
/* If the first node is closer to the given node, return 1 */
if (index1 < index2)
{
return 1;
}
else if (index1 > index2)
{
return -1;
}
else
if(n1.getNodeId().equals(n2.getNodeId()))
{
return 0;
}
//System.out.println("\n **************** Compare Starting **************** ");
//System.out.println("Comparing to: " + this.nodeId);
int index1 = nodeId.xor(n1.getNodeId()).getFirstSetBitIndex();
//System.out.println("Node " + n1.getNodeId() + " distance: " + index1);
int index2 = nodeId.xor(n2.getNodeId()).getFirstSetBitIndex();
//System.out.println("Node " + n2.getNodeId() + " distance: " + index2);
/* If the first node is closer to the given node, return 1 */
int retval;
if (index1 < index2)
{
retval = 1;
}
else if (index1 > index2)
{
retval = -1;
}
else
{
retval = -1;
}
//System.out.println("Returned: " + retval);
//System.out.println("**************** Compare Ended ***************** \n");
return retval;
}
}
}

View File

@ -8,6 +8,7 @@ package kademlia.node;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Random;
import kademlia.message.Streamable;
@ -83,7 +84,9 @@ public class NodeId implements Streamable
@Override
public int hashCode()
{
return Arrays.hashCode(this.getBytes());
int hash = 7;
hash = 83 * hash + Arrays.hashCode(this.keyBytes);
return hash;
}
/**
@ -119,12 +122,17 @@ public class NodeId implements Streamable
{
byte[] result = new byte[ID_LENGTH / 8];
byte[] nidBytes = nid.getBytes();
for (int i = 0; i < ID_LENGTH / 8; i++)
{
result[i] = (byte) (this.keyBytes[i] ^ nidBytes[i]);
//System.out.println("XOR Result: " + result[i]);
}
return new NodeId(result);
NodeId resNid = new NodeId(result);
//System.out.println("Resulting Nid: " + resNid + " First set bit: " + resNid.getFirstSetBitIndex());
return resNid;
}
/**
@ -187,10 +195,12 @@ public class NodeId implements Streamable
@Override
public String toString()
{
StringBuilder sb = new StringBuilder("NodeId: ");
sb.append(new String(this.keyBytes));
// StringBuilder sb = new StringBuilder("NodeId: ");
BigInteger bi = new BigInteger(1, this.keyBytes);
return String.format("%0" + (this.keyBytes.length << 1) + "X", bi);
//sb.append(Hex.encodeBase64URLSafeString(this.keyBytes));
return sb.toString();
//return sb.toString();
}
}

View File

@ -125,11 +125,20 @@ public class NodeLookupOperation implements Operation, Receiver
for (Node o : list)
{
/* If this node is not in the list, add the node */
System.out.println("Trying to add node " + o.getNodeId() + " hash: " + o.hashCode());
System.out.println("Contains Key for this node: " + nodes.containsKey(o));
if (!nodes.containsKey(o))
{
System.out.println("Adding unasked node " + o.getNodeId());
nodes.put(o, UNASKED);
}
}
System.out.println(this.localNode.getNodeId() + " Nodes List: ");
for (Node o : this.nodes.keySet())
{
System.out.println(o.getNodeId() + " hash: " + o.hashCode());
}
}
/**
@ -153,6 +162,11 @@ public class NodeLookupOperation implements Operation, Receiver
/* Get unqueried nodes among the K closest seen that have not FAILED */
ArrayList<Node> unasked = this.closestNodesNotFailed(UNASKED);
System.out.println("Unasked nodes found: ");
for (Node nn : unasked)
{
System.out.println(nn.getNodeId());
}
if (unasked.isEmpty() && this.messagesTransiting.isEmpty())
{
@ -256,6 +270,7 @@ public class NodeLookupOperation implements Operation, Receiver
/* Add the origin node to our routing table */
Node origin = msg.getOrigin();
System.out.println(this.localNode.getNodeId() + " Lookup Operation Response From: " + origin.getNodeId());
this.localNode.getRoutingTable().insert(origin);
/* Set that we've completed ASKing the origin node */

View File

@ -7,7 +7,6 @@ package kademlia.routing;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import kademlia.node.Node;
import kademlia.node.NodeId;
@ -42,7 +41,9 @@ public class KadBucket implements Bucket
}
else
{
//System.out.println("Adding new node - " + n.getNodeId() + " to bucket depth: " + this.depth);
nodes.put(n.getNodeId(), n);
//System.out.println(this);
}
}
@ -92,7 +93,7 @@ public class KadBucket implements Bucket
@Override
public String toString()
{
StringBuilder sb = new StringBuilder("Printing bucket at depth: ");
StringBuilder sb = new StringBuilder("Bucket at depth: ");
sb.append(this.depth);
sb.append("\n Nodes: \n");
for (Node n : this.nodes.values())

View File

@ -12,7 +12,7 @@ import kademlia.node.NodeId;
public class RoutingTable
{
private final Node node; // The current node
private final Node localNode; // The current node
private final KadBucket[] buckets;
@ -20,9 +20,9 @@ public class RoutingTable
buckets = new KadBucket[NodeId.ID_LENGTH]; // 160 buckets; 1 for each level in the tree
}
public RoutingTable(Node node)
public RoutingTable(Node localNode)
{
this.node = node;
this.localNode = localNode;
/* Initialize all of the buckets to a specific depth */
for (int i = 0; i < NodeId.ID_LENGTH; i++)
@ -39,7 +39,11 @@ public class RoutingTable
public void insert(Node n)
{
/* Find the first set bit: how far this node is away from the contact node */
int bucketId = this.node.getNodeId().xor(n.getNodeId()).getFirstSetBitIndex();
NodeId id = this.localNode.getNodeId().xor(n.getNodeId());
//System.out.println(" First Bit Set: " + id.getFirstSetBitIndex());
int bucketId = id.getFirstSetBitIndex();
System.out.println(this.localNode.getNodeId() + " Adding Node " + n.getNodeId() + " to bucket at depth: " + bucketId);
/* Put this contact to the bucket that stores contacts prefixLength distance away */
this.buckets[bucketId].insert(n);
@ -53,7 +57,7 @@ public class RoutingTable
public void remove(Node n)
{
/* Find the first set bit: how far this node is away from the contact node */
int bucketId = this.node.getNodeId().xor(n.getNodeId()).getFirstSetBitIndex();
int bucketId = this.localNode.getNodeId().xor(n.getNodeId()).getFirstSetBitIndex();
/* If the bucket has the contact, remove it */
if (this.buckets[bucketId].containNode(n))
@ -75,7 +79,7 @@ public class RoutingTable
ArrayList<Node> closest = new ArrayList<>(num);
/* Get the bucket number to search for closest from */
int bucketNumber = this.node.getNodeId().xor(target).getFirstSetBitIndex();
int bucketNumber = this.localNode.getNodeId().xor(target).getFirstSetBitIndex();
/* Add the contacts from this bucket to the return contacts */
for (Node c : this.buckets[bucketNumber].getNodes())
@ -158,12 +162,14 @@ public class RoutingTable
StringBuilder sb = new StringBuilder("\nPrinting Routing Table Started ***************** \n");
for (KadBucket b : this.buckets)
{
// System.out.println("Bucket: " + b);
if (b.numNodes() > 0)
{
sb.append("# nodes in Bucket with depth ");
sb.append(b.getDepth());
sb.append(": ");
sb.append(b.numNodes());
sb.append("\n");
sb.append(b.toString());
sb.append("\n");
}

View File

@ -17,22 +17,49 @@ public class NodeConnectionTest
try
{
/* Setting up 2 Kad networks */
Kademlia kad1 = new Kademlia("Joshua", new NodeId("12345678947584567467"), 7574);
Kademlia kad2 = new Kademlia("Crystal", new NodeId("12345678999324567838"), 7572);
Kademlia kad1 = new Kademlia("JoshuaK", new NodeId("ASF45678947584567467"), 7574);
System.out.println("Created Node Kad 1: " + kad1.getNode().getNodeId());
Kademlia kad2 = new Kademlia("Crystal", new NodeId("ASERTKJDHGVHERJHGFLK"), 7572);
//NodeId diff12 = kad1.getNode().getNodeId().xor(kad2.getNode().getNodeId());
System.out.println("Created Node Kad 2: " + kad2.getNode().getNodeId());
// System.out.println(kad1.getNode().getNodeId() + " ^ " + kad2.getNode().getNodeId() + " = " + diff12);
// System.out.println("Kad 1 - Kad 2 distance: " + diff12.getFirstSetBitIndex());
/* Connecting 2 to 1 */
System.out.println("Connecting Kad 1 and Kad 2");
kad1.connect(kad2.getNode());
System.out.println("Kad 1: ");
System.out.println(kad1.getNode().getRoutingTable());
System.out.println("Kad 2: ");
System.out.println(kad2.getNode().getRoutingTable());
// System.out.println("Kad 1: ");
// System.out.println(kad1.getNode().getRoutingTable());
// System.out.println("Kad 2: ");
// System.out.println(kad2.getNode().getRoutingTable());
/* Creating a new node 3 and connecting it to 1, hoping it'll get onto 2 also */
Kademlia kad3 = new Kademlia("Jessica", new NodeId("88888736882323647625"), 7783);
kad3.connect(kad1.getNode());
System.out.println("Kad 3: ");
Kademlia kad3 = new Kademlia("Jessica", new NodeId("ASERTKJDOLKMNBVFR45G"), 7783);
System.out.println("\n\n\n\n\n\nCreated Node Kad 3: " + kad3.getNode().getNodeId());
System.out.println("Connecting Kad 3 and Kad 2");
kad3.connect(kad2.getNode());
// NodeId diff32 = kad3.getNode().getNodeId().xor(kad2.getNode().getNodeId());
// NodeId diff31 = kad1.getNode().getNodeId().xor(kad3.getNode().getNodeId());
// System.out.println("Kad 3 - Kad 1 distance: " + diff31.getFirstSetBitIndex());
// System.out.println("Kad 3 - Kad 2 distance: " + diff32.getFirstSetBitIndex());
Kademlia kad4 = new Kademlia("Sandy", new NodeId("ASERTK85OLKMN85FR4SS"), 7789);
System.out.println("\n\n\n\n\n\nCreated Node Kad 4: " + kad4.getNode().getNodeId());
System.out.println("Connecting Kad 4 and Kad 2");
kad4.connect(kad2.getNode());
System.out.println("\n\nKad 1: " + kad1.getNode().getNodeId() + " Routing Table: ");
System.out.println(kad1.getNode().getRoutingTable());
System.out.println("\n\nKad 2: " + kad2.getNode().getNodeId() + " Routing Table: ");
System.out.println(kad2.getNode().getRoutingTable());
System.out.println("\n\nKad 3: " + kad3.getNode().getNodeId() + " Routing Table: ");
System.out.println(kad3.getNode().getRoutingTable());
System.out.println("\n\nKad 4: " + kad4.getNode().getNodeId() + " Routing Table: ");
System.out.println(kad4.getNode().getRoutingTable());
}
catch (IOException e)
{