async def bootstrap_node(self, addr): """ Announce node including capabilities """ result = await self.protocol.ping(addr, self.node.id, self.serialize_capabilities()) return NuCypherNode(result[1], addr[0], addr[1]) if result[0] else None
def rpc_store(self, sender, nodeid, key, value): source = NuCypherNode(nodeid, sender[0], sender[1]) self.welcomeIfNewNode(source) self.log.debug("got a store request from %s" % str(sender)) # TODO: Why is this logic here? This is madness. See #172. if value.startswith(bytes(constants.BYTESTRING_IS_URSULA_IFACE_INFO)): header, signature, sender_pubkey_sig, message = dht_value_splitter( value, return_remainder=True) # TODO: TTL? hrac = keccak_digest(message) do_store = self.determine_legality_of_dht_key(signature, sender_pubkey_sig, message, hrac, key, value) elif value.startswith(bytes(constants.BYTESTRING_IS_TREASURE_MAP)): header, signature, sender_pubkey_sig, hrac, message = dht_with_hrac_splitter( value, return_remainder=True) # TODO: TTL? do_store = self.determine_legality_of_dht_key(signature, sender_pubkey_sig, message, hrac, key, value) else: self.log.info( "Got request to store bad k/v: {} / {}".format(key, value)) do_store = False if do_store: self.log.info("Storing k/v: {} / {}".format(key, value)) self.storage[key] = value if value.startswith(bytes(constants.BYTESTRING_IS_URSULA_IFACE_INFO)): self.ursulas[key] = value if value.startswith(bytes(constants.BYTESTRING_IS_TREASURE_MAP)): self.treasure_maps[key] = value return do_store
def __init__(self, ksize=20, alpha=3, id=None, storage=None, *args, **kwargs): super().__init__(ksize=20, alpha=3, id=None, storage=None, *args, **kwargs) self.node = NuCypherNode( id or digest(random.getrandbits(255)) ) # TODO: Assume that this can be attacked to get closer to desired kFrags.
def rpc_ping(self, sender, nodeid, node_capabilities=[]): source = NuCypherNode(nodeid, sender[0], sender[1], capabilities_as_strings=node_capabilities) self.welcomeIfNewNode(source) return self.sourceNode.id
def rpc_store(self, sender, nodeid, key, value): source = NuCypherNode(nodeid, sender[0], sender[1]) self.welcomeIfNewNode(source) self.log.debug("got a store request from %s" % str(sender)) if value.startswith(b"uaddr") or value.startswith(b"trmap"): signature, sender_pubkey_sig, hrac, message = dht_value_splitter( value[5::], return_remainder=True) # extra_info is a hash of the policy_group.id in the case of a treasure map, or a TTL in the case # of an Ursula interface. TODO: Decide whether to keep this notion and, if so, use the TTL. do_store = self.determine_legality_of_dht_key( signature, sender_pubkey_sig, message, hrac, key, value) else: self.log.info("Got request to store bad k/v: {} / {}".format( key, value)) do_store = False if do_store: self.log.info("Storing k/v: {} / {}".format(key, value)) self.storage[key] = value return do_store
def rpc_store(self, sender, nodeid, key, value): source = NuCypherNode(nodeid, sender[0], sender[1]) self.welcomeIfNewNode(source) self.log.debug("got a store request from %s" % str(sender)) if value.startswith(BYTESTRING_IS_URSULA_IFACE_INFO) or value.startswith( BYTESTRING_IS_TREASURE_MAP): header, signature, sender_pubkey_sig, hrac, message = dht_value_splitter( value, return_remainder=True) # TODO: TTL? do_store = self.determine_legality_of_dht_key(signature, sender_pubkey_sig, message, hrac, key, value) else: self.log.info( "Got request to store bad k/v: {} / {}".format(key, value)) do_store = False if do_store: self.log.info("Storing k/v: {} / {}".format(key, value)) self.storage[key] = value return do_store
class NuCypherDHTServer(Server): protocol_class = NuCypherHashProtocol capabilities = () digests_set = 0 def __init__(self, ksize=20, alpha=3, id=None, storage=None, *args, **kwargs): super().__init__(ksize=20, alpha=3, id=None, storage=None, *args, **kwargs) self.node = NuCypherNode( id or digest(random.getrandbits(255)) ) # TODO: Assume that this can be attacked to get closer to desired kFrags. def serialize_capabilities(self): return [ ServerCapability.stringify(capability) for capability in self.capabilities ] async def bootstrap_node(self, addr): """ Announce node including capabilities """ result = await self.protocol.ping(addr, self.node.id, self.serialize_capabilities()) return NuCypherNode(result[1], addr[0], addr[1]) if result[0] else None async def set_digest(self, dkey, value): """ Set the given SHA1 digest key (bytes) to the given value in the network. Returns True if a digest was in fact set. """ node = self.node_class(dkey) nearest = self.protocol.router.findNeighbors(node) if len(nearest) == 0: self.log.warning("There are no known neighbors to set key %s" % dkey.hex()) return False spider = NodeSpiderCrawl(self.protocol, node, nearest, self.ksize, self.alpha) nodes = await spider.find() self.log.info("setting '%s' on %s" % (dkey.hex(), list(map(str, nodes)))) # if this node is close too, then store here as well if self.node.distanceTo(node) < max( [n.distanceTo(node) for n in nodes]): self.storage[dkey] = value ds = [] for n in nodes: _disposition, value_was_set = await self.protocol.callStore( n, dkey, value) if value_was_set: self.digests_set += 1 ds.append(value_was_set) # return true only if at least one store call succeeded return any(ds) def get_now(self, key): loop = asyncio.get_event_loop() return loop.run_until_complete(self.get(bytes(key))) async def set(self, key, value): """ Set the given string key to the given value in the network. """ self.log.debug("setting '%s' = '%s' on network" % (key, value)) key = digest(bytes(key)) return await self.set_digest(key, value)