def parse(self, raw_data):
        deserializer = Deserializer(raw_data)

        self.timestamp = deserializer.parse_u32()

        hash_count = deserializer.parse_u16()

        self.prev_hashes = []
        for i in range(0, hash_count):
            prev_hash = deserializer.read_and_move(32)
            self.prev_hashes.append(prev_hash)

        system_tx_count = deserializer.parse_u8()
        self.system_txs = []
        for i in range(0, system_tx_count):
            tx = TransactionParser.parse(
                deserializer.data
            )  # TODO: (is) Better to deserialize passing deserializer directly
            self.system_txs.append(tx)
            deserializer.read_and_move(tx.get_len() + 1)  # one byte for type

        payment_tx_count = deserializer.parse_u8()
        self.payment_txs = []
        for i in range(0, payment_tx_count):
            tx = TransactionParser.parse(
                deserializer.data
            )  # TODO: (is) Better to deserialize passing deserializer directly
            self.payment_txs.append(tx)
            deserializer.read_and_move(tx.get_len() + 1)  # one byte for type
    def test_pack_parse_reveal_transaction(self):
        for _ in range(10):
            dummy_private = Private.generate()

            original = RevealRandomTransaction()
            original.commit_hash = sha256(b"previous_transaction").digest()
            original.key = Keys.to_bytes(dummy_private)

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

            self.assertEqual(TransactionParser.pack(original),
                             TransactionParser.pack(restored))
            self.assertEqual(original.get_hash(), restored.get_hash())
Example #3
0
 def broadcast_stakehold_transaction(self):
     node_private = self.block_signer.private_key
     tx = TransactionFactory.create_stake_hold_transaction(
         1000, node_private)
     self.logger.info("Broadcasted StakeHold transaction")
     self.network.broadcast_transaction(self.node_id,
                                        TransactionParser.pack(tx))
Example #4
0
    def try_to_publish_public_key(self, current_block_number):
        if self.epoch_private_keys:
            return

        epoch_hashes = self.epoch.get_epoch_hashes()
        for _, epoch_hash in epoch_hashes.items():
            allowed_round_validators = self.permissions.get_ordered_randomizers_pubkeys_for_round(
                epoch_hash, Round.PUBLIC)
            pubkey_publishers_pubkeys = [
                validator.public_key for validator in allowed_round_validators
            ]
            if self.node_pubkey in pubkey_publishers_pubkeys:
                node_private = self.block_signer.private_key
                pubkey_index = self.permissions.get_signer_index_from_public_key(
                    self.node_pubkey, epoch_hash)

                generated_private = Private.generate()
                tx = TransactionFactory.create_public_key_transaction(
                    generated_private=generated_private,
                    epoch_hash=epoch_hash,
                    validator_index=pubkey_index,
                    node_private=node_private)
                if self.behaviour.malicious_wrong_signature:
                    tx.signature = b'0' + tx.signature[1:]

                self.epoch_private_keys.append(generated_private)
                self.logger.debug("Broadcasted public key")
                self.logger.debug(Keys.to_visual_string(tx.generated_pubkey))
                self.mempool.add_transaction(tx)
                self.network.broadcast_transaction(self.node_id,
                                                   TransactionParser.pack(tx))
    def pack(self):
        raw_block = Serializer.write_u32(self.timestamp)

        raw_block += Serializer.write_u16(len(self.prev_hashes))
        for prev_hash in self.prev_hashes:
            raw_block += prev_hash

        raw_block += Serializer.write_u8(len(self.system_txs))
        for tx in self.system_txs:
            raw_block += TransactionParser.pack(tx)

        raw_block += Serializer.write_u8(len(self.payment_txs))
        for tx in self.payment_txs:
            raw_block += TransactionParser.pack(tx)

        return raw_block
Example #6
0
 def try_to_reveal_random(self):
     for epoch_hash in list(self.reveals_to_send.keys()):
         reveal = self.reveals_to_send[epoch_hash]
         self.logger.info("Broadcasting reveal")
         self.mempool.add_transaction(reveal)
         self.network.broadcast_transaction(self.node_id,
                                            TransactionParser.pack(reveal))
         del self.reveals_to_send[epoch_hash]
    def test_pack_parse_commit_transaction(self):
        for i in range(10):
            dummy_private = Private.generate()
            original = CommitRandomTransaction()
            original.rand = Private.encrypt(os.urandom(32), dummy_private)
            original.pubkey_index = i
            original.signature = Private.sign(
                original.get_signing_hash(b"epoch_hash"), dummy_private)

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

            self.assertEqual(TransactionParser.pack(original),
                             TransactionParser.pack(restored))
            self.assertEqual(original.get_hash(), restored.get_hash())
            self.assertEqual(original.get_signing_hash(b"epoch_hash"),
                             restored.get_signing_hash(b"epoch_hash"))
Example #8
0
 def broadcast_payments(self):
     for utxo in self.owned_utxos:
         tx = TransactionFactory.create_payment(
             utxo, 0, [os.urandom(32), os.urandom(32)], [10, 5])
         self.mempool.add_transaction(tx)
         self.network.broadcast_transaction(self.node_id,
                                            TransactionParser.pack(tx))
         # self.logger.info("Broadcasted payment with hash %s", tx.get_hash())
     self.owned_utxos.clear()
Example #9
0
 def broadcast_gossip_positive(self, signed_block_hash):
     node_private = self.block_signer.private_key
     tx = TransactionFactory.create_positive_gossip_transaction(
         signed_block_hash, node_private)
     self.mempool.append_gossip_tx(
         tx)  # ADD ! TO LOCAL MEMPOOL BEFORE BROADCAST
     # self.logger.info("Broadcasted positive gossip transaction")
     self.network.broadcast_transaction(self.node_id,
                                        TransactionParser.pack(tx))
Example #10
0
 def try_to_share_random(self):
     epoch_hashes = self.epoch.get_epoch_hashes()
     for top, epoch_hash in epoch_hashes.items():
         if epoch_hash in self.sent_shares_epochs: continue
         allowed_to_share_random = self.permissions.get_secret_sharers_pubkeys(
             epoch_hash)
         if not self.node_pubkey in allowed_to_share_random: continue
         split_random = self.form_split_random_transaction(top, epoch_hash)
         self.sent_shares_epochs.append(epoch_hash)
         self.mempool.add_transaction(split_random)
         self.network.broadcast_transaction(
             self.node_id, TransactionParser.pack(split_random))
Example #11
0
 def try_to_commit_random(self):
     epoch_hashes = self.epoch.get_epoch_hashes().values()
     for epoch_hash in epoch_hashes:
         if epoch_hash not in self.reveals_to_send:
             allowed_to_commit_list = self.permissions.get_commiters_pubkeys(
                 epoch_hash)
             if self.node_pubkey not in allowed_to_commit_list:
                 continue
             pubkey_index = self.permissions.get_committer_index_from_public_key(
                 self.node_pubkey, epoch_hash)
             commit, reveal = TransactionFactory.create_commit_reveal_pair(
                 self.block_signer.private_key, os.urandom(32),
                 pubkey_index, epoch_hash)
             self.reveals_to_send[epoch_hash] = reveal
             self.logger.info("Broadcasting commit")
             self.mempool.add_transaction(commit)
             self.network.broadcast_transaction(
                 self.node_id, TransactionParser.pack(commit))
Example #12
0
    def handle_transaction_message(self, node_id, raw_transaction):
        transaction = TransactionParser.parse(raw_transaction)

        verifier = MempoolTransactionsAcceptor(self.epoch, self.permissions,
                                               self.logger)
        if verifier.check_if_valid(transaction):
            self.mempool.add_transaction(transaction)
            # PROCESS NEGATIVE GOSSIP
            if isinstance(transaction, NegativeGossipTransaction):
                self.logger.info(
                    "Received negative gossip about block %s at timeslot %s",
                    transaction.number_of_block,
                    self.epoch.get_current_timeframe_block_number())

                current_gossips = self.mempool.get_negative_gossips_by_block(
                    transaction.number_of_block)
                for gossip in current_gossips:
                    # negative gossip already send by node, skip positive gossip searching and broadcasting
                    if gossip.pubkey == self.node_pubkey:
                        return
                if self.dag.has_block_number(transaction.number_of_block):
                    signed_block_by_number = self.dag.blocks_by_number[
                        transaction.number_of_block]
                    self.broadcast_gossip_positive(
                        signed_block_by_number[0].get_hash())
            # PROCESS POSITIVE GOSSIP
            if isinstance(transaction, PositiveGossipTransaction):
                # ----> ! make request ONLY if block in timeslot
                self.logger.info(
                    "Received positive gossip about block %s at timeslot %s",
                    transaction.block_hash.hex(),
                    self.epoch.get_current_timeframe_block_number())
                if transaction.block_hash not in self.dag.blocks_by_hash:
                    self.network.get_block_by_hash(
                        sender_node_id=self.node_id,
                        receiver_node_id=
                        node_id,  # request TO ----> receiver_node_id
                        block_hash=transaction.block_hash)
        else:
            self.logger.error("Received tx is invalid")
Example #13
0
 def broadcast_stakerelease_transaction(self):
     node_private = self.block_signer.private_key
     tx = TransactionFactory.create_stake_release_transaction(node_private)
     self.logger.info("Broadcasted release stake transaction")
     self.network.broadcast_transaction(self.node_id,
                                        TransactionParser.pack(tx))