diff --git a/README.md b/README.md index f5f1a2b..a071ec4 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# Loki Observer OMG block explorer +# Oxen Observer OMG block explorer -Block explorer using Loki 8+ LMQ RPC interface that does everything through RPC requests. Sexy, +Block explorer using Oxen 8+ LMQ RPC interface that does everything through RPC requests. Sexy, awesome, safe. ## Prerequisite packages @@ -23,7 +23,7 @@ Quick and dirty setup instructions for now: (Note that we require a very recent python3-jinja package (2.11+), which may not be installed by the above.) -You'll also need to run lokid with `--lmq-local-control ipc:///path/to/loki-observer/mainnet.sock`. +You'll also need to run oxend with `--lmq-local-control ipc:///path/to/loki-observer/mainnet.sock`. ## Running in debug mode @@ -60,13 +60,13 @@ Create a "vassal" config for loki-observer, `/etc/uwsgi-emperor/vassals/loki-obs logger = file:logfile=/path/to/loki-observer/mainnet.log Set ownership of this user to whatever use you want it to run as, and set the group to `_loki` (so -that it can open the lokid unix socket): +that it can open the oxend unix socket): chown MYUSERNAME:_loki /etc/uwsgi-emperor/vassals/loki-observer.ini In the loki-observer/mainnet.py, set: - config.lokid_rpc = 'ipc:///var/lib/loki/lokid.sock' + config.oxend_rpc = 'ipc:///var/lib/loki/oxend.sock' and finally, proxy requests from the webserver to the wsgi socket. For Apache I do this with: @@ -88,4 +88,4 @@ make uwsgi restart (for example because you are changing things) then it is suff apache2/uwsgi-emperor layers). If you want to set up a testnet or devnet observer the procedure is essentially the same, but -using testnet.py or devnet.py pointing to a lokid.sock from a testnet or devnet lokid. +using testnet.py or devnet.py pointing to a oxend.sock from a testnet or devnet oxend. diff --git a/config.py b/config.py index 817b0ba..518bca7 100644 --- a/config.py +++ b/config.py @@ -7,10 +7,10 @@ # into `mainnet.py`/`testnet.py`/etc. -# LMQ RPC endpoint of lokid; can be a unix socket 'ipc:///path/to/lokid.sock' (preferred) or a tcp +# LMQ RPC endpoint of oxend; can be a unix socket 'ipc:///path/to/oxend.sock' (preferred) or a tcp # socket 'tcp://127.0.0.1:5678'. Typically you want this running with admin permission. # Leave this as None here, and set it for each observer in the mainnet.py/testnet.py/etc. script. -lokid_rpc = None +oxend_rpc = None # Default blocks per page for the index. blocks_per_page=20 @@ -25,9 +25,9 @@ autorefresh_option=True enable_mixins_details=True # URLs to networks other than the one we are on: -mainnet_url='https://blocks.lokinet.dev' -testnet_url='https://testnet.lokinet.dev' -devnet_url='https://devnet.lokinet.dev' +mainnet_url='https://oxen.observer' +testnet_url='https://testnet.oxen.observer' +devnet_url='https://devnet.oxen.observer' # Same as above, but these apply if we are on a .loki URL: lokinet_mainnet_url='http://blocks.loki' diff --git a/devnet.py b/devnet.py index bf504e9..c5f617c 100644 --- a/devnet.py +++ b/devnet.py @@ -1,3 +1,3 @@ from observer import app, config -config.lokid_rpc = 'ipc://lokid/devnet.sock' +config.oxend_rpc = 'ipc://oxend/devnet.sock' diff --git a/lmq.py b/lmq.py index e3d9d92..066a9a1 100644 --- a/lmq.py +++ b/lmq.py @@ -4,16 +4,16 @@ import json import sys from datetime import datetime, timedelta -lmq, lokid = None, None +lmq, oxend = None, None def lmq_connection(): - global lmq, lokid + global lmq, oxend if lmq is None: lmq = pylokimq.LokiMQ(pylokimq.LogLevel.warn) lmq.max_message_size = 200*1024*1024 lmq.start() - if lokid is None: - lokid = lmq.connect_remote(config.lokid_rpc) - return (lmq, lokid) + if oxend is None: + oxend = lmq.connect_remote(config.oxend_rpc) + return (lmq, oxend) cached = {} cached_args = {} @@ -31,7 +31,7 @@ class FutureJSON(): result in unbounded memory growth. lmq - the lmq object - lokid - the lokid lmq connection id object + oxend - the oxend lmq connection id object endpoint - the lmq endpoint, e.g. 'rpc.get_info' cache_seconds - how long to cache the response; can be None to not cache it at all cache_key - fixed string to enable different caches of the same endpoint @@ -40,7 +40,7 @@ class FutureJSON(): timeout - maximum time to spend waiting for a reply """ - def __init__(self, lmq, lokid, endpoint, cache_seconds=3, *, cache_key='', args=None, fail_okay=False, timeout=10): + def __init__(self, lmq, oxend, endpoint, cache_seconds=3, *, cache_key='', args=None, fail_okay=False, timeout=10): self.endpoint = endpoint self.cache_key = self.endpoint + cache_key self.fail_okay = fail_okay @@ -53,7 +53,7 @@ class FutureJSON(): else: self.json = None self.args = args - self.future = lmq.request_future(lokid, self.endpoint, [] if self.args is None else [self.args], timeout=timeout) + self.future = lmq.request_future(oxend, self.endpoint, [] if self.args is None else [self.args], timeout=timeout) self.cache_seconds = cache_seconds def get(self): diff --git a/mainnet.py b/mainnet.py index 200c069..7303b79 100644 --- a/mainnet.py +++ b/mainnet.py @@ -1,3 +1,3 @@ from observer import app, config -config.lokid_rpc = 'ipc://lokid/mainnet.sock' +config.oxend_rpc = 'ipc://oxend/mainnet.sock' diff --git a/observer.py b/observer.py index b08a2cc..5a32b7b 100644 --- a/observer.py +++ b/observer.py @@ -115,10 +115,10 @@ def format_si(value): i += 1 return filter_round(value) + '{}'.format(si_suffix[i]) -@app.template_filter('loki') -def format_loki(atomic, tag=True, fixed=False, decimals=9, zero=None): +@app.template_filter('oxen') +def format_oxen(atomic, tag=True, fixed=False, decimals=9, zero=None): """Formats an atomic current value as a human currency value. - tag - if False then don't append " LOKI" + tag - if False then don't append " OXEN" fixed - if True then don't strip insignificant trailing 0's and '.' decimals - at how many decimal we should round; the default is full precision fixed - if specified, replace 0 with this string @@ -130,7 +130,7 @@ def format_loki(atomic, tag=True, fixed=False, decimals=9, zero=None): if not fixed and decimals > 0: disp = disp.rstrip('0').rstrip('.') if tag: - disp += ' LOKI' + disp += ' OXEN' return disp # For some inexplicable reason some hex fields are provided as array of byte integer values rather @@ -169,8 +169,8 @@ def css(): return flask.send_from_directory('static', 'style.css') -def get_sns_future(lmq, lokid): - return FutureJSON(lmq, lokid, 'rpc.get_service_nodes', 5, +def get_sns_future(lmq, oxend): + return FutureJSON(lmq, oxend, 'rpc.get_service_nodes', 5, args={ 'all': False, 'fields': { x: True for x in ('service_node_pubkey', 'requested_unlock_height', 'last_reward_block_height', @@ -200,8 +200,8 @@ def get_sns(sns_future, info_future): return awaiting_sns, active_sns, inactive_sns -def get_quorums_future(lmq, lokid, height): - return FutureJSON(lmq, lokid, 'rpc.get_quorum_state', 30, +def get_quorums_future(lmq, oxend, height): + return FutureJSON(lmq, oxend, 'rpc.get_quorum_state', 30, args={ 'start_height': height-55, 'end_height': height }) @@ -218,8 +218,8 @@ def get_quorums(quorums_future): print("Something getting wrong in quorums: found unknown quorum_type={}".format(q['quorum_type']), file=sys.stderr) return quo -def get_mempool_future(lmq, lokid): - return FutureJSON(lmq, lokid, 'rpc.get_transaction_pool', 5, args={"tx_extra":True, "stake_info":True}) +def get_mempool_future(lmq, oxend): + return FutureJSON(lmq, oxend, 'rpc.get_transaction_pool', 5, args={"tx_extra":True, "stake_info":True}) def parse_mempool(mempool_future): # mempool RPC return values are about as nasty as can be. For each mempool tx, we get back @@ -257,19 +257,19 @@ def template_globals(): @app.route('/autorefresh/') @app.route('/') def main(refresh=None, page=0, per_page=None, first=None, last=None): - lmq, lokid = lmq_connection() - inforeq = FutureJSON(lmq, lokid, 'rpc.get_info', 1) - stake = FutureJSON(lmq, lokid, 'rpc.get_staking_requirement', 10) - base_fee = FutureJSON(lmq, lokid, 'rpc.get_fee_estimate', 10) - hfinfo = FutureJSON(lmq, lokid, 'rpc.hard_fork_info', 10) - mempool = get_mempool_future(lmq, lokid) - sns = get_sns_future(lmq, lokid) - checkpoints = FutureJSON(lmq, lokid, 'rpc.get_checkpoints', args={"count": 3}) + lmq, oxend = lmq_connection() + inforeq = FutureJSON(lmq, oxend, 'rpc.get_info', 1) + stake = FutureJSON(lmq, oxend, 'rpc.get_staking_requirement', 10) + base_fee = FutureJSON(lmq, oxend, 'rpc.get_fee_estimate', 10) + hfinfo = FutureJSON(lmq, oxend, 'rpc.hard_fork_info', 10) + mempool = get_mempool_future(lmq, oxend) + sns = get_sns_future(lmq, oxend) + checkpoints = FutureJSON(lmq, oxend, 'rpc.get_checkpoints', args={"count": 3}) - # This call is slow the first time it gets called in lokid but will be fast after that, so call + # This call is slow the first time it gets called in oxend but will be fast after that, so call # it with a very short timeout. It's also an admin-only command, so will always fail if we're # using a restricted RPC interface. - coinbase = FutureJSON(lmq, lokid, 'admin.get_coinbase_tx_sum', 10, timeout=1, fail_okay=True, + coinbase = FutureJSON(lmq, oxend, 'admin.get_coinbase_tx_sum', 10, timeout=1, fail_okay=True, args={"height":0, "count":2**31-1}) custom_per_page = '' @@ -298,7 +298,7 @@ def main(refresh=None, page=0, per_page=None, first=None, last=None): end_height = max(0, height - per_page*page - 1) start_height = max(0, end_height - per_page + 1) - blocks = FutureJSON(lmq, lokid, 'rpc.get_block_headers_range', cache_key='main', args={ + blocks = FutureJSON(lmq, oxend, 'rpc.get_block_headers_range', cache_key='main', args={ 'start_height': start_height, 'end_height': end_height, 'get_tx_hashes': True, @@ -313,7 +313,7 @@ def main(refresh=None, page=0, per_page=None, first=None, last=None): txids.append(b['miner_tx_hash']) if 'tx_hashes' in b: txids += b['tx_hashes'] - txs = parse_txs(tx_req(lmq, lokid, txids, cache_key='mempool').get()) + txs = parse_txs(tx_req(lmq, oxend, txids, cache_key='mempool').get()) i = 0 for tx in txs: # TXs should come back in the same order so we can just skip ahead one when the block @@ -353,9 +353,9 @@ def main(refresh=None, page=0, per_page=None, first=None, last=None): @app.route('/txpool') def mempool(): - lmq, lokid = lmq_connection() - info = FutureJSON(lmq, lokid, 'rpc.get_info', 1) - mempool = get_mempool_future(lmq, lokid) + lmq, oxend = lmq_connection() + info = FutureJSON(lmq, oxend, 'rpc.get_info', 1) + mempool = get_mempool_future(lmq, oxend) return flask.render_template('mempool.html', info=info.get(), @@ -364,9 +364,9 @@ def mempool(): @app.route('/service_nodes') def sns(): - lmq, lokid = lmq_connection() - info = FutureJSON(lmq, lokid, 'rpc.get_info', 1) - awaiting, active, inactive = get_sns(get_sns_future(lmq, lokid), info) + lmq, oxend = lmq_connection() + info = FutureJSON(lmq, oxend, 'rpc.get_info', 1) + awaiting, active, inactive = get_sns(get_sns_future(lmq, oxend), info) return flask.render_template('service_nodes.html', info=info.get(), @@ -375,8 +375,8 @@ def sns(): inactive_sns=inactive, ) -def tx_req(lmq, lokid, txids, cache_key='single', **kwargs): - return FutureJSON(lmq, lokid, 'rpc.get_transactions', cache_seconds=10, cache_key=cache_key, +def tx_req(lmq, oxend, txids, cache_key='single', **kwargs): + return FutureJSON(lmq, oxend, 'rpc.get_transactions', cache_seconds=10, cache_key=cache_key, args={ "txs_hashes": txids, "decode_as_json": True, @@ -386,38 +386,38 @@ def tx_req(lmq, lokid, txids, cache_key='single', **kwargs): }, **kwargs) -def sn_req(lmq, lokid, pubkey, **kwargs): - return FutureJSON(lmq, lokid, 'rpc.get_service_nodes', 5, cache_key='single', +def sn_req(lmq, oxend, pubkey, **kwargs): + return FutureJSON(lmq, oxend, 'rpc.get_service_nodes', 5, cache_key='single', args={"service_node_pubkeys": [pubkey]}, **kwargs ) -def block_header_req(lmq, lokid, hash_or_height, **kwargs): +def block_header_req(lmq, oxend, hash_or_height, **kwargs): if isinstance(hash_or_height, int) or (len(hash_or_height) <= 10 and hash_or_height.isdigit()): - return FutureJSON(lmq, lokid, 'rpc.get_block_header_by_height', cache_key='single', + return FutureJSON(lmq, oxend, 'rpc.get_block_header_by_height', cache_key='single', args={ "height": int(hash_or_height) }, **kwargs) else: - return FutureJSON(lmq, lokid, 'rpc.get_block_header_by_hash', cache_key='single', + return FutureJSON(lmq, oxend, 'rpc.get_block_header_by_hash', cache_key='single', args={ 'hash': hash_or_height }, **kwargs) -def block_with_txs_req(lmq, lokid, hash_or_height, **kwargs): +def block_with_txs_req(lmq, oxend, hash_or_height, **kwargs): args = { 'get_tx_hashes': True } if isinstance(hash_or_height, int) or (len(hash_or_height) <= 10 and hash_or_height.isdigit()): args['height'] = int(hash_or_height) else: args['hash'] = hash_or_height - return FutureJSON(lmq, lokid, 'rpc.get_block', cache_key='single', args=args, **kwargs) + return FutureJSON(lmq, oxend, 'rpc.get_block', cache_key='single', args=args, **kwargs) @app.route('/service_node/') # For backwards compatibility with old explorer URLs @app.route('/sn/') def show_sn(pubkey): - lmq, lokid = lmq_connection() - info = FutureJSON(lmq, lokid, 'rpc.get_info', 1) - hfinfo = FutureJSON(lmq, lokid, 'rpc.hard_fork_info', 10) - sn = sn_req(lmq, lokid, pubkey).get() + lmq, oxend = lmq_connection() + info = FutureJSON(lmq, oxend, 'rpc.get_info', 1) + hfinfo = FutureJSON(lmq, oxend, 'rpc.hard_fork_info', 10) + sn = sn_req(lmq, oxend, pubkey).get() if 'service_node_states' not in sn or not sn['service_node_states']: return flask.render_template('not_found.html', @@ -452,7 +452,7 @@ def parse_txs(txs_rpc): for tx in txs_rpc['txs']: if 'info' not in tx: - # We have serialized JSON data inside a field in the JSON, because of lokid's + # We have serialized JSON data inside a field in the JSON, because of oxend's # multiple incompatible JSON generators 🤮: tx['info'] = json.loads(tx["as_json"]) del tx['as_json'] @@ -462,7 +462,7 @@ def parse_txs(txs_rpc): return txs_rpc['txs'] -def get_block_txs_future(lmq, lokid, block): +def get_block_txs_future(lmq, oxend, block): hashes = [] if 'tx_hashes' in block: hashes += block['tx_hashes'] @@ -475,7 +475,7 @@ def get_block_txs_future(lmq, lokid, block): except Exception as e: print("Something getting wrong: cannot parse block json for block {}: {}".format(block_height, e), file=sys.stderr) - return tx_req(lmq, lokid, hashes, cache_key='block') + return tx_req(lmq, oxend, hashes, cache_key='block') @app.route('/block/') @@ -483,15 +483,15 @@ def get_block_txs_future(lmq, lokid, block): @app.route('/block/') @app.route('/block//') def show_block(height=None, hash=None, more_details=False): - lmq, lokid = lmq_connection() - info = FutureJSON(lmq, lokid, 'rpc.get_info', 1) - hfinfo = FutureJSON(lmq, lokid, 'rpc.hard_fork_info', 10) + lmq, oxend = lmq_connection() + info = FutureJSON(lmq, oxend, 'rpc.get_info', 1) + hfinfo = FutureJSON(lmq, oxend, 'rpc.hard_fork_info', 10) if height is not None: val = height elif hash is not None: val = hash - block = None if val is None else block_with_txs_req(lmq, lokid, val).get() + block = None if val is None else block_with_txs_req(lmq, oxend, val).get() if block is None: return flask.render_template("not_found.html", info=info.get(), @@ -503,10 +503,10 @@ def show_block(height=None, hash=None, more_details=False): next_block = None block_height = block['block_header']['height'] - txs = get_block_txs_future(lmq, lokid, block) + txs = get_block_txs_future(lmq, oxend, block) if info.get()['height'] > 1 + block_height: - next_block = block_header_req(lmq, lokid, '{}'.format(block_height + 1)) + next_block = block_header_req(lmq, oxend, '{}'.format(block_height + 1)) if more_details: formatter = HtmlFormatter(cssclass="syntax-highlight", style="native") @@ -534,17 +534,17 @@ def show_block(height=None, hash=None, more_details=False): @app.route('/block/latest') def show_block_latest(): - lmq, lokid = lmq_connection() - height = FutureJSON(lmq, lokid, 'rpc.get_info', 1).get()['height'] - 1 + lmq, oxend = lmq_connection() + height = FutureJSON(lmq, oxend, 'rpc.get_info', 1).get()['height'] - 1 return flask.redirect(flask.url_for('show_block', height=height), code=302) @app.route('/tx/') @app.route('/tx//') def show_tx(txid, more_details=False): - lmq, lokid = lmq_connection() - info = FutureJSON(lmq, lokid, 'rpc.get_info', 1) - txs = tx_req(lmq, lokid, [txid]).get() + lmq, oxend = lmq_connection() + info = FutureJSON(lmq, oxend, 'rpc.get_info', 1) + txs = tx_req(lmq, oxend, [txid]).get() if 'txs' not in txs or not txs['txs']: return flask.render_template('not_found.html', @@ -557,7 +557,7 @@ def show_tx(txid, more_details=False): # If this is a state change, see if we have the quorum stored to provide context testing_quorum = None if tx['info']['version'] >= 4 and 'sn_state_change' in tx['extra']: - testing_quorum = FutureJSON(lmq, lokid, 'rpc.get_quorum_state', 60, cache_key='tx_state_change', + testing_quorum = FutureJSON(lmq, oxend, 'rpc.get_quorum_state', 60, cache_key='tx_state_change', args={ 'quorum_type': 0, 'start_height': tx['extra']['sn_state_change']['height'] }) kindex_info = {} # { amount => { keyindex => {output-info} } } @@ -581,14 +581,14 @@ def show_tx(txid, more_details=False): del inp['key']['key_offsets'] outs_req = [{"amount":inp['key']['amount'], "index":ki} for inp in tx['info']['vin'] for ki in inp['key']['key_indices']] - outputs = FutureJSON(lmq, lokid, 'rpc.get_outs', args={ + outputs = FutureJSON(lmq, oxend, 'rpc.get_outs', args={ 'get_txid': True, 'outputs': outs_req, }).get() if outputs and 'outs' in outputs and len(outputs['outs']) == len(outs_req): outputs = outputs['outs'] # Also load block details for all of those outputs: - block_info_req = FutureJSON(lmq, lokid, 'rpc.get_block_header_by_height', args={ + block_info_req = FutureJSON(lmq, oxend, 'rpc.get_block_header_by_height', args={ 'heights': [o["height"] for o in outputs] }) i = 0 @@ -637,9 +637,9 @@ def show_tx(txid, more_details=False): @app.route('/quorums') def show_quorums(): - lmq, lokid = lmq_connection() - info = FutureJSON(lmq, lokid, 'rpc.get_info', 1) - quos = get_quorums_future(lmq, lokid, info.get()['height']) + lmq, oxend = lmq_connection() + info = FutureJSON(lmq, oxend, 'rpc.get_info', 1) + quos = get_quorums_future(lmq, oxend, info.get()['height']) return flask.render_template('quorums.html', info=info.get(), @@ -649,8 +649,8 @@ def show_quorums(): @app.route('/search') def search(): - lmq, lokid = lmq_connection() - info = FutureJSON(lmq, lokid, 'rpc.get_info', 1) + lmq, oxend = lmq_connection() + info = FutureJSON(lmq, oxend, 'rpc.get_info', 1) val = (flask.request.args.get('value') or '').strip() if val and len(val) < 10 and val.isdigit(): # Block height @@ -664,9 +664,9 @@ def search(): ) # Initiate all the lookups at once, then redirect to whichever one responds affirmatively - snreq = sn_req(lmq, lokid, val) - blreq = block_header_req(lmq, lokid, val, fail_okay=True) - txreq = tx_req(lmq, lokid, [val]) + snreq = sn_req(lmq, oxend, val) + blreq = block_header_req(lmq, oxend, val, fail_okay=True) + txreq = tx_req(lmq, oxend, [val]) sn = snreq.get() if 'service_node_states' in sn and sn['service_node_states']: @@ -686,9 +686,9 @@ def search(): @app.route('/api/networkinfo') def api_networkinfo(): - lmq, lokid = lmq_connection() - info = FutureJSON(lmq, lokid, 'rpc.get_info', 1) - hfinfo = FutureJSON(lmq, lokid, 'rpc.hard_fork_info', 10) + lmq, oxend = lmq_connection() + info = FutureJSON(lmq, oxend, 'rpc.get_info', 1) + hfinfo = FutureJSON(lmq, oxend, 'rpc.hard_fork_info', 10) info = info.get() data = {**info} @@ -700,9 +700,9 @@ def api_networkinfo(): @app.route('/api/emission') def api_emission(): - lmq, lokid = lmq_connection() - info = FutureJSON(lmq, lokid, 'rpc.get_info', 1) - coinbase = FutureJSON(lmq, lokid, 'admin.get_coinbase_tx_sum', 10, timeout=1, fail_okay=True, + lmq, oxend = lmq_connection() + info = FutureJSON(lmq, oxend, 'rpc.get_info', 1) + coinbase = FutureJSON(lmq, oxend, 'admin.get_coinbase_tx_sum', 10, timeout=1, fail_okay=True, args={"height":0, "count":2**31-1}).get() if not coinbase: return flask.jsonify(None) @@ -722,8 +722,8 @@ def api_emission(): @app.route('/api/circulating_supply') def api_circulating_supply(): - lmq, lokid = lmq_connection() - coinbase = FutureJSON(lmq, lokid, 'admin.get_coinbase_tx_sum', 10, timeout=1, fail_okay=True, + lmq, oxend = lmq_connection() + coinbase = FutureJSON(lmq, oxend, 'admin.get_coinbase_tx_sum', 10, timeout=1, fail_okay=True, args={"height":0, "count":2**31-1}).get() return flask.jsonify((coinbase["emission_amount"] - coinbase["burn_amount"]) // 1000000000 if coinbase else None) @@ -731,8 +731,8 @@ def api_circulating_supply(): # FIXME: need better error handling here @app.route('/api/transaction/') def api_tx(txid): - lmq, lokid = lmq_connection() - tx = tx_req(lmq, lokid, [txid]).get() + lmq, oxend = lmq_connection() + tx = tx_req(lmq, oxend, [txid]).get() txs = parse_txs(tx) return flask.jsonify({ "status": tx['status'], @@ -742,9 +742,9 @@ def api_tx(txid): @app.route('/api/block/') @app.route('/api/block/') def api_block(blkid=None, height=None): - lmq, lokid = lmq_connection() - block = block_with_txs_req(lmq, lokid, blkid if blkid is not None else height).get() - txs = get_block_txs_future(lmq, lokid, block) + lmq, oxend = lmq_connection() + block = block_with_txs_req(lmq, oxend, blkid if blkid is not None else height).get() + txs = get_block_txs_future(lmq, oxend, block) if 'block_header' in block: data = block['block_header'].copy() @@ -761,7 +761,7 @@ ticker_cache, ticker_cache_expires = {}, None @app.route('/api/price/') def api_price(fiat=None): global ticker_cache, ticker_cache_expires, ticker_vs, ticker_vs_expires - # TODO: will need to change to 'oxen' when the ticker changes: + # TODO: will need to change to 'oxen' when/if the ticker changes: ticker = 'loki-network' if not ticker_cache or not ticker_cache_expires or ticker_cache_expires < time.time(): diff --git a/templates/_basic.html b/templates/_basic.html index 4183c84..8a3a52b 100644 --- a/templates/_basic.html +++ b/templates/_basic.html @@ -3,7 +3,7 @@ {% block head %} - {% block title %}{% endblock %}Loki{{' TESTNET' if info and info.testnet else ' DEVNET' if info and info.devnet else ''}} + <title>{% block title %}{% endblock %}Oxen{{' TESTNET' if info and info.testnet else ' DEVNET' if info and info.devnet else ''}} Blockchain Explorer {% if refresh %} @@ -16,7 +16,7 @@ @@ -172,7 +172,7 @@ {{symbol.display(b.txs[0])}} {{b.miner_tx_hash}} {{fee.display(b.txs[0])}} - {{b.reward | loki(tag=False, fixed=True, decimals=2)}} + {{b.reward | oxen(tag=False, fixed=True, decimals=2)}} 0/{{b.txs[0].info.vout | length}} {{b.txs[0].size | si}} diff --git a/templates/mempool.html b/templates/mempool.html index 75d637a..c8a9509 100644 --- a/templates/mempool.html +++ b/templates/mempool.html @@ -13,7 +13,7 @@ 🚫 Deregistration 📋 IP Change Penalty 🔓 Stake Unlock - 🎫 Loki Name System Purchase + 🎫 Oxen Name System Purchase 💾 LNS Update diff --git a/templates/sn.html b/templates/sn.html index aeeb734..2092821 100644 --- a/templates/sn.html +++ b/templates/sn.html @@ -41,7 +41,7 @@ {{sn.state_height}} - {{sn.staking_requirement | loki}} + {{sn.staking_requirement | oxen}} {%if not solo_node%} {{(sn.portions_for_operator / portions_base * 100) | round(3) | chop0}}% @@ -50,12 +50,12 @@ {%if sn.total_contributed >= sn.staking_requirement%}100% {%else%} - {{sn.total_contributed | loki}} ({{(sn.total_contributed / sn.staking_requirement * 100) | round(2) | chop0}}%) + {{sn.total_contributed | oxen}} ({{(sn.total_contributed / sn.staking_requirement * 100) | round(2) | chop0}}%) {%endif%} {%if sn.total_reserved != sn.total_contributed%} - {{sn.total_reserved | loki}} + {{sn.total_reserved | oxen}} {%endif%} @@ -132,10 +132,10 @@ {%endif%}

{%else%} -

Awaiting registration. This service node has {{(sn.staking_requirement - sn.total_contributed) | loki}} +

Awaiting registration. This service node has {{(sn.staking_requirement - sn.total_contributed) | oxen}} remaining to be contributed. {%if sn.num_open_spots > 0%} - The minimum required stake contribution is {{((sn.staking_requirement - sn.total_reserved) / sn.num_open_spots) | loki}}. + The minimum required stake contribution is {{((sn.staking_requirement - sn.total_reserved) / sn.num_open_spots) | oxen}}. {%endif%}

{%endif%} @@ -166,12 +166,12 @@ {%for c in sn.contributors%} {{c.address}} - {{c.amount | loki}} + {{c.amount | oxen}} {%-if c.locked_contributions and c.locked_contributions|length > 1%} ({{c.locked_contributions|length}} contributions) {%endif-%} - {{c.reserved | loki}} + {{c.reserved | oxen}} {%endfor%} diff --git a/templates/tx.html b/templates/tx.html index dd1bc3f..5251347 100644 --- a/templates/tx.html +++ b/templates/tx.html @@ -58,7 +58,7 @@ {%else%} {% import 'include/tx_fee.html' as fee %} {{fee.display(tx)}} - ({{(tx.info.rct_signatures.txnFee * 1000 / tx.size) | loki(tag=false, decimals=6)}}) + ({{(tx.info.rct_signatures.txnFee * 1000 / tx.size) | oxen(tag=false, decimals=6)}}) {%endif%}
{{tx.size|si}}B @@ -138,9 +138,9 @@ This tx does not includes a vote from this testing service node (only 7 votes ar

{{unlock_signature}}

{# FIXME #} {% elif tx.info.type == 4 and 'lns' in tx.extra %} {% if 'buy' in tx.extra.lns %} -

🎫 Loki Name Service Registration

+

🎫 Oxen Name Service Registration

{% elif 'update' in tx.extra.lns %} -

💾 Loki Name Service Update

+

💾 Oxen Name Service Update

{% endif %} {#FIXME - show some metadata?#} {% elif 'sn_registration' in tx.extra %} @@ -187,7 +187,7 @@ This tx does not includes a vote from this testing service node (only 7 votes ar {%if tx.info.vout%}

Outputs

{{tx.info.vout|length}} output(s) for total of - {{tx.info.vout | sum(attribute='amount') | loki(zero='???') | safe}}

+ {{tx.info.vout | sum(attribute='amount') | oxen(zero='???') | safe}}
@@ -203,7 +203,7 @@ This tx does not includes a vote from this testing service node (only 7 votes ar {%for out in tx.info.vout%} - + {%endfor%} @@ -256,7 +256,7 @@ This tx does not includes a vote from this testing service node (only 7 votes ar

Prove to someone that you have sent them Loki in this transaction

TX private key can be obtained using get_tx_key - command in loki-wallet-cli command line tool + command in oxen-wallet-cli command line tool
{%if enable_js%} Note: Address/Subaddress and TX private key are NOT sent to the server, as the calculations are done on the client side @@ -522,7 +522,7 @@ This tx does not includes a vote from this testing service node (only 7 votes ar

Inputs

{{tx.info.vin|length}} input(s) for total of - {{tx.info.vin | sum(attribute='key.amount') | loki(zero='???') | safe}}

+ {{tx.info.vin | sum(attribute='key.amount') | oxen(zero='???') | safe}}
{#FIXME#} @@ -556,7 +556,7 @@ This tx does not includes a vote from this testing service node (only 7 votes ar {%endif%} {%endif%} - + {%if config.enable_mixins_details%} diff --git a/testnet.py b/testnet.py index ae70bdb..3f9e972 100644 --- a/testnet.py +++ b/testnet.py @@ -1,3 +1,3 @@ from observer import app, config -config.lokid_rpc = 'ipc://lokid/testnet.sock' +config.oxend_rpc = 'ipc://oxend/testnet.sock'
{{out.target.key}}{{out.amount | loki(zero='?')}}{{out.amount | oxen(zero='?')}} {%if 'output_indices' in tx%}{{tx.output_indices[loop.index0]}}{# FIXME: of {{num_outputs}}#}{%endif%}
Amount: {{inp.key.amount | loki(zero='?')}}Amount: {{inp.key.amount | oxen(zero='?')}}