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 UnknownNameError, InvalidStreamInfoError, RequestCanceledError
from lbrynet.core.Error import InsufficientFundsError from lbrynet.core.Error import InsufficientFundsError
from lbrynet.core.sqlite_helpers import rerun_if_locked 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 bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
from twisted.internet import threads, reactor, defer, task from twisted.internet import threads, reactor, defer, task
from twisted.python.failure import Failure from twisted.python.failure import Failure
@ -73,9 +80,6 @@ class LBRYWallet(object):
d.addCallback(lambda _: start_manage()) d.addCallback(lambda _: start_manage())
return d return d
def _start(self):
pass
@staticmethod @staticmethod
def log_stop_error(err): def log_stop_error(err):
log.error("An error occurred stopping the wallet: %s", err.getTraceback()) log.error("An error occurred stopping the wallet: %s", err.getTraceback())
@ -95,9 +99,6 @@ class LBRYWallet(object):
d.addErrback(self.log_stop_error) d.addErrback(self.log_stop_error)
return d return d
def _stop(self):
pass
def manage(self): def manage(self):
log.info("Doing manage") log.info("Doing manage")
self.next_manage_call = None self.next_manage_call = None
@ -256,13 +257,15 @@ class LBRYWallet(object):
payments_to_send = {} payments_to_send = {}
for address, points in self.queued_payments.items(): for address, points in self.queued_payments.items():
log.info("Should be sending %s points to %s", str(points), str(address)) 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.total_reserved_points -= points
self.wallet_balance -= points self.wallet_balance -= points
del self.queued_payments[address] del self.queued_payments[address]
if payments_to_send: if payments_to_send:
log.info("Creating a transaction with outputs %s", str(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") log.info("There were no payments to send")
return defer.succeed(True) return defer.succeed(True)
@ -304,6 +307,8 @@ class LBRYWallet(object):
d = defer.succeed(True) d = defer.succeed(True)
d.addCallback(lambda _: r_dict) d.addCallback(lambda _: r_dict)
return d return d
elif 'error' in result:
log.warning("Got an error looking up a name: %s", result['error'])
return Failure(UnknownNameError(name)) return Failure(UnknownNameError(name))
def claim_name(self, name, sd_hash, amount, description=None, key_fee=None, 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): def get_most_recent_blocktime(self):
return defer.fail(NotImplementedError()) return defer.fail(NotImplementedError())
def get_blockchain_info(self): def get_best_blockhash(self):
return defer.fail(NotImplementedError()) return defer.fail(NotImplementedError())
def get_name_claims(self): def get_name_claims(self):
@ -516,6 +521,12 @@ class LBRYWallet(object):
def _get_balance_for_address(self, address): def _get_balance_for_address(self, address):
return defer.fail(NotImplementedError()) return defer.fail(NotImplementedError())
def _start(self):
pass
def _stop(self):
pass
class LBRYcrdWallet(LBRYWallet): class LBRYcrdWallet(LBRYWallet):
def __init__(self, db_dir, wallet_dir=None, wallet_conf=None, lbrycrdd_path=None): 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): def get_block(self, blockhash):
return threads.deferToThread(self._get_block_rpc, blockhash) return threads.deferToThread(self._get_block_rpc, blockhash)
def get_blockchain_info(self): def get_best_blockhash(self):
return threads.deferToThread(self._get_blockchain_info_rpc) d = threads.deferToThread(self._get_blockchain_info_rpc)
d.addCallback(lambda blockchain_info: blockchain_info['bestblockhash'])
return d
def get_nametrie(self): def get_nametrie(self):
return threads.deferToThread(self._get_nametrie_rpc) return threads.deferToThread(self._get_nametrie_rpc)
@ -613,7 +626,8 @@ class LBRYcrdWallet(LBRYWallet):
return threads.deferToThread(self._get_balance_for_address_rpc, address) return threads.deferToThread(self._get_balance_for_address_rpc, address)
def _do_send_many(self, payments_to_send): 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): def _send_name_claim(self, name, value, amount):
return threads.deferToThread(self._send_name_claim_rpc, name, value, amount) return threads.deferToThread(self._send_name_claim_rpc, name, value, amount)
@ -701,8 +715,7 @@ class LBRYcrdWallet(LBRYWallet):
@_catch_connection_error @_catch_connection_error
def _do_send_many_rpc(self, payments): def _do_send_many_rpc(self, payments):
rpc_conn = self._get_rpc_conn() rpc_conn = self._get_rpc_conn()
rpc_conn.sendmany("", payments) return rpc_conn.sendmany("", payments)
return True
@_catch_connection_error @_catch_connection_error
def _get_info_rpc(self): def _get_info_rpc(self):
@ -813,6 +826,156 @@ class LBRYcrdWallet(LBRYWallet):
self.lbrycrdd.wait() 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): class LBRYcrdAddressRequester(object):
implements([IRequestCreator]) implements([IRequestCreator])

View file

@ -7,6 +7,7 @@ import locale
import sys import sys
from yapsy.PluginManager import PluginManager from yapsy.PluginManager import PluginManager
from twisted.internet import defer, threads, stdio, task, error from twisted.internet import defer, threads, stdio, task, error
from twisted.python.failure import Failure
# from lbrynet.core.client.AutoDownloader import AutoFetcher # from lbrynet.core.client.AutoDownloader import AutoFetcher
from lbrynet.lbrynet_console.ConsoleControl import ConsoleControl from lbrynet.lbrynet_console.ConsoleControl import ConsoleControl
from lbrynet.lbrynet_console.LBRYSettings import LBRYSettings 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 ModifyLBRYFileOptionsChooserFactory, StatusFactory
from lbrynet.lbrynet_console.ControlHandlers import PeerStatsAndSettingsChooserFactory, PublishFactory from lbrynet.lbrynet_console.ControlHandlers import PeerStatsAndSettingsChooserFactory, PublishFactory
from lbrynet.lbrynet_console.ControlHandlers import BlockchainStatusFactory from lbrynet.lbrynet_console.ControlHandlers import BlockchainStatusFactory
from lbrynet.core.LBRYcrdWallet import LBRYcrdWallet from lbrynet.core.LBRYcrdWallet import LBRYcrdWallet, LBRYumWallet
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -253,8 +254,12 @@ class LBRYConsole():
d = defer.succeed(LBRYcrdWallet(self.db_dir, wallet_dir=self.lbrycrd_dir, d = defer.succeed(LBRYcrdWallet(self.db_dir, wallet_dir=self.lbrycrd_dir,
wallet_conf=self.lbrycrd_conf, wallet_conf=self.lbrycrd_conf,
lbrycrdd_path=lbrycrdd_path)) lbrycrdd_path=lbrycrdd_path))
else: elif self.wallet_type == 'ptc':
d = defer.succeed(PTCWallet(self.db_dir)) 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}) d.addCallback(lambda wallet: {"wallet": wallet})
return d return d
@ -372,14 +377,14 @@ class LBRYConsole():
ModifyLBRYFileOptionsChooserFactory(self.lbry_file_manager), ModifyLBRYFileOptionsChooserFactory(self.lbry_file_manager),
AddStreamFromHashFactory(self.sd_identifier, self.session, self.session.wallet), AddStreamFromHashFactory(self.sd_identifier, self.session, self.session.wallet),
StatusFactory(self, self.session.rate_limiter, self.lbry_file_manager, 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), # AutoFetcherStartFactory(self.autofetcher),
# AutoFetcherStopFactory(self.autofetcher), # AutoFetcherStopFactory(self.autofetcher),
# AutoFetcherStatusFactory(self.autofetcher), # AutoFetcherStatusFactory(self.autofetcher),
ImmediateAnnounceAllBlobsFactory(self.session.blob_manager) ImmediateAnnounceAllBlobsFactory(self.session.blob_manager)
] ]
self.add_control_handlers(handlers) self.add_control_handlers(handlers)
if self.wallet_type == 'lbrycrd': if self.wallet_type in ['lbrycrd', 'lbryum']:
lbrycrd_handlers = [ lbrycrd_handlers = [
AddStreamFromLBRYcrdNameFactory(self.sd_identifier, self.session, AddStreamFromLBRYcrdNameFactory(self.sd_identifier, self.session,
self.session.wallet), self.session.wallet),
@ -520,7 +525,7 @@ def launch_lbry_console():
help="The port on which the console will listen for DHT connections.", help="The port on which the console will listen for DHT connections.",
type=int, default=4444) type=int, default=4444)
parser.add_argument("--wallet_type", parser.add_argument("--wallet_type",
help="Either 'lbrycrd' or 'ptc'.", help="Either 'lbrycrd' or 'ptc' or 'lbryum'.",
type=str, default="lbrycrd") type=str, default="lbrycrd")
parser.add_argument("--lbrycrd_wallet_dir", parser.add_argument("--lbrycrd_wallet_dir",
help="The directory in which lbrycrd data will stored. Used if lbrycrdd is " 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): def check_if_running(self):
if self.is_running: if self.is_running:
msg = "Autofetcher is running\n" msg = "Autofetcher is running\n"
msg += "Last block hash: " + str(self.lastbestblock['bestblockhash']) msg += "Last block hash: " + str(self.lastbestblock)
else: else:
msg = "Autofetcher is not running" msg = "Autofetcher is not running"
return msg return msg
def _get_names(self): def _get_names(self):
d = self.wallet.get_blockchain_info() d = self.wallet.get_best_blockhash()
d.addCallback(lambda c: get_new_streams(c) if c != self.lastbestblock else []) d.addCallback(lambda blockhash: get_new_streams(blockhash) if blockhash != self.lastbestblock else [])
def get_new_streams(c): def get_new_streams(blockhash):
self.lastbestblock = c self.lastbestblock = blockhash
d = self.wallet.get_block(c['bestblockhash']) d = self.wallet.get_block(blockhash)
d.addCallback(lambda block: get_new_streams_in_txes(block['tx'], c)) d.addCallback(lambda block: get_new_streams_in_txes(block['tx'], blockhash))
return d return d
def get_new_streams_in_txes(txids, c): def get_new_streams_in_txes(txids, blockhash):
ds = [] ds = []
for t in txids: for t in txids:
d = self.wallet.get_claims_from_tx(t) 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) ds.append(d)
d = defer.DeferredList(ds, consumeErrors=True) d = defer.DeferredList(ds, consumeErrors=True)
d.addCallback(lambda result: [r[1] for r in result if r[0]]) 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]) d.addCallback(lambda stream_lists: [stream for streams in stream_lists for stream in streams])
return d 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']) #claims = self.wallet.get_claims_for_tx(t['txid'])
# if self.first_run: # if self.first_run:
# # claims = self.rpc_conn.getclaimsfortx("96aca2c60efded5806b7336430c5987b9092ffbea9c6ed444e3bf8e008993e11") # # claims = self.rpc_conn.getclaimsfortx("96aca2c60efded5806b7336430c5987b9092ffbea9c6ed444e3bf8e008993e11")
@ -173,7 +173,7 @@ class FetcherDaemon(object):
self.seen.append(claim) self.seen.append(claim)
else: else:
if self.verbose: if self.verbose:
print "[" + str(datetime.now()) + "] No claims in block", c['bestblockhash'] print "[" + str(datetime.now()) + "] No claims in block", blockhash
return rtn return rtn
d.addCallback(lambda streams: defer.DeferredList( d.addCallback(lambda streams: defer.DeferredList(

View file

@ -8,7 +8,7 @@ from setuptools import setup, find_packages
setup(name='lbrynet', setup(name='lbrynet',
version='0.0.4', version='0.0.4',
packages=find_packages(), 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={ entry_points={
'console_scripts': [ 'console_scripts': [
'lbrynet-console = lbrynet.lbrynet_console.LBRYConsole:launch_lbry_console', 'lbrynet-console = lbrynet.lbrynet_console.LBRYConsole:launch_lbry_console',
@ -43,5 +43,6 @@ setup(name='lbrynet',
'lbrynet/lbrynet_gui/lbry.conf', 'lbrynet/lbrynet_gui/lbry.conf',
] ]
) )
] ],
dependency_links=['https://github.com/lbryio/lbryum/tarball/master/#egg=lbryum'],
) )