Three-part completion of the tier-2 arc from 0278:
1. systemd — scripts/asm-sequencer/deploy/{asm-sequencer.service,README.md}
Sandboxed unit (NoNewPrivileges, ProtectSystem=strict, PrivateTmp,
MemoryDenyWriteExecute), EnvironmentFile at /etc/asm-sequencer/env,
SIGINT graceful shutdown, auto-restart, nginx reverse-proxy snippet.
2. User-funded endpoints — server.mjs adds:
GET /tip current reservoir + token metadata for local tx build
POST /submit body {signedTxHex, tipTxid, tipVout, amountUnits}
under mutex: verify tip, provider.sendRawTransaction,
advance local chain. 409 stale with currentTip on race.
Chipnet proof via scripts/chipnet-asm-sequencer-userfunded-test.mjs:
5/5 accepted, 15 total /submit attempts (mean 3.0), 6.6 s wall time,
daemon chain depth 0 → 5. Users signed their own BCH inputs locally;
daemon received signed hex only, never saw a user key.
Txids: 32ba4055… → 10945cf9… → 71ef9a7e… → ed8fedaa… → 05e7f66d…
Funded A/C/E/F/G from H via new scripts/chipnet-fund-from-h.mjs
(one tx dc725fa5f3252b40…, 5×150k sats outputs, 32.6M-sat change
back to H).
3. Wallet-side client — sequencerRelay.ts in both:
- shells/app/src/asm-core/
- design/potidaea/src/
Same API: getSequencerEndpoint/setSequencerEndpoint (localStorage
key asm-sequencer.endpoint), sequencerReachable, sequencerClaim,
claimViaRelayOrFallback. Probe-first-then-commit dispatch — the
relay and local path both advance the SAME reservoir UTXO so parallel
execution would create a self-double-spend risk; the probe cost is
worth paying for correctness. Default disabled; opts in via LS key.
Snapshot 0279 + wiki/asm/zero-contention-protocol.md updated.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
60 lines
1.7 KiB
Desktop File
60 lines
1.7 KiB
Desktop File
[Unit]
|
|
Description=ASM sequencer (tier-2 relay for same-target reservoir races)
|
|
Documentation=file:///opt/deviant/wiki/asm/zero-contention-protocol.md
|
|
After=network-online.target
|
|
Wants=network-online.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=asm-seq
|
|
Group=asm-seq
|
|
WorkingDirectory=/opt/deviant
|
|
|
|
# EnvironmentFile holds the coordinator WIF, listen port, token selection.
|
|
# Must be mode 600, owned by asm-seq:asm-seq. Never commit this file.
|
|
# PORT=8710
|
|
# COORD=h (chipnet) or <your-prod-handle>
|
|
# TOKEN=asm2
|
|
# MAX_CHAIN_DEPTH=200
|
|
EnvironmentFile=/etc/asm-sequencer/env
|
|
|
|
ExecStart=/usr/bin/node /opt/deviant/scripts/asm-sequencer/server.mjs
|
|
|
|
# Graceful SIGINT shutdown (the server prints its totalServed stats on signal)
|
|
KillSignal=SIGINT
|
|
TimeoutStopSec=15
|
|
|
|
# Automatic restart with backoff — the sequencer is stateless (first /claim
|
|
# after restart re-fetches tip from the node), so restarts are safe.
|
|
Restart=on-failure
|
|
RestartSec=5
|
|
|
|
# Sandboxing — the only writes the service does are chipnet broadcasts via
|
|
# the configured electrum. No local filesystem writes required.
|
|
NoNewPrivileges=yes
|
|
ProtectSystem=strict
|
|
ProtectHome=yes
|
|
PrivateTmp=yes
|
|
PrivateDevices=yes
|
|
ProtectKernelTunables=yes
|
|
ProtectKernelModules=yes
|
|
ProtectControlGroups=yes
|
|
LockPersonality=yes
|
|
MemoryDenyWriteExecute=yes
|
|
RestrictRealtime=yes
|
|
RestrictSUIDSGID=yes
|
|
RestrictNamespaces=yes
|
|
SystemCallArchitectures=native
|
|
|
|
# Resource caps — a sequencer serving one category has a small footprint.
|
|
MemoryHigh=256M
|
|
MemoryMax=512M
|
|
TasksMax=64
|
|
|
|
# Network — only outbound to the chipnet electrum pool + inbound on PORT.
|
|
# Bind-mount or firewall rules handle the inbound; the service doesn't need
|
|
# raw-socket or multicast access.
|
|
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|