1 ## Copyright 2002-2004 Andrew Loewenstern, All Rights Reserved
2 # see LICENSE.txt for license information
4 """Represents a khashmir node in the DHT."""
6 from twisted.python import log
8 from node import Node, NULL_ID
10 class KNodeError(Exception):
11 """An error occurred in contacting the node."""
13 class KNodeBase(Node):
14 """A basic node that can only be pinged and help find other nodes."""
16 def checkSender(self, dict):
17 """Check the sender's info to make sure it meets expectations."""
21 log.msg("No peer id in response")
22 raise KNodeError, "No peer id in response."
24 if self.id != NULL_ID and senderid != self.id:
25 log.msg("Got response from different node than expected.")
26 self.table.invalidateNode(self)
27 raise KNodeError, "Node ID has changed"
33 df = self.conn.sendRequest('ping', {"id":id})
34 df.addCallback(self.checkSender)
38 """Use the node to bootstrap into the system."""
39 df = self.conn.sendRequest('join', {"id":id})
40 df.addCallback(self.checkSender)
43 def find_node(self, id, target):
44 """Request the nearest nodes to the target that the node knows about."""
45 df = self.conn.sendRequest('find_node', {"target" : target, "id": id})
46 df.addCallback(self.checkSender)
49 class KNodeRead(KNodeBase):
50 """More advanced node that can also find and send values."""
52 def find_value(self, id, key):
53 """Request the nearest nodes to the key that the node knows about."""
54 df = self.conn.sendRequest('find_value', {"key" : key, "id" : id})
55 df.addCallback(self.checkSender)
58 def get_value(self, id, key, num):
59 """Request the values that the node has for the key."""
60 df = self.conn.sendRequest('get_value', {"key" : key, "num": num, "id" : id})
61 df.addCallback(self.checkSender)
64 class KNodeWrite(KNodeRead):
65 """Most advanced node that can also store values."""
67 def store_value(self, id, key, value, token):
68 """Store a value in the node."""
69 df = self.conn.sendRequest('store_value', {"key" : key, "value" : value, "token" : token, "id": id})
70 df.addCallback(self.checkSender)