docs(snapshot): sync workspace documentation
This commit is contained in:
424
mevnode-bot-topology.html
Normal file
424
mevnode-bot-topology.html
Normal file
@@ -0,0 +1,424 @@
|
||||
<!doctype html>
|
||||
<html lang="pl">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>mevnode topology</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #f4efe7;
|
||||
--panel: #fffaf2;
|
||||
--ink: #1f1c17;
|
||||
--muted: #6b6358;
|
||||
--line: #d9ccb7;
|
||||
--accent: #b6412f;
|
||||
--accent-2: #0e6f74;
|
||||
--accent-3: #7c5e10;
|
||||
--shadow: 0 18px 40px rgba(31, 28, 23, 0.08);
|
||||
--radius: 18px;
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; }
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: "IBM Plex Sans", "Segoe UI", sans-serif;
|
||||
background:
|
||||
radial-gradient(circle at top left, rgba(182, 65, 47, 0.12), transparent 28%),
|
||||
radial-gradient(circle at top right, rgba(14, 111, 116, 0.12), transparent 24%),
|
||||
linear-gradient(180deg, #fbf7f0 0%, var(--bg) 100%);
|
||||
color: var(--ink);
|
||||
}
|
||||
|
||||
.page {
|
||||
max-width: 1480px;
|
||||
margin: 0 auto;
|
||||
padding: 32px 20px 48px;
|
||||
}
|
||||
|
||||
.hero {
|
||||
display: grid;
|
||||
grid-template-columns: 1.2fr 0.8fr;
|
||||
gap: 24px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.hero-card,
|
||||
.legend,
|
||||
.node,
|
||||
.strip,
|
||||
.note {
|
||||
background: rgba(255, 250, 242, 0.88);
|
||||
border: 1px solid rgba(217, 204, 183, 0.9);
|
||||
border-radius: var(--radius);
|
||||
box-shadow: var(--shadow);
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.hero-card {
|
||||
padding: 28px;
|
||||
}
|
||||
|
||||
.eyebrow {
|
||||
display: inline-block;
|
||||
padding: 6px 10px;
|
||||
border-radius: 999px;
|
||||
border: 1px solid rgba(182, 65, 47, 0.22);
|
||||
color: var(--accent);
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 16px 0 10px;
|
||||
font-family: "IBM Plex Serif", Georgia, serif;
|
||||
font-size: clamp(2rem, 4vw, 3.8rem);
|
||||
line-height: 0.98;
|
||||
}
|
||||
|
||||
.hero-card p,
|
||||
.legend p,
|
||||
.note p,
|
||||
.box p,
|
||||
.strip p {
|
||||
margin: 0;
|
||||
color: var(--muted);
|
||||
line-height: 1.55;
|
||||
}
|
||||
|
||||
.legend {
|
||||
padding: 24px;
|
||||
display: grid;
|
||||
gap: 14px;
|
||||
align-content: start;
|
||||
}
|
||||
|
||||
.legend-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
color: var(--ink);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.swatch {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border-radius: 999px;
|
||||
flex: 0 0 14px;
|
||||
}
|
||||
|
||||
.swatch.read { background: var(--accent-2); }
|
||||
.swatch.write { background: var(--accent); }
|
||||
.swatch.ops { background: var(--accent-3); }
|
||||
.swatch.store { background: #4a5565; }
|
||||
|
||||
.diagram {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(280px, 0.9fr) 120px minmax(320px, 1.25fr);
|
||||
gap: 18px;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.node {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.node h2 {
|
||||
margin: 0 0 12px;
|
||||
font-size: 1.35rem;
|
||||
font-family: "IBM Plex Serif", Georgia, serif;
|
||||
}
|
||||
|
||||
.node-head {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
gap: 12px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.node-head span {
|
||||
color: var(--muted);
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.stack {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.box {
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 14px;
|
||||
padding: 14px;
|
||||
background: #fffdf8;
|
||||
}
|
||||
|
||||
.box h3 {
|
||||
margin: 0 0 6px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.box ul {
|
||||
margin: 10px 0 0;
|
||||
padding-left: 18px;
|
||||
color: var(--ink);
|
||||
}
|
||||
|
||||
.box li {
|
||||
margin: 6px 0;
|
||||
line-height: 1.45;
|
||||
}
|
||||
|
||||
.box.read { border-left: 6px solid var(--accent-2); }
|
||||
.box.write { border-left: 6px solid var(--accent); }
|
||||
.box.ops { border-left: 6px solid var(--accent-3); }
|
||||
.box.store { border-left: 6px solid #4a5565; }
|
||||
|
||||
.bridge {
|
||||
display: grid;
|
||||
grid-template-rows: 1fr auto 1fr auto 1fr;
|
||||
align-items: center;
|
||||
justify-items: center;
|
||||
color: var(--muted);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.bridge-line {
|
||||
width: 2px;
|
||||
height: 100%;
|
||||
background:
|
||||
linear-gradient(180deg,
|
||||
rgba(14, 111, 116, 0.95) 0%,
|
||||
rgba(14, 111, 116, 0.95) 38%,
|
||||
rgba(182, 65, 47, 0.95) 38%,
|
||||
rgba(182, 65, 47, 0.95) 72%,
|
||||
rgba(124, 94, 16, 0.95) 72%,
|
||||
rgba(124, 94, 16, 0.95) 100%);
|
||||
border-radius: 999px;
|
||||
min-height: 88px;
|
||||
}
|
||||
|
||||
.bridge-tag {
|
||||
writing-mode: vertical-rl;
|
||||
transform: rotate(180deg);
|
||||
padding: 10px 0;
|
||||
font-size: 12px;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.strips {
|
||||
margin-top: 24px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
.strip {
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.strip h3 {
|
||||
margin: 0 0 10px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.strip code,
|
||||
.note code {
|
||||
font-family: "IBM Plex Mono", "Fira Code", monospace;
|
||||
font-size: 0.95em;
|
||||
background: rgba(31, 28, 23, 0.06);
|
||||
padding: 2px 6px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.note {
|
||||
margin-top: 24px;
|
||||
padding: 18px 20px;
|
||||
}
|
||||
|
||||
@media (max-width: 1120px) {
|
||||
.hero,
|
||||
.diagram,
|
||||
.strips {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.bridge {
|
||||
grid-template-columns: 1fr auto 1fr auto 1fr;
|
||||
grid-template-rows: unset;
|
||||
}
|
||||
|
||||
.bridge-line {
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
min-height: 2px;
|
||||
}
|
||||
|
||||
.bridge-tag {
|
||||
writing-mode: horizontal-tb;
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="page">
|
||||
<section class="hero">
|
||||
<div class="hero-card">
|
||||
<div class="eyebrow">Topology / mev stack</div>
|
||||
<h1>mevnode_sol daje chain access. mevnode_bot robi produkt, ingest i execution.</h1>
|
||||
<p>
|
||||
Ten układ rozdziela warstwę validatora od warstwy aplikacyjnej. Na <strong>sol</strong>
|
||||
trzymasz tylko Agave, Yellowstone i lokalne RPC. Na <strong>bot</strong> działa
|
||||
<strong>single-node k3s</strong> z frontendem, API, DLOB, strategiami i bazami danych.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<aside class="legend">
|
||||
<div class="legend-item"><span class="swatch read"></span> Read path: Yellowstone / live stream</div>
|
||||
<div class="legend-item"><span class="swatch write"></span> Write path: RPC / TPU / Jito</div>
|
||||
<div class="legend-item"><span class="swatch ops"></span> Ops path: monitoring, metryki, GitOps</div>
|
||||
<div class="legend-item"><span class="swatch store"></span> Data path: Postgres, Redis, analityka</div>
|
||||
<p>
|
||||
Zasada jest prosta: <strong>na bot nie trafia nigdy Agave ani ledger</strong>.
|
||||
`mevnode_bot` ma tylko klienty, logikę tradingową i interfejs użytkownika.
|
||||
</p>
|
||||
</aside>
|
||||
</section>
|
||||
|
||||
<section class="diagram">
|
||||
<article class="node">
|
||||
<div class="node-head">
|
||||
<h2>mevnode_sol</h2>
|
||||
<span>bare metal / validator host</span>
|
||||
</div>
|
||||
<div class="stack">
|
||||
<div class="box read">
|
||||
<h3>Agave validator</h3>
|
||||
<p>Źródło stanu chaina, snapshotów i lokalnego read/write RPC.</p>
|
||||
<ul>
|
||||
<li><code>127.0.0.1:8899</code> RPC</li>
|
||||
<li><code>10.91.0.1:10000</code> Yellowstone gRPC</li>
|
||||
<li><code>10.91.0.1:8999</code> Prometheus plugin metrics</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="box write">
|
||||
<h3>Write capability</h3>
|
||||
<p>Bot może później używać lokalnego RPC przez proxy lub iść bezpośrednio przez TPU/Jito.</p>
|
||||
</div>
|
||||
|
||||
<div class="box ops">
|
||||
<h3>Node-only responsibilities</h3>
|
||||
<ul>
|
||||
<li>snapshot recovery</li>
|
||||
<li>accounts index</li>
|
||||
<li>geyser / yellowstone plugin</li>
|
||||
<li>node metrics</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<div class="bridge" aria-hidden="true">
|
||||
<div class="bridge-line"></div>
|
||||
<div class="bridge-tag">wg0 / yellowstone / rpc / metrics</div>
|
||||
<div class="bridge-line"></div>
|
||||
<div class="bridge-tag">low latency read + controlled write</div>
|
||||
<div class="bridge-line"></div>
|
||||
</div>
|
||||
|
||||
<article class="node">
|
||||
<div class="node-head">
|
||||
<h2>mevnode_bot</h2>
|
||||
<span>single-node k3s / app + execution host</span>
|
||||
</div>
|
||||
<div class="stack">
|
||||
<div class="box read">
|
||||
<h3>Read plane</h3>
|
||||
<ul>
|
||||
<li><strong>yellowstone-consumer</strong>: bierze live stream z <code>10.91.0.1:10000</code></li>
|
||||
<li><strong>trade-ingestor</strong>: transformuje i dystrybuuje dane aplikacyjne</li>
|
||||
<li><strong>dlob-publisher</strong>: dociąga stan kont przez RPC i buduje DLOB</li>
|
||||
<li><strong>dlob-server</strong>: wystawia gotowy widok dla API i UI</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="box write">
|
||||
<h3>Execution plane</h3>
|
||||
<ul>
|
||||
<li><strong>strategy-engine</strong>: decyzje tradingowe</li>
|
||||
<li><strong>risk-manager</strong>: limity i walidacja</li>
|
||||
<li><strong>order-manager</strong>: lifecycle zleceń</li>
|
||||
<li><strong>tx-router</strong>: wybiera <code>RPC</code>, <code>TPU</code> albo <code>Jito</code></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="box store">
|
||||
<h3>Data plane</h3>
|
||||
<ul>
|
||||
<li><strong>Postgres</strong>: trwały storage, pozycje, historia, config</li>
|
||||
<li><strong>Hasura</strong>: warstwa GraphQL nad Postgres</li>
|
||||
<li><strong>Redis</strong>: cache, pub/sub, szybki stan DLOB</li>
|
||||
<li><strong>ClickHouse</strong>: opcjonalnie później pod cięższą analitykę</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="box ops">
|
||||
<h3>Product and ops</h3>
|
||||
<ul>
|
||||
<li><strong>frontend</strong> + <strong>api</strong> + <strong>ingress</strong></li>
|
||||
<li><strong>Prometheus</strong> + <strong>Grafana</strong></li>
|
||||
<li><strong>Portainer agent</strong> dla widoczności klastra w Portainerze</li>
|
||||
<li><strong>GitOps</strong>: Argo lub Flux z Gitea</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<section class="strips">
|
||||
<div class="strip">
|
||||
<h3>Read path</h3>
|
||||
<p>
|
||||
<code>Yellowstone gRPC</code> daje live account updates, sloty i transakcje.
|
||||
<code>Agave RPC</code> zostaje do odczytów punktowych typu
|
||||
<code>getAccountInfo</code>, <code>getMultipleAccounts</code>,
|
||||
<code>getHealth</code> i <code>getLatestBlockhash</code>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="strip">
|
||||
<h3>Write path</h3>
|
||||
<p>
|
||||
Wysyłka transakcji nie idzie przez Yellowstone. To robi
|
||||
<code>RPC</code>, <code>TPU</code> albo <code>Jito</code>.
|
||||
Dzięki temu read plane i write plane są od siebie operacyjnie odseparowane.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="strip">
|
||||
<h3>Deployment rule</h3>
|
||||
<p>
|
||||
Wszystko aplikacyjne i webowe ląduje na <code>mevnode_bot</code>.
|
||||
Wszystko validatorowe zostaje na <code>mevnode_sol</code>.
|
||||
To upraszcza debug, upgrade i kontrolę ryzyka.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="note">
|
||||
<p>
|
||||
Docelowy przepływ: <code>mevnode_sol -> wg0 -> yellowstone-consumer / dlob-publisher -> redis / postgres -> api -> frontend</code>.
|
||||
Osobno działa execution path: <code>strategy-engine -> tx-router -> RPC / TPU / Jito</code>.
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user