Backends

Introduction

Backends are responsible to interact with cryptoassets network themselves. cryptoassets.core provides abstraction layer, so that you can separate your own application database and code from the underlying cryptoasset network API.

Backend base class

Base classes for cryptocurrency backend.

class cryptoassets.core.backend.base.CoinBackend[source]

Cryptocurrency management backend.

Provide necessecities for low-level cryptocurrency usage, like creating wallets, addresses, sending and receiving the currency.

Manage communications with the cryptocurrency network. The commucications can be done either by API service (block.io, blockchain.info) or raw protocol daemon (bitcoind).

The accounting amounts are in the integer amounts defined by the datbase models, e.g. satoshis for Bitcoin. If the backend supplies amounts in different unit, they most be converted forth and back by the backend. For the example, see cryptoassets.core.backend.blockio.

max_tracked_incoming_confirmations = None

If track_incoming_confirmations is set to true, this is how many confirmations we track for each incoming transactions until we consider it “closed”. Please note that this is API will most likely be changed in the future and this variable move to somewhere else. The variable is set by Configurator.setup_backend.

require_tracking_incoming_confirmations()[source]

Does this backend need to have some help to get incoming transaction confirmations tracked.

Some daemons and walletnotify methods, namely bitcoind, only notify us back the first occurence of an incoming transactions. If we want to receive further confirmations from the transaction, we need to manually poll the transactions where our confirmation threshold is not yet met.

Set this to true and the cryptoassets helper service will start a background job (cryptoassets.core.tools.confirmationupdate to keep receiving updates about the confirmations).

Returns:True or False
create_address(label)[source]

Create a new receiving address.

get_balances(addresses)[source]

Get balances on multiple addresses.

Return the address balance in the native format (backend converts to satoshis, etc.)

Yield:(address, balance) tuples
send(recipients)[source]

Broadcast outgoing transaction.

This is called by send/receive process.

Parameters:recipients – Dict of (address, internal amount)
get_backend_balance()[source]

Get full available hot wallet balance on the backend.

May take backend-specific optional kwargs like confirmations.

This is used for cryptoassets.core.tools.walletimport.

Returns:Decimal
list_received_transactions(extra)[source]

List all received transactions the backend is aware off.

Parameters:extra – Dict of backend-specific optional arguments like dict(confirmations=0).
Returns:Instance of cryptoassets.core.backend.base.ListTransactionsIterator.
create_transaction_updater(conflict_resolver, event_handler_registry)[source]

Create transaction updater to handle database writes with this backend.

Creates cryptoassets.core.backend.transactionupdater.TransactionUpdater instance. This TransactionUpdater is bound to this backend and provides safe APIs for doing broadcast and deposit updates.

setup_incoming_transactions(conflict_resolver, event_handler_registry)[source]

Configure the incoming transaction notifies from backend.

The configuration for wallet notifies have been given to the backend earlier in the backend constructor. Now we read this configure, resolve the walletnotify handler class and instiate it.

We’ll hook into backend by creating cryptoassets.core.backend.transactionupdater.TransactionUpdater instance, which gets the list of event_handler_registry it needs to call on upcoming transaction.

Parameters:
  • conflict_resolver – cryptoassets.core.utils.conflictresolver.ConflictResolver instance which is used to manage transactions
  • event_handler_registry
    param event_handler_registry:
     :py:class`cryptoassets.core.event.registry.EventHandlerRegistry` instance or None if we don’t want to notify of new transactions and just update the database
Returns:

Instance of cryptoassets.core.backend.base.IncomingTransactionRunnable

class cryptoassets.core.backend.base.ListTransactionsIterator(backend)[source]

Helper to iterate all transactions in the backend.

Because different backends iterate to different directions, we abstract this away.

Note

bitcoind iterates from index 0 with different batch sizes. block.io iterates from the latest transcation with fixed batch size of 100 and needs before txid parameter for the next batch.

fetch_next_txids()[source]

Get next batch of transactions.

txdata must be dict bitcoind-like format:

{
    confirmations: 0,
    txid: "xxx",
    "details": {
        "category": "received",
        "amount": Decimal(1),
        "address": "foobar"
    }
}
Returns:List of next (txid, txdata) paits to iterate or empty list if iterating is done.
class cryptoassets.core.backend.base.IncomingTransactionRunnable[source]

Backend specific thread/process taking care of accepting incoming transaction notifications from the network.

register_new_addresses()[source]

Backend has created new addresses and the incoming transcation monitor must know about them.

Some monitoring systems need to refresh after new addresses have been added to the pool.

Transaction updater

class cryptoassets.core.backend.transactionupdater.TransactionUpdater(conflict_resolver, backend, coin, event_handler_registry)[source]

TransactionUpdater write transactions updates from API/backend to the database.

TransactionUpdater uses cryptoassets.core.utils.conflictresolver.ConflictResolver database transaction helper when updating transactions. This gives us guarantees that updates having possible db transaction conflicts are gracefully handled.

The backend has hooked up some kind of wallet notify handler. The wallet notify handler uses TransactionUpdater to write updates of incoming transactoins to the database.

TransactionUpdater is also responsible to fire any notification handlers to signal the cryptoassets client application to handle new transactions.

TransactionUpdater is generally run inside cryptoassets.core.service.main.Server process, as this process is responsible for all incoming transaction updates. No web or other front end should try to make their own updates.

Parameters:
  • conflict_resolvercryptoassets.core.utils.conflictresolver.ConflictResolver
  • backendcryptoasets.core.backend.base.CoinBackend instance. TODO: To be removed - redundant with coin.
  • coincryptoasets.core.coin.registry.Coin instance
  • event_handler_registry – :py:class`cryptoassets.core.event.registry.EventHandlerRegistry` instance
last_wallet_notify = None

UTC timestamp when we got the last transaction notification

event_handler_registry = None

event_handler_registry registry we are going to inform about transaction status updates

stats = None

Diagnostics and bookkeeping statistics

verify_amount(transaction_type, txdata, address, amount)[source]

Check that transaction amounts have not somehow changed between confirmations.

It gets tricky here because bitcoind reports its internal stuff and has negative amounts for send transactions, versus what you see in blockchain and other services is only receiving outputs. We place some temporary workaround we hope to get rid of later.

update_network_transaction_confirmations(transaction_type, txid, txdata)[source]

Create or update NetworkTransaction in the database.

Ask the backend about updates for a network transaction. Any action is taken only if the confirmation count has changed since the last call.

For desposits, updates the confirmation count of inbound network deposit transaction. For all associated receiving addresses and transactions, confirmation and crediting check if performed, account balances updated and txupdate event fired.

For broadcasts, updates the confirmation count of outbound transactions.

Relevant event handlers are fired (cryptoassets.core.transactionupdater.TransactionUpdater.event_handler_registry)

Parameters:
  • transaction_type – “deposit” or “broadcast”. Note that we might have two ntx’s for one real network transaction, as we are sending bitcoins to ourselves.
  • txid – Network transaction hash
  • txdata – Transaction details, as given by the backend, translated to bitcoind format
Returns:

Tuple (new or existing network transaction id, fired txupdate events as a list)

handle_wallet_notify(txid)[source]

Handle incoming wallet notifications.

Fetch transaction info from the backend and update all receiving addresses we are managing within that transaction.

Parameters:txid – Network transaction hash