oxen-observer/templates/sn.html
2023-01-11 19:39:10 -04:00

9.5 KiB

{% extends "_basic.html" %} {% block content %} {%-set portions_base = 2**64 - 4 %} {%-set solo_node = sn.contributors|length == 1 and sn.funded %} {%-set decommed = sn.funded and not sn.active %}

Service Node Details

Service Node Public Key: {{sn.service_node_pubkey}}

{%if sn.pubkey_ed25519 %} {%if sn.pubkey_ed25519 != sn.service_node_pubkey%}

Service Node Auxiliary Pubkey: {{sn.pubkey_ed25519}}

{%endif%}

Lokinet Address: {{sn.pubkey_ed25519 | base32z}}.snode

{%endif%}

Operator Address: {{sn.operator_address}}

Metadata

Registration height: {{sn.registration_height}} {%if sn.registration_hf_version < hf.version%} (hardfork v{{sn.registration_hf_version}}) {%endif%} {%if sn.funded%} {%if sn.active%} Active since block: {%else%}{# decommissioned #} Decommissioned since block: {%endif%} {%else%} Last contribution block: {%endif%} {{sn.state_height}} Staking requirement: {{sn.staking_requirement | oxen}} {%if not solo_node%} Operator fee: {{(sn.portions_for_operator / portions_base * 100) | round(3) | chop0}}% {%endif%} Total contributed: {%if sn.total_contributed >= sn.staking_requirement%}100% {%else%} {{sn.total_contributed | oxen}} ({{(sn.total_contributed / sn.staking_requirement * 100) | round(2) | chop0}}%) {%endif%} {%if 'total_reserved' in sn and sn.total_reserved != sn.total_contributed%} Reserved stakes: {{(sn.total_reserved - sn.total_contributed) | oxen}} {%endif%} {%if decommed %}Remaining{%else%}Allowed{%endif%} downtime: {%if sn.earned_downtime_blocks > 0%} {{ (sn.earned_downtime_blocks * 120) | reltime(in_ago=false) }} ({{sn.earned_downtime_blocks}} blocks) {%if not decommed and sn.earned_downtime_blocks < 60%} (Note: ≥ 60 blocks required) {%endif%} {%else%} None {%endif%} Version: {%if sn.last_uptime_proof == 0%} Not received {%else%} {{sn.service_node_version[0]}}.{{sn.service_node_version[1]}}.{{sn.service_node_version[2]}} {%endif%} Last uptime proof: {%if sn.last_uptime_proof == 0%} Not received {%else%} {{sn.last_uptime_proof | from_timestamp | ago}} ago {%endif%} {%if info.service_node%}{# SN tests are only conducted by SNs #} {% import 'include/reachable.html' as reachable %} {{reachable.display(sn)}} {{reachable.display(sn, true)}} {%endif%} {%set pulse_voted = sn.pulse_participation | selectattr("voted") | list | length%} {%set pulse_total = sn.pulse_participation | length%} = 8 and pulse_voted < 4%} class="omg warning"{%endif%}>Pulse votes: {{pulse_voted}} / {{pulse_total}} {%set cp_voted = sn.checkpoint_participation | selectattr("voted") | list | length%} {%set cp_total = sn.checkpoint_participation | length%} = 8 and cp_voted < 4%} class="omg warning"{%endif%}>Checkpoint votes: {{cp_voted}} / {{cp_total}} Swarm ID: {%if sn.swarm_id == 18446744073709551615%}(none){%else%}0x{{'{:016x}'.format(sn.swarm_id)}}{%endif%} {%set next_test = namespace(height=none)%} {%for q in quorums.obligation[-13:]%} {%if next_test.height%}{%break%}{%endif%} {%if q.height + 13 >= info.height%} {%for w in q.quorum.workers%} {%if w == sn.service_node_pubkey%} {%set next_test.height = q.height + 13%} {%break%} {%endif%} {%endfor%} {%endif%} {%endfor%} Next SN test: {%if next_test.height%} Block {{next_test.height}} ({%if next_test.height == info.height%}Now!{%else%}~{{((next_test.height - info.height) * 120) | reltime(in_ago=false)}}{%endif%}) {%else%} Unknown {%endif%}

Service Node Status

{%if sn.active %}

Registered, staked, and active on the network since block {{sn.state_height}}.

{%elif sn.funded%}

Decommissioned: this service node is registered and staked, but is currently decommissioned (since block {{sn.state_height}}) for failing to meet service node requirements. {%if sn.earned_downtime_blocks > 0%} If it does not return to active duty within {{sn.earned_downtime_blocks}} blocks (about {{(sn.earned_downtime_blocks * 120) | reltime(in_ago=false)}}) it will face deregistration. {%else%} The decommission time has expired; service node deregistration is imminent. {%endif%}

{%else%}

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

{%endif%}

{%if sn.requested_unlock_height > 0%} This service node is scheduled to expire at block {{sn.requested_unlock_height}}, in approximately {{((sn.requested_unlock_height - info.height + 1) * 120) | reltime(in_ago=false) }} ({{(server.timestamp + (sn.requested_unlock_height - info.height + 1) * 120) | from_timestamp | format_datetime('short')}} UTC, est.) {%else%} This service node is staking infinitely: no unlock has been initiated by any of its contributors. {%endif%}

{{sn.contributors|length}} Contributor{%if sn.contributors|length > 1%}s{%endif%}

{%for c in sn.contributors%} {%endfor%}
Contributor Amount Reserved
{{c.address}} {{c.amount | oxen}} {%-if c.locked_contributions and c.locked_contributions|length > 1%} ({{c.locked_contributions|length}} contributions) {%endif-%} {{(c.reserved if 'reserved' in c else c.amount) | oxen}}
{#FIXME:#} {%if pending_stakes and pending_stakes|length > 0%}

{{pending_stakes|length}} pending mempool contribution(s)

{%for s in pending_stakes%} {%endfor%}
Contributor TX Amount
{{s.address}} {{s.txid}} {{s.amount}}
{%endif%} {%if details_html%}
{{details_html | safe}} {%else%}
Show raw details
{%endif%}
{% endblock %}