This commit is contained in:
Lex Berezhny 2018-11-05 00:09:30 -05:00
parent 6ecfc94ff1
commit 90e06abba2
4 changed files with 167 additions and 33 deletions

View file

@ -296,40 +296,60 @@ class LbryWalletManager(BaseWalletManager):
'fee': dewies_to_lbc(tx.fee), 'fee': dewies_to_lbc(tx.fee),
'date': datetime.fromtimestamp(ts).isoformat(' ')[:-3] if tx.height > 0 else None, 'date': datetime.fromtimestamp(ts).isoformat(' ')[:-3] if tx.height > 0 else None,
'confirmations': headers.height - tx.height if tx.height > 0 else 0, 'confirmations': headers.height - tx.height if tx.height > 0 else 0,
'claim_info': [{ 'claim_info': [],
'address': txo.get_address(account.ledger), 'update_info': [],
'balance_delta': dewies_to_lbc(-txo.amount), 'support_info': [],
'amount': dewies_to_lbc(txo.amount), 'abandon_info': []
'claim_id': txo.claim_id,
'claim_name': txo.claim_name,
'nout': txo.position
} for txo in tx.my_claim_outputs],
'update_info': [{
'address': txo.get_address(account.ledger),
'balance_delta': dewies_to_lbc(-txo.amount),
'amount': dewies_to_lbc(txo.amount),
'claim_id': txo.claim_id,
'claim_name': txo.claim_name,
'nout': txo.position
} for txo in tx.my_update_outputs],
'support_info': [{
'address': txo.get_address(account.ledger),
'balance_delta': dewies_to_lbc(txo.amount),
'amount': dewies_to_lbc(txo.amount),
'claim_id': txo.claim_id,
'claim_name': txo.claim_name,
'is_tip': not txo.is_my_account,
'nout': txo.position
} for txo in tx.my_support_outputs],
'abandon_info': [{
'address': txo.get_address(account.ledger),
'balance_delta': dewies_to_lbc(-txo.amount),
'amount': dewies_to_lbc(txo.amount),
'claim_id': txo.claim_id,
'claim_name': txo.claim_name,
'nout': txo.position
} for txo in tx.my_abandon_outputs],
} }
for txo in tx.my_claim_outputs:
item['claim_info'].append({
'address': txo.get_address(account.ledger),
'balance_delta': dewies_to_lbc(-txo.amount),
'amount': dewies_to_lbc(txo.amount),
'claim_id': txo.claim_id,
'claim_name': txo.claim_name,
'nout': txo.position
})
for txo in tx.my_update_outputs:
item['update_info'].append({
'address': txo.get_address(account.ledger),
'balance_delta': dewies_to_lbc(-txo.amount),
'amount': dewies_to_lbc(txo.amount),
'claim_id': txo.claim_id,
'claim_name': txo.claim_name,
'nout': txo.position
})
for txo in tx.my_support_outputs:
is_tip = next(tx.my_inputs, None) is None
item['support_info'].append({
'address': txo.get_address(account.ledger),
'balance_delta': dewies_to_lbc(txo.amount if is_tip else -txo.amount),
'amount': dewies_to_lbc(txo.amount),
'claim_id': txo.claim_id,
'claim_name': txo.claim_name,
'is_tip': is_tip,
'nout': txo.position
})
for txo in tx.other_support_outputs:
is_tip = next(tx.my_inputs, None) is not None
item['support_info'].append({
'address': txo.get_address(account.ledger),
'balance_delta': dewies_to_lbc(-txo.amount),
'amount': dewies_to_lbc(txo.amount),
'claim_id': txo.claim_id,
'claim_name': txo.claim_name,
'is_tip': is_tip,
'nout': txo.position
})
for txo in tx.my_abandon_outputs:
item['abandon_info'].append({
'address': txo.get_address(account.ledger),
'balance_delta': dewies_to_lbc(-txo.amount),
'amount': dewies_to_lbc(txo.amount),
'claim_id': txo.claim_id,
'claim_name': txo.claim_name,
'nout': txo.position
})
if all([txi.txo_ref.txo is not None for txi in tx.inputs]): if all([txi.txo_ref.txo is not None for txi in tx.inputs]):
item['fee'] = dewies_to_lbc(tx.fee) item['fee'] = dewies_to_lbc(tx.fee)
else: else:

View file

@ -161,11 +161,22 @@ class Transaction(BaseTransaction):
def abandon(cls, claims: Iterable[Output], funding_accounts: Iterable[Account], change_account: Account): def abandon(cls, claims: Iterable[Output], funding_accounts: Iterable[Account], change_account: Account):
return cls.create([Input.spend(txo) for txo in claims], [], funding_accounts, change_account) return cls.create([Input.spend(txo) for txo in claims], [], funding_accounts, change_account)
@property
def my_inputs(self):
for txi in self.inputs:
if txi.txo_ref.txo is not None and txi.txo_ref.txo.is_my_account:
yield txi
def _filter_my_outputs(self, f): def _filter_my_outputs(self, f):
for txo in self.outputs: for txo in self.outputs:
if txo.is_my_account and f(txo.script): if txo.is_my_account and f(txo.script):
yield txo yield txo
def _filter_other_outputs(self, f):
for txo in self.outputs:
if not txo.is_my_account and f(txo.script):
yield txo
@property @property
def my_claim_outputs(self): def my_claim_outputs(self):
return self._filter_my_outputs(lambda s: s.is_claim_name) return self._filter_my_outputs(lambda s: s.is_claim_name)
@ -178,6 +189,10 @@ class Transaction(BaseTransaction):
def my_support_outputs(self): def my_support_outputs(self):
return self._filter_my_outputs(lambda s: s.is_support_claim) return self._filter_my_outputs(lambda s: s.is_support_claim)
@property
def other_support_outputs(self):
return self._filter_other_outputs(lambda s: s.is_support_claim)
@property @property
def my_abandon_outputs(self): def my_abandon_outputs(self):
for txi in self.inputs: for txi in self.inputs:

View file

@ -2,6 +2,7 @@ import json
import asyncio import asyncio
import tempfile import tempfile
import logging import logging
from functools import partial
from types import SimpleNamespace from types import SimpleNamespace
from twisted.trial import unittest from twisted.trial import unittest
@ -527,3 +528,100 @@ class PublishCommand(CommandTestCase):
'hovercraft', '1.0', file_path=file.name, 'hovercraft', '1.0', file_path=file.name,
channel_name='@baz', channel_account_id=[account1_id] channel_name='@baz', channel_account_id=[account1_id]
)) ))
class SupportingSupports(CommandTestCase):
VERBOSITY = logging.INFO
async def on_transaction_dict(self, tx):
await asyncio.wait([
self.ledger.on_transaction.where(
partial(lambda address, event: address == event.address, address)
) for address in self.get_all_addresses(tx)
])
@staticmethod
def get_all_addresses(tx):
addresses = set()
for txi in tx['inputs']:
addresses.add(txi['address'])
for txo in tx['outputs']:
addresses.add(txo['address'])
return list(addresses)
async def test_regular_supports_and_tip_supports(self):
# account2 will be used to send tips and supports to account1
account2_id = (await self.daemon.jsonrpc_account_create('second account'))['id']
# give account2 some spending LBC
result = await self.out(self.daemon.jsonrpc_wallet_send(
'5.0', await self.daemon.jsonrpc_address_unused(account2_id)
))
await self.confirm_tx(result['txid'])
# create the claim we'll be tipping and supporting
with tempfile.NamedTemporaryFile() as file:
file.write(b'hi!')
file.flush()
claim = await self.out(self.daemon.jsonrpc_publish(
'hovercraft', '1.0', file_path=file.name
))
self.assertTrue(claim['success'])
await self.confirm_tx(claim['tx']['txid'])
# account1 and account2 balances:
self.assertEqual('3.979769', await self.daemon.jsonrpc_account_balance())
self.assertEqual('5.0', await self.daemon.jsonrpc_account_balance(account2_id))
# send a tip to the claim using account2
tip = await self.out(
self.daemon.jsonrpc_claim_tip(claim['claim_id'], '1.0', account2_id)
)
await self.on_transaction_dict(tip)
await self.generate(1)
await self.on_transaction_dict(tip)
# tips don't affect balance so account1 balance is same but account2 balance went down
self.assertEqual('3.979769', await self.daemon.jsonrpc_account_balance())
self.assertEqual('3.9998585', await self.daemon.jsonrpc_account_balance(account2_id))
# verify that the incoming tip is marked correctly as is_tip=True in account1
txs = await self.out(self.daemon.jsonrpc_transaction_list())
self.assertEqual(len(txs[0]['support_info']), 1)
self.assertEqual(txs[0]['support_info'][0]['balance_delta'], '1.0')
self.assertEqual(txs[0]['support_info'][0]['claim_id'], claim['claim_id'])
self.assertEqual(txs[0]['support_info'][0]['is_tip'], True)
self.assertEqual(txs[0]['value'], '1.0')
# verify that the outgoing tip is marked correctly as is_tip=True in account2
txs2 = await self.out(
self.daemon.jsonrpc_transaction_list(account2_id)
)
self.assertEqual(len(txs2[0]['support_info']), 1)
self.assertEqual(txs2[0]['support_info'][0]['balance_delta'], '-1.0')
self.assertEqual(txs2[0]['support_info'][0]['claim_id'], claim['claim_id'])
self.assertEqual(txs2[0]['support_info'][0]['is_tip'], True)
self.assertEqual(txs2[0]['value'], '-1.0001415')
# send a support to the claim using account2
support = await self.out(
self.daemon.jsonrpc_claim_new_support('hovercraft', claim['claim_id'], '2.0', account2_id)
)
await self.on_transaction_dict(support)
await self.generate(1)
await self.on_transaction_dict(support)
# account2 balance went down ~2
self.assertEqual('3.979769', await self.daemon.jsonrpc_account_balance())
self.assertEqual('1.999717', await self.daemon.jsonrpc_account_balance(account2_id))
# verify that the outgoing support is marked correctly as is_tip=False in account2
txs2 = await self.out(
self.daemon.jsonrpc_transaction_list(account2_id)
)
self.assertEqual(len(txs2[0]['support_info']), 1)
self.assertEqual(txs2[0]['support_info'][0]['balance_delta'], '-2.0')
self.assertEqual(txs2[0]['support_info'][0]['claim_id'], claim['claim_id'])
self.assertEqual(txs2[0]['support_info'][0]['is_tip'], False)
self.assertEqual(txs2[0]['value'], '-0.0001415')

View file

@ -16,4 +16,5 @@ commands =
coverage run -p --source={envsitepackagesdir}/lbrynet -m twisted.trial --reactor=asyncio integration.cli coverage run -p --source={envsitepackagesdir}/lbrynet -m twisted.trial --reactor=asyncio integration.cli
coverage run -p --source={envsitepackagesdir}/lbrynet -m twisted.trial --reactor=asyncio integration.wallet.test_commands.AccountManagement coverage run -p --source={envsitepackagesdir}/lbrynet -m twisted.trial --reactor=asyncio integration.wallet.test_commands.AccountManagement
coverage run -p --source={envsitepackagesdir}/lbrynet -m twisted.trial --reactor=asyncio integration.wallet.test_commands.PublishCommand coverage run -p --source={envsitepackagesdir}/lbrynet -m twisted.trial --reactor=asyncio integration.wallet.test_commands.PublishCommand
coverage run -p --source={envsitepackagesdir}/lbrynet -m twisted.trial --reactor=asyncio integration.wallet.test_commands.SupportingSupports
coverage run -p --source={envsitepackagesdir}/lbrynet -m twisted.trial --reactor=asyncio integration.wallet.test_commands.EpicAdventuresOfChris45 coverage run -p --source={envsitepackagesdir}/lbrynet -m twisted.trial --reactor=asyncio integration.wallet.test_commands.EpicAdventuresOfChris45