dewies_to_lbc and lbc_to_dewies

This commit is contained in:
Lex Berezhny 2018-10-03 16:38:47 -04:00
parent 7b9ff3e8b5
commit 22df26eeb6
6 changed files with 101 additions and 59 deletions

View file

@ -5,12 +5,10 @@ import requests
import urllib import urllib
import json import json
import textwrap import textwrap
import re
from operator import itemgetter from operator import itemgetter
from binascii import hexlify, unhexlify from binascii import hexlify, unhexlify
from copy import deepcopy from copy import deepcopy
from decimal import Decimal
from twisted.internet import defer, reactor from twisted.internet import defer, reactor
from twisted.internet.task import LoopingCall from twisted.internet.task import LoopingCall
from twisted.python.failure import Failure from twisted.python.failure import Failure
@ -48,6 +46,7 @@ from lbrynet.core.SinglePeerDownloader import SinglePeerDownloader
from lbrynet.core.client.StandaloneBlobDownloader import StandaloneBlobDownloader from lbrynet.core.client.StandaloneBlobDownloader import StandaloneBlobDownloader
from lbrynet.wallet.account import Account as LBCAccount from lbrynet.wallet.account import Account as LBCAccount
from lbrynet.wallet.manager import LbryWalletManager from lbrynet.wallet.manager import LbryWalletManager
from lbrynet.wallet.dewies import dewies_to_lbc, lbc_to_dewies
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
requires = AuthJSONRPCServer.requires requires = AuthJSONRPCServer.requires
@ -1190,7 +1189,7 @@ class Daemon(AuthJSONRPCServer):
dewies = yield account.get_balance( dewies = yield account.get_balance(
0 if include_unconfirmed else 6 0 if include_unconfirmed else 6
) )
return Decimal(dewies) / COIN return dewies_to_lbc(dewies)
@requires("wallet") @requires("wallet")
@defer.inlineCallbacks @defer.inlineCallbacks
@ -1454,7 +1453,7 @@ class Daemon(AuthJSONRPCServer):
return self.get_account_or_error(account_id).get_max_gap() return self.get_account_or_error(account_id).get_max_gap()
@requires("wallet") @requires("wallet")
def jsonrpc_account_fund(self, to_account, from_account, amount=0, def jsonrpc_account_fund(self, to_account, from_account, amount='0.0',
everything=False, outputs=1, broadcast=False): everything=False, outputs=1, broadcast=False):
""" """
Transfer some amount (or --everything) to an account from another Transfer some amount (or --everything) to an account from another
@ -1973,7 +1972,6 @@ class Daemon(AuthJSONRPCServer):
@requires(STREAM_IDENTIFIER_COMPONENT, WALLET_COMPONENT, EXCHANGE_RATE_MANAGER_COMPONENT, BLOB_COMPONENT, @requires(STREAM_IDENTIFIER_COMPONENT, WALLET_COMPONENT, EXCHANGE_RATE_MANAGER_COMPONENT, BLOB_COMPONENT,
DHT_COMPONENT, RATE_LIMITER_COMPONENT, PAYMENT_RATE_COMPONENT, DATABASE_COMPONENT, DHT_COMPONENT, RATE_LIMITER_COMPONENT, PAYMENT_RATE_COMPONENT, DATABASE_COMPONENT,
conditions=[WALLET_IS_UNLOCKED]) conditions=[WALLET_IS_UNLOCKED])
@defer.inlineCallbacks
def jsonrpc_stream_cost_estimate(self, uri, size=None): def jsonrpc_stream_cost_estimate(self, uri, size=None):
""" """
Get estimated cost for a lbry stream Get estimated cost for a lbry stream
@ -1990,8 +1988,7 @@ class Daemon(AuthJSONRPCServer):
(float) Estimated cost in lbry credits, returns None if uri is not (float) Estimated cost in lbry credits, returns None if uri is not
resolvable resolvable
""" """
cost = yield self.get_est_cost(uri, size) return self.get_est_cost(uri, size)
defer.returnValue(cost)
@requires(WALLET_COMPONENT, conditions=[WALLET_IS_UNLOCKED]) @requires(WALLET_COMPONENT, conditions=[WALLET_IS_UNLOCKED])
@defer.inlineCallbacks @defer.inlineCallbacks
@ -2045,7 +2042,6 @@ class Daemon(AuthJSONRPCServer):
}) })
@requires(WALLET_COMPONENT) @requires(WALLET_COMPONENT)
@defer.inlineCallbacks
def jsonrpc_channel_list(self): def jsonrpc_channel_list(self):
""" """
Get certificate claim infos for channels that can be published to Get certificate claim infos for channels that can be published to
@ -2060,10 +2056,7 @@ class Daemon(AuthJSONRPCServer):
(list) ClaimDict, includes 'is_mine' field to indicate if the certificate claim (list) ClaimDict, includes 'is_mine' field to indicate if the certificate claim
is in the wallet. is in the wallet.
""" """
return self.wallet_manager.channel_list()
result = yield self.wallet_manager.channel_list()
response = yield self._render_response(result)
defer.returnValue(response)
@requires(WALLET_COMPONENT) @requires(WALLET_COMPONENT)
@defer.inlineCallbacks @defer.inlineCallbacks
@ -3285,13 +3278,11 @@ class Daemon(AuthJSONRPCServer):
raise ValueError("Couldn't find account: {}.".format(account_id)) raise ValueError("Couldn't find account: {}.".format(account_id))
@staticmethod @staticmethod
def get_dewies_or_error(argument: str, amount: str): def get_dewies_or_error(argument: str, lbc: str):
if isinstance(amount, str): try:
result = re.search(r'^(\d{1,10})\.(\d{1,8})$', amount) return lbc_to_dewies(lbc)
if result is not None: except ValueError as e:
whole, fractional = result.groups() raise ValueError("Invalid value for '{}': {}".format(argument, e.args[0]))
return int(whole+fractional.ljust(8, "0"))
raise ValueError("Invalid value for '{}' argument: {}".format(argument, amount))
def loggly_time_string(dt): def loggly_time_string(dt):

View file

@ -3,6 +3,7 @@ from binascii import hexlify
from datetime import datetime from datetime import datetime
from json import JSONEncoder from json import JSONEncoder
from lbrynet.wallet.transaction import Transaction, Output from lbrynet.wallet.transaction import Transaction, Output
from lbrynet.wallet.dewies import dewies_to_lbc
class JSONResponseEncoder(JSONEncoder): class JSONResponseEncoder(JSONEncoder):
@ -30,9 +31,9 @@ class JSONResponseEncoder(JSONEncoder):
'height': tx.height, 'height': tx.height,
'inputs': [self.encode_input(txo) for txo in tx.inputs], 'inputs': [self.encode_input(txo) for txo in tx.inputs],
'outputs': [self.encode_output(txo) for txo in tx.outputs], 'outputs': [self.encode_output(txo) for txo in tx.outputs],
'total_input': tx.input_sum, 'total_input': dewies_to_lbc(tx.input_sum),
'total_output': tx.input_sum - tx.fee, 'total_output': dewies_to_lbc(tx.input_sum - tx.fee),
'total_fee': tx.fee, 'total_fee': dewies_to_lbc(tx.fee),
'hex': hexlify(tx.raw).decode(), 'hex': hexlify(tx.raw).decode(),
} }
@ -40,7 +41,7 @@ class JSONResponseEncoder(JSONEncoder):
output = { output = {
'txid': txo.tx_ref.id, 'txid': txo.tx_ref.id,
'nout': txo.position, 'nout': txo.position,
'amount': txo.amount, 'amount': dewies_to_lbc(txo.amount),
'address': txo.get_address(self.ledger), 'address': txo.get_address(self.ledger),
'is_claim': txo.script.is_claim_name, 'is_claim': txo.script.is_claim_name,
'is_support': txo.script.is_support_claim, 'is_support': txo.script.is_support_claim,

39
lbrynet/wallet/dewies.py Normal file
View file

@ -0,0 +1,39 @@
import re
import textwrap
from torba.constants import COIN
def lbc_to_dewies(lbc):
if isinstance(lbc, str):
result = re.search(r'^(\d{1,10})\.(\d{1,8})$', lbc)
if result is not None:
whole, fractional = result.groups()
return int(whole+fractional.ljust(8, "0"))
raise ValueError(textwrap.dedent(
r"""
Decimal inputs require a value in the ones place and in the tenths place
separated by a period. The value provided, '{}', is not of the correct
format.
The following are examples of valid decimal inputs:
1.0
2.34500
4534.4
2323434.0000
The following are NOT valid:
83
.456
123.
""".format(lbc)
))
def dewies_to_lbc(dewies):
lbc = '{:.8f}'.format(dewies / COIN).rstrip('0')
if lbc.endswith('.'):
return lbc+'0'
else:
return lbc

View file

@ -15,6 +15,7 @@ from .ledger import MainNetLedger
from .account import BaseAccount, generate_certificate from .account import BaseAccount, generate_certificate
from .transaction import Transaction from .transaction import Transaction
from .database import WalletDatabase from .database import WalletDatabase
from .dewies import dewies_to_lbc
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -259,30 +260,30 @@ class LbryWalletManager(BaseWalletManager):
history.append({ history.append({
'txid': tx.id, 'txid': tx.id,
'timestamp': ts, 'timestamp': ts,
'value': tx.net_account_balance/COIN, 'value': dewies_to_lbc(tx.net_account_balance),
'fee': tx.fee/COIN, 'fee': dewies_to_lbc(tx.fee),
'date': datetime.fromtimestamp(ts).isoformat(' ')[:-3], 'date': datetime.fromtimestamp(ts).isoformat(' ')[:-3],
'confirmations': headers.height - tx.height, 'confirmations': headers.height - tx.height,
'claim_info': [{ 'claim_info': [{
'address': txo.get_address(account.ledger), 'address': txo.get_address(account.ledger),
'balance_delta': -txo.amount/COIN, 'balance_delta': dewies_to_lbc(-txo.amount),
'amount': txo.amount/COIN, 'amount': dewies_to_lbc(txo.amount),
'claim_id': txo.claim_id, 'claim_id': txo.claim_id,
'claim_name': txo.claim_name, 'claim_name': txo.claim_name,
'nout': txo.position 'nout': txo.position
} for txo in tx.my_claim_outputs], } for txo in tx.my_claim_outputs],
'update_info': [{ 'update_info': [{
'address': txo.get_address(account.ledger), 'address': txo.get_address(account.ledger),
'balance_delta': -txo.amount/COIN, 'balance_delta': dewies_to_lbc(-txo.amount),
'amount': txo.amount/COIN, 'amount': dewies_to_lbc(txo.amount),
'claim_id': txo.claim_id, 'claim_id': txo.claim_id,
'claim_name': txo.claim_name, 'claim_name': txo.claim_name,
'nout': txo.position 'nout': txo.position
} for txo in tx.my_update_outputs], } for txo in tx.my_update_outputs],
'support_info': [{ 'support_info': [{
'address': txo.get_address(account.ledger), 'address': txo.get_address(account.ledger),
'balance_delta': -txo.amount/COIN, 'balance_delta': dewies_to_lbc(-txo.amount),
'amount': txo.amount/COIN, 'amount': dewies_to_lbc(txo.amount),
'claim_id': txo.claim_id, 'claim_id': txo.claim_id,
'claim_name': txo.claim_name, 'claim_name': txo.claim_name,
'is_tip': False, # TODO: need to add lookup 'is_tip': False, # TODO: need to add lookup
@ -290,8 +291,8 @@ class LbryWalletManager(BaseWalletManager):
} for txo in tx.my_support_outputs], } for txo in tx.my_support_outputs],
'abandon_info': [{ 'abandon_info': [{
'address': txo.get_address(account.ledger), 'address': txo.get_address(account.ledger),
'balance_delta': txo.amount/COIN, 'balance_delta': dewies_to_lbc(-txo.amount),
'amount': txo.amount/COIN, 'amount': dewies_to_lbc(txo.amount),
'claim_id': txo.claim_id, 'claim_id': txo.claim_id,
'claim_name': txo.claim_name, 'claim_name': txo.claim_name,
'nout': txo.position 'nout': txo.position

View file

@ -313,29 +313,3 @@ class TestFileListSorting(unittest.TestCase):
setattr(lbry_file, key, faked_attributes[key]) setattr(lbry_file, key, faked_attributes[key])
return lbry_file return lbry_file
class TestDeweyInputOutput(unittest.TestCase):
def test_input(self):
self.assertEqual(LBRYDaemon.get_dewies_or_error("", "1.0"), 100000000)
self.assertEqual(LBRYDaemon.get_dewies_or_error("", "2.00000000"), 200000000)
self.assertEqual(LBRYDaemon.get_dewies_or_error("", "2000000000.0"), 200000000000000000)
def test_invalid_input(self):
with self.assertRaises(ValueError):
LBRYDaemon.get_dewies_or_error("", "1")
with self.assertRaises(ValueError):
LBRYDaemon.get_dewies_or_error("", "-1.0")
with self.assertRaises(ValueError):
LBRYDaemon.get_dewies_or_error("", "10000000000.0")
with self.assertRaises(ValueError):
LBRYDaemon.get_dewies_or_error("", "1.000000000")
with self.assertRaises(ValueError):
LBRYDaemon.get_dewies_or_error("", "-0")
with self.assertRaises(ValueError):
LBRYDaemon.get_dewies_or_error("", "1")
with self.assertRaises(ValueError):
LBRYDaemon.get_dewies_or_error("", ".1")
with self.assertRaises(ValueError):
LBRYDaemon.get_dewies_or_error("", "1e-7")

View file

@ -0,0 +1,36 @@
from twisted.trial import unittest
from lbrynet.wallet.dewies import lbc_to_dewies as l2d, dewies_to_lbc as d2l
class TestDeweyConversion(unittest.TestCase):
def test_good_output(self):
self.assertEqual(d2l(1), "0.00000001")
self.assertEqual(d2l(10**7), "0.1")
self.assertEqual(d2l(2*10**8), "2.0")
self.assertEqual(d2l(2*10**17), "2000000000.0")
def test_good_input(self):
self.assertEqual(l2d("0.00000001"), 1)
self.assertEqual(l2d("0.1"), 10**7)
self.assertEqual(l2d("1.0"), 10**8)
self.assertEqual(l2d("2.00000000"), 2*10**8)
self.assertEqual(l2d("2000000000.0"), 2*10**17)
def test_bad_input(self):
with self.assertRaises(ValueError):
l2d("1")
with self.assertRaises(ValueError):
l2d("-1.0")
with self.assertRaises(ValueError):
l2d("10000000000.0")
with self.assertRaises(ValueError):
l2d("1.000000000")
with self.assertRaises(ValueError):
l2d("-0")
with self.assertRaises(ValueError):
l2d("1")
with self.assertRaises(ValueError):
l2d(".1")
with self.assertRaises(ValueError):
l2d("1e-7")