Ejemplo n.º 1
0
    def test_weight_inf(self):
        # this should succeed
        parents = [tx.hash for tx in self.genesis_txs]
        genesis_block = self.genesis_blocks[0]

        value = genesis_block.outputs[0].value
        address = get_address_from_public_key(self.genesis_public_key)
        script = P2PKH.create_output_script(address)
        output = TxOutput(value, script)

        _input = TxInput(genesis_block.hash, 0, b'')
        tx = Transaction(inputs=[_input],
                         outputs=[output],
                         parents=parents,
                         storage=self.tx_storage)
        tx.weight = float('inf')

        data_to_sign = tx.get_sighash_all()
        public_bytes, signature = self.wallet.get_input_aux_data(
            data_to_sign, self.genesis_private_key)
        _input.data = P2PKH.create_input_data(public_bytes, signature)

        tx.update_hash()
        self.assertTrue(isinf(tx.weight))
        with self.assertRaises(WeightError):
            tx.verify()
Ejemplo n.º 2
0
    def test_output_value(self):
        from hathor.transaction.base_transaction import bytes_to_output_value
        # first test using a small output value with 8 bytes. It should fail
        parents = [tx.hash for tx in self.genesis_txs]
        outputs = [TxOutput(1, b'')]
        tx = Transaction(outputs=outputs, parents=parents)
        original_struct = tx.get_struct()
        struct_bytes = tx.get_funds_struct()

        # we'll get the struct without the last output bytes and add it ourselves
        struct_bytes = struct_bytes[:-7]
        # add small value using 8 bytes and expect failure when trying to deserialize
        struct_bytes += (-1).to_bytes(8, byteorder='big', signed=True)
        struct_bytes += int_to_bytes(0, 1)
        struct_bytes += int_to_bytes(0, 2)
        struct_bytes += tx.get_graph_struct()
        struct_bytes += int_to_bytes(tx.nonce, tx.SERIALIZATION_NONCE_SIZE)

        len_difference = len(struct_bytes) - len(original_struct)
        assert len_difference == 4, 'new struct is incorrect, len difference={}'.format(len_difference)

        with self.assertRaises(ValueError):
            Transaction.create_from_struct(struct_bytes)

        # now use 8 bytes and make sure it's working
        outputs = [TxOutput(MAX_OUTPUT_VALUE, b'')]
        tx = Transaction(outputs=outputs, parents=parents)
        tx.update_hash()
        original_struct = tx.get_struct()
        tx2 = Transaction.create_from_struct(original_struct)
        tx2.update_hash()
        assert tx == tx2

        # Validating that all output values must be positive
        value = 1
        address = decode_address('WUDtnw3GYjvUnZmiHAmus6hhs9GoSUSJMG')
        script = P2PKH.create_output_script(address)
        output = TxOutput(value, script)
        output.value = -1
        tx = Transaction(inputs=[], outputs=[output], parents=parents, storage=self.tx_storage)
        with self.assertRaises(InvalidOutputValue):
            tx.resolve()

        # 'Manually resolving', to validate verify method
        tx.hash = bytes.fromhex('012cba011be3c29f1c406f9015e42698b97169dbc6652d1f5e4d5c5e83138858')
        with self.assertRaises(InvalidOutputValue):
            tx.verify()

        # Invalid output value
        invalid_output = bytes.fromhex('ffffffff')
        with self.assertRaises(InvalidOutputValue):
            bytes_to_output_value(invalid_output)

        # Can't instantiate an output with negative value
        with self.assertRaises(AssertionError):
            TxOutput(-1, script)
Ejemplo n.º 3
0
 def _render_POST_thread(self, tx: Transaction, request: Request) -> Transaction:
     """ Method called in a thread to solve tx pow without stratum
     """
     # TODO Tx should be resolved in the frontend
     def _should_stop():
         return request.should_stop_mining_thread
     tx.start_mining(sleep_seconds=self.sleep_seconds, should_stop=_should_stop)
     if request.should_stop_mining_thread:
         raise CancelledError()
     tx.update_hash()
     tx.verify()
     return tx
Ejemplo n.º 4
0
    def test_sigops_output_single_below_limit(self) -> None:
        genesis_block = self.genesis_blocks[0]
        value = genesis_block.outputs[0].value - 1
        _input = TxInput(genesis_block.hash, 0, b'')

        hscript = create_script_with_sigops(settings.MAX_TX_SIGOPS_OUTPUT - 1)
        output3 = TxOutput(value, hscript)
        tx = Transaction(inputs=[_input],
                         outputs=[output3],
                         storage=self.tx_storage)
        tx.update_hash()
        tx.verify_sigops_output()
Ejemplo n.º 5
0
    def test_sigops_input_single_below_limit(self) -> None:
        genesis_block = self.genesis_blocks[0]
        value = genesis_block.outputs[0].value - 1
        address = get_address_from_public_key(self.genesis_public_key)
        script = P2PKH.create_output_script(address)
        _output = TxOutput(value, script)

        hscript = create_script_with_sigops(settings.MAX_TX_SIGOPS_INPUT - 1)
        input3 = TxInput(genesis_block.hash, 0, hscript)
        tx = Transaction(inputs=[input3],
                         outputs=[_output],
                         storage=self.tx_storage)
        tx.update_hash()
        tx.verify_sigops_input()
Ejemplo n.º 6
0
    def test_sigops_output_single_above_limit(self) -> None:
        genesis_block = self.genesis_blocks[0]
        value = genesis_block.outputs[0].value - 1
        _input = TxInput(genesis_block.hash, 0, b'')

        hscript = create_script_with_sigops(settings.MAX_TX_SIGOPS_OUTPUT + 1)
        output1 = TxOutput(value, hscript)
        tx = Transaction(inputs=[_input],
                         outputs=[output1],
                         storage=self.tx_storage)
        tx.update_hash()
        # This calls verify to ensure that verify_sigops_output is being called on verify
        with self.assertRaises(TooManySigOps):
            tx.verify()
Ejemplo n.º 7
0
    def test_sigops_input_single_above_limit(self) -> None:
        genesis_block = self.genesis_blocks[0]
        value = genesis_block.outputs[0].value - 1
        address = get_address_from_public_key(self.genesis_public_key)
        script = P2PKH.create_output_script(address)
        _output = TxOutput(value, script)

        hscript = create_script_with_sigops(settings.MAX_TX_SIGOPS_INPUT + 1)
        input1 = TxInput(genesis_block.hash, 0, hscript)
        tx = Transaction(inputs=[input1],
                         outputs=[_output],
                         storage=self.tx_storage)
        tx.update_hash()
        with self.assertRaises(TooManySigOps):
            tx.verify()
Ejemplo n.º 8
0
    def test_sigops_output_multi_above_limit(self) -> None:
        genesis_block = self.genesis_blocks[0]
        value = genesis_block.outputs[0].value - 1
        _input = TxInput(genesis_block.hash, 0, b'')
        num_outputs = 5

        hscript = create_script_with_sigops(
            (settings.MAX_TX_SIGOPS_OUTPUT + num_outputs) // num_outputs)
        output2 = TxOutput(value, hscript)
        tx = Transaction(inputs=[_input],
                         outputs=[output2] * num_outputs,
                         storage=self.tx_storage)
        tx.update_hash()
        with self.assertRaises(TooManySigOps):
            tx.verify()
Ejemplo n.º 9
0
    def _gen_tx_spending_genesis_block(self):
        parents = [tx.hash for tx in self.genesis_txs]
        genesis_block = self.genesis_blocks[0]

        _input = TxInput(genesis_block.hash, 0, b'')

        value = genesis_block.outputs[0].value
        address = get_address_from_public_key(self.genesis_public_key)
        script = P2PKH.create_output_script(address)
        output = TxOutput(value, script)

        tx = Transaction(nonce=100, inputs=[_input], outputs=[output], parents=parents, storage=self.tx_storage)

        data_to_sign = tx.get_sighash_all(clear_input_data=True)
        public_bytes, signature = self.wallet.get_input_aux_data(data_to_sign, self.genesis_private_key)
        tx.inputs[0].data = P2PKH.create_input_data(public_bytes, signature)

        tx.update_hash()
        return tx
Ejemplo n.º 10
0
 def _get_new_tx(self, nonce):
     tx = Transaction(nonce=nonce, storage=self.cache_storage)
     tx.update_hash()
     meta = TransactionMetadata(hash=tx.hash)
     tx._metadata = meta
     return tx