enable lbryum, the lightweight lbrycrd client

This commit is contained in:
Jimmy Kiselak 2016-02-19 00:44:08 -05:00
parent 4451978af6
commit bdb0ad4836
4 changed files with 201 additions and 32 deletions

View file

@ -4,6 +4,13 @@ from lbrynet.core.client.ClientRequest import ClientRequest
from lbrynet.core.Error import UnknownNameError, InvalidStreamInfoError, RequestCanceledError
from lbrynet.core.Error import InsufficientFundsError
from lbrynet.core.sqlite_helpers import rerun_if_locked
from lbryum import SimpleConfig, Network
from lbryum.bitcoin import COIN, TYPE_ADDRESS
from lbryum.wallet import WalletStorage, Wallet
from lbryum.commands import known_commands, Commands
from lbryum.transaction import Transaction
from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
from twisted.internet import threads, reactor, defer, task
from twisted.python.failure import Failure
@ -73,9 +80,6 @@ class LBRYWallet(object):
d.addCallback(lambda _: start_manage())
return d
def _start(self):
pass
@staticmethod
def log_stop_error(err):
log.error("An error occurred stopping the wallet: %s", err.getTraceback())
@ -95,9 +99,6 @@ class LBRYWallet(object):
d.addErrback(self.log_stop_error)
return d
def _stop(self):
pass
def manage(self):
log.info("Doing manage")
self.next_manage_call = None
@ -256,13 +257,15 @@ class LBRYWallet(object):
payments_to_send = {}
for address, points in self.queued_payments.items():
log.info("Should be sending %s points to %s", str(points), str(address))
payments_to_send[address] = float(points)
payments_to_send[address] = points
self.total_reserved_points -= points
self.wallet_balance -= points
del self.queued_payments[address]
if payments_to_send:
log.info("Creating a transaction with outputs %s", str(payments_to_send))
return self._do_send_many(payments_to_send)
d = self._do_send_many(payments_to_send)
d.addCallback(lambda txid: log.debug("Sent transaction %s", txid))
return d
log.info("There were no payments to send")
return defer.succeed(True)
@ -304,6 +307,8 @@ class LBRYWallet(object):
d = defer.succeed(True)
d.addCallback(lambda _: r_dict)
return d
elif 'error' in result:
log.warning("Got an error looking up a name: %s", result['error'])
return Failure(UnknownNameError(name))
def claim_name(self, name, sd_hash, amount, description=None, key_fee=None,
@ -483,7 +488,7 @@ class LBRYWallet(object):
def get_most_recent_blocktime(self):
return defer.fail(NotImplementedError())
def get_blockchain_info(self):
def get_best_blockhash(self):
return defer.fail(NotImplementedError())
def get_name_claims(self):
@ -516,6 +521,12 @@ class LBRYWallet(object):
def _get_balance_for_address(self, address):
return defer.fail(NotImplementedError())
def _start(self):
pass
def _stop(self):
pass
class LBRYcrdWallet(LBRYWallet):
def __init__(self, db_dir, wallet_dir=None, wallet_conf=None, lbrycrdd_path=None):
@ -588,8 +599,10 @@ class LBRYcrdWallet(LBRYWallet):
def get_block(self, blockhash):
return threads.deferToThread(self._get_block_rpc, blockhash)
def get_blockchain_info(self):
return threads.deferToThread(self._get_blockchain_info_rpc)
def get_best_blockhash(self):
d = threads.deferToThread(self._get_blockchain_info_rpc)
d.addCallback(lambda blockchain_info: blockchain_info['bestblockhash'])
return d
def get_nametrie(self):
return threads.deferToThread(self._get_nametrie_rpc)
@ -613,7 +626,8 @@ class LBRYcrdWallet(LBRYWallet):
return threads.deferToThread(self._get_balance_for_address_rpc, address)
def _do_send_many(self, payments_to_send):
return threads.deferToThread(self._do_send_many_rpc, payments_to_send)
outputs = {address: float(points) for address, points in payments_to_send.iteritems()}
return threads.deferToThread(self._do_send_many_rpc, outputs)
def _send_name_claim(self, name, value, amount):
return threads.deferToThread(self._send_name_claim_rpc, name, value, amount)
@ -701,8 +715,7 @@ class LBRYcrdWallet(LBRYWallet):
@_catch_connection_error
def _do_send_many_rpc(self, payments):
rpc_conn = self._get_rpc_conn()
rpc_conn.sendmany("", payments)
return True
return rpc_conn.sendmany("", payments)
@_catch_connection_error
def _get_info_rpc(self):
@ -813,6 +826,156 @@ class LBRYcrdWallet(LBRYWallet):
self.lbrycrdd.wait()
class LBRYumWallet(LBRYWallet):
def __init__(self, db_dir):
LBRYWallet.__init__(self, db_dir)
self.config = None
self.network = None
self.wallet = None
self.cmd_runner = None
self.first_run = False
def _start(self):
network_start_d = defer.Deferred()
def setup_network():
self.config = SimpleConfig()
self.network = Network(self.config)
return defer.succeed(self.network.start())
d = setup_network()
def check_started():
if self.network.is_connecting():
return False
start_check.stop()
if self.network.is_connected():
network_start_d.callback(True)
else:
network_start_d.errback(ValueError("Failed to connect to network."))
start_check = task.LoopingCall(check_started)
d.addCallback(lambda _: start_check.start(.1))
d.addCallback(lambda _: network_start_d)
d.addCallback(lambda _: self._load_wallet())
d.addCallback(lambda _: self._get_cmd_runner())
return d
def _stop(self):
d = defer.Deferred()
def check_stopped():
if self.network.is_connected():
return False
stop_check.stop()
self.network = None
d.callback(True)
self.network.stop()
stop_check = task.LoopingCall(check_stopped)
stop_check.start(.1)
return d
def _load_wallet(self):
def get_wallet():
path = self.config.get_wallet_path()
storage = WalletStorage(path)
wallet = Wallet(storage)
if not storage.file_exists:
self.first_run = True
seed = wallet.make_seed()
wallet.add_seed(seed, None)
wallet.create_master_keys(None)
wallet.create_main_account()
wallet.synchronize()
self.wallet = wallet
d = threads.deferToThread(get_wallet)
d.addCallback(self._save_wallet)
d.addCallback(lambda _: self.wallet.start_threads(self.network))
return d
def _get_cmd_runner(self):
self.cmd_runner = Commands(self.config, self.wallet, self.network)
def get_balance(self):
cmd = known_commands['getbalance']
func = getattr(self.cmd_runner, cmd.name)
d = threads.deferToThread(func)
d.addCallback(lambda result: result['unmatured'] if 'unmatured' in result else result['confirmed'])
d.addCallback(Decimal)
return d
def get_new_address(self):
d = threads.deferToThread(self.wallet.create_new_address)
d.addCallback(self._save_wallet)
return d
def get_block(self, blockhash):
return defer.fail(NotImplementedError())
def get_most_recent_blocktime(self):
header = self.network.get_header(self.network.get_local_height())
return defer.succeed(header['timestamp'])
def get_best_blockhash(self):
height = self.network.get_local_height()
d = threads.deferToThread(self.network.blockchain.read_header, height)
d.addCallback(lambda header: self.network.blockchain.hash_header(header))
return d
def get_name_claims(self):
return defer.fail(NotImplementedError())
def check_first_run(self):
return defer.succeed(self.first_run)
def _get_raw_tx(self, txid):
cmd = known_commands['gettransaction']
func = getattr(self.cmd_runner, cmd.name)
return threads.deferToThread(func, txid)
def _send_name_claim(self, name, val, amount):
return defer.fail(NotImplementedError())
def _get_decoded_tx(self, raw_tx):
return defer.fail(NotImplementedError())
def _send_abandon(self, txid, address, amount):
return defer.fail(NotImplementedError())
def _do_send_many(self, payments_to_send):
log.warning("Doing send many. payments to send: %s", str(payments_to_send))
outputs = [(TYPE_ADDRESS, address, int(amount*COIN)) for address, amount in payments_to_send.iteritems()]
d = threads.deferToThread(self.wallet.mktx, outputs, None, self.config)
d.addCallback(lambda tx: threads.deferToThread(self.wallet.sendtx, tx))
d.addCallback(self._save_wallet)
return d
def _get_value_for_name(self, name):
cmd = known_commands['getvalueforname']
func = getattr(self.cmd_runner, cmd.name)
return threads.deferToThread(func, name)
def get_claims_from_tx(self, txid):
cmd = known_commands['getclaimsfromtx']
func = getattr(self.cmd_runner, cmd.name)
return threads.deferToThread(func, txid)
def _get_balance_for_address(self, address):
return defer.succeed(Decimal(self.wallet.get_addr_received(address))/COIN)
def _save_wallet(self, val):
d = threads.deferToThread(self.wallet.storage.write)
d.addCallback(lambda _: val)
return d
class LBRYcrdAddressRequester(object):
implements([IRequestCreator])

View file

@ -7,6 +7,7 @@ import locale
import sys
from yapsy.PluginManager import PluginManager
from twisted.internet import defer, threads, stdio, task, error
from twisted.python.failure import Failure
# from lbrynet.core.client.AutoDownloader import AutoFetcher
from lbrynet.lbrynet_console.ConsoleControl import ConsoleControl
from lbrynet.lbrynet_console.LBRYSettings import LBRYSettings
@ -40,7 +41,7 @@ from lbrynet.lbrynet_console.ControlHandlers import ShowServerStatusFactory, Mod
from lbrynet.lbrynet_console.ControlHandlers import ModifyLBRYFileOptionsChooserFactory, StatusFactory
from lbrynet.lbrynet_console.ControlHandlers import PeerStatsAndSettingsChooserFactory, PublishFactory
from lbrynet.lbrynet_console.ControlHandlers import BlockchainStatusFactory
from lbrynet.core.LBRYcrdWallet import LBRYcrdWallet
from lbrynet.core.LBRYcrdWallet import LBRYcrdWallet, LBRYumWallet
log = logging.getLogger(__name__)
@ -253,8 +254,12 @@ class LBRYConsole():
d = defer.succeed(LBRYcrdWallet(self.db_dir, wallet_dir=self.lbrycrd_dir,
wallet_conf=self.lbrycrd_conf,
lbrycrdd_path=lbrycrdd_path))
else:
elif self.wallet_type == 'ptc':
d = defer.succeed(PTCWallet(self.db_dir))
elif self.wallet_type == 'lbryum':
d = defer.succeed(LBRYumWallet(self.db_dir))
else:
d = defer.fail(Failure(ValueError("Invalid wallet type")))
d.addCallback(lambda wallet: {"wallet": wallet})
return d
@ -372,14 +377,14 @@ class LBRYConsole():
ModifyLBRYFileOptionsChooserFactory(self.lbry_file_manager),
AddStreamFromHashFactory(self.sd_identifier, self.session, self.session.wallet),
StatusFactory(self, self.session.rate_limiter, self.lbry_file_manager,
self.session.blob_manager, self.session.wallet if self.wallet_type == 'lbrycrd' else None),
self.session.blob_manager, self.session.wallet if self.wallet_type in ['lbrycrd', 'lbryum'] else None),
# AutoFetcherStartFactory(self.autofetcher),
# AutoFetcherStopFactory(self.autofetcher),
# AutoFetcherStatusFactory(self.autofetcher),
ImmediateAnnounceAllBlobsFactory(self.session.blob_manager)
]
self.add_control_handlers(handlers)
if self.wallet_type == 'lbrycrd':
if self.wallet_type in ['lbrycrd', 'lbryum']:
lbrycrd_handlers = [
AddStreamFromLBRYcrdNameFactory(self.sd_identifier, self.session,
self.session.wallet),
@ -520,7 +525,7 @@ def launch_lbry_console():
help="The port on which the console will listen for DHT connections.",
type=int, default=4444)
parser.add_argument("--wallet_type",
help="Either 'lbrycrd' or 'ptc'.",
help="Either 'lbrycrd' or 'ptc' or 'lbryum'.",
type=str, default="lbrycrd")
parser.add_argument("--lbrycrd_wallet_dir",
help="The directory in which lbrycrd data will stored. Used if lbrycrdd is "

View file

@ -129,33 +129,33 @@ class FetcherDaemon(object):
def check_if_running(self):
if self.is_running:
msg = "Autofetcher is running\n"
msg += "Last block hash: " + str(self.lastbestblock['bestblockhash'])
msg += "Last block hash: " + str(self.lastbestblock)
else:
msg = "Autofetcher is not running"
return msg
def _get_names(self):
d = self.wallet.get_blockchain_info()
d.addCallback(lambda c: get_new_streams(c) if c != self.lastbestblock else [])
d = self.wallet.get_best_blockhash()
d.addCallback(lambda blockhash: get_new_streams(blockhash) if blockhash != self.lastbestblock else [])
def get_new_streams(c):
self.lastbestblock = c
d = self.wallet.get_block(c['bestblockhash'])
d.addCallback(lambda block: get_new_streams_in_txes(block['tx'], c))
def get_new_streams(blockhash):
self.lastbestblock = blockhash
d = self.wallet.get_block(blockhash)
d.addCallback(lambda block: get_new_streams_in_txes(block['tx'], blockhash))
return d
def get_new_streams_in_txes(txids, c):
def get_new_streams_in_txes(txids, blockhash):
ds = []
for t in txids:
d = self.wallet.get_claims_from_tx(t)
d.addCallback(get_new_streams_in_tx, t, c)
d.addCallback(get_new_streams_in_tx, t, blockhash)
ds.append(d)
d = defer.DeferredList(ds, consumeErrors=True)
d.addCallback(lambda result: [r[1] for r in result if r[0]])
d.addCallback(lambda stream_lists: [stream for streams in stream_lists for stream in streams])
return d
def get_new_streams_in_tx(claims, t, c):
def get_new_streams_in_tx(claims, t, blockhash):
#claims = self.wallet.get_claims_for_tx(t['txid'])
# if self.first_run:
# # claims = self.rpc_conn.getclaimsfortx("96aca2c60efded5806b7336430c5987b9092ffbea9c6ed444e3bf8e008993e11")
@ -173,7 +173,7 @@ class FetcherDaemon(object):
self.seen.append(claim)
else:
if self.verbose:
print "[" + str(datetime.now()) + "] No claims in block", c['bestblockhash']
print "[" + str(datetime.now()) + "] No claims in block", blockhash
return rtn
d.addCallback(lambda streams: defer.DeferredList(

View file

@ -8,7 +8,7 @@ from setuptools import setup, find_packages
setup(name='lbrynet',
version='0.0.4',
packages=find_packages(),
install_requires=['pycrypto', 'twisted', 'miniupnpc', 'yapsy', 'seccure', 'python-bitcoinrpc==0.1', 'txJSON-RPC', 'requests>=2.4.2', 'unqlite==0.2.0', 'leveldb'],
install_requires=['pycrypto', 'twisted', 'miniupnpc', 'yapsy', 'seccure', 'python-bitcoinrpc==0.1', 'txJSON-RPC', 'requests>=2.4.2', 'unqlite==0.2.0', 'leveldb', 'lbryum'],
entry_points={
'console_scripts': [
'lbrynet-console = lbrynet.lbrynet_console.LBRYConsole:launch_lbry_console',
@ -43,5 +43,6 @@ setup(name='lbrynet',
'lbrynet/lbrynet_gui/lbry.conf',
]
)
]
],
dependency_links=['https://github.com/lbryio/lbryum/tarball/master/#egg=lbryum'],
)