def __init__(self, genesis_creation_time): self.genesis_creation_time = genesis_creation_time self.blocks_by_hash = {} self.blocks_by_number = {} signed_genesis_block = SignedBlock() signed_genesis_block.set_block(self.genesis_block()) self.add_signed_block(0, signed_genesis_block)
def handle_block_message(self, node_id, raw_signed_block): current_block_number = self.dag.get_current_timeframe_block_number() current_validator = self.permissions.get_permission( self.dag, current_block_number) signed_block = SignedBlock() signed_block.parse(raw_signed_block) print("Node ", self.node_id, "received block from node", node_id, "with block hash", signed_block.block.get_hash().hexdigest()) if signed_block.verify_signature(current_validator.public_key): self.dag.add_signed_block(current_block_number, signed_block) else: self.network.gossip_malicious(current_validator.public_key)
def __init__(self, genesis_creation_time): self.blocks_by_hash = {} # just hash map hash:block self.blocks_by_number = { } # key is timeslot number, value is a list of blocks in this timeslot self.block_numbers_by_hash = {} self.transactions_by_hash = {} # key is tx_hash, value is tx self.payments_by_hash = {} self.existing_links = [] self.tops = {} self.new_block_listeners = [] self.new_top_block_event_listeners = [] self.genesis = Genesis(genesis_creation_time) signed_genesis_block = SignedBlock() signed_genesis_block.set_block(self.genesis) self.add_signed_block(0, signed_genesis_block)
def sign_block(block, private): block_hash = block.get_hash() signature = Private.sign(block_hash, private) signed_block = SignedBlock() signed_block.set_block(block) signed_block.set_signature(signature) return signed_block
def sign_block(self, private): #TODO move somewhere more approptiate block = Block() block.prev_hashes = [*self.get_top_blocks()] block.timestamp = int(datetime.datetime.now().timestamp()) block.randoms = [] block_hash = block.get_hash().digest() signature = private.sign(block_hash, 0)[ 0] #for some reason it returns tuple with second item being None signed_block = SignedBlock() signed_block.set_block(block) signed_block.set_signature(signature) current_block_number = self.get_current_timeframe_block_number() self.add_signed_block(current_block_number, signed_block) print(block_hash.hex(), " was added to blockchain under number ", current_block_number) return signed_block
def test_top_blocks(self): block1 = Block() block1.prev_hashes = [self.genesis_block().get_hash().digest()] block1.timestamp = 32452345234 block1.randoms = [] signed_block1 = SignedBlock() signed_block1.set_block(block1) self.add_signed_block(1, signed_block1) block2 = Block() block2.prev_hashes = [block1.get_hash().digest()] block2.timestamp = 32452345 block2.randoms = [] signed_block2 = SignedBlock() signed_block2.set_block(block2) self.add_signed_block(2, signed_block2) block3 = Block() block3.prev_hashes = [block1.get_hash().digest()] block3.timestamp = 1231827398 block3.randoms = [] signed_block3 = SignedBlock() signed_block3.set_block(block3) self.add_signed_block(3, signed_block3) for keyhash in self.blocks_by_hash: print(binascii.hexlify(keyhash)) top_hashes = self.get_top_blocks() print("tops") for keyhash in top_hashes: print(binascii.hexlify(keyhash))
def handle_block_message(self, node_id, raw_signed_block): signed_block = SignedBlock() signed_block.parse(raw_signed_block) block_number = self.epoch.get_block_number_from_timestamp( signed_block.block.timestamp) self.logger.info( "Received block with number %s at timeslot %s with hash %s", block_number, self.epoch.get_current_timeframe_block_number(), signed_block.block.get_hash().hex()) # CHECK_ANCESTOR blocks_by_hash = self.dag.blocks_by_hash is_orphan_block = False for prev_hash in signed_block.block.prev_hashes: # by every previous hash if prev_hash not in blocks_by_hash: # verify local ancestor for incoming block is_orphan_block = True # CHECK_ORPHAN_DISTANCE block_out_of_epoch = False epoch_end_block = self.epoch.get_epoch_end_block_number( self.epoch.current_epoch) if block_number >= epoch_end_block: # income block from future epoch, cant validate signer block_out_of_epoch = True # CHECK ALLOWED SIGNER if not block_out_of_epoch: # if incoming block not out of current epoch allowed_signers = self.get_allowed_signers_for_block_number( block_number) allowed_pubkey = None for allowed_signer in allowed_signers: if signed_block.verify_signature(allowed_signer): allowed_pubkey = allowed_signer break else: allowed_pubkey = 'block_out_of_epoch' # process block as orphan if allowed_pubkey: # IF SIGNER ALLOWED if not is_orphan_block: # PROCESS NORMAL BLOCK (same epoch) if self.epoch.is_new_epoch_upcoming( block_number): # CHECK IS NEW EPOCH self.epoch.accept_tops_as_epoch_hashes() block_verifier = BlockAcceptor( self.epoch, self.logger) # VERIFY BLOCK AS NORMAL if block_verifier.check_if_valid(signed_block.block): self.insert_verified_block(signed_block, allowed_pubkey) return else: # PROCESS ORPHAN BLOCK (same epoch) orphan_block_verifier = OrphanBlockAcceptor( self.epoch, self.blocks_buffer, self.logger) if orphan_block_verifier.check_if_valid(signed_block.block): self.blocks_buffer.append(signed_block) self.logger.info("Orphan block added to buffer") # for every parent for received block for prev_hash in signed_block.block.prev_hashes: # check received block ancestor if prev_hash not in self.dag.blocks_by_hash: # check parent in local dag # if parent not exist in local DAG ask for parent self.network.direct_request_block_by_hash( self.node_id, node_id, prev_hash) if len(self.blocks_buffer) > 0: self.process_block_buffer() self.logger.info("Orphan block buffer process success") else: self.logger.error( "Received block from %d, but its signature is wrong", node_id)