Beispiel #1
0
    def send_inventory(self, serialized_transaction) -> msg_getdata:
        message = msg_inv()
        inventory = CInv()
        inventory.type = MSG_TX
        hash_transaction = Hash(serialized_transaction)
        inventory.hash = hash_transaction
        message.inv.append(inventory)

        timeout = time() + NODE_COMMUNICATION_TIMEOUT

        while time() < timeout:
            node = self.connect()
            if node is None:
                self.reset_connection()
                continue

            if not self.send_message(message):
                self.terminate(node)
                continue

            messages = self.capture_messages([
                msg_getdata,
            ])
            if not messages:
                self.terminate(node)
                continue

            logger.info('[%s] Node responded correctly.', node)
            return messages[0]
Beispiel #2
0
    def publish(self, raw_transaction: str) -> Optional[str]:
        '''
        Method for publishing transactions.

        Args:
            raw_transaction (str): hex string containing signed transaction

        Returns:
            str, None: transaction address or None if transaction wasn't published

        Example:
            >>> raw_transaction = '010000000184a38a4e8743964249665fb241fbd3...35b'
            >>> network.publish(raw_transaction)
            70eefae0106b787e592e12914e4040efd8181dd299fa314d8f66da6a95cd1cfe
        '''
        for attempt in range(1, TRANSACTION_BROADCASTING_MAX_ATTEMPTS + 1):
            transaction_address = self.broadcast_transaction(raw_transaction)

            if transaction_address is None:
                logger.warning(
                    'Transaction broadcast attempt no. %s failed. Retrying...',
                    attempt)
                continue

            logger.info(
                'Transaction broadcast is successful. End of broadcasting process.'
            )
            return transaction_address

        logger.warning(
            '%s attempts to broadcast transaction failed. Broadcasting process terminates!',
            TRANSACTION_BROADCASTING_MAX_ATTEMPTS)
Beispiel #3
0
 def audit_contract(self, tx_address: str) -> EthereumContract:
     tx_dict = self.get_transaction(tx_address)
     if not tx_dict:
         logger.info(
             f'Cannot audit contract, no such transaction: {tx_address} ({self.name})'
         )
         return
     return EthereumContract(self, tx_dict)
Beispiel #4
0
    def sign(transaction: Transaction, private_key: str) -> Transaction:
        '''
        Signing the transaction.

        Args:
            transaction (Transaction): Ethereum unsigned transaction object
            private_key (str): private key

        Returns:
            Transaction: Ethereum signed transaction object
        '''
        transaction.sign(private_key)
        logger.info('Transaction signed')
        return transaction
Beispiel #5
0
    def publish(self, raw_transaction: str):
        for attempt in range(1, TRANSACTION_BROADCASTING_MAX_ATTEMPTS + 1):
            transaction_address = self.broadcast_transaction(raw_transaction)

            if transaction_address is None:
                logger.warning(
                    'Transaction broadcast attempt no. %s failed. Retrying...',
                    attempt)
                continue

            logger.info(
                'Transaction broadcast is successful. End of broadcasting process.'
            )
            return transaction_address

        logger.warning(
            '%s attempts to broadcast transaction failed. Broadcasting process terminates!',
            TRANSACTION_BROADCASTING_MAX_ATTEMPTS)
Beispiel #6
0
    def get_utxo(cls, address, amount):
        if cls.is_test_network() and cls.name != 'test-bitcoin':
            logger.info('%s: network is not supported to get utxo', cls.name)
            raise NotImplementedError

        network = cls.symbols[0].lower()
        if network == 'doge' or cls.name == 'test-bitcoin':
            return get_utxo_from_api(network,
                                     address,
                                     amount,
                                     use_blockcypher=True,
                                     testnet=cls.is_test_network())

        if network not in CRYPTOID_SUPPORTED_NETWORKS:
            logger.info('%s: network is not supported', network)
            raise NotImplementedError

        api_key = os.getenv('CRYPTOID_API_KEY')
        return get_utxo_from_api(network,
                                 address,
                                 amount,
                                 cryptoid_api_key=api_key)
Beispiel #7
0
    def send_inventory(self, serialized_transaction) -> Optional[msg_getdata]:
        '''
        Sends inventory message with given serialized transaction to connected node.

        Returns:
            msg_getdata, None: get data request or None if something went wrong

        Note:
            This method is used by `broadcast_transaction` to inform connected node about existence
            of the new transaction.
        '''
        message = msg_inv()
        inventory = CInv()
        inventory.type = MSG_TX
        hash_transaction = Hash(serialized_transaction)
        inventory.hash = hash_transaction
        message.inv.append(inventory)

        timeout = time() + NODE_COMMUNICATION_TIMEOUT

        while time() < timeout:
            node = self.connect()
            if node is None:
                self.reset_connection()
                continue

            if not self.send_message(message):
                self.terminate(node)
                continue

            messages = self.capture_messages([
                msg_getdata,
            ])
            if not messages:
                self.terminate(node)
                continue

            logger.info('[%s] Node responded correctly.', node)
            return messages[0]
Beispiel #8
0
    def audit_contract(self, tx_address: str) -> EthereumContract:
        '''
        Getting details about an Atomic Swap contract.

        Args:
            transaction_address (str): hex string with transaction address which created an Atomic Swap

        Returns:
            EthereumContract: contract object

        Example:
            >>> from clove.network import EthereumTestnet
            >>> network = EthereumTestnet()
            >>> network.audit_contract('0xfe4bcc1b522923ca6f8dc2721134c7d8636b34737aeafb2d6d0868d73e226891')
            <clove.network.ethereum.contract.EthereumContract at 0x7f7b3fec3e80>
        '''
        tx_dict = self.get_transaction(tx_address)
        if not tx_dict:
            logger.info(
                f'Cannot audit contract, no such transaction: {tx_address} ({self.name})'
            )
            return
        return EthereumContract(self, tx_dict)
Beispiel #9
0
    def broadcast_transaction(self, raw_transaction: str) -> Optional[str]:
        '''
        Sends given transaction to connected node.

        Args:
            raw_transaction (str): hex string containing signed transaction

        Returns:
            str, None: transaction address if transaction was sent, None otherwise.
        '''
        deserialized_transaction = self.deserialize_raw_transaction(
            raw_transaction)
        serialized_transaction = deserialized_transaction.serialize()

        get_data = self.send_inventory(serialized_transaction)
        if not get_data:
            logger.debug(
                ConnectionProblem(
                    'Clove could not get connected with any of the nodes for too long.'
                ))
            self.reset_connection()
            return

        node = self.get_current_node()

        if all(el.hash != Hash(serialized_transaction) for el in get_data.inv):
            logger.debug(
                UnexpectedResponseFromNode(
                    'Node did not ask for our transaction', node))
            self.reset_connection()
            return

        message = msg_tx()
        message.tx = deserialized_transaction

        if not self.send_message(message, 20):
            return

        logger.info('[%s] Looking for reject message.', node)
        messages = self.capture_messages([
            msg_reject,
        ],
                                         timeout=REJECT_TIMEOUT,
                                         buf_size=8192,
                                         ignore_empty=True)
        if messages:
            logger.debug(TransactionRejected(messages[0], node))
            self.reset_connection()
            return
        logger.info('[%s] Reject message not found.', node)

        transaction_address = b2lx(deserialized_transaction.GetHash())
        logger.info('[%s] Transaction %s has just been sent.', node,
                    transaction_address)
        return transaction_address
Beispiel #10
0
        with open(file_path, 'r') as f:
            file_lines = f.readlines()
            file_length = len(file_lines)

            indices = [
                i for i, line in enumerate(file_lines)
                if 'Class with all the necessary' in line
            ]
            if not indices:
                logger.error("Couldn't find network class in %s", filename)
                continue
            try:
                count = search_checklocktime(file_lines, indices[0], filename)
                if count is None:
                    fork.append(filename)
                    logger.info("%s network is forked and cannot be searched",
                                filename)
                    continue
                elif count == 0:
                    failed.append(filename)
                    logger.error(
                        "Couldn't find OP_CHECKLOCKTIMEVERIFY in %s network",
                        filename)
                    continue
                found.append(filename)
                logger.info("Found %s in %s network", count, filename)

            except (HTTPError, URLError):
                failed.append(filename)
                logger.error("HTTP error in %s network", filename)
                continue
Beispiel #11
0
 def sign(transaction: Transaction, private_key: str) -> Transaction:
     transaction.sign(private_key)
     logger.info('Transaction signed')
     return transaction