broadcast_transaction

Function

def broadcast_transaction(account, tx, auto_gas=True, attempts=18):
    tx_hash = None
    tx['chainId'] = 369
    if not auto_gas:
        tx = apply_estimated_gas(tx)
        tx = apply_median_gas_strategy(tx)
        tx = apply_gas_multiplier(tx)
    logging.debug("Broadcasting TX: {}".format(tx))
    _attempts = attempts
    while _attempts > 0:
        try:
            signed_tx = web3.eth.account.sign_transaction(tx, private_key=account.key)
            tx_hash = web3.eth.send_raw_transaction(signed_tx.rawTransaction)
        except Exception as e:
            logging.debug(e)
            if "insufficient funds" in str(e):
                logging.error("Not enough gas for this TX: {}".format(tx))
                return False
            elif "nonce too low" in str(e):
                tx['nonce'] = get_nonce(account.address)
                continue
            elif "could not replace existing tx" in str(e):
                tx['gas'] = int(tx['gas'] * 1.0369)
                if 'maxFeePerGas' in tx:
                    tx['maxFeePerGas'] = int(tx['maxFeePerGas'] * 1.0369)
                if 'maxPriorityFeePerGas' in tx:
                    tx['maxPriorityFeePerGas'] = int(tx['maxPriorityFeePerGas'] * 1.0369)
                continue
            elif "already known" in str(e):
                pass
            else:
                _attempts -= 1
                time.sleep(1)
        if not tx_hash:
            _attempts -= 1
            time.sleep(1)
            if _attempts != 0:
                logging.debug("Rebroadcasting TX ... {}".format(attempts - _attempts))
            continue
        else:
            try:
                tx_receipt = web3.eth.wait_for_transaction_receipt(tx_hash, timeout=10)
            except Exception as e:
                logging.debug(e)
                _attempts -= 1
                time.sleep(1)
                if _attempts != 0:
                    logging.debug("Rebroadcasting TX ... {}".format(attempts - _attempts))
            else:
                logging.debug("Confirmed TX: {}".format(tx_receipt))
                return tx_receipt
    return False

Description

  • Set chain ID to 369 (PulseChain)

  • Check if auto gas is not enabled

    • Apply the estimated gas required to the transaction

    • Apply median gas strategy to the transaction

    • Apply the gas multiplier to the transaction

  • Set max attempts

  • Sign the transaction

  • Send the signed raw transaction to the RPC server and get back a transaction hash

  • If it fails check for a few errors and act accordingly

    • If nonce is too low then get the current nonce and try again

    • If unable to replace the current transaction/nonce then increase the gas by 3.69% and try again

    • If the transaction is already known then proceed as normal

  • If no transaction hash was set, it’s because this function was previously interrupted, we loop and check when the transaction/nonce has been confirmed or else start from the beginning and rebroadcast the transaction

  • Wait for the transaction receipt for 10 seconds, it will throw an exception if it’s still pending

    • If there are attempts remaining then rebroadcast the transaction and check again

  • Return the transaction receipt if everything is ok