def create_positive_gossip_transaction(block_hash, node_private):
     tx = PositiveGossipTransaction()
     tx.timestamp = Time.get_current_time()
     tx.block_hash = block_hash
     tx.pubkey = Private.publickey(node_private)
     tx.signature = Private.sign(tx.get_hash(), node_private)
     return tx
 def create_negative_gossip_transaction(number_of_block, node_private):
     tx = NegativeGossipTransaction()
     tx.timestamp = Time.get_current_time()
     tx.number_of_block = number_of_block
     tx.pubkey = Private.publickey(node_private)
     tx.signature = Private.sign(tx.get_hash(), node_private)
     return tx
    def test_parse_pack_gossip_negative(self):
        private = Private.generate()
        original = NegativeGossipTransaction()
        original.pubkey = Private.publickey(private)
        original.timestamp = Time.get_current_time()
        original.number_of_block = 47
        original.signature = Private.sign(original.get_hash(), private)

        raw = original.pack()
        restored = NegativeGossipTransaction()
        restored.parse(raw)

        self.assertEqual(original.get_hash(), restored.get_hash())
    def test_pack_parse_penalty_gossip_transaction(self):
        private = Private.generate()
        original = PenaltyGossipTransaction()
        original.timestamp = Time.get_current_time()
        block = BlockFactory.create_block_with_timestamp(
            [], timestamp=original.timestamp)

        gossip_positive_tx = PositiveGossipTransaction()
        gossip_positive_tx.pubkey = Private.publickey(private)
        gossip_positive_tx.timestamp = Time.get_current_time()
        gossip_positive_tx.block_hash = BlockFactory.sign_block(
            block, private).get_hash()
        gossip_positive_tx.signature = Private.sign(original.get_hash(),
                                                    private)

        gossip_negative_tx = NegativeGossipTransaction()
        gossip_negative_tx.pubkey = Private.publickey(private)
        gossip_negative_tx.timestamp = Time.get_current_time()
        gossip_negative_tx.number_of_block = 47
        gossip_negative_tx.signature = Private.sign(original.get_hash(),
                                                    private)

        original.conflicts = [
            gossip_positive_tx.get_hash(),
            gossip_negative_tx.get_hash()
        ]
        original.signature = Private.sign(original.get_hash(), private)

        original.block_hash = BlockFactory.sign_block(block,
                                                      private).get_hash()

        raw = original.pack()
        restored = PenaltyGossipTransaction()
        restored.parse(raw)

        self.assertEqual(original.get_hash(), restored.get_hash())
    def test_parse_pack_gossip_positive(self):
        private = Private.generate()
        original = PositiveGossipTransaction()
        original.pubkey = Private.publickey(private)
        original.timestamp = Time.get_current_time()

        block = BlockFactory.create_block_with_timestamp(
            [], timestamp=original.timestamp)
        original.block_hash = BlockFactory.sign_block(block,
                                                      private).get_hash()
        original.signature = Private.sign(original.get_hash(), private)

        raw = original.pack()
        restored = PositiveGossipTransaction()
        restored.parse(raw)

        self.assertEqual(original.get_hash(), restored.get_hash())
    def test_remove_from_validators_by_penalty_gossip(self):
        # base initialization
        dag = Dag(0)
        epoch = Epoch(dag)
        permissions = Permissions(epoch)
        node_private = Private.generate()

        initial_validators = Validators.read_genesis_validators_from_file()

        genesis_hash = dag.genesis_block().get_hash()
        prev_hash = genesis_hash
        for i in range(1, 9):
            block = BlockFactory.create_block_with_timestamp([prev_hash],
                                                             BLOCK_TIME * i)
            signed_block = BlockFactory.sign_block(block, node_private)
            dag.add_signed_block(i, signed_block)
            prev_hash = block.get_hash()

        # get one of validators
        genesis_validator_private = Private.generate()
        genesis_validator_public = initial_validators[9].public_key

        # put to 10 block gossip+ AND gossip- by one node
        block = BlockFactory.create_block_with_timestamp([prev_hash],
                                                         BLOCK_TIME * 10)

        gossip_negative_tx = NegativeGossipTransaction()
        gossip_negative_tx.pubkey = genesis_validator_public
        gossip_negative_tx.timestamp = Time.get_current_time()
        gossip_negative_tx.number_of_block = 5
        gossip_negative_tx.signature = Private.sign(
            gossip_negative_tx.get_hash(), genesis_validator_private)
        # create and add to block negative gossip
        block.system_txs.append(gossip_negative_tx)

        gossip_positive_tx = PositiveGossipTransaction()
        gossip_positive_tx.pubkey = genesis_validator_public
        gossip_positive_tx.timestamp = Time.get_current_time()
        gossip_positive_tx.block_hash = dag.blocks_by_number[5][0].get_hash()
        gossip_positive_tx.signature = Private.sign(
            gossip_positive_tx.get_hash(), genesis_validator_private)
        # create and add to block positive gossip for same number 5 block
        block.system_txs.append(gossip_positive_tx)

        signed_block = BlockFactory.sign_block(block,
                                               genesis_validator_private)
        dag.add_signed_block(10, signed_block)
        prev_hash = block.get_hash()
        # --------------------------------------------------

        # put to 11 block penalty gossip
        block = BlockFactory.create_block_with_timestamp([prev_hash],
                                                         BLOCK_TIME * 11)
        penalty_gossip_tx = PenaltyGossipTransaction()
        penalty_gossip_tx.timestamp = Time.get_current_time()
        penalty_gossip_tx.conflicts = [
            gossip_positive_tx.get_hash(),
            gossip_negative_tx.get_hash()
        ]
        # set genesis validator for sign penalty gossip
        penalty_gossip_tx.signature = Private.sign(
            penalty_gossip_tx.get_hash(), genesis_validator_private)
        block.system_txs.append(penalty_gossip_tx)

        signed_block = BlockFactory.sign_block(block,
                                               genesis_validator_private)
        dag.add_signed_block(11, signed_block)
        prev_hash = block.get_hash()
        # --------------------------------------------------

        # verify that genesis node is steel in validators list
        current_epoch_hash = epoch.get_epoch_hashes()
        # for now we DO NOT NEED to recalculate validators (send genesis block hash)
        resulting_validators = permissions.get_validators(
            current_epoch_hash.get(prev_hash))
        pub_keys = []
        for validator in resulting_validators:
            pub_keys.append(validator.public_key)
        self.assertIn(genesis_validator_public, pub_keys)

        # produce epoch till end
        from chain.params import ROUND_DURATION
        for i in range(12, (ROUND_DURATION * 6 + 4)):
            block = BlockFactory.create_block_with_timestamp([prev_hash],
                                                             BLOCK_TIME * i)
            signed_block = BlockFactory.sign_block(block, node_private)
            dag.add_signed_block(i, signed_block)
            prev_hash = block.get_hash()

        # check for new epoch
        self.assertTrue(epoch.is_new_epoch_upcoming(i))
        self.assertTrue(epoch.current_epoch == 2)

        # recalculate validators for last block hash
        resulting_validators = permissions.get_validators(prev_hash)
        pub_keys = []
        for validator in resulting_validators:
            pub_keys.append(validator.public_key)

        self.assertNotIn(genesis_validator_public, pub_keys)
Esempio n. 7
0
 def create_block_dummy(prev_hashes):
     block = Block()
     block.prev_hashes = prev_hashes
     block.timestamp = Time.get_current_time()
     block.system_txs = []
     return block
Esempio n. 8
0
 def get_current_timeframe_block_number(self):
     return self.get_block_number_from_timestamp(Time.get_current_time())
 def create_penalty_gossip_transaction(conflict, node_private):
     tx = PenaltyGossipTransaction()
     tx.timestamp = Time.get_current_time()
     tx.conflicts = conflict
     tx.signature = Private.sign(tx.get_hash(), node_private)
     return tx
Esempio n. 10
0
    def __init__(self):
        self.node_to_visualize_after_exit = 0
        self.params_validate()
        self.discrete_mode = True
        self.malicious_validators_count = GENESIS_VALIDATORS_COUNT / 2 - 1
        # set up logging to file - see previous section for more details
        self.logger = logging.basicConfig(level=logging.DEBUG,
                                          format='%(asctime)s %(levelname)-6s %(name)-6s %(message)s')

        if self.discrete_mode:
            Time.use_test_time()
            Time.set_current_time(BLOCK_TIME)
        else:
            Time.set_current_time(int(datetime.datetime.now().timestamp()))
        self.genesis_creation_time = Time.get_current_time() - BLOCK_TIME  # so we start right from the first block

        self.private_keys = BlockSigners()
        self.network = Network()
        self.nodes = []
        self.tasks = []
        try:
            # -------------------------------------
            # main init section
            # -------------------------------------
            self.launch()
            # add some extra nodes
            #self.add_node(10)
            # -------------------------------------

            if self.discrete_mode:
                should_continue = True
                terminated_nodes_count = 0
                while should_continue:
                    initial_node_count = len(self.nodes) - 1 # one node less because of announcer
                    for node in self.nodes:
                        try:
                            if not node.terminated:
                                node.step()
                        except AssertionError:
                            print("Node", node.node_id, "crashed")
                            self.network.unregister_node(node)
                            node.terminated = True
                            terminated_nodes_count += 1
                            if terminated_nodes_count == initial_node_count:
                                print("No alive nodes left. Terminating")
                                should_continue = False
                                break
                        
                    Time.advance_time(1)

                    # add some nodes on defined time
                    # will be possible after syncronization mechanism will be implemented)
                    # if Time.get_current_time() == 40:
                    #    self.add_node(1)
            else:
                self.tasks = [node.run() for node in self.nodes]
                loop = asyncio.get_event_loop()
                loop.run_until_complete(asyncio.gather(*self.tasks))
                loop.close()
        
        finally:
            if self.node_to_visualize_after_exit:
                save_dag_to_graphviz(self.node_to_visualize_after_exit.dag)
                show_node_stats(self.node_to_visualize_after_exit)