PageSourceSearch

https://smartiecoin.com/masternodes.html

html smartiecoin.com collected 2026-10-08 23:36:55 UTC 23,230 bytes, 539 lines download raw bytes

1<!doctype html>
2<html lang="en">
3<head>
4  <meta charset="utf-8">
5  <meta name="viewport" content="width=device-width, initial-scale=1">
6  <title>Masternode + Quorum Health | Smartiecoin (SMT)</title>
7  <meta name="description" content="Live masternode and LLMQ quorum health for the Smartiecoin (SMT) network: node counts, DKG sessions, active quorums, and progress toward 100-node milestones.">
8  <meta name="theme-color" content="#0a0a0b">
9  <meta property="og:type" content="website">
10  <meta property="og:title" content="Smartiecoin Masternode + Quorum Health">
11  <meta property="og:description" content="Live masternode and LLMQ quorum health for the Smartiecoin network.">
12  <meta property="og:image" content="https://smartiecoin.com/assets/logo-social.png">
13  <meta property="og:image:width" content="1200">
14  <meta property="og:image:height" content="630">
15  <meta property="og:image:alt" content="Smartiecoin logo">
16  <meta property="og:url" content="https://smartiecoin.com/masternodes.html">
17  <meta name="twitter:card" content="summary_large_image">
18  <meta name="twitter:image" content="https://smartiecoin.com/assets/logo-social.png">
19  <meta name="twitter:image:alt" content="Smartiecoin logo">
20  <link rel="icon" type="image/png" sizes="64x64" href="assets/favicon.png">
21  <link rel="apple-touch-icon" href="assets/logo-mark.png">
22  <link rel="preconnect" href="https://fonts.googleapis.com">
23  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
24  <link href="https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700&family=Geist+Mono:wght@400;500&display=swap" rel="stylesheet">
25  <link rel="stylesheet" href="styles.css">
26  
27</head>
28<body>
29  <a class="skip-link" href="#main">Skip to content</a>
30
31
32  <header class="site-header">
33    <div class="container header-row">
34      <a class="brand" href="index.html">
35        <img class="brand-logo" src="assets/logo-mark.png" alt="Smartiecoin logo" width="30" height="30">
36        <span>Smartiecoin</span>
37        <strong>SMT</strong>
38      </a>
39
40      <button class="menu-toggle" type="button" aria-expanded="false" aria-controls="primary-nav">Menu</button>
41
42      <nav id="primary-nav" class="nav-links" aria-label="Primary">
43        <a href="index.html#snapshot">Snapshot</a>
44        <a href="index.html#tokenomics">Tokenomics</a>
45        <a href="index.html#live">Live Stats</a>
46        <a href="index.html#tech">Technology</a>
47        <a href="masternodes.html" aria-current="page">Masternodes</a>
48        <a href="https://explorer.smartiecoin.com/mempool/" target="_blank" rel="noopener">Mempool&nbsp;↗</a>
49        <a href="index.html#links">Links</a>
50      </nav>
51    </div>
52  </header>
53
54  <main id="main">
55    <section class="mn-hero">
56      <div class="container">
57        <p class="eyebrow">Network Health</p>
58        <h1>Masternode + Quorum Dashboard</h1>
59        <p class="lead">
60          Live snapshot of the Smartiecoin masternode set and LLMQ quorum health. This page tracks
61          node counts, active quorums, and DKG sessions as the network grows toward the thresholds
62          required to activate InstantSend, ChainLocks, and platform quorums at scale.
63        </p>
64        <div class="mn-meta">
65          <span><span id="freshness-dot" class="dot"></span><span id="freshness-label">Loading...</span></span>
66          <span>Source: <code>smartiecoin-cli</code> on a synced node</span>
67          <span>Updated: <span id="fetched-at">-</span></span>
68          <span>Auto-refresh: <span id="refresh-countdown">60s</span></span>
69        </div>
70      </div>
71    </section>
72
73    <section class="section">
74      <div class="container">
75        <div class="mn-grid" id="stat-cards">
76          <article class="card mn-stat accent-orange">
77            <span class="label">Enabled Nodes</span>
78            <div class="value"><span id="stat-enabled" class="skeleton">--</span></div>
79            <div class="sub"><span id="stat-total">total --</span></div>
80          </article>
81          <article class="card mn-stat accent-sky">
82            <span class="label">Evo Nodes</span>
83            <div class="value"><span id="stat-evo" class="skeleton">--</span></div>
84            <div class="sub">75,000 SMT collateral</div>
85          </article>
86          <article class="card mn-stat accent-mint">
87            <span class="label">Regular Nodes</span>
88            <div class="value"><span id="stat-regular" class="skeleton">--</span></div>
89            <div class="sub">15,000 SMT collateral</div>
90          </article>
91          <article class="card mn-stat accent-violet">
92            <span class="label">DKG Sessions</span>
93            <div class="value"><span id="stat-dkg" class="skeleton">--</span></div>
94            <div class="sub"><span id="stat-dkg-sub">monitoring--</span></div>
95          </article>
96        </div>
97      </div>
98    </section>
99
100    <section class="section">
101      <div class="container">
102        <article class="card mn-progress-card">
103          <div class="mn-progress-head">
104            <h3>Network Growth - Milestones</h3>
105            <span class="pct"><span id="progress-nodes" class="skeleton">--</span> nodes</span>
106          </div>
107          <div class="mn-progress-track">
108            <div class="mn-progress-bar" id="progress-bar"></div>
109            <div class="mn-progress-ticks" id="progress-ticks"></div>
110          </div>
111          <div class="mn-progress-scale" id="progress-scale"></div>
112          <div class="mn-milestones" id="progress-milestones"></div>
113          <p class="mn-progress-foot">
114            <span id="progress-foot">Each milestone unlocks a stronger LLMQ. Regular (15k SMT) and Evo (75k SMT) nodes count equally toward all of them.</span>
115          </p>
116        </article>
117      </div>
118    </section>
119
120    <section class="section">
121      <div class="container">
122        <div class="mn-grid-2 mn-grid">
123          <article class="card quorum-list">
124            <h3>Active Quorums</h3>
125            <div id="quorum-rows">
126              <div class="quorum-row is-empty">
127                <span class="q-name skeleton">LLMQ_TYPE</span>
128                <span class="q-count skeleton">-</span>
129                <span class="q-bar"><span style="width: 0%"></span></span>
130                <span class="q-status off">...</span>
131              </div>
132            </div>
133          </article>
134
135          <article class="card dkg-card">
136            <h3>DKG Health</h3>
137            <p class="sub">Distributed Key Generation stats across currently forming quorums.</p>
138            <div class="dkg-metrics">
139              <div class="m" id="dkg-sessions-box">
140                <div class="k">Sessions</div>
141                <div class="v"><span id="dkg-sessions" class="skeleton">-</span></div>
142              </div>
143              <div class="m" id="dkg-bad-box">
144                <div class="k">Worst Bad Members</div>
145                <div class="v"><span id="dkg-bad" class="skeleton">-</span></div>
146              </div>
147              <div class="m" id="dkg-commits-box">
148                <div class="k">Premature Commits</div>
149                <div class="v"><span id="dkg-commits" class="skeleton">-</span></div>
150              </div>
151            </div>
152            <ul class="dkg-sessions" id="dkg-list">
153              <li><span class="q skeleton">LLMQ_TYPE idx -</span><span class="phase skeleton">phase -</span><span class="bad skeleton">bad -</span></li>
154            </ul>
155          </article>
156        </div>
157
158        <div id="notice" class="mn-note" hidden></div>
159      </div>
160    </section>
161
162    <section class="section">
163      <div class="container">
164        <div class="section-head">
165          <h2>What these numbers mean</h2>
166          <p>
167            <strong>Regular and Evo masternodes participate equally</strong> in every quorum that
168            matters for day-to-day network operation - ChainLocks, InstantSend, and hard-fork
169            signaling. The collateral difference (15k SMT for Regular, 75k SMT for Evo) only changes
170            the masternode role; it doesn't make Evo nodes "count more" in these LLMQs. The single
171            exception is Smartiecoin Platform (LLMQ_100_67), which is Evo-only - and Platform is
172            <strong>not a current network priority</strong>.
173          </p>
174          <p style="margin-top: 0.6rem;">
175            Because Regular nodes cost 5x less collateral, they are the most cost-effective way to
176            grow the network and stabilize the LLMQs that secure transactions and finality today.
177            When <strong>Bad Members</strong> in a DKG session rise close to the quorum size, the
178            session can fail - this is expected while the network is still growing.
179          </p>
180        </div>
181        <div class="cards cards-2">
182          <article class="card">
183            <h3>Raw Data</h3>
184            <p>
185              All data on this page comes from <code>smartiecoin-cli</code> on a synced full node
186              (<code>
186masternode count</code>, <code>masternodelist json</code>, <code>quorum list</code>,
187              <code>quorum dkgstatus</code>) and is refreshed every minute.
188            </p>
189            <p style="margin-top: 0.6rem;">
190              <a class="btn btn-soft" href="assets/quorum-health.json" target="_blank" rel="noopener">View JSON</a>
191            </p>
192          </article>
193          <article class="card">
194            <h3>Run Your Own Masternode</h3>
195            <p>
196              Grow the network and help stabilize quorums. Check the repository for setup guides,
197              the required collateral, and the <code>protx register_prepare</code> flow.
198            </p>
199            <p style="margin-top: 0.6rem;">
200              <a class="btn btn-soft" href="https://github.com/SmartiesCoin/Smartiecoin" target="_blank" rel="noopener">Smartiecoin on GitHub</a>
201            </p>
202          </article>
203        </div>
204      </div>
205    </section>
206  </main>
207
208  <footer class="site-footer">
209    <div class="container footer-row">
210      <p>Smartiecoin (SMT) - Live network health from the official full node.</p>
211      <p><span id="year"></span> smartiecoin.com · <a href="https://explorer.smartiecoin.com/mempool/" target="_blank" rel="noopener">Mempool</a></p>
212    </div>
213  </footer>
214
215  
215<script>
216    (function () {
217      var DATA_URL = 'https://explorer.smartiecoin.com/quorum-health.json';
218      var FALLBACK_URL = 'assets/quorum-health.json';
219      var REFRESH_MS = 60 * 1000;
220      var STALE_AFTER_MIN = 10;
221
222      // Each LLMQ is described by what it does on the Smartiecoin network and
223      // whether it's a current priority. "inactive" means the chain knows about
224      // it but it's not part of the current activation roadmap.
225      // The "target" is signingActiveQuorumCount from src/llmq/params.h - the
226      // number of recent quorums of this type kept active for signing.
227      var QUORUM_META = {
228        llmq_10_60:  { label: 'LLMQ_10_60',  target: 4,  purpose: 'ChainLocks - 10-member quorums for small networks',     status: 'active' },
229        llmq_10_75:  { label: 'LLMQ_10_75',  target: 2,  purpose: 'InstantSend - 10-member rotated quorums for small networks', status: 'active' },
230        llmq_60_75:  { label: 'LLMQ_60_75',  target: 32, purpose: 'InstantSend DIP0024 - 60-member rotated quorums',       status: 'active' },
231        llmq_400_60: { label: 'LLMQ_400_60', target: 4,  purpose: 'ChainLocks at scale - 400-member quorums',              status: 'pending' },
232        llmq_400_85: { label: 'LLMQ_400_85', target: 4,  purpose: 'Hard-fork signaling (MNHF) - 400-member quorums',       status: 'pending' },
233        llmq_100_67: { label: 'LLMQ_100_67', target: 24, purpose: 'Smartiecoin Platform - not a current priority',         status: 'inactive' }
234      };
235
236      var $ = function (id) { return document.getElementById(id); };
237
238      function fmtNum(n) {
239        if (n === null || n === undefined || isNaN(n)) return '-';
240        return Number(n).toLocaleString('en-US');
241      }
242
243      function clearSkeleton(el) {
244        if (el) el.classList.remove('skeleton');
245      }
246
247      function setText(id, text) {
248        var el = $(id);
249        if (!el) return;
250        el.textContent = text;
251        clearSkeleton(el);
252      }
253
254      function minutesSince(iso) {
255        if (!iso) return Infinity;
256        var t = Date.parse(iso);
257        if (isNaN(t)) return Infinity;
258        return (Date.now() - t) / 60000;
259      }
260
261      function fmtAgo(iso) {
262        var mins = minutesSince(iso);
263        if (!isFinite(mins)) return 'never';
264        if (mins < 1) return 'just now';
265        if (mins < 60) return Math.round(mins) + ' min ago';
266        var hrs = mins / 60;
267        if (hrs < 24) return Math.round(hrs) + ' hr ago';
268        return Math.round(hrs / 24) + ' d ago';
269      }
270
271      function setFreshness(iso, isError) {
272        var dot = $('freshness-dot');
273        var label = $('freshness-label');
274        dot.classList.remove('stale', 'down');
275        if (isError || !iso) {
276          dot.classList.add('down');
277          label.textContent = 'Data unavailable';
278          return;
279        }
280        var mins = minutesSince(iso);
281        if (mins > STALE_AFTER_MIN) {
282          dot.classList.add('stale');
283          label.textContent = 'Data is stale (' + fmtAgo(iso) + ')';
284        } else {
285          label.textContent = 'Live';
286        }
287      }
288
289      function showNotice(msg, isError) {
290        var n = $('notice');
291        n.hidden = false;
292        n.textContent = msg;
293        n.classList.toggle('mn-error', !!isError);
294      }
295
296      function hideNotice() {
297        $('notice').hidden = true;
298      }
299
300      function renderStats(data) {
301        var nodes = data.nodes || {};
302        setText('stat-enabled', fmtNum(nodes.enabled));
303        var totalEl = $('stat-total');
304        totalEl.textContent = 'total ' + fmtNum(nodes.total);
305        setText('stat-evo', fmtNum(nodes.evo));
306        setText('stat-regular', fmtNum(nodes.regular));
307
308        var dkg = data.dkg || {};
309        setText('stat-dkg', fmtNum(dkg.sessions_count));
310        var subEl = $('stat-dkg-sub');
311        var bad = dkg.worst_bad_members || 0;
312        var commits = dkg.total_premature_commits || 0;
313        subEl.textContent = 'worst bad: ' + bad + ' | commits: ' + commits;
314      }
315
316      var MILESTONES = [
317        { nodes: 60,  title: 'InstantSend DIP0024', sub: 'LLMQ_60_75 reliable at 60 nodes' },
318        { nodes: 100, title: 'Platform possible',   sub: 'LLMQ_100_67 - optional, Evo-only' },
319        { nodes: 400, title: 'Full ChainLocks + MNHF', sub: 'LLMQ_400_60 / LLMQ_400_85 at scale' }
320      ];
321      var MILESTONE_MAX = 400;
322
323      function renderProgress(data) {
324        var nodes = data.nodes || {};
325        var enabled = nodes.enabled || 0;
326
327        var fillPct = Math.max(0, Math.min(100, (enabled / MILESTONE_MAX) * 100));
328        setText('progress-nodes', enabled.toString());
329        $('progress-bar').style.width = fillPct + '%';
330
331        var ticks = $('progress-ticks');
332        var scale = $('progress-scale');
333        var cards = $('progress-milestones');
334        ticks.innerHTML = '';
335        scale.innerHTML = '';
336        cards.innerHTML = '';
337
338        MILESTONES.forEach(function (m) {
339          var left = (m.nodes / MILESTONE_MAX) * 100;
340          var reached = enabled >= m.nodes;
341
342          var tick = document.createElement('span');
343          if (reached) tick.className = 'reached';
344          tick.style.left = left + '%';
345          ticks.appendChild(tick);
346
347          var num = document.createElement('span');
348          if (reached) num.className = 'reached';
349          num.style.left = left + '%';
350          num.textContent = m.nodes;
351          scale.appendChild(num);
352
353          var card = document.createElement('div');
354          card.className = 'mn-ms-card' + (reached ? ' reached' : '');
355          var statusCls = reached ? 'reached' : 'pending';
356          var statusTxt = reached ? 'REACHED' : 'PENDING';
357          card.innerHTML =
358            '<span class="ms-num">' + m.nodes + '</span>' +
359            '<div class="ms-body">' +
360              '<div class="ms-title">' + m.title + '</div>' +
361              '<div class="ms-sub">' + m.sub + '</div>' +
362            '</div>' +
363            '<span class="ms-status ' + statusCls + '">' + statusTxt + '</span>';
364          cards.appendChild(card);
365        });
366
367        var next = null;
368        for (var i = 0; i < MILESTONES.length; i++) {
369          if (enabled < MILESTONES[i].nodes) { next = MILESTONES[i]; break; }
370        }
371        var foot;
372        if (!next) {
373          foot = 'All network growth milestones reached. The chain can form every LLMQ type reliably.';
374        } else {
375          var remaining = next.nodes - enabled;
376          foot = 'Next milestone: ' + next.nodes + ' nodes (' + remaining + ' more to go) - ' + next.title + '.';
377        }
378        $('progress-foot').textContent = foot;
379      }
380
381      function renderQuorums(data) {
382        var container = $('quorum-rows');
383        container.innerHTML = '';
384        var quorums = data.quorums || [];
385
386        var known = Object.keys(QUORUM_META);
387        var byType = {};
388        quorums.forEach(function (q) {
389          byType[q.type] = q;
390        });
391        known.forEach(function (t) {
392          if (!byType[t]) byType[t] = { type: t, active_count: 0 };
393        });
394
395        known.forEach(function (t) {
396          var q = byType[t];
397          var meta = QUORUM_META[t] || { label: t.toUpperCase(), target: 4, purpose: '', status: 'active' };
398          var count = q.active_count || 0;
399          var target = meta.target || 4;
400          var pct = Math.max(0, Math.min(100, Math.round((count / target) * 100)));
401
402          var statusClass, statusText;
403          if (meta.status === 'inactive') {
404            statusClass = 'inactive';
405            statusText = 'NOT A PRIORITY';
406          } else if (count >= target) {
407            statusClass = 'ok';
408            statusText = 'HEALTHY';
409          } else if (count > 0) {
410            statusClass = 'warn';
411            statusText = 'FORMING';
412          } else if (meta.status === 'pending') {
413            statusClass = 'off';
414            statusText = 'WAITING ON GROWTH';
415          } else {
416            statusClass = 'off';
417            statusText = 'EMPTY';
418          }
419
420          var rowClass = 'quorum-row';
421          if (count === 0) rowClass += ' is-empty';
422          if (meta.status === 'inactive') rowClass += ' is-inactive';
423
424          var row = document.createElement('div');
425          row.className = rowClass;
426          row.innerHTML =
427            '<span class="q-name-wrap">' +
428              '<span class="q-name">' + meta.label + '</span>' +
429              (meta.purpose ? '<span class="q-purpose">' + meta.purpose + '</span>' : '') +
430            '</span>' +
431            '<span class="q-count">' + count + ' / ' + target + '</span>' +
432            '<span class="q-bar"><span style="width:' + pct + '%"></span></span>' +
433            '<span class="q-status ' + statusClass + '">' + statusText + '</span>';
434          container.appendChild(row);
435        });
436      }
437
438      function renderDkg(data) {
439        var dkg = data.dkg || {};
440        setText('dkg-sessions', fmtNum(dkg.sessions_count));
441        setText('dkg-bad', fmtNum(dkg.worst_bad_members));
442        setText('dkg-commits', fmtNum(dkg.total_premature_commits));
443
444        var badBox = $('dkg-bad-box');
445        badBox.classList.remove('warn', 'ok');
446        if ((dkg.worst_bad_members || 0) >= 10) badBox.classList.add('warn');
447        else if ((dkg.sessions_count || 0) > 0) badBox.classList.add('ok');
448
449        var list = $('dkg-list');
450        list.innerHTML = '';
451        var sessions = dkg.sessions || [];
452        if (!sessions.length) {
453          var li = document.createElement('li');
454          li.innerHTML = '<span class="q">No active DKG sessions</span><span class="phase">-</span><span class="bad">-</span>';
455          list.appendChild(li);
456          return;
457        }
458        sessions.forEach(function (s) {
459          var typeKey = 'llmq_' + (s.llmqType || 'unknown');
460          var label = (QUORUM_META[typeKey] && QUORUM_META[typeKey].label) || ('Type ' + s.llmqType);
461          var li = document.createElement('li');
462          if ((s.badMembers || 0) >= 10) li.className = 'is-bad';
463          li.innerHTML =
464            '<span class="q">' + label + ' idx ' + (s.quorumIndex != null ? s.quorumIndex : '-') + (s.aborted ? ' (aborted)' : '') + '</span>' +
465            '<span class="phase">phase ' + (s.phase != null ? s.phase : '-') + '</span>' +
466            '<span class="bad">bad ' + (s.badMembers || 0) + '</span>';
467          list.appendChild(li);
468        });
469      }
470
471      function renderAll(data) {
472        renderStats(data);
473        renderProgress(data);
474        renderQuorums(data);
475        renderDkg(data);
476        $('fetched-at').textContent = fmtAgo(data.fetched_at);
477        setFreshness(data.fetched_at, false);
478      }
479
480      function renderError() {
481        ['stat-enabled','stat-evo','stat-regular','stat-dkg','progress-nodes','dkg-sessions','dkg-bad','dkg-commits'].forEach(function (id) {
482          var el = $(id);
483          if (el) { el.textContent = '-'; clearSkeleton(el); }
484        });
485        $('progress-bar').style.width = '0%';
486        $('quorum-rows').innerHTML = '<div class="quorum-row is-empty"><span class="q-name">No data</span><span class="q-count">-</span><span class="q-bar"><span style="width:0%"></span></span><span class="q-status off">OFFLINE</span></div>';
487        $('dkg-list').innerHTML = '<li><span class="q">Data unavailable</span><span class="phase">-</span><span class="bad">-</span></li>';
488        $('fetched-at').textContent = 'never';
489        setFreshness(null, true);
490        showNotice('Could not load quorum data. The snapshot job may be warming up or the VPS may be offline.', true);
491      }
492
493      function fetchJson(url) {
494        return fetch(url, { cache: 'no-store' }).then(function (r) {
495          if (!r.ok) throw new Error('HTTP ' + r.status);
496          return r.json();
497        });
498      }
499
500      function load() {
501        fetchJson(DATA_URL)
502          .catch(function () { return fetchJson(FALLBACK_URL); })
503          .then(function (data) {
504            hideNotice();
505            renderAll(data);
506            if (data.placeholder) {
507              showNotice('Showing fallback snapshot. The live explorer feed 
507is temporarily unavailable.', false);
508            }
509          })
510          .catch(function () {
511            renderError();
512          });
513      }
514
515      var countdown = REFRESH_MS / 1000;
516      setInterval(function () {
517        countdown -= 1;
518        if (countdown <= 0) countdown = REFRESH_MS / 1000;
519        $('refresh-countdown').textContent = countdown + 's';
520      }, 1000);
521
522      load();
523      setInterval(load, REFRESH_MS);
524
525      $('year').textContent = new Date().getFullYear();
526
527      var menuBtn = document.querySelector('.menu-toggle');
528      var nav = document.getElementById('primary-nav');
529      if (menuBtn && nav) {
530        menuBtn.addEventListener('click', function () {
531          var open = menuBtn.getAttribute('aria-expanded') === 'true';
532          menuBtn.setAttribute('aria-expanded', open ? 'false' : 'true');
533          nav.classList.toggle('is-open', !open);
534        });
535      }
536    })();
537  </script>
537
538</body>
539</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.