Esempio n. 1
0
    def setUp(self):
        super().setUp()
        self.genesis_blocks = [tx for tx in get_genesis_transactions(None) if tx.is_block]
        self.genesis_txs = [tx for tx in get_genesis_transactions(None) if not tx.is_block]

        # read genesis keys
        self.genesis_private_key = get_genesis_key()
        self.genesis_public_key = self.genesis_private_key.public_key()
Esempio n. 2
0
 def test_new_tx(self):
     self.factory.connections.add(self.protocol)
     self.protocol.state = HathorAdminWebsocketProtocol.STATE_OPEN
     self.manager.pubsub.publish(HathorEvents.NETWORK_NEW_TX_ACCEPTED,
                                 tx=get_genesis_transactions(
                                     self.manager.tx_storage)[1])
     self.run_to_completion()
     value = self._decode_value(self.transport.value())
     self.assertEqual(value['tx_id'],
                      get_genesis_transactions(None)[1].hash.hex())
     self.assertEqual(value['type'], 'network:new_tx_accepted')
Esempio n. 3
0
 def test_input_spent_received(self):
     self.factory.connections.add(self.protocol)
     self.protocol.state = HathorAdminWebsocketProtocol.STATE_OPEN
     gen_tx = get_genesis_transactions(None)[0]
     gen_tx2 = get_genesis_transactions(None)[1]
     spent = SpentTx(gen_tx2.hash, gen_tx.hash, 0, 10, gen_tx.timestamp + 1)
     self.manager.pubsub.publish(HathorEvents.WALLET_INPUT_SPENT,
                                 output_spent=spent)
     self.run_to_completion()
     value = self._decode_value(self.transport.value())
     self.assertEqual(value['type'], 'wallet:output_spent')
     self.assertEqual(value['output_spent']['tx_id'], gen_tx2.hash.hex())
     self.assertEqual(value['output_spent']['from_tx_id'],
                      gen_tx.hash.hex())
 def test_blocks_are_blocked(self):
     genesis_tx = get_genesis_transactions(self.manager.tx_storage)[0]
     response_success = yield self.web.get(
         "transaction_acc_weight",
         {b'id': bytes(genesis_tx.hash.hex(), 'utf-8')})
     data_success = response_success.json_value()
     self.assertFalse(data_success['success'])
 def _create_genesis_cache(self) -> None:
     from hathor.transaction.genesis import get_genesis_transactions
     self._genesis_cache = {}
     assert self._genesis_cache is not None
     for genesis in get_genesis_transactions(self):
         assert genesis.hash is not None
         self._genesis_cache[genesis.hash] = genesis
Esempio n. 6
0
    def test_get_tips(self):
        genesis_txs = [tx for tx in get_genesis_transactions(self.manager.tx_storage) if not tx.is_block]

        # Tips are only the genesis
        response1 = yield self.web.get("tips")
        data1 = response1.json_value()
        self.assertEqual(len(data1), len(genesis_txs))

        self.manager.wallet.unlock(b'MYPASS')

        # Add blocks to have funds
        add_new_blocks(self.manager, 2, advance_clock=1)
        add_blocks_unlock_reward(self.manager)

        # Add one tx, now you have only one tip
        tx = add_new_transactions(self.manager, 1)[0]

        response2 = yield self.web.get("tips")
        data2 = response2.json_value()
        self.assertEqual(len(data2), 1)

        # Getting tips sending timestamp as parameter
        response3 = yield self.web.get("tips", {b'timestamp': tx.timestamp - 1})
        data3 = response3.json_value()
        self.assertEqual(len(data3), 2)
Esempio n. 7
0
    def test_genesis_weight(self):
        genesis_blocks = [tx for tx in get_genesis_transactions(None) if tx.is_block]
        genesis_block = genesis_blocks[0]

        genesis_txs = [tx for tx in get_genesis_transactions(None) if not tx.is_block]
        genesis_tx = genesis_txs[0]

        network = 'testnet'
        manager = self.create_peer(network, unlock_wallet=True)

        # Validate the block and tx weight
        # in test mode weight is always 1
        self.assertEqual(manager.calculate_block_difficulty(genesis_block), 1)
        self.assertEqual(manager.minimum_tx_weight(genesis_tx), 1)
        manager.test_mode = TestMode.DISABLED
        self.assertEqual(manager.calculate_block_difficulty(genesis_block), genesis_block.weight)
        self.assertEqual(manager.minimum_tx_weight(genesis_tx), genesis_tx.weight)
Esempio n. 8
0
    def test_output(self):
        # Test if block output is valid
        genesis = get_genesis_transactions(None)

        for g in genesis:
            if g.is_block:
                for output in g.outputs:
                    self.assertEqual(output.script.hex(), get_genesis_output())
Esempio n. 9
0
    def test_get(self):
        genesis_tx = get_genesis_transactions(self.manager.tx_storage)[1]
        response_success = yield self.web.get(
            "decode_tx",
            {b'hex_tx': bytes(genesis_tx.get_struct().hex(), 'utf-8')})
        data_success = response_success.json_value()

        self.assertTrue(data_success['success'])
        data_genesis = genesis_tx.to_json(decode_script=True)
        data_genesis['raw'] = genesis_tx.get_struct().hex()
        data_genesis['nonce'] = str(data_genesis['nonce'])
        self.assertEqual(data_success['tx'], data_genesis)
        self.assertTrue('meta' in data_success)
        self.assertTrue('spent_outputs' in data_success)

        # Invalid hex
        response_error1 = yield self.web.get("decode_tx", {b'hex_tx': b'XXXX'})
        data_error1 = response_error1.json_value()

        self.assertFalse(data_error1['success'])

        # Invalid tx hex
        response_error2 = yield self.web.get("decode_tx", {b'hex_tx': b'a12c'})
        data_error2 = response_error2.json_value()

        self.assertFalse(data_error2['success'])

        # Token creation tx
        script_type_out = parse_address_script(
            get_genesis_transactions(
                self.manager.tx_storage)[0].outputs[0].script)
        address = script_type_out.address
        add_blocks_unlock_reward(self.manager)
        tx2 = create_tokens(self.manager,
                            address,
                            mint_amount=100,
                            propagate=True)
        response = yield self.web.get(
            'decode_tx', {b'hex_tx': bytes(tx2.get_struct().hex(), 'utf-8')})
        data = response.json_value()
        self.assertTrue(data['success'])
Esempio n. 10
0
 def setUp(self):
     super().setUp()
     self.block = get_genesis_transactions(None)[0]
     self.transport = StringTransportWithDisconnection()
     self.protocol = StratumClient()
     self.protocol.makeConnection(self.transport)
     self.job_request_params = {
         'data': self.block.get_header_without_nonce().hex(),
         'job_id': 'a734d03fe4b64739be2894742f3de20f',
         'nonce_size': Block.SERIALIZATION_NONCE_SIZE,
         'weight': self.block.weight,
     }
Esempio n. 11
0
 def test_output_received(self):
     self.factory.connections.add(self.protocol)
     self.protocol.state = HathorAdminWebsocketProtocol.STATE_OPEN
     gen_tx = get_genesis_transactions(None)[0]
     output = UnspentTx(gen_tx.hash, 0, 10, gen_tx.timestamp, '',
                        gen_tx.outputs[0].token_data)
     self.manager.pubsub.publish(HathorEvents.WALLET_OUTPUT_RECEIVED,
                                 total=10,
                                 output=output)
     self.run_to_completion()
     value = self._decode_value(self.transport.value())
     self.assertEqual(value['total'], 10)
     self.assertEqual(value['type'], 'wallet:output_received')
     self.assertEqual(value['output']['tx_id'], gen_tx.hash.hex())
Esempio n. 12
0
 def test_separate_inputs(self):
     block = add_new_block(self.manager, advance_clock=5)
     my_input = TxInput(block.hash, 0, b'')
     genesis_blocks = [
         tx for tx in get_genesis_transactions(None) if tx.is_block
     ]
     genesis_block = genesis_blocks[0]
     other_input = TxInput(genesis_block.hash, 0, b'')
     my_inputs, other_inputs = self.manager.wallet.separate_inputs(
         [my_input, other_input], self.manager.tx_storage)
     self.assertEqual(len(my_inputs), 1)
     self.assertEqual(my_inputs[0], my_input)
     self.assertEqual(len(other_inputs), 1)
     self.assertEqual(other_inputs[0], other_input)
Esempio n. 13
0
    def setUp(self):
        super().setUp()

        # import sys
        # from twisted.python import log
        # log.startLogging(sys.stdout)

        # self.set_random_seed(0)

        first_timestamp = min(tx.timestamp
                              for tx in get_genesis_transactions(None))
        self.clock.advance(first_timestamp +
                           random.randint(3600, 120 * 24 * 3600))

        self.network = 'testnet'
Esempio n. 14
0
    def test_get_one(self):
        genesis_tx = get_genesis_transactions(self.manager.tx_storage)[0]
        response_success = yield self.web.get(
            "transaction", {b'id': bytes(genesis_tx.hash.hex(), 'utf-8')})
        data_success = response_success.json_value()
        self.assertTrue(data_success['success'])
        dict_test = genesis_tx.to_json(decode_script=True)
        dict_test['raw'] = genesis_tx.get_struct().hex()
        dict_test['nonce'] = str(dict_test['nonce'])
        if genesis_tx.is_block:
            dict_test['height'] = genesis_tx.calculate_height()
        self.assertEqual(data_success['tx'], dict_test)

        # Test sending hash that does not exist
        response_error1 = yield self.web.get(
            "transaction", {
                b'id':
                b'000000831cff82fa730cbdf8640fae6c130aab1681336e2f8574e314a5533848'
            })
        data_error1 = response_error1.json_value()
        self.assertFalse(data_error1['success'])

        # Test sending invalid hash
        response_error2 = yield self.web.get(
            "transaction", {
                b'id':
                b'000000831cff82fa730cbdf8640fae6c130aab1681336e2f8574e314a553384'
            })
        data_error2 = response_error2.json_value()
        self.assertFalse(data_error2['success'])

        # Adding blocks to have funds
        add_new_blocks(self.manager, 2, advance_clock=1)
        add_blocks_unlock_reward(self.manager)
        tx = add_new_transactions(self.manager, 1)[0]

        tx2 = Transaction.create_from_struct(tx.get_struct())
        tx2.parents = [tx.parents[1], tx.parents[0]]
        tx2.resolve()

        self.manager.propagate_tx(tx2)

        # Now we get a tx with conflict, voided_by and twin
        response_conflict = yield self.web.get(
            "transaction", {b'id': bytes(tx2.hash.hex(), 'utf-8')})
        data_conflict = response_conflict.json_value()
        self.assertTrue(data_conflict['success'])
    def _reset_cache(self) -> None:
        """Reset all caches. This function should not be called unless you know what you are doing."""
        if not self.with_index:
            raise NotImplementedError
        self._cache_block_count = 0
        self._cache_tx_count = 0

        self.block_index = IndexesManager()
        self.tx_index = IndexesManager()
        self.all_index = IndexesManager()
        self.wallet_index = None
        self.tokens_index = None

        self._latest_timestamp = 0
        from hathor.transaction.genesis import get_genesis_transactions
        self._first_timestamp = min(x.timestamp
                                    for x in get_genesis_transactions(self))
Esempio n. 16
0
    def is_genesis(self) -> bool:
        """ Check whether this transaction is a genesis transaction

        :rtype: bool
        """
        if self.hash is None:
            return False
        if self.storage:
            genesis = self.storage.get_genesis(self.hash)
            if genesis:
                return True
            else:
                return False
        else:
            from hathor.transaction.genesis import get_genesis_transactions
            for genesis in get_genesis_transactions(self.storage):
                if self == genesis:
                    return True
            return False
Esempio n. 17
0
    def test_subscribe_address(self):
        self.assertEqual(len(self.factory.address_connections), 0)
        self.protocol.state = HathorAdminWebsocketProtocol.STATE_OPEN
        # Subscribe to address
        address = '1Q4qyTjhpUXUZXzwKs6Yvh2RNnF5J1XN9a'
        payload = json.dumps({
            'type': 'subscribe_address',
            'address': address
        }).encode('utf-8')
        self.protocol.onMessage(payload, True)
        self.assertEqual(len(self.factory.address_connections), 1)

        block_genesis = [
            tx for tx in get_genesis_transactions(self.manager.tx_storage)
            if tx.is_block
        ][0]

        # Test publish address history
        # First clean the transport to make sure the value comes from this execution
        self.transport.clear()
        element = block_genesis.to_json_extended()
        self.manager.pubsub.publish(HathorEvents.WALLET_ADDRESS_HISTORY,
                                    address=address,
                                    history=element)
        self.run_to_completion()
        value = self._decode_value(self.transport.value())
        self.assertEqual(value['type'], 'wallet:address_history')
        self.assertEqual(value['address'], address)
        self.assertEqual(value['history']['tx_id'], block_genesis.hash_hex)
        self.assertEqual(value['history']['timestamp'],
                         block_genesis.timestamp)

        # Publishing with address that was not subscribed must not generate any value in the ws
        # First clean the transport to make sure the value comes from this execution
        self.transport.clear()
        wrong_address = '1Q4qyTjhpUXUZXzwKs6Yvh2RNnF5J1XN9b'
        self.manager.pubsub.publish(HathorEvents.WALLET_ADDRESS_HISTORY,
                                    address=wrong_address,
                                    history=element)
        self.run_to_completion()
        value = self._decode_value(self.transport.value())
        self.assertIsNone(value)
Esempio n. 18
0
    def setUp(self):
        super().setUp()

        self.clock = HeapClock()
        self.set_random_seed(self.seed_config)

        print('-' * 30)
        print('Simulation seed config:', self.random_seed)
        print('-' * 30)

        def verify_pow(self) -> None:
            assert self.hash is not None

        self.old_verify_pow = BaseTransaction.verify_pow
        BaseTransaction.verify_pow = verify_pow

        self.network = 'testnet'

        first_timestamp = min(tx.timestamp
                              for tx in get_genesis_transactions(None))
        self.clock.advance(first_timestamp +
                           random.randint(3600, 120 * 24 * 3600))
    def test_get_data(self):
        genesis_tx = get_genesis_transactions(self.manager.tx_storage)[1]
        response_success = yield self.web.get(
            "transaction_acc_weight",
            {b'id': bytes(genesis_tx.hash.hex(), 'utf-8')})
        data_success = response_success.json_value()
        self.assertTrue(data_success['success'])
        self.assertEqual(data_success['accumulated_weight'], genesis_tx.weight)
        self.assertEqual(data_success['confirmation_level'], 0)

        # Adding blocks to have funds
        add_new_blocks(self.manager, 2, advance_clock=1)
        add_blocks_unlock_reward(self.manager)
        tx = add_new_transactions(self.manager, 5)[0]
        add_new_blocks(self.manager, 2, advance_clock=1)
        add_blocks_unlock_reward(self.manager)
        response_success2 = yield self.web.get(
            "transaction_acc_weight", {b'id': bytes(tx.hash.hex(), 'utf-8')})
        data_success2 = response_success2.json_value()
        self.assertGreater(data_success2['accumulated_weight'], tx.weight)
        self.assertEqual(data_success2['confirmation_level'], 1)

        # Test sending hash that does not exist
        response_error1 = yield self.web.get(
            "transaction_acc_weight", {
                b'id':
                b'000000831cff82fa730cbdf8640fae6c130aab1681336e2f8574e314a5533848'
            })
        data_error1 = response_error1.json_value()
        self.assertFalse(data_error1['success'])

        # Test sending invalid hash
        response_error2 = yield self.web.get(
            "transaction_acc_weight", {
                b'id':
                b'000000831cff82fa730cbdf8640fae6c130aab1681336e2f8574e314a553384'
            })
        data_error2 = response_error2.json_value()
        self.assertFalse(data_error2['success'])
Esempio n. 20
0
    def test_checkmultisig(self):
        with self.assertRaises(MissingStackItems):
            op_checkmultisig([], log=[], extras=None)

        block = [x for x in get_genesis_transactions(None) if x.is_block][0]

        from hathor.transaction import Transaction, TxInput, TxOutput
        txin = TxInput(tx_id=block.hash, index=0, data=b'')
        txout = TxOutput(value=block.outputs[0].value, script=b'')
        tx = Transaction(inputs=[txin], outputs=[txout])

        data_to_sign = tx.get_sighash_all()
        extras = ScriptExtras(tx=tx, txin=None, spent_tx=None)

        wallet = HDWallet()
        wallet._manually_initialize()
        wallet.words = wallet.mnemonic.generate()
        wallet._manually_initialize()

        keys_count = 3
        keys = []

        for i in range(keys_count):
            privkey = list(wallet.keys.values())[i]
            keys.append({
                'privkey': privkey,
                'pubkey': privkey.sec(),
                'signature': wallet.get_input_aux_data(data_to_sign, privkey)[1]
            })

        wrong_privkey = list(wallet.keys.values())[3]
        wrong_key = {
            'privkey': wrong_privkey,
            'pubkey': wrong_privkey.sec(),
            'signature': wallet.get_input_aux_data(data_to_sign, wrong_privkey)[1]
        }

        # All signatures match
        stack = [
            keys[0]['signature'], keys[2]['signature'], 2, keys[0]['pubkey'], keys[1]['pubkey'], keys[2]['pubkey'], 3
        ]
        op_checkmultisig(stack, log=[], extras=extras)
        self.assertEqual(1, stack.pop())

        # New set of valid signatures
        stack = [
            keys[0]['signature'], keys[1]['signature'], 2, keys[0]['pubkey'], keys[1]['pubkey'], keys[2]['pubkey'], 3
        ]
        op_checkmultisig(stack, log=[], extras=extras)
        self.assertEqual(1, stack.pop())

        # Changing the signatures but they match
        stack = [
            keys[1]['signature'], keys[2]['signature'], 2, keys[0]['pubkey'], keys[1]['pubkey'], keys[2]['pubkey'], 3
        ]
        op_checkmultisig(stack, log=[], extras=extras)
        self.assertEqual(1, stack.pop())

        # Signatures are valid but in wrong order
        stack = [
            keys[1]['signature'], keys[0]['signature'], 2, keys[0]['pubkey'], keys[1]['pubkey'], keys[2]['pubkey'], 3
        ]
        op_checkmultisig(stack, log=[], extras=extras)
        self.assertEqual(0, stack.pop())

        # Adding wrong signature, so we get error
        stack = [
            keys[0]['signature'], wrong_key['signature'], 2, keys[0]['pubkey'], keys[1]['pubkey'], keys[2]['pubkey'], 3
        ]
        op_checkmultisig(stack, log=[], extras=extras)
        self.assertEqual(0, stack.pop())

        # Adding same signature twice, so we get error
        stack = [
            keys[0]['signature'], keys[0]['signature'], 2, keys[0]['pubkey'], keys[1]['pubkey'], keys[2]['pubkey'], 3
        ]
        op_checkmultisig(stack, log=[], extras=extras)
        self.assertEqual(0, stack.pop())

        # Adding less signatures than required, so we get error
        stack = [keys[0]['signature'], 2, keys[0]['pubkey'], keys[1]['pubkey'], keys[2]['pubkey'], 3]
        with self.assertRaises(MissingStackItems):
            op_checkmultisig(stack, log=[], extras=extras)

        # Quantity of signatures is more than it should
        stack = [
            keys[0]['signature'], keys[1]['signature'], 3, keys[0]['pubkey'], keys[1]['pubkey'], keys[2]['pubkey'], 3
        ]
        with self.assertRaises(MissingStackItems):
            op_checkmultisig(stack, log=[], extras=extras)

        # Quantity of pubkeys is more than it should
        stack = [
            keys[0]['signature'], keys[1]['signature'], 2, keys[0]['pubkey'], keys[1]['pubkey'], keys[2]['pubkey'], 4
        ]
        with self.assertRaises(InvalidStackData):
            op_checkmultisig(stack, log=[], extras=extras)

        # Exception pubkey_count should be integer
        stack = [
            keys[0]['signature'], keys[1]['signature'], 2, keys[0]['pubkey'], keys[1]['pubkey'], keys[2]['pubkey'], '3'
        ]
        with self.assertRaises(InvalidStackData):
            op_checkmultisig(stack, log=[], extras=extras)

        # Exception not enough pub keys
        stack = [keys[0]['pubkey'], keys[1]['pubkey'], 3]
        with self.assertRaises(MissingStackItems):
            op_checkmultisig(stack, log=[], extras=extras)

        # Exception stack empty after pubkeys
        stack = [keys[0]['pubkey'], keys[1]['pubkey'], keys[2]['pubkey'], 3]
        with self.assertRaises(MissingStackItems):
            op_checkmultisig(stack, log=[], extras=extras)
Esempio n. 21
0
    def test_wallet_create_transaction(self):
        genesis_private_key_bytes = get_private_key_bytes(
            self.genesis_private_key,
            encryption_algorithm=serialization.BestAvailableEncryption(
                PASSWORD))
        genesis_address = get_address_b58_from_public_key(
            self.genesis_public_key)
        # create wallet with genesis block key
        key_pair = KeyPair(private_key_bytes=genesis_private_key_bytes,
                           address=genesis_address,
                           used=True)
        keys = {}
        keys[key_pair.address] = key_pair
        w = Wallet(keys=keys, directory=self.directory)
        w.unlock(PASSWORD)
        genesis_blocks = [
            tx for tx in get_genesis_transactions(None) if tx.is_block
        ]
        genesis_block = genesis_blocks[0]
        genesis_value = sum([output.value for output in genesis_block.outputs])

        # wallet will receive genesis block and store in unspent_tx
        w.on_new_tx(genesis_block)
        for index in range(len(genesis_block.outputs)):
            utxo = w.unspent_txs[settings.HATHOR_TOKEN_UID].get(
                (genesis_block.hash, index))
            self.assertIsNotNone(utxo)
        self.assertEqual(w.balance[settings.HATHOR_TOKEN_UID],
                         WalletBalance(0, genesis_value))

        # create transaction spending this value, but sending to same wallet
        new_address = w.get_unused_address()
        out = WalletOutputInfo(decode_address(new_address), 100, timelock=None)
        tx1 = w.prepare_transaction_compute_inputs(Transaction, outputs=[out])
        tx1.storage = self.storage
        tx1.update_hash()
        self.storage.save_transaction(tx1)
        w.on_new_tx(tx1)
        self.assertEqual(len(w.spent_txs), 1)
        self.assertEqual(w.balance[settings.HATHOR_TOKEN_UID],
                         WalletBalance(0, genesis_value))

        # pass inputs and outputs to prepare_transaction, but not the input keys
        # spend output last transaction
        input_info = WalletInputInfo(tx1.hash, 1, None)
        new_address = w.get_unused_address()
        key2 = w.keys[new_address]
        out = WalletOutputInfo(decode_address(key2.address),
                               100,
                               timelock=None)
        tx2 = w.prepare_transaction_incomplete_inputs(Transaction,
                                                      inputs=[input_info],
                                                      outputs=[out],
                                                      tx_storage=self.storage)
        tx2.storage = self.storage
        tx2.update_hash()
        self.storage.save_transaction(tx2)
        w.on_new_tx(tx2)
        self.assertEqual(len(w.spent_txs), 2)
        self.assertEqual(w.balance[settings.HATHOR_TOKEN_UID],
                         WalletBalance(0, genesis_value))

        # test keypair exception
        with self.assertRaises(WalletLocked):
            key_pair.get_private_key(None)
Esempio n. 22
0
    def test_pow(self):
        genesis = get_genesis_transactions(None)

        for g in genesis:
            self.assertEqual(g.calculate_hash(), g.hash)
            self.assertIsNone(g.verify_pow())
Esempio n. 23
0
    def test_verify(self):
        genesis = get_genesis_transactions(None)

        for g in genesis:
            g.verify_without_storage()
Esempio n. 24
0
    def test_genesis_tokens(self):
        genesis_blocks = [tx for tx in get_genesis_transactions(None) if tx.is_block]
        genesis_block = genesis_blocks[0]

        self.assertEqual(settings.GENESIS_TOKENS, sum([output.value for output in genesis_block.outputs]))
    def test_match_values(self):
        decode_resource = StubSite(NanoContractDecodeResource(self.manager))
        execute_resource = StubSite(NanoContractExecuteResource(self.manager))
        match_value_resource = StubSite(NanoContractMatchValueResource(self.manager))
        pushtx_resource = StubSite(PushTxResource(self.manager))
        signtx_resource = StubSite(SignTxResource(self.manager))
        decodetx_resource = StubSite(DecodeTxResource(self.manager))
        add_new_blocks(self.manager, 3)
        add_blocks_unlock_reward(self.manager)
        self.reactor.advance(3)
        # Options
        yield match_value_resource.options("wallet/nano_contracts/match_values")

        total_value = self.manager.get_tokens_issued_per_block(1)

        address1 = self.get_address(0)
        data_post = {
            'oracle_data_id': 'some_id',
            'total_value': total_value,
            'input_value': total_value,
            'min_timestamp': 1,
            'fallback_address': self.get_address(1),
            'values': [{
                'address': address1,
                'value': 300
            }]
        }
        # Error missing parameter
        response_error = yield match_value_resource.post("wallet/nano_contracts/match_value", data_post)
        data_error = response_error.json_value()
        self.assertFalse(data_error['success'])
        self.assertEqual(data_error['message'], 'Missing parameter: oracle_pubkey_hash')

        # create nano contract
        data_post['oracle_pubkey_hash'] = '6o6ul2c+sqAariBVW+CwNaSJb9w='
        response = yield match_value_resource.post("wallet/nano_contracts/match_value", data_post)
        data = response.json_value()
        self.assertTrue(data['success'])
        self.assertIsNotNone(data['hex_tx'])
        nano_contract_hex = data['hex_tx']

        # Error missing parameter
        response_error = yield decode_resource.get("wallet/nano_contracts/decode", {})
        data_error = response_error.json_value()
        self.assertFalse(data_error['success'])
        self.assertEqual(data_error['message'], 'Missing parameter: hex_tx')

        # Error invalid hex
        response_error2 = yield decode_resource.get("wallet/nano_contracts/decode", {b'hex_tx': b'123'})
        data_error2 = response_error2.json_value()
        self.assertFalse(data_error2['success'])

        # Error valid hex but invalid tx struct
        response_error3 = yield decode_resource.get("wallet/nano_contracts/decode", {b'hex_tx': b'1334'})
        data_error3 = response_error3.json_value()
        self.assertFalse(data_error3['success'])

        # decode
        genesis_output = [tx for tx in get_genesis_transactions(None) if tx.is_block][0].outputs[0]
        partial_tx = Transaction.create_from_struct(bytes.fromhex(nano_contract_hex))
        partial_tx.outputs.append(genesis_output)
        response_decode = yield decode_resource.get("wallet/nano_contracts/decode",
                                                    {b'hex_tx': bytes(partial_tx.get_struct().hex(), 'utf-8')})
        data = response_decode.json_value()
        self.assertTrue(data['success'])
        nano_contract = data['nano_contract']
        self.assertIsNotNone(nano_contract)
        self.assertEqual(nano_contract['type'], 'NanoContractMatchValues')
        self.assertEqual(len(data['other_inputs']), 0)
        self.assertEqual(len(data['my_inputs']), 1)
        self.assertEqual(len(data['outputs']), 1)
        self.assertEqual(data['outputs'][0], genesis_output.to_human_readable())

        address2 = self.get_address(2)
        data_put = {'new_values': [{'address': address2, 'value': 500}], 'input_value': total_value}
        # Error missing parameter
        response_error = yield match_value_resource.put("wallet/nano_contracts/match_value", data_put)
        data_error = response_error.json_value()
        self.assertFalse(data_error['success'])
        self.assertEqual(data_error['message'], 'Missing parameter: hex_tx')

        # update
        data_put['hex_tx'] = partial_tx.get_struct().hex()
        response = yield match_value_resource.put("wallet/nano_contracts/match_value", data_put)
        data = response.json_value()
        self.assertTrue(data['success'])
        self.assertIsNotNone(data['hex_tx'])

        # Error nano contract not found
        new_tx = Transaction.create_from_struct(partial_tx.get_struct())
        new_tx.outputs = []
        data_put['hex_tx'] = new_tx.get_struct().hex()
        response = yield match_value_resource.put("wallet/nano_contracts/match_value", data_put)
        data = response.json_value()
        self.assertFalse(data['success'])

        # Error missing parameter
        response_error = yield signtx_resource.get("wallet/sign_tx", {})
        data_error = response_error.json_value()
        self.assertFalse(data_error['success'])
        self.assertEqual(data_error['message'], 'Missing parameter: hex_tx')

        # Error wrong parameter value
        response_error2 = yield signtx_resource.get("wallet/sign_tx", {b'hex_tx': b'123', b'prepare_to_send': b'true'})
        data_error2 = response_error2.json_value()
        self.assertFalse(data_error2['success'])

        # Error valid hex but wrong tx struct value
        response_error3 = yield signtx_resource.get("wallet/sign_tx", {
            b'hex_tx': b'1334',
            b'prepare_to_send': b'true'
        })
        data_error3 = response_error3.json_value()
        self.assertFalse(data_error3['success'])

        # sign tx
        response = yield signtx_resource.get("wallet/sign_tx", {
            b'hex_tx': bytes(nano_contract_hex, 'utf-8'),
            b'prepare_to_send': b'true'
        })
        data = response.json_value()
        self.assertTrue(data['success'])
        nano_contract_hex = data['hex_tx']

        # sign tx without preparing
        response2 = yield signtx_resource.get("wallet/sign_tx", {b'hex_tx': bytes(nano_contract_hex, 'utf-8')})
        data2 = response2.json_value()
        self.assertTrue(data2['success'])
        self.assertIsNotNone(data2['hex_tx'])

        # propagate tx
        response = yield pushtx_resource.get("push_tx", {b'hex_tx': bytes(nano_contract_hex, 'utf-8')})
        data = response.json_value()
        self.assertTrue(data['success'])

        self.reactor.advance(3)

        # get tx hash
        response = yield decodetx_resource.get("decode_tx", {b'hex_tx': bytes(nano_contract_hex, 'utf-8')})
        data = response.json_value()
        self.assertTrue(data['success'])
        hash_hex = data['tx']['hash']

        # Options
        yield execute_resource.options("wallet/nano_contracts/execute")

        # Error no data
        response_error = yield execute_resource.post("wallet/nano_contracts/execute")
        data_error = response_error.json_value()
        self.assertFalse(data_error['success'])

        # Error missing parameter
        data = {
            'spent_tx_index': 0,
            'oracle_data': 'B3NvbWVfaWQEW/xjGQIBLA==',
            'oracle_signature': 'MEUCIGeqbmLRI6lrgXMy4sQEgK94F5m14oVL5Z7oLLVII7BUAiEApKTMuWlwvws574'
                                '+jtqKW5/AuH+ICD0u+HyMyHe0aric=',
            'oracle_pubkey': 'Awmloohhey8WhajdDURgvbk1z3JHX2vxDSBjz9uG9wEp',
            'address': address1,
            'value': total_value,
        }
        response_error2 = yield execute_resource.post("wallet/nano_contracts/execute", data)
        data_error2 = response_error2.json_value()
        self.assertFalse(data_error2['success'])
        self.assertEqual(data_error2['message'], 'Missing parameter: spent_tx_id')

        # execute nano contract
        data['spent_tx_id'] = hash_hex
        response = yield execute_resource.post("wallet/nano_contracts/execute", data)
        data = response.json_value()
        self.assertTrue(data['success'])
Esempio n. 26
0
    def test_get(self):
        # Mining new block
        response_mining = yield self.web_mining.get('mining')
        data_mining = response_mining.json_value()
        block_bytes = resolve_block_bytes(
            block_bytes=data_mining['block_bytes'])
        yield self.web_mining.post(
            'mining',
            {'block_bytes': base64.b64encode(block_bytes).decode('utf-8')})

        # Unlocking wallet
        self.manager.wallet.unlock(b'MYPASS')

        # Creating a valid transaction to be pushed to the network
        blocks = add_new_blocks(self.manager, 3, advance_clock=2)
        add_blocks_unlock_reward(self.manager)
        tx_id = blocks[0].hash
        output = blocks[0].outputs[0]
        script_type_out = parse_address_script(output.script)
        address = script_type_out.address
        private_key = self.manager.wallet.get_private_key(address)

        output_address = decode_address(self.get_address(0))
        value = self.manager.get_tokens_issued_per_block(1)
        o = TxOutput(value, create_output_script(output_address, None))
        i = TxInput(tx_id, 0, b'')
        tx = Transaction(inputs=[i], outputs=[o])

        data_to_sign = tx.get_sighash_all()
        public_key_bytes, signature_bytes = self.manager.wallet.get_input_aux_data(
            data_to_sign, private_key)
        i.data = P2PKH.create_input_data(public_key_bytes, signature_bytes)
        tx.inputs = [i]
        tx.timestamp = int(self.clock.seconds())
        tx.weight = self.manager.minimum_tx_weight(tx)
        tx.parents = self.manager.get_new_tx_parents(tx.timestamp)
        tx.resolve()

        response = yield self.web.get(
            'push_tx', {b'hex_tx': bytes(tx.get_struct().hex(), 'utf-8')})
        data = response.json_value()
        self.assertTrue(data['success'])

        # Sending token to random address without input
        data_json = {
            'outputs': [{
                'address': self.get_address(0),
                'value': 5
            }],
            'inputs': []
        }
        yield self.web_tokens.post('wallet/send_tokens', {'data': data_json})

        # modify tx so it will be a double spending, then rejected
        tx.weight += 0.1
        tx.resolve()
        response_success = yield self.web.get(
            'push_tx', {b'hex_tx': bytes(tx.get_struct().hex(), 'utf-8')})
        data_success = response_success.json_value()
        self.assertFalse(data_success['success'])

        # Invalid tx (don't have inputs)
        genesis_tx = get_genesis_transactions(self.manager.tx_storage)[1]
        response_genesis = yield self.web.get(
            'push_tx',
            {b'hex_tx': bytes(genesis_tx.get_struct().hex(), 'utf-8')})
        data_genesis = response_genesis.json_value()
        self.assertFalse(data_genesis['success'])

        # Invalid hex
        response_error1 = yield self.web.get('push_tx', {b'hex_tx': b'XXXX'})
        data_error1 = response_error1.json_value()

        self.assertFalse(data_error1['success'])

        # Invalid tx hex
        response_error2 = yield self.web.get('push_tx', {b'hex_tx': b'a12c'})
        data_error2 = response_error2.json_value()

        self.assertFalse(data_error2['success'])

        # Token creation tx
        tx2 = create_tokens(self.manager,
                            address,
                            mint_amount=100,
                            propagate=False)
        response = yield self.web.get(
            'push_tx', {b'hex_tx': bytes(tx2.get_struct().hex(), 'utf-8')})
        data = response.json_value()
        self.assertTrue(data['success'])