better customization during testing

This commit is contained in:
Lex Berezhny 2018-06-14 15:17:59 -04:00
parent 52846a3b24
commit 4dee59a49d
8 changed files with 25 additions and 82 deletions

View file

@ -8,7 +8,7 @@ from torba.coin.bitcoinsegwit import MainNetLedger
class TestKeyChain(unittest.TestCase):
def setUp(self):
self.ledger = MainNetLedger(db=':memory:')
self.ledger = MainNetLedger(db=MainNetLedger.database_class(':memory:'))
return self.ledger.db.start()
@defer.inlineCallbacks
@ -68,7 +68,7 @@ class TestKeyChain(unittest.TestCase):
class TestAccount(unittest.TestCase):
def setUp(self):
self.ledger = MainNetLedger(db=':memory:')
self.ledger = MainNetLedger(db=MainNetLedger.database_class(':memory:'))
return self.ledger.db.start()
@defer.inlineCallbacks

View file

@ -19,7 +19,7 @@ def search(*args, **kwargs):
class BaseSelectionTestCase(unittest.TestCase):
def setUp(self):
self.ledger = MainNetLedger(db=':memory:')
self.ledger = MainNetLedger(db=MainNetLedger.database_class(':memory:'))
return self.ledger.db.start()
def estimates(self, *args):

View file

@ -33,7 +33,7 @@ class MockNetwork:
class TestSynchronization(unittest.TestCase):
def setUp(self):
self.ledger = MainNetLedger(db=':memory:')
self.ledger = MainNetLedger(db=MainNetLedger.database_class(':memory:'))
return self.ledger.db.start()
@defer.inlineCallbacks

View file

@ -4,8 +4,6 @@ from twisted.internet import defer
from torba.coin.bitcoinsegwit import MainNetLedger as ledger_class
from torba.constants import CENT, COIN
from torba.manager import WalletManager
from torba.wallet import Wallet
NULL_HASH = b'\x00'*32
@ -32,7 +30,7 @@ def get_transaction(txo=None):
class TestSizeAndFeeEstimation(unittest.TestCase):
def setUp(self):
self.ledger = ledger_class(db=':memory:')
self.ledger = ledger_class(db=ledger_class.database_class(':memory:'))
return self.ledger.db.start()
def io_fee(self, io):
@ -145,7 +143,7 @@ class TestTransactionSerialization(unittest.TestCase):
class TestTransactionSigning(unittest.TestCase):
def setUp(self):
self.ledger = ledger_class(db=':memory:')
self.ledger = ledger_class(db=ledger_class.database_class(':memory:'))
return self.ledger.db.start()
@defer.inlineCallbacks

View file

@ -55,9 +55,9 @@ class BaseLedger(six.with_metaclass(LedgerRegistry)):
def __init__(self, config=None, db=None, network=None):
self.config = config or {}
self.db = self.database_class(
db or os.path.join(self.path, "blockchain.db")
) # type: basedatabase.BaseSQLiteWalletStorage
self.db = db or self.database_class(
os.path.join(self.path, "blockchain.db")
) # type: basedatabase.BaseDatabase
self.network = network or self.network_class(self)
self.network.on_header.listen(self.process_header)
self.network.on_status.listen(self.process_status)

View file

@ -300,7 +300,7 @@ class BaseTransaction:
@classmethod
@defer.inlineCallbacks
def pay(cls, outputs, funding_accounts, change_account):
# type: (List[BaseOutput], List[torba.baseaccount.BaseAccount], torba.baseaccount.BaseAccount) -> BaseTransaction
# type: (List[BaseOutput], List[torba.baseaccount.BaseAccount], torba.baseaccount.BaseAccount) -> defer.Deferred
""" Efficiently spend utxos from funding_accounts to cover the new outputs. """
tx = cls().add_outputs(outputs)

View file

@ -1,23 +1,20 @@
import functools
from typing import List, Dict, Type
from twisted.internet import defer
from torba.baseledger import BaseLedger, LedgerRegistry
from torba.basetransaction import BaseTransaction, NULL_HASH
from torba.coinselection import CoinSelector
from torba.constants import COIN
from torba.wallet import Wallet, WalletStorage
class WalletManager(object):
def __init__(self, wallets=None, ledgers=None):
self.wallets = wallets or [] # type: List[Wallet]
self.ledgers = ledgers or {} # type: Dict[Type[BaseLedger],BaseLedger]
# type: (List[Wallet], Dict[Type[BaseLedger],BaseLedger]) -> None
self.wallets = wallets or []
self.ledgers = ledgers or {}
self.running = False
@classmethod
def from_config(cls, config):
def from_config(cls, config): # type: (Dict) -> WalletManager
wallets = []
manager = cls(wallets)
for coin_id, ledger_config in config.get('ledgers', {}).items():
@ -32,20 +29,23 @@ class WalletManager(object):
ledger_class = LedgerRegistry.get_ledger_class(ledger_id)
ledger = self.ledgers.get(ledger_class)
if ledger is None:
ledger = self.create_ledger(ledger_class, ledger_config or {})
ledger = ledger_class(ledger_config or {})
self.ledgers[ledger_class] = ledger
return ledger
def create_ledger(self, ledger_class, config):
return ledger_class(config)
def create_wallet(self, path):
storage = WalletStorage(path)
wallet = Wallet.from_storage(storage, self)
self.wallets.append(wallet)
return wallet
@defer.inlineCallbacks
def get_balance(self):
balances = {}
for ledger in self.ledgers:
for account in self.get_accounts(ledger.coin_class):
balances.setdefault(ledger.coin_class.name, 0)
balances[ledger.coin_class.name] += yield account.get_balance()
for ledger in self.ledgers.values():
for account in ledger.accounts:
balances.setdefault(ledger.get_id(), 0)
balances[ledger.get_id()] += yield account.get_balance()
defer.returnValue(balances)
@property
@ -64,22 +64,6 @@ class WalletManager(object):
if account.coin.__class__ is coin_class:
yield account
def get_accounts_view(self, coin_class):
return AccountsView(
functools.partial(self.get_accounts, coin_class)
)
def create_wallet(self, path, coin_class):
storage = WalletStorage(path)
wallet = Wallet.from_storage(storage, self)
self.wallets.append(wallet)
self.create_account(wallet, coin_class)
return wallet
def create_account(self, wallet, coin_class):
ledger = self.get_or_create_ledger(coin_class.get_id())
return wallet.generate_account(ledger)
@defer.inlineCallbacks
def start(self):
self.running = True
@ -93,42 +77,3 @@ class WalletManager(object):
l.stop() for l in self.ledgers.values()
])
self.running = False
def send_amount_to_address(self, amount, address):
amount = int(amount * COIN)
account = self.default_account
ledger = account.ledger
tx_class = ledger.transaction_class # type: BaseTransaction
in_class, out_class = tx_class.input_class, tx_class.output_class
estimators = [
txo.get_estimator(ledger) for txo in account.get_unspent_utxos()
]
tx_class.create()
cost_of_output = ledger.get_input_output_fee(
out_class.pay_pubkey_hash(COIN, NULL_HASH)
)
selector = CoinSelector(estimators, amount, cost_of_output)
spendables = selector.select()
if not spendables:
raise ValueError('Not enough funds to cover this transaction.')
outputs = [
out_class.pay_pubkey_hash(amount, coin.address_to_hash160(address))
]
spent_sum = sum(s.effective_amount for s in spendables)
if spent_sum > amount:
change_address = account.get_least_used_change_address()
change_hash160 = coin.address_to_hash160(change_address)
outputs.append(out_class.pay_pubkey_hash(spent_sum - amount, change_hash160))
tx = tx_class() \
.add_inputs([s.txi for s in spendables]) \
.add_outputs(outputs) \
.sign(account)
return tx

View file

@ -1,6 +1,6 @@
[tox]
#envlist = py{27,36}-unit,py36-integration-{torba.coin.bitcoincash,torba.coin.bitcoinsegwit}
envlist = py36-unit,py36-integration-torba.coin.bitcoinsegwit
envlist = py{27,36}-unit,py36-integration-torba.coin.bitcoinsegwit
[testenv]
deps =