def get_allowed_signers_for_block_number(self, block_number): # TODO take cached epoch hashes if block is of lastest epoch prev_epoch_number = self.epoch.get_epoch_number(block_number) - 1 prev_epoch_start = self.epoch.get_epoch_start_block_number( prev_epoch_number) prev_epoch_end = self.epoch.get_epoch_end_block_number( prev_epoch_number) # this will extract every unconnected block in epoch, which is practically epoch hash # TODO maybe consider blocks to be epoch hashes if they are in final round and consider everything else is orphan epoch_hashes = self.dag.get_branches_for_timeslot_range( prev_epoch_start, prev_epoch_end + 1) if prev_epoch_number == 0: epoch_hashes = [self.dag.genesis_block().get_hash()] allowed_signers = [] for epoch_hash in epoch_hashes: epoch_block_number = Epoch.convert_to_epoch_block_number( block_number) allowed_pubkey = self.permissions.get_sign_permission( epoch_hash, epoch_block_number).public_key allowed_signers.append(allowed_pubkey) assert len(allowed_signers) > 0, "No signers allowed to sign block" return allowed_signers
def try_to_sign_block(self, current_block_number): epoch_block_number = Epoch.convert_to_epoch_block_number( current_block_number) allowed_to_sign = False epoch_hashes = self.epoch.get_epoch_hashes() for top, epoch_hash in epoch_hashes.items(): permission = self.permissions.get_sign_permission( epoch_hash, epoch_block_number) if permission.public_key == self.node_pubkey: allowed_to_sign = True break if allowed_to_sign: should_skip_maliciously = self.behaviour.is_malicious_skip_block() # first_epoch_ever = self.epoch.get_epoch_number(current_block_number) == 1 if should_skip_maliciously: # and not first_epoch_ever: # skip first epoch check self.epoch_private_keys.clear() self.logger.info("Maliciously skiped block") else: if self.last_signed_block_number < current_block_number: self.last_signed_block_number = current_block_number self.sign_block(current_block_number) else: # skip once more block broadcast in same timeslot pass
def try_to_send_negative_gossip(self, previous_timeslot_number): if previous_timeslot_number not in self.dag.blocks_by_number: epoch_block_number = Epoch.convert_to_epoch_block_number( previous_timeslot_number) allowed_to_send_negative_gossip = False epoch_hashes = self.epoch.get_epoch_hashes() for _, epoch_hash in epoch_hashes.items(): permissions = self.permissions.get_gossip_permission( epoch_hash, epoch_block_number) for permission in permissions: if permission.public_key == self.node_pubkey: allowed_to_send_negative_gossip = True break if allowed_to_send_negative_gossip: self.broadcast_gossip_negative(previous_timeslot_number) return True return False
def get_allowed_signers_for_next_block(self, block): current_block_number = self.epoch.get_current_timeframe_block_number() epoch_block_number = Epoch.convert_to_epoch_block_number( current_block_number) if self.epoch.is_new_epoch_upcoming(current_block_number): self.epoch.accept_tops_as_epoch_hashes() epoch_hashes = self.epoch.get_epoch_hashes() allowed_signers = [] for prev_hash in block.prev_hashes: epoch_hash = None if prev_hash in epoch_hashes: epoch_hash = epoch_hashes[prev_hash] else: epoch_hash = self.epoch.find_epoch_hash_for_block(prev_hash) if epoch_hash: # self.logger.info("Calculating permissions from epoch_hash %s", epoch_hash.hex()) allowed_pubkey = self.permissions.get_sign_permission( epoch_hash, epoch_block_number) allowed_signers.append(allowed_pubkey) assert len( allowed_signers) > 0, "No signers allowed to sign next block" return allowed_signers