Skip to content

Commit

Permalink
Convert --amount, --amount_everything to generic amount (int or str) …
Browse files Browse the repository at this point in the history
…in daemon.py.

Unpack the generic amount in transaction.py and account.py.
Eliminate separate "everything" keyword args.
  • Loading branch information
moodyjon committed Jun 8, 2022
1 parent 67579f0 commit 04c7bdf
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 88 deletions.
97 changes: 38 additions & 59 deletions lbry/extras/daemon/daemon.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import tracemalloc
from decimal import Decimal
from urllib.parse import urlencode, quote
from typing import Callable, Optional, List
from typing import Callable, Optional, List, Union
from binascii import hexlify, unhexlify
from traceback import format_exc
from functools import wraps, partial
Expand All @@ -25,7 +25,7 @@
Wallet, ENCRYPT_ON_DISK, SingleKey, HierarchicalDeterministic,
Transaction, Output, Input, Account, database
)
from lbry.wallet.dewies import dewies_to_lbc, lbc_to_dewies, dict_values_to_lbc
from lbry.wallet.dewies import dewies_to_lbc, lbc_to_dewies, dict_values_to_lbc, AMOUNT_EVERYTHING
from lbry.wallet.constants import TXO_TYPES, CLAIM_TYPE_NAMES
from lbry.wallet.bip32 import PrivateKey
from lbry.crypto.base58 import Base58
Expand Down Expand Up @@ -1569,34 +1569,17 @@ async def jsonrpc_wallet_send(
account = wallet.get_account_or_default(change_account_id)
accounts = wallet.get_accounts_or_all(funding_account_ids)

amount = self.get_dewies_or_error('amount', amount, everything=amount_everything)
amount = self.get_amount_or_error('amount', amount, everything=amount_everything)

if addresses is None:
raise InputValueIsNoneError('addresses')
if addresses and not isinstance(addresses, list):
addresses = [addresses]

outputs = []
for address in addresses:
self.valid_address_or_error(address, allow_script_address=True)
if self.ledger.is_pubkey_address(address):
outputs.append(
Output.pay_pubkey_hash(
amount, self.ledger.address_to_hash160(address)
)
)
elif self.ledger.is_script_address(address):
outputs.append(
Output.pay_script_hash(
amount, self.ledger.address_to_hash160(address)
)
)
else:
raise ValueError(f"Unsupported address: '{address}'") # TODO: use error from lbry.error

tx = await Transaction.create(
[], outputs, accounts, account, everything=amount_everything
)
tx = await Transaction.pay(amount, addresses, accounts, account)
if not preview:
await self.broadcast_or_release(tx, blocking)
self.component_manager.loop.create_task(self.analytics_manager.send_credits_sent())
Expand Down Expand Up @@ -1868,7 +1851,7 @@ def jsonrpc_account_fund(self, to_account=None, from_account=None, amount=None,
wallet = self.wallet_manager.get_wallet_or_default(wallet_id)
to_account = wallet.get_account_or_default(to_account)
from_account = wallet.get_account_or_default(from_account)
amount = self.get_dewies_or_error('amount', amount, everything=everything,
amount = self.get_amount_or_error('amount', amount, everything=everything,
default_value=0, argument_everything='everything')
if not isinstance(outputs, int):
# TODO: use error from lbry.error
Expand All @@ -1877,8 +1860,7 @@ def jsonrpc_account_fund(self, to_account=None, from_account=None, amount=None,
# TODO: use error from lbry.error
raise ValueError("Using --everything along with --outputs is not supported.")
return from_account.fund(
to_account=to_account, amount=amount, everything=everything,
outputs=outputs, broadcast=broadcast
to_account=to_account, amount=amount, outputs=outputs, broadcast=broadcast
)

@requires("wallet")
Expand Down Expand Up @@ -2770,7 +2752,7 @@ async def jsonrpc_channel_create(
account = wallet.get_account_or_default(account_id)
funding_accounts = wallet.get_accounts_or_all(funding_account_ids)
self.valid_channel_name_or_error(name)
amount = self.get_dewies_or_error('bid', bid, positive_value=True, everything=bid_everything)
amount = self.get_amount_or_error('bid', bid, positive_value=True, everything=bid_everything)
claim_address = await self.get_receiving_address(claim_address, account)

existing_channels = await self.ledger.get_channels(accounts=wallet.accounts, claim_name=name)
Expand All @@ -2785,8 +2767,7 @@ async def jsonrpc_channel_create(
claim = Claim()
claim.channel.update(**kwargs)
tx = await Transaction.claim_create(
name, claim, amount, claim_address, funding_accounts, funding_accounts[0],
everything=bid_everything
name, claim, amount, claim_address, funding_accounts, funding_accounts[0]
)
txo = tx.outputs[0]
txo.set_channel_private_key(
Expand Down Expand Up @@ -2925,7 +2906,7 @@ async def jsonrpc_channel_update(
f"A claim with id '{claim_id}' was found but it is not a channel."
)

amount = self.get_dewies_or_error('bid', bid, positive_value=True, everything=bid_everything,
amount = self.get_amount_or_error('bid', bid, positive_value=True, everything=bid_everything,
default_value=old_txo.amount)

if claim_address is not None:
Expand All @@ -2940,8 +2921,7 @@ async def jsonrpc_channel_update(
claim = Claim.from_bytes(old_txo.claim.to_bytes())
claim.channel.update(**kwargs)
tx = await Transaction.claim_update(
old_txo, claim, amount, claim_address, funding_accounts, funding_accounts[0],
everything=bid_everything
old_txo, claim, amount, claim_address, funding_accounts, funding_accounts[0]
)
new_txo = tx.outputs[0]

Expand Down Expand Up @@ -3364,7 +3344,7 @@ async def jsonrpc_stream_repost(self, name, bid=None, claim_id=None, allow_dupli
account = wallet.get_account_or_default(account_id)
funding_accounts = wallet.get_accounts_or_all(funding_account_ids)
channel = await self.get_channel_or_none(wallet, channel_account_id, channel_id, channel_name, for_signing=True)
amount = self.get_dewies_or_error('bid', bid, positive_value=True, everything=bid_everything)
amount = self.get_amount_or_error('bid', bid, positive_value=True, everything=bid_everything)
claim_address = await self.get_receiving_address(claim_address, account)
claims = await account.get_claims(claim_name=name)
if len(claims) > 0:
Expand All @@ -3383,8 +3363,7 @@ async def jsonrpc_stream_repost(self, name, bid=None, claim_id=None, allow_dupli
claim = Claim()
claim.repost.reference.claim_id = claim_id
tx = await Transaction.claim_create(
name, claim, amount, claim_address, funding_accounts, funding_accounts[0], channel,
everything=bid_everything
name, claim, amount, claim_address, funding_accounts, funding_accounts[0], channel
)
new_txo = tx.outputs[0]

Expand Down Expand Up @@ -3519,7 +3498,7 @@ async def jsonrpc_stream_create(
account = wallet.get_account_or_default(account_id)
funding_accounts = wallet.get_accounts_or_all(funding_account_ids)
channel = await self.get_channel_or_none(wallet, channel_account_id, channel_id, channel_name, for_signing=True)
amount = self.get_dewies_or_error('bid', bid, positive_value=True, everything=bid_everything)
amount = self.get_amount_or_error('bid', bid, positive_value=True, everything=bid_everything)
claim_address = await self.get_receiving_address(claim_address, account)
kwargs['fee_address'] = self.get_fee_address(kwargs, claim_address)

Expand All @@ -3544,8 +3523,7 @@ async def jsonrpc_stream_create(
else:
claim.stream.update(**kwargs)
tx = await Transaction.claim_create(
name, claim, amount, claim_address, funding_accounts, funding_accounts[0], channel,
everything=bid_everything
name, claim, amount, claim_address, funding_accounts, funding_accounts[0], channel
)
new_txo = tx.outputs[0]

Expand Down Expand Up @@ -3729,7 +3707,7 @@ async def jsonrpc_stream_update(
f"A claim with id '{claim_id}' was found but it is not a stream or repost claim."
)

amount = self.get_dewies_or_error('bid', bid, positive_value=True, everything=bid_everything,
amount = self.get_amount_or_error('bid', bid, positive_value=True, everything=bid_everything,
default_value=old_txo.amount)

if claim_address is not None:
Expand Down Expand Up @@ -3775,8 +3753,7 @@ async def jsonrpc_stream_update(
claim.clear_signature()
tx = await Transaction.claim_update(
old_txo, claim, amount, claim_address, funding_accounts, funding_accounts[0],
channel if not clear_channel else None,
everything=bid_everything
channel if not clear_channel else None
)

new_txo = tx.outputs[0]
Expand Down Expand Up @@ -4020,7 +3997,7 @@ async def jsonrpc_collection_create(
funding_accounts = wallet.get_accounts_or_all(funding_account_ids)
self.valid_collection_name_or_error(name)
channel = await self.get_channel_or_none(wallet, channel_account_id, channel_id, channel_name, for_signing=True)
amount = self.get_dewies_or_error('bid', bid, positive_value=True, everything=bid_everything)
amount = self.get_amount_or_error('bid', bid, positive_value=True, everything=bid_everything)

claim_address = await self.get_receiving_address(claim_address, account)

Expand All @@ -4038,8 +4015,7 @@ async def jsonrpc_collection_create(
claim = Claim()
claim.collection.update(claims=claims, **kwargs)
tx = await Transaction.claim_create(
name, claim, amount, claim_address, funding_accounts, funding_accounts[0], channel,
everything=bid_everything
name, claim, amount, claim_address, funding_accounts, funding_accounts[0], channel
)
new_txo = tx.outputs[0]

Expand Down Expand Up @@ -4168,7 +4144,7 @@ async def jsonrpc_collection_update(
f"A claim with id '{claim_id}' was found but it is not a collection."
)

amount = self.get_dewies_or_error('bid', bid, positive_value=True, everything=bid_everything,
amount = self.get_amount_or_error('bid', bid, positive_value=True, everything=bid_everything,
default_value=old_txo.amount)

if claim_address is not None:
Expand All @@ -4190,8 +4166,7 @@ async def jsonrpc_collection_update(
claim = Claim.from_bytes(old_txo.claim.to_bytes())
claim.collection.update(**kwargs)
tx = await Transaction.claim_update(
old_txo, claim, amount, claim_address, funding_accounts, funding_accounts[0], channel,
everything=bid_everything
old_txo, claim, amount, claim_address, funding_accounts, funding_accounts[0], channel
)
new_txo = tx.outputs[0]

Expand Down Expand Up @@ -4354,7 +4329,7 @@ async def jsonrpc_support_create(
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, channel_account_id, channel_id, channel_name, for_signing=True)
amount = self.get_dewies_or_error('amount', amount, everything=amount_everything)
amount = self.get_amount_or_error('amount', amount, everything=amount_everything)

claim = await self.ledger.get_claim_by_claim_id(claim_id)
claim_address = claim.get_address(self.ledger)
Expand All @@ -4364,7 +4339,7 @@ async def jsonrpc_support_create(

tx = await Transaction.support(
claim.claim_name, claim_id, amount, claim_address, funding_accounts, funding_accounts[0], channel,
comment=comment, everything=amount_everything
comment=comment
)
new_txo = tx.outputs[0]

Expand Down Expand Up @@ -5485,25 +5460,29 @@ async def get_channel_or_error(
raise ValueError(f"Couldn't find channel with channel_{key} '{value}'.")

@staticmethod
def get_dewies_or_error(argument: str, lbc: Optional[str],
def get_dewies_or_error(argument: str, lbc: str, positive_value: bool = False) -> int:
try:
dewies = lbc_to_dewies(lbc)
if positive_value and dewies <= 0:
# TODO: use error from lbry.error
raise ValueError(f"'{argument}' value must be greater than 0.0")
return dewies
except ValueError as e:
# TODO: use error from lbry.error
raise ValueError(f"Invalid value for '{argument}': {e.args[0]}")

@staticmethod
def get_amount_or_error(argument: str, lbc: Optional[str],
positive_value: bool = False, everything: bool = False,
default_value: Optional[int] = None,
argument_everything: Optional[str] = None) -> int:
argument_everything: Optional[str] = None) -> Union[int, str]:
if everything:
if lbc is not None:
argument_everything = argument_everything or argument + '_everything'
raise ConflictingInputValueError(argument, argument_everything)
return 0
return AMOUNT_EVERYTHING
elif lbc is not None:
try:
dewies = lbc_to_dewies(lbc)
if positive_value and dewies <= 0:
# TODO: use error from lbry.error
raise ValueError(f"'{argument}' value must be greater than 0.0")
return dewies
except ValueError as e:
# TODO: use error from lbry.error
raise ValueError(f"Invalid value for '{argument}': {e.args[0]}")
return Daemon.get_dewies_or_error(argument, lbc, positive_value=positive_value)
elif default_value is not None:
return default_value
else:
Expand Down
10 changes: 6 additions & 4 deletions lbry/wallet/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@
import random
from hashlib import sha256
from string import hexdigits
from typing import Type, Dict, Tuple, Optional, Any, List
from typing import Type, Dict, Tuple, Optional, Any, List, Union

from lbry.error import InvalidPasswordError
from lbry.crypto.crypt import aes_encrypt, aes_decrypt
from lbry.wallet.dewies import amount_to_dewies

from .bip32 import PrivateKey, PublicKey, KeyPath, from_extended_key_string
from .mnemonic import Mnemonic
Expand Down Expand Up @@ -526,9 +527,10 @@ def get_transactions(self, **constraints):
def get_transaction_count(self, **constraints):
return self.ledger.get_transaction_count(wallet=self.wallet, accounts=[self], **constraints)

async def fund(self, to_account, amount=None, everything=False,
async def fund(self, to_account, amount: Union[int, str],
outputs=1, broadcast=False, **constraints):
assert self.ledger == to_account.ledger, 'Can only transfer between accounts of the same ledger.'
dewies, everything = amount_to_dewies(amount)
if everything:
utxos = await self.get_utxos(**constraints)
await self.ledger.reserve_outputs(utxos)
Expand All @@ -538,13 +540,13 @@ async def fund(self, to_account, amount=None, everything=False,
funding_accounts=[self],
change_account=to_account
)
elif amount > 0:
elif dewies > 0:
to_address = await to_account.change.get_or_create_usable_address()
to_hash160 = to_account.ledger.address_to_hash160(to_address)
tx = await Transaction.create(
inputs=[],
outputs=[
Output.pay_pubkey_hash(amount//outputs, to_hash160)
Output.pay_pubkey_hash(dewies//outputs, to_hash160)
for _ in range(outputs)
],
funding_accounts=[self],
Expand Down
18 changes: 18 additions & 0 deletions lbry/wallet/dewies.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,24 @@
import textwrap
from typing import Tuple, Union
from .util import coins_to_satoshis, satoshis_to_coins

# Symbolic amount EVERYTHING
AMOUNT_EVERYTHING = "EVERYTHING"

def amount_is_everything(amount: Union[int, str]) -> bool:
if isinstance(amount, str):
if amount != AMOUNT_EVERYTHING:
raise ValueError(f"The value '{amount}' for argument 'amount' is invalid.")
return True
elif isinstance(amount, int):
return False
else:
raise ValueError(f"The value '{amount}' for argument 'amount' is invalid.")

def amount_to_dewies(amount: Union[int, str]) -> Tuple[int, bool]:
everything = amount_is_everything(amount)
dewies = 0 if everything else amount
return dewies, everything

def lbc_to_dewies(lbc: str) -> int:
try:
Expand Down
Loading

0 comments on commit 04c7bdf

Please sign in to comment.