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 byConfigurator.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
-
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.
-
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_resolver –
cryptoassets.core.utils.conflictresolver.ConflictResolver
- backend –
cryptoasets.core.backend.base.CoinBackend
instance. TODO: To be removed - redundant withcoin
. - coin –
cryptoasets.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)
- conflict_resolver –