diff --git a/ipv8/REST/dht_endpoint.py b/ipv8/REST/dht_endpoint.py index 9d34d2151..662de07ff 100644 --- a/ipv8/REST/dht_endpoint.py +++ b/ipv8/REST/dht_endpoint.py @@ -6,13 +6,14 @@ import json import struct -from twisted.internet.defer import inlineCallbacks, returnValue +from twisted.internet.defer import inlineCallbacks from twisted.web import http, resource from twisted.web.server import NOT_DONE_YET from ..dht.community import DHTCommunity, MAX_ENTRY_SIZE from ..attestation.trustchain.community import TrustChainCommunity from ..dht.discovery import DHTDiscoveryCommunity +from ..attestation.trustchain.listener import BlockListener class DHTEndpoint(resource.Resource): @@ -32,12 +33,25 @@ def __init__(self, session): self.putChild(b"block", DHTBlockEndpoint(dht_overlays[0], tc_overlays[0])) -class DHTBlockEndpoint(resource.Resource): +class DHTBlockEndpoint(resource.Resource, BlockListener): """ This endpoint is responsible for returning the latest Trustchain block of a peer. Additionally, it ensures this peer's latest TC block is available """ + def received_block(self, block): + """ + Wrapper callback method, inherited from the BlockListener abstract class, which will publish the latest + TrustChain block to the DHT + + :param block: the latest block added to the Database. This is not actually used by the inner method + :return: None + """ + self.publish_latest_block() + + def should_sign(self, block): + pass + KEY_SUFFIX = b'_BLOCK' def __init__(self, dht, trustchain): @@ -48,7 +62,7 @@ def __init__(self, dht, trustchain): self._hashed_dht_key = sha1(self.trustchain.my_peer.mid + self.KEY_SUFFIX).digest() - trustchain.set_new_block_cb(self.publish_latest_block) + trustchain.add_listener(self, [trustchain.UNIVERSAL_BLOCK_LISTENER]) @inlineCallbacks def publish_latest_block(self): @@ -57,7 +71,6 @@ def publish_latest_block(self): :return: """ - # latest_block = self.trustchain.persistence.get_latest(self.trustchain.my_peer.key.pub().key_to_bin()) latest_block = self.trustchain.persistence.get_latest(self.trustchain.my_peer.public_key.key_to_bin()) if latest_block: diff --git a/ipv8/attestation/trustchain/community.py b/ipv8/attestation/trustchain/community.py index 157e92bb1..8b1aac30b 100644 --- a/ipv8/attestation/trustchain/community.py +++ b/ipv8/attestation/trustchain/community.py @@ -53,6 +53,7 @@ class TrustChainCommunity(Community): "66f0373ca425015cc9fad75b267de0cfb46ed798796058b23e12fc4c42ce9868f1eb7d59cc2023c039" "14175ebb9703")) + UNIVERSAL_BLOCK_LISTENER = 'UNIVERSAL_BLOCK_LISTENER' DB_CLASS = TrustChainDB DB_NAME = 'trustchain' version = b'\x02' @@ -73,8 +74,6 @@ def __init__(self, *args, **kwargs): self.db_cleanup_lc = self.register_task("db_cleanup", LoopingCall(self.do_db_cleanup)) self.db_cleanup_lc.start(600) - self.new_block_cb = lambda: None - self.decode_map.update({ chr(1): self.received_half_block, chr(2): self.received_crawl_request, @@ -85,13 +84,6 @@ def __init__(self, *args, **kwargs): chr(7): self.received_empty_crawl_response, }) - def set_new_block_cb(self, f): - """ - Set the callback for when a new block is added to the DB. The callback should take no arguments and should - return nothing: [] -> None - """ - self.new_block_cb = f - def do_db_cleanup(self): """ Cleanup the database if necessary. @@ -260,7 +252,6 @@ def sign_block(self, peer, public_key=EMPTY_PK, block_type=b'unknown', transacti if not self.persistence.contains(block): self.persistence.add_block(block) - self.new_block_cb() self.notify_listeners(block) # This is a source block with no counterparty @@ -352,7 +343,6 @@ def validate_persist_block(self, block): pass elif not self.persistence.contains(block): self.persistence.add_block(block) - self.new_block_cb() self.notify_listeners(block) return validation @@ -361,7 +351,12 @@ def notify_listeners(self, block): """ Notify listeners of a specific new block. """ - if block.type not in self.listeners_map or self.shutting_down: + # Call the listeners associated to the universal block, if there are any + for listener in self.listeners_map.get(self.UNIVERSAL_BLOCK_LISTENER, []): + listener.received_block(block) + + # Avoid proceeding any further if the type of the block coincides with the UNIVERSAL_BLOCK_LISTENER + if block.type not in self.listeners_map or self.shutting_down or block.type == self.UNIVERSAL_BLOCK_LISTENER: return for listener in self.listeners_map[block.type]: