Esempio n. 1
0
    def random_block_generator(genesis, initial_leaf_number, block_number):
        """
        Randomly generates blocks according to the given parameters.
        """
        max_initial_leaf_number = initial_leaf_number
        max_block_number = block_number

        all_blocks = set()
        all_blocks.add(hash(genesis))
        leaves = set()
        block_counter = 1
        yield genesis

        while block_counter <= max_block_number:
            if block_counter <= max_initial_leaf_number + 1:
                parents = {hash(genesis)}
            else:
                parents = frozenset(
                    sample(leaves, randint(1, max(1, round(len(leaves) / 5)))))
            cur_block = Block(block_counter, parents)

            leaves -= cur_block.get_parents()
            leaves.add(hash(cur_block))
            all_blocks.add(hash(cur_block))
            block_counter += 1
            yield cur_block
Esempio n. 2
0
    def add(self, block: Block, is_malicious: bool = False):
        super().add(block)

        global_id = hash(block)
        if is_malicious:
            self._malicious_blocks_to_add_to_honest_dag.append(global_id)

            if self.did_attack_fail():
                self._first_parallel_block_gid = global_id

            # The malicious attack generates a chain, so the new tip is the current block
            self._competing_chain_tip_gid = global_id
            self._competing_chain_tip_antipast -= self._G.node[global_id][self._BLUE_DIFF_PAST_ORDER_KEY].keys()
            self._competing_chain_tip_antipast -= self._G.node[global_id][self._RED_DIFF_PAST_ORDER_KEY].keys()

            # Because we are under the assumption that a selfish miner has zero network latency and the
            # simulation design, the assumption is that no new blocks are mined between the moment a new
            # selfish block is mined and the moment it is added to the DAG
            self._virtual_competing_chain_block_parents = \
                self._get_competing_chain_tip_parents(global_id,
                                                      self._competing_chain_tip_antipast,
                                                      block.get_parents())
        else:
            # Add malicious blocks to the honest DAG as soon as possible
            if self.did_attack_fail():
                self._add_malicious_blocks_to_honest_dag()

            # This is possible because this is a competing chain attack,
            # where the honest chain doesn't include any malicious blocks
            self._honest_dag.add(block)

        if self.did_attack_succeed():
            self._add_malicious_blocks_to_honest_dag()

        if not self.did_attack_fail():
            # need to update the data structure only if in the middle of a (seemingly) successful attack
            self._competing_chain_tip_antipast.add(global_id)
            if global_id == self._competing_chain_tip_gid or \
                    self._is_a_bluer_than_b(self._competing_chain_tip_gid, global_id):
                self._virtual_competing_chain_block_parents -= block.get_parents()
                self._virtual_competing_chain_block_parents.add(global_id)
            elif not self._is_attack_viable():
                self._stop_attack()
Esempio n. 3
0
    def add(self, block: Block):
        global_id = hash(block)
        parents = block.get_parents()

        # add the block to the phantom
        self._G.add_node(global_id)
        self._G.node[global_id][self._BLOCK_DATA_KEY] = block
        for parent in parents:
            self._G.add_edge(global_id, parent)

        # update the leaves
        self._leaves -= parents
        self._leaves.add(global_id)

        # update the coloring of the graph and everything related (the blue anticones and the topological order too)
        self._update_coloring_incrementally(global_id)
        self._update_topological_order_incrementally(global_id)