2018-07-12 21:05:24 +02:00
|
|
|
import tempfile
|
2018-07-30 01:15:06 +02:00
|
|
|
import logging
|
2018-07-31 15:48:57 +02:00
|
|
|
import asyncio
|
2018-07-12 21:44:07 +02:00
|
|
|
from types import SimpleNamespace
|
2018-07-05 04:16:02 +02:00
|
|
|
|
2018-07-31 15:48:57 +02:00
|
|
|
|
2018-07-06 07:17:20 +02:00
|
|
|
from twisted.internet import defer
|
2018-07-05 04:16:02 +02:00
|
|
|
from orchstr8.testcase import IntegrationTestCase, d2f
|
|
|
|
|
|
|
|
import lbryschema
|
|
|
|
lbryschema.BLOCKCHAIN_NAME = 'lbrycrd_regtest'
|
|
|
|
|
|
|
|
from lbrynet import conf as lbry_conf
|
2018-07-31 15:48:57 +02:00
|
|
|
from lbrynet.dht.node import Node
|
2018-07-05 04:16:02 +02:00
|
|
|
from lbrynet.daemon.Daemon import Daemon
|
|
|
|
from lbrynet.wallet.manager import LbryWalletManager
|
2018-07-31 15:48:57 +02:00
|
|
|
from lbrynet.daemon.Components import WalletComponent, DHTComponent, HashAnnouncerComponent, ExchangeRateManagerComponent
|
|
|
|
from lbrynet.daemon.Components import REFLECTOR_COMPONENT, HASH_ANNOUNCER_COMPONENT, EXCHANGE_RATE_MANAGER_COMPONENT
|
|
|
|
from lbrynet.daemon.Components import UPNP_COMPONENT
|
2018-07-22 03:12:33 +02:00
|
|
|
from lbrynet.daemon.ComponentManager import ComponentManager
|
2018-07-05 04:16:02 +02:00
|
|
|
|
|
|
|
|
2018-07-30 01:15:06 +02:00
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
2018-07-31 15:48:57 +02:00
|
|
|
class FakeDHT(DHTComponent):
|
2018-07-05 04:16:02 +02:00
|
|
|
|
2018-07-31 15:48:57 +02:00
|
|
|
def start(self):
|
|
|
|
self.dht_node = Node()
|
2018-07-12 05:18:59 +02:00
|
|
|
|
2018-07-12 19:23:18 +02:00
|
|
|
|
2018-07-31 15:48:57 +02:00
|
|
|
class FakeExchangeRateComponent(ExchangeRateManagerComponent):
|
2018-07-12 05:18:59 +02:00
|
|
|
|
2018-07-31 15:48:57 +02:00
|
|
|
def start(self):
|
|
|
|
self.exchange_rate_manager = SimpleNamespace()
|
2018-07-12 21:44:07 +02:00
|
|
|
|
2018-07-31 15:48:57 +02:00
|
|
|
def stop(self):
|
|
|
|
pass
|
2018-07-12 21:44:07 +02:00
|
|
|
|
|
|
|
|
2018-07-31 15:48:57 +02:00
|
|
|
class FakeHashAnnouncerComponent(HashAnnouncerComponent):
|
2018-07-12 21:44:07 +02:00
|
|
|
|
2018-07-31 15:48:57 +02:00
|
|
|
def start(self):
|
|
|
|
self.hash_announcer = SimpleNamespace()
|
2018-07-12 21:44:07 +02:00
|
|
|
|
2018-07-31 15:48:57 +02:00
|
|
|
def stop(self):
|
|
|
|
pass
|
2018-07-12 21:44:07 +02:00
|
|
|
|
|
|
|
|
2018-07-31 15:48:57 +02:00
|
|
|
class FakeAnalytics:
|
2018-07-12 21:44:07 +02:00
|
|
|
|
2018-07-31 15:48:57 +02:00
|
|
|
@property
|
|
|
|
def is_started(self):
|
|
|
|
return True
|
2018-07-12 21:05:24 +02:00
|
|
|
|
2018-07-31 15:48:57 +02:00
|
|
|
def send_new_channel(self):
|
|
|
|
pass
|
2018-07-12 21:05:24 +02:00
|
|
|
|
2018-07-31 15:48:57 +02:00
|
|
|
def shutdown(self):
|
|
|
|
pass
|
2018-07-12 21:44:07 +02:00
|
|
|
|
2018-07-31 15:48:57 +02:00
|
|
|
def send_claim_action(self, action):
|
|
|
|
pass
|
2018-07-12 05:18:59 +02:00
|
|
|
|
2018-07-05 04:16:02 +02:00
|
|
|
|
|
|
|
class CommandTestCase(IntegrationTestCase):
|
|
|
|
|
|
|
|
WALLET_MANAGER = LbryWalletManager
|
|
|
|
|
|
|
|
async def setUp(self):
|
|
|
|
await super().setUp()
|
|
|
|
|
2018-07-30 01:15:06 +02:00
|
|
|
if self.VERBOSE:
|
|
|
|
log.setLevel(logging.DEBUG)
|
|
|
|
logging.getLogger('lbrynet.core').setLevel(logging.DEBUG)
|
|
|
|
|
2018-07-05 04:16:02 +02:00
|
|
|
lbry_conf.settings = None
|
|
|
|
lbry_conf.initialize_settings(load_conf_file=False)
|
|
|
|
lbry_conf.settings['data_dir'] = self.stack.wallet.data_path
|
|
|
|
lbry_conf.settings['lbryum_wallet_dir'] = self.stack.wallet.data_path
|
|
|
|
lbry_conf.settings['download_directory'] = self.stack.wallet.data_path
|
|
|
|
lbry_conf.settings['use_upnp'] = False
|
2018-07-31 15:48:57 +02:00
|
|
|
lbry_conf.settings['reflect_uploads'] = False
|
2018-07-05 04:16:02 +02:00
|
|
|
lbry_conf.settings['blockchain_name'] = 'lbrycrd_regtest'
|
|
|
|
lbry_conf.settings['lbryum_servers'] = [('localhost', 50001)]
|
|
|
|
lbry_conf.settings['known_dht_nodes'] = []
|
|
|
|
lbry_conf.settings.node_id = None
|
|
|
|
|
|
|
|
await d2f(self.account.ensure_address_gap())
|
2018-07-15 21:50:32 +02:00
|
|
|
address = (await d2f(self.account.receiving.get_addresses(1, only_usable=True)))[0]
|
|
|
|
sendtxid = await self.blockchain.send_to_address(address, 10)
|
2018-07-30 01:15:06 +02:00
|
|
|
await self.confirm_tx(sendtxid)
|
2018-07-12 21:05:24 +02:00
|
|
|
|
2018-07-31 15:48:57 +02:00
|
|
|
def wallet_maker(component_manager):
|
|
|
|
self.wallet_component = WalletComponent(component_manager)
|
|
|
|
self.wallet_component.wallet = self.manager
|
|
|
|
self.wallet_component._running = True
|
|
|
|
return self.wallet_component
|
|
|
|
|
2018-07-22 03:12:33 +02:00
|
|
|
analytics_manager = FakeAnalytics()
|
2018-07-31 15:48:57 +02:00
|
|
|
self.daemon = Daemon(analytics_manager, ComponentManager(
|
|
|
|
analytics_manager,
|
|
|
|
skip_components=[
|
|
|
|
#UPNP_COMPONENT,
|
|
|
|
REFLECTOR_COMPONENT,
|
|
|
|
#HASH_ANNOUNCER_COMPONENT,
|
|
|
|
#EXCHANGE_RATE_MANAGER_COMPONENT
|
|
|
|
],
|
|
|
|
dht=FakeDHT, wallet=wallet_maker,
|
|
|
|
hash_announcer=FakeHashAnnouncerComponent,
|
|
|
|
exchange_rate_manager=FakeExchangeRateComponent
|
|
|
|
))
|
|
|
|
await d2f(self.daemon.setup())
|
|
|
|
self.manager.old_db = self.daemon.session.storage
|
|
|
|
|
|
|
|
async def tearDown(self):
|
|
|
|
await super().tearDown()
|
|
|
|
self.wallet_component._running = False
|
|
|
|
await d2f(self.daemon._shutdown())
|
2018-07-12 21:05:24 +02:00
|
|
|
|
2018-07-30 01:15:06 +02:00
|
|
|
async def confirm_tx(self, txid):
|
|
|
|
""" Wait for tx to be in mempool, then generate a block, wait for tx to be in a block. """
|
|
|
|
await self.on_transaction_id(txid)
|
|
|
|
await self.generate(1)
|
|
|
|
await self.on_transaction_id(txid)
|
2018-07-31 15:48:57 +02:00
|
|
|
|
|
|
|
def d_confirm_tx(self, txid):
|
|
|
|
return defer.Deferred.fromFuture(asyncio.ensure_future(self.confirm_tx(txid)))
|
2018-07-30 01:15:06 +02:00
|
|
|
|
|
|
|
async def generate(self, blocks):
|
|
|
|
""" Ask lbrycrd to generate some blocks and wait until ledger has them. """
|
|
|
|
await self.blockchain.generate(blocks)
|
|
|
|
await self.ledger.on_header.where(self.blockchain.is_expected_block)
|
2018-07-31 15:48:57 +02:00
|
|
|
|
|
|
|
def d_generate(self, blocks):
|
|
|
|
return defer.Deferred.fromFuture(asyncio.ensure_future(self.generate(blocks)))
|
2018-07-30 01:15:06 +02:00
|
|
|
|
2018-07-05 04:16:02 +02:00
|
|
|
|
2018-07-17 05:32:37 +02:00
|
|
|
class CommonWorkflowTests(CommandTestCase):
|
2018-07-05 04:16:02 +02:00
|
|
|
|
2018-07-17 05:32:37 +02:00
|
|
|
VERBOSE = False
|
2018-07-05 04:16:02 +02:00
|
|
|
|
2018-07-31 15:48:57 +02:00
|
|
|
@defer.inlineCallbacks
|
|
|
|
def test_user_creating_channel_and_publishing_file(self):
|
2018-07-06 07:17:20 +02:00
|
|
|
|
2018-07-17 05:32:37 +02:00
|
|
|
# User checks their balance.
|
2018-07-31 15:48:57 +02:00
|
|
|
result = yield self.daemon.jsonrpc_wallet_balance(include_unconfirmed=True)
|
2018-07-17 05:32:37 +02:00
|
|
|
self.assertEqual(result, 10)
|
2018-07-10 06:20:37 +02:00
|
|
|
|
2018-07-17 05:32:37 +02:00
|
|
|
# Decides to get a cool new channel.
|
2018-07-31 15:48:57 +02:00
|
|
|
channel = yield self.daemon.jsonrpc_channel_new('@spam', 1)
|
2018-07-17 05:32:37 +02:00
|
|
|
self.assertTrue(channel['success'])
|
2018-07-31 15:48:57 +02:00
|
|
|
yield self.d_confirm_tx(channel['txid'])
|
2018-07-10 06:20:37 +02:00
|
|
|
|
2018-07-30 01:15:06 +02:00
|
|
|
# Check balance, include utxos with less than 6 confirmations (unconfirmed).
|
2018-07-31 15:48:57 +02:00
|
|
|
result = yield self.daemon.jsonrpc_wallet_balance(include_unconfirmed=True)
|
2018-07-17 05:32:37 +02:00
|
|
|
self.assertEqual(result, 8.99)
|
2018-07-10 06:20:37 +02:00
|
|
|
|
2018-07-30 01:15:06 +02:00
|
|
|
# Check confirmed balance, only includes utxos with 6+ confirmations.
|
2018-07-31 15:48:57 +02:00
|
|
|
result = yield self.daemon.jsonrpc_wallet_balance()
|
2018-07-22 03:12:33 +02:00
|
|
|
self.assertEqual(result, 0)
|
|
|
|
|
|
|
|
# Add some confirmations (there is already 1 confirmation, so we add 5 to equal 6 total).
|
2018-07-31 15:48:57 +02:00
|
|
|
yield self.d_generate(5)
|
2018-07-22 03:12:33 +02:00
|
|
|
|
2018-07-30 01:15:06 +02:00
|
|
|
# Check balance again after some confirmations, should be correct again.
|
2018-07-31 15:48:57 +02:00
|
|
|
result = yield self.daemon.jsonrpc_wallet_balance()
|
2018-07-22 03:12:33 +02:00
|
|
|
self.assertEqual(result, 8.99)
|
|
|
|
|
2018-07-17 05:32:37 +02:00
|
|
|
# Now lets publish a hello world file to the channel.
|
2018-07-12 21:05:24 +02:00
|
|
|
with tempfile.NamedTemporaryFile() as file:
|
|
|
|
file.write(b'hello world!')
|
|
|
|
file.flush()
|
2018-07-31 15:48:57 +02:00
|
|
|
claim = yield self.daemon.jsonrpc_publish(
|
2018-07-30 01:15:06 +02:00
|
|
|
'hovercraft', 1, file_path=file.name, channel_name='@spam', channel_id=channel['claim_id']
|
2018-07-31 15:48:57 +02:00
|
|
|
)
|
2018-07-30 01:15:06 +02:00
|
|
|
self.assertTrue(claim['success'])
|
2018-07-31 15:48:57 +02:00
|
|
|
yield self.d_confirm_tx(claim['txid'])
|
2018-07-30 01:15:06 +02:00
|
|
|
|
|
|
|
# Check unconfirmed balance.
|
2018-07-31 15:48:57 +02:00
|
|
|
result = yield self.daemon.jsonrpc_wallet_balance(include_unconfirmed=True)
|
2018-07-30 01:15:06 +02:00
|
|
|
self.assertEqual(round(result, 2), 7.97)
|
|
|
|
|
|
|
|
# Resolve our claim.
|
2018-07-31 15:48:57 +02:00
|
|
|
response = yield self.ledger.resolve(0, 10, 'lbry://@spam/hovercraft')
|
2018-07-30 01:15:06 +02:00
|
|
|
self.assertIn('lbry://@spam/hovercraft', response)
|
|
|
|
|
|
|
|
# A few confirmations before trying to spend again.
|
2018-07-31 15:48:57 +02:00
|
|
|
yield self.d_generate(5)
|
2018-07-30 01:15:06 +02:00
|
|
|
|
|
|
|
# Verify confirmed balance.
|
2018-07-31 15:48:57 +02:00
|
|
|
result = yield self.daemon.jsonrpc_wallet_balance()
|
2018-07-30 01:15:06 +02:00
|
|
|
self.assertEqual(round(result, 2), 7.97)
|
|
|
|
|
|
|
|
# Now lets update an existing claim.
|
|
|
|
with tempfile.NamedTemporaryFile() as file:
|
|
|
|
file.write(b'hello world x2!')
|
|
|
|
file.flush()
|
2018-07-31 15:48:57 +02:00
|
|
|
claim = yield self.daemon.jsonrpc_publish(
|
2018-07-30 01:15:06 +02:00
|
|
|
'hovercraft', 1, file_path=file.name, channel_name='@spam', channel_id=channel['claim_id']
|
2018-07-31 15:48:57 +02:00
|
|
|
)
|
2018-07-30 01:15:06 +02:00
|
|
|
self.assertTrue(claim['success'])
|
2018-07-31 15:48:57 +02:00
|
|
|
yield self.d_confirm_tx(claim['txid'])
|