Add country data to display of service nodes.
To enable: ``` $ sudo apt install python3-geoip2 # or: 'pip install geoip2' for the latest $ sudo apt install geoipupdate ``` If necessary, sign up for an account with MaxMind: https://www.maxmind.com/en/geolite2/signup Edit `/etc/GeoIP.conf` with the details of your MaxMind account: ``` AccountID 123456 LicenseKey xxxxxxxxxxxxxxxx EditionIDs GeoLite2-City GeoLite2-ASN ``` Edit `/etc/cron.d/geoipupdate`: ``` # MaxMind database updates take place on Tuesdays and Fridays. # 00 12 * * 2,5 root test -x /usr/bin/geoipupdate && grep -q '^AccountID .*[^0]\+' /etc/GeoIP.conf && /usr/bin/geoipupdate ``` Edit `./local_config.py`: ``` config.geoip_dir = '/var/lib/GeoIP' ```
This commit is contained in:
parent
07182822c8
commit
3c55bb8106
|
@ -6,3 +6,4 @@ from observer import config
|
|||
# Example config override:
|
||||
#config.blocks_per_page = 10
|
||||
|
||||
config.geoip_dir = '/var/lib/GeoIP'
|
||||
|
|
13
observer.py
13
observer.py
|
@ -26,6 +26,7 @@ import sha3
|
|||
import config
|
||||
import local_config
|
||||
from lmq import FutureJSON, omq_connection
|
||||
import geoip2.database
|
||||
|
||||
# Make a dict of config.* to pass to templating
|
||||
conf = {x: getattr(config, x) for x in dir(config) if not x.startswith('__')}
|
||||
|
@ -47,7 +48,6 @@ class Hex64Converter(BaseConverter):
|
|||
|
||||
app.url_map.converters['hex64'] = Hex64Converter
|
||||
|
||||
|
||||
@app.template_filter('format_datetime')
|
||||
def format_datetime(value, format='long'):
|
||||
return babel.dates.format_datetime(value, format, tzinfo=babel.dates.get_timezone('UTC'))
|
||||
|
@ -186,10 +186,11 @@ def get_sns_future(omq, oxend):
|
|||
'last_reward_transaction_index', 'active', 'funded', 'earned_downtime_blocks',
|
||||
'service_node_version', 'contributors', 'total_contributed', 'total_reserved',
|
||||
'staking_requirement', 'portions_for_operator', 'operator_address', 'pubkey_ed25519',
|
||||
'last_uptime_proof', 'state_height', 'swarm_id') } })
|
||||
'last_uptime_proof', 'state_height', 'swarm_id', 'public_ip') } })
|
||||
|
||||
def get_sns(sns_future, info_future):
|
||||
info = info_future.get()
|
||||
geoip = geoip2.database.Reader(config.geoip_dir + '/GeoLite2-City.mmdb')
|
||||
awaiting_sns, active_sns, inactive_sns = [], [], []
|
||||
sn_states = sns_future.get()
|
||||
sn_states = sn_states['service_node_states'] if 'service_node_states' in sn_states else []
|
||||
|
@ -197,6 +198,7 @@ def get_sns(sns_future, info_future):
|
|||
sn['contribution_open'] = sn['staking_requirement'] - sn['total_reserved']
|
||||
sn['contribution_required'] = sn['staking_requirement'] - sn['total_contributed']
|
||||
sn['num_contributions'] = sum(len(x['locked_contributions']) for x in sn['contributors'] if 'locked_contributions' in x)
|
||||
sn['country'] = geoip.city(sn['public_ip']).country.names['en']
|
||||
|
||||
if sn['active']:
|
||||
active_sns.append(sn)
|
||||
|
@ -570,6 +572,8 @@ def show_sn(pubkey, more_details=False):
|
|||
hfinfo = FutureJSON(omq, oxend, 'rpc.hard_fork_info', 10)
|
||||
sn = sn_req(omq, oxend, pubkey).get()
|
||||
quos = get_quorums_future(omq, oxend, info.get()['height'])
|
||||
geoip_c = geoip2.database.Reader(config.geoip_dir + '/GeoLite2-City.mmdb')
|
||||
geoip_a = geoip2.database.Reader(config.geoip_dir + '/GeoLite2-ASN.mmdb')
|
||||
|
||||
|
||||
if 'service_node_states' not in sn or not sn['service_node_states']:
|
||||
|
@ -588,6 +592,11 @@ def show_sn(pubkey, more_details=False):
|
|||
sn['num_reserved_spots'] = sum(x["amount"] < x["reserved"] for x in sn["contributors"])
|
||||
# Available open contribution spots:
|
||||
sn['num_open_spots'] = 0 if sn['total_reserved'] >= sn['staking_requirement'] else max(0, 4 - sn['num_contributions'] - sn['num_reserved_spots'])
|
||||
sn['country'] = geoip_c.city(sn['public_ip']).country.names['en']
|
||||
city = geoip_c.city(sn['public_ip']).city
|
||||
if city.names:
|
||||
sn['city'] = city.names['en']
|
||||
sn['asn'] = geoip_a.asn(sn['public_ip']).autonomous_system_organization
|
||||
|
||||
if more_details:
|
||||
formatter = HtmlFormatter(cssclass="syntax-highlight", style="paraiso-dark")
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
<td title="Can also be the height of the last activation, IP penalty, or recommission">Last Reward Height</td>
|
||||
<td>Last Uptime Proof</td>
|
||||
<td>Expiry Date UTC (Estimated)</td>
|
||||
<td>Country</td>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
|
@ -28,6 +29,7 @@
|
|||
Staking Infinitely
|
||||
{%endif%}
|
||||
</td>
|
||||
<td>{{sn.country}}</td>
|
||||
</tr>
|
||||
{%endfor%}
|
||||
</tbody>
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
<td>Open For Contribution</td>
|
||||
<td>Min. Contribution</td>
|
||||
<td>Expiry Date UTC (Estimated)</td>
|
||||
<td>Country</td>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
|
@ -35,6 +36,7 @@
|
|||
Staking Infinitely
|
||||
{%endif%}
|
||||
</td>
|
||||
<td>{{sn.country}}</td>
|
||||
</tr>
|
||||
{%endfor%}
|
||||
{%if limit_awaiting and (awaiting_sns | length) > limit_awaiting%}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<td>Decommission Height</td>
|
||||
<td>Last Uptime Proof</td>
|
||||
<td>Blocks until Dereg.</td>
|
||||
<td>Country</td>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
|
@ -19,6 +20,7 @@
|
|||
<td>{%if sn.decomm_blocks_remaining > 0%}{{sn.decomm_blocks_remaining}} ({{(sn.decomm_blocks_remaining * 120) | reltime}})
|
||||
{%-else%}None (deregistration imminent!)
|
||||
{%-endif%}</td>
|
||||
<td>{{sn.country}}</td>
|
||||
</tr>
|
||||
{%endfor%}
|
||||
|
||||
|
|
|
@ -19,6 +19,11 @@
|
|||
<h4 style="margin:5px"><label>Lokinet Address:</label> {{sn.pubkey_ed25519 | base32z}}.snode</h4>
|
||||
{%endif%}
|
||||
<h4 style="margin:5px"><label>Operator Address:</label> {{sn.operator_address}}</h4>
|
||||
<h4 style="margin:5px"><label>Country:</label> {{sn.country}}</h4>
|
||||
{%if sn.city %}
|
||||
<h4 style="margin:5px"><label>City:</label> {{sn.city}}</h4>
|
||||
{%endif%}
|
||||
<h4 style="margin:5px"><label>Network:</label> {{sn.asn}}</h4>
|
||||
</div>
|
||||
<img class="qr" src="/qr/{{sn.service_node_pubkey}}" title="{{sn.service_node_pubkey}}">
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue