From 82cdc8c86ab3ae0516281eb64d8500570aa19747 Mon Sep 17 00:00:00 2001 From: Lex Berezhny Date: Mon, 8 Jun 2020 23:06:16 -0400 Subject: [PATCH] back ported partial signed supports feature --- lbry/lbry/extras/daemon/Daemon.py | 5 ++-- lbry/lbry/wallet/script.py | 23 +++++++++++++++++++ lbry/lbry/wallet/transaction.py | 21 +++++++++++++---- lbry/tests/integration/test_claim_commands.py | 8 +++++++ 4 files changed, 51 insertions(+), 6 deletions(-) diff --git a/lbry/lbry/extras/daemon/Daemon.py b/lbry/lbry/extras/daemon/Daemon.py index afb94ee59..156da485f 100644 --- a/lbry/lbry/extras/daemon/Daemon.py +++ b/lbry/lbry/extras/daemon/Daemon.py @@ -3277,7 +3277,7 @@ class Daemon(metaclass=JSONRPCServerType): @requires(WALLET_COMPONENT) async def jsonrpc_support_create( self, claim_id, amount, tip=False, account_id=None, wallet_id=None, funding_account_ids=None, - preview=False, blocking=False): + channel_id=None, preview=False, blocking=False): """ Create a support or a tip for name claim. @@ -3301,6 +3301,7 @@ class Daemon(metaclass=JSONRPCServerType): wallet = self.wallet_manager.get_wallet_or_default(wallet_id) assert not wallet.is_locked, "Cannot spend funds with locked wallet, unlock first." funding_accounts = wallet.get_accounts_or_all(funding_account_ids) + channel = await self.get_channel_or_none(wallet, None, channel_id, None, for_signing=True) amount = self.get_dewies_or_error("amount", amount) claim = await self.ledger.get_claim_by_claim_id(wallet.accounts, claim_id) claim_address = claim.get_address(self.ledger) @@ -3309,7 +3310,7 @@ class Daemon(metaclass=JSONRPCServerType): claim_address = await account.receiving.get_or_create_usable_address() tx = await Transaction.support( - claim.claim_name, claim_id, amount, claim_address, funding_accounts, funding_accounts[0] + claim.claim_name, claim_id, amount, claim_address, funding_accounts, funding_accounts[0], channel ) if not preview: diff --git a/lbry/lbry/wallet/script.py b/lbry/lbry/wallet/script.py index 02f1bfda0..88931db45 100644 --- a/lbry/lbry/wallet/script.py +++ b/lbry/lbry/wallet/script.py @@ -42,6 +42,17 @@ class OutputScript(BaseOutputScript): SUPPORT_CLAIM_OPCODES + BaseOutputScript.PAY_SCRIPT_HASH.opcodes )) + SUPPORT_CLAIM_DATA_OPCODES = ( + OP_SUPPORT_CLAIM, PUSH_SINGLE('claim_name'), PUSH_SINGLE('claim_id'), PUSH_SINGLE('support'), + OP_2DROP, OP_2DROP + ) + SUPPORT_CLAIM_DATA_PUBKEY = Template('support_claim+data+pay_pubkey_hash', ( + SUPPORT_CLAIM_DATA_OPCODES + BaseOutputScript.PAY_PUBKEY_HASH.opcodes + )) + SUPPORT_CLAIM_DATA_SCRIPT = Template('support_claim+data+pay_script_hash', ( + SUPPORT_CLAIM_DATA_OPCODES + BaseOutputScript.PAY_SCRIPT_HASH.opcodes + )) + UPDATE_CLAIM_OPCODES = ( OP_UPDATE_CLAIM, PUSH_SINGLE('claim_name'), PUSH_SINGLE('claim_id'), PUSH_SINGLE('claim'), OP_2DROP, OP_2DROP @@ -73,6 +84,8 @@ class OutputScript(BaseOutputScript): CLAIM_NAME_SCRIPT, SUPPORT_CLAIM_PUBKEY, SUPPORT_CLAIM_SCRIPT, + SUPPORT_CLAIM_DATA_PUBKEY, + SUPPORT_CLAIM_DATA_SCRIPT, UPDATE_CLAIM_PUBKEY, UPDATE_CLAIM_SCRIPT, SELL_CLAIM, SELL_SCRIPT, @@ -104,6 +117,16 @@ class OutputScript(BaseOutputScript): 'pubkey_hash': pubkey_hash }) + @classmethod + def pay_support_data_pubkey_hash( + cls, claim_name: bytes, claim_id: bytes, support: bytes, pubkey_hash: bytes): + return cls(template=cls.SUPPORT_CLAIM_DATA_PUBKEY, values={ + 'claim_name': claim_name, + 'claim_id': claim_id, + 'support': support, + 'pubkey_hash': pubkey_hash + }) + @classmethod def sell_script(cls, price): return cls(template=cls.SELL_SCRIPT, values={ diff --git a/lbry/lbry/wallet/transaction.py b/lbry/lbry/wallet/transaction.py index fba9d3506..8ef407a60 100644 --- a/lbry/lbry/wallet/transaction.py +++ b/lbry/lbry/wallet/transaction.py @@ -194,6 +194,14 @@ class Output(BaseOutput): script = cls.script_class.pay_support_pubkey_hash(claim_name.encode(), unhexlify(claim_id)[::-1], pubkey_hash) return cls(amount, script) + @classmethod + def pay_support_data_pubkey_hash( + cls, amount: int, claim_name: str, claim_id: str, support: bytes, pubkey_hash: bytes) -> 'Output': + script = OutputScript.pay_support_data_pubkey_hash( + claim_name.encode(), unhexlify(claim_id)[::-1], support, pubkey_hash + ) + return cls(amount, script) + @classmethod def add_purchase_data(cls, purchase: Purchase) -> 'Output': script = cls.script_class.return_data(purchase) @@ -287,11 +295,16 @@ class Transaction(BaseTransaction): @classmethod def support(cls, claim_name: str, claim_id: str, amount: int, holding_address: str, - funding_accounts: List[Account], change_account: Account): + funding_accounts: List[Account], change_account: Account, signing_channel: Output = None): ledger, wallet = cls.ensure_all_have_same_ledger_and_wallet(funding_accounts, change_account) - support_output = Output.pay_support_pubkey_hash( - amount, claim_name, claim_id, ledger.address_to_hash160(holding_address) - ) + if signing_channel: + support_output = Output.pay_support_data_pubkey_hash( + amount, claim_name, claim_id, b'beef', ledger.address_to_hash160(holding_address) + ) + else: + support_output = Output.pay_support_pubkey_hash( + amount, claim_name, claim_id, ledger.address_to_hash160(holding_address) + ) return cls.create([], [support_output], funding_accounts, change_account) @classmethod diff --git a/lbry/tests/integration/test_claim_commands.py b/lbry/tests/integration/test_claim_commands.py index fbb08fd19..06db27e4d 100644 --- a/lbry/tests/integration/test_claim_commands.py +++ b/lbry/tests/integration/test_claim_commands.py @@ -1211,3 +1211,11 @@ class SupportCommands(CommandTestCase): self.assertFalse(txs2[0]['support_info'][0]['is_tip']) self.assertEqual(txs2[0]['value'], '0.0') self.assertEqual(txs2[0]['fee'], '-0.0001415') + + async def test_signed_supports(self): + channel_id = self.get_claim_id(await self.channel_create()) + stream_id = self.get_claim_id(await self.stream_create()) + await self.support_create(stream_id, '0.3', channel_id=channel_id) + supports = await self.daemon.jsonrpc_support_list() + self.assertEqual(1, len(supports['items'])) + self.assertEqual(supports['items'][0].script.values['support'], b'beef')