XMR amounts in http interface.

This commit is contained in:
tecnovert 2020-11-29 01:04:26 +02:00
parent 327394e81b
commit 2d4131d4ee
No known key found for this signature in database
GPG key ID: 8ED6D8750C4E3F93
7 changed files with 72 additions and 18 deletions

View file

@ -7,6 +7,7 @@
from enum import IntEnum
from .util import (
COIN,
format_amount
)
XMR_COIN = 10 ** 12
@ -193,7 +194,7 @@ chainparams = {
class CoinInterface:
def format_amount(self, amount_int):
return format_amount(feerate, self.exp())
return format_amount(amount_int, self.exp())
def coin_name(self):
return chainparams[self.coin_type()]['name'].capitalize()

View file

@ -17,8 +17,6 @@ from jinja2 import Environment, PackageLoader
from . import __version__
from .util import (
COIN,
format8,
make_int,
dumpj,
)
@ -157,6 +155,8 @@ def describeBid(swap_client, bid, offer, edit_bid, show_txns):
coin_from = Coins(offer.coin_from)
coin_to = Coins(offer.coin_to)
ci_from = swap_client.ci(coin_from)
ci_to = swap_client.ci(coin_to)
ticker_from = swap_client.getTicker(coin_from)
ticker_to = swap_client.getTicker(coin_to)
@ -189,8 +189,8 @@ def describeBid(swap_client, bid, offer, edit_bid, show_txns):
state_description = ''
data = {
'amt_from': format8(bid.amount),
'amt_to': format8((bid.amount * offer.rate) // COIN),
'amt_from': ci_from.format_amount(bid.amount),
'amt_to': ci_to.format_amount((bid.amount * offer.rate) // ci_from.COIN()),
'ticker_from': ticker_from,
'ticker_to': ticker_to,
'bid_state': strBidState(bid.state),
@ -374,6 +374,8 @@ class HttpHandler(BaseHTTPRequestHandler):
'error': w['error']
})
continue
ci = swap_client.ci(k)
fee_rate = swap_client.getFeeRateForCoin(k)
tx_vsize = swap_client.getContractSpendTxVSize(k)
est_fee = (fee_rate * tx_vsize) / 1000
@ -381,8 +383,8 @@ class HttpHandler(BaseHTTPRequestHandler):
'name': w['name'],
'version': w['version'],
'cid': str(int(k)),
'fee_rate': format8(fee_rate * COIN),
'est_fee': format8(est_fee * COIN),
'fee_rate': ci.format_amount(int(fee_rate * ci.COIN())),
'est_fee': ci.format_amount(int(est_fee * ci.COIN())),
'balance': w['balance'],
'blocks': w['blocks'],
'synced': w['synced'],
@ -437,6 +439,7 @@ class HttpHandler(BaseHTTPRequestHandler):
raise ValueError('Unknown Coin From')
try:
coin_to = Coins(int(form_data[b'coin_to'][0]))
ci_to = swap_client.ci(coin_to)
except Exception:
raise ValueError('Unknown Coin To')
@ -444,7 +447,7 @@ class HttpHandler(BaseHTTPRequestHandler):
value_to = inputAmount(form_data[b'amt_to'][0].decode('utf-8'))
min_bid = int(value_from)
rate = int((value_to / value_from) * COIN)
rate = int((value_to / value_from) * ci_to.COIN())
autoaccept = True if b'autoaccept' in form_data else False
lock_seconds = int(form_data[b'lockhrs'][0]) * 60 * 60
# TODO: More accurate rate
@ -516,8 +519,8 @@ class HttpHandler(BaseHTTPRequestHandler):
'coin_from': ci_from.coin_name(),
'coin_to': ci_to.coin_name(),
'amt_from': ci_from.format_amount(offer.amount_from),
'amt_to': ci_to.format_amount((offer.amount_from * offer.rate) // COIN),
'rate': format8(offer.rate),
'amt_to': ci_to.format_amount((offer.amount_from * offer.rate) // ci_from.COIN()),
'rate': ci_to.format_amount(offer.rate),
'lock_type': getLockName(offer.lock_type),
'lock_value': offer.lock_value,
'addr_from': offer.addr_from,
@ -540,7 +543,7 @@ class HttpHandler(BaseHTTPRequestHandler):
sent_bid_id=sent_bid_id,
messages=messages,
data=data,
bids=[(b[1].hex(), format8(b[3]), strBidState(b[4]), strTxState(b[6]), strTxState(b[7])) for b in bids],
bids=[(b[1].hex(), ci_from.format_amount(b[3]), strBidState(b[4]), strTxState(b[6]), strTxState(b[7])) for b in bids],
addrs=None if show_bid_form is None else swap_client.listSmsgAddresses('bid'),
form_id=os.urandom(8).hex(),
), 'UTF-8')
@ -583,6 +586,18 @@ class HttpHandler(BaseHTTPRequestHandler):
offers = swap_client.listOffers(sent, filters)
formatted_offers = []
for o in offers:
ci_from = swap_client.ci(Coins(o.coin_from))
ci_to = swap_client.ci(Coins(o.coin_to))
formatted_offers.append((
time.strftime('%Y-%m-%d %H:%M', time.localtime(o.created_at)),
o.offer_id.hex(),
ci_from.coin_name(), ci_to.coin_name(),
ci_from.format_amount(o.amount_from),
ci_to.format_amount((o.amount_from * o.rate) // ci_from.COIN()),
ci_to.format_amount(o.rate)))
template = env.get_template('offers.html')
return bytes(template.render(
title=self.server.title,
@ -591,8 +606,7 @@ class HttpHandler(BaseHTTPRequestHandler):
coins=listAvailableCoins(swap_client),
messages=messages,
filters=filters,
offers=[(time.strftime('%Y-%m-%d %H:%M', time.localtime(o.created_at)),
o.offer_id.hex(), getCoinName(Coins(o.coin_from)), getCoinName(Coins(o.coin_to)), format8(o.amount_from), format8((o.amount_from * o.rate) // COIN), format8(o.rate)) for o in offers],
offers=formatted_offers,
form_id=os.urandom(8).hex(),
), 'UTF-8')

View file

@ -81,6 +81,10 @@ class BTCInterface(CoinInterface):
def coin_type():
return Coins.BTC
@staticmethod
def COIN():
return COIN
@staticmethod
def exp():
return 8
@ -118,9 +122,6 @@ class BTCInterface(CoinInterface):
self._network = network
self.blocks_confirmed = coin_settings['blocks_confirmed']
def coin_name(self):
return chainparams[self.coin_type()]['name']
def testDaemonRPC(self):
self.rpc_callback('getwalletinfo', [])

View file

@ -37,6 +37,10 @@ class XMRInterface(CoinInterface):
def coin_type():
return Coins.XMR
@staticmethod
def COIN():
return XMR_COIN
@staticmethod
def exp():
return 12
@ -279,6 +283,7 @@ class XMRInterface(CoinInterface):
rv = self.rpc_wallet_cb('incoming_transfers', params)
if 'transfers' in rv:
for transfer in rv['transfers']:
print('[rm] transfer', transfer)
if transfer['tx_hash'] == txid \
and (current_height is None or current_height - transfer['block_height'] > self.blocks_confirmed):
return {'txid': transfer['tx_hash'], 'amount': transfer['amount'], 'height': transfer['block_height']}

View file

@ -276,6 +276,8 @@ def validate_amount(amount, scale=8):
def format_amount(i, display_scale, scale=None):
if not isinstance(i, int):
raise ValueError('Amount must be an integer.') # Raise error instead of converting as amounts should always be integers
if scale is None:
scale = display_scale
ep = 10 ** scale
@ -284,7 +286,7 @@ def format_amount(i, display_scale, scale=None):
remainder = n % ep
if display_scale != scale:
remainder %= (10 ** display_scale)
rv = '{}.{:0>{prec}}'.format(quotient, remainder, prec=display_scale)
rv = '{}.{:0>{scale}}'.format(quotient, remainder, scale=display_scale)
if i < 0:
rv = '-' + rv
return rv

View file

@ -200,6 +200,20 @@ class Test(unittest.TestCase):
amount_from = 100 * (10 ** scale_from)
rate = 0.1 * (10 ** scale_to)
amount_to = int((amount_from * rate) // (10 ** scale_from))
assert('100.00000000' == format_amount(amount_from, scale_from))
assert('10.000000000000' == format_amount(amount_to, scale_to))
scale_from = 12
scale_to = 8
amount_from = 1 * (10 ** scale_from)
rate = 12 * (10 ** scale_to)
amount_to = int((amount_from * rate) // (10 ** scale_from))
assert('1.000000000000' == format_amount(amount_from, scale_from))
assert('12.00000000' == format_amount(amount_to, scale_to))
if __name__ == '__main__':
unittest.main()

View file

@ -81,6 +81,8 @@ XMR_BASE_ZMQ_PORT = 22792
XMR_BASE_WALLET_RPC_PORT = 23792
PREFIX_SECRET_KEY_REGTEST = 0x2e
delay_event = threading.Event()
stop_test = False
@ -263,8 +265,9 @@ def make_rpc_func(node_id, base_rpc_port=BASE_RPC_PORT):
def signal_handler(sig, frame):
global stop_test
print('signal {} detected.'.format(sig))
logging.info('signal {} detected.'.format(sig))
stop_test = True
delay_event.set()
def waitForXMRNode(rpc_offset, max_tries=7):
@ -531,6 +534,11 @@ class Test(unittest.TestCase):
return
raise ValueError('wait_for_bid timed out.')
def delay_for(self, delay_for=60):
logging.info('Delaying for {} seconds.'.format(delay_for))
delay_event.clear()
delay_event.wait(delay_for)
def test_01_part_xmr(self):
logging.info('---------- Test PART to XMR')
swap_clients = self.swap_clients
@ -557,6 +565,12 @@ class Test(unittest.TestCase):
self.wait_for_bid(swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=180)
self.wait_for_bid(swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True)
js_0_end = json.loads(urlopen('http://localhost:1800/json/wallets').read())
end_xmr = float(js_0_end['6']['balance']) + float(js_0_end['6']['unconfirmed'])
assert(end_xmr > 10.9 and end_xmr < 11.0)
self.delay_for(600)
def test_02_leader_recover_a_lock_tx(self):
logging.info('---------- Test PART to XMR leader recovers coin a lock tx')
swap_clients = self.swap_clients
@ -658,6 +672,9 @@ class Test(unittest.TestCase):
self.wait_for_bid(swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=180)
self.wait_for_bid(swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True)
def pass_06_delay(self):
self.delay_for(60)
if __name__ == '__main__':
unittest.main()