Beispiel #1
0
 def _rpc(self, method, args):
     """ Returns the result of an rpc call to the Bitcoin Core RPC API.
     If the connection is permanently or unrecognizably broken, None
     is returned *and the reactor is shutdown* (because we consider this
     condition unsafe - TODO possibly create a "freeze" mode that could
     restart when the connection is healed, but that is tricky).
     Should not be called directly from outside code.
     """
     if method not in ['importaddress', 'walletpassphrase', 'getaccount',
                       'gettransaction', 'getrawtransaction', 'gettxout',
                       'importmulti', 'listtransactions', 'getblockcount',
                       'scantxoutset']:
         log.debug('rpc: ' + method + " " + str(args))
     try:
         res = self.jsonRpc.call(method, args)
     except JsonRpcConnectionError as e:
         # note that we only raise this in case the connection error is
         # a refusal, or is unrecognized/unknown by our code. So this does
         # NOT happen in a reset or broken pipe scenario.
         # It is safest to simply shut down.
         # Why not sys.exit? sys.exit calls do *not* work inside delayedCalls
         # or deferreds in twisted, since a bare exception catch prevents
         # an actual system exit (i.e. SystemExit is caught as a
         # BareException type).
         log.error("Failure of RPC connection to Bitcoin Core. "
                   "Application cannot continue, shutting down.")
         stop_reactor()
         return None
     # note that JsonRpcError is not caught here; for some calls, we
     # have specific behaviour requirements depending on these errors,
     # so this is handled elsewhere in BitcoinCoreInterface.
     return res
 def dummy_taker_finished(res, fromtx=False,
                            waittime=0.0, txdetails=None):
     jmprint("Taker is finished")
     # check that the funds have arrived.
     mbal = mgr.daemon.services["wallet"].get_balance_by_mixdepth()[4]
     assert mbal == cj_amount
     jmprint("Funds: {} sats successfully arrived into mixdepth 4.".format(cj_amount))
     stop_reactor()
Beispiel #3
0
    def __init__(self, wallet):
        # The two principal member variables
        # are the blockchaininterface instance,
        # which is currently global in JM but
        # could be more flexible in future, and
        # the JM wallet object.
        self.bci = jm_single().bc_interface

        # main loop used to check for transactions, instantiated
        # after wallet is synced:
        self.monitor_loop = None
        self.wallet = wallet
        self.synced = False

        # used to flag RPC failure at construction of object:
        self.rpc_error = False

        # keep track of the quasi-real-time blockheight
        # (updated in main monitor loop)
        self.current_blockheight = None

        if self.bci is not None:
            if not self.update_blockheight():
                # this accounts for the unusual case
                # where the application started up with
                # a functioning blockchain interface, but
                # that bci is now failing when we are starting
                # the wallet service.
                jlog.error("Failure of RPC connection to Bitcoin Core in "
                           "wallet service startup. Application cannot "
                           "continue, shutting down.")
                self.rpc_error = ("Failure of RPC connection to Bitcoin "
                                  "Core in wallet service startup.")
                # no need to call stopService as it has not yet been started.
                stop_reactor()
        else:
            jlog.warning("No blockchain source available, " +
                         "wallet tools will not show correct balances.")

        # Dicts of registered callbacks, by type
        # and then by txinfo, for events
        # on transactions.
        self.callbacks = {
            "all": [],  # note: list, not dict
            "unconfirmed": {},
            "confirmed": {},
        }

        self.restart_callback = None

        # transactions we are actively monitoring,
        # i.e. they are not new but we want to track:
        self.active_txs = {}
        # to ensure transactions are only processed once:
        self.processed_txids = set()

        self.set_autofreeze_warning_cb()
Beispiel #4
0
 def critical_error():
     jlog.error("Critical error updating blockheight.")
     # this cleanup (a) closes the wallet, removing the lock
     # and (b) signals to clients that the service is no longer
     # in a running state, both of which can be useful
     # post reactor shutdown.
     self.stopService()
     stop_reactor()
     return False
 def try_to_create_my_orders(self):
     """Because wallet syncing is not synchronous(!),
     we cannot calculate our offers until we know the wallet
     contents, so poll until BlockchainInterface.wallet_synced
     is flagged as True. TODO: Use a deferred, probably.
     Note that create_my_orders() is defined by subclasses.
     """
     if not self.wallet_service.synced:
         return
     self.offerlist = self.create_my_orders()
     self.sync_wait_loop.stop()
     if not self.offerlist:
         jlog.info("Failed to create offers, giving up.")
         stop_reactor()
     jlog.info('offerlist={}'.format(self.offerlist))