iuna

iuna

iuna - experimental mainnet-candidate protocol
git clone https://getiuna.org/git/iuna.git
Log | Files | Refs | README | LICENSE

commit afa9e771bc1723ebb3f89a6fe3d79163abcf14ab
parent d120e49c6aa58d168b038572026bd406baa8af2a
Author: Joris Hartog <jorishartog@hotmail.com>
Date:   Sun, 30 Aug 2026 23:03:22 +0200

Add docker e2e checkpoints

Diffstat:
M.dockerignore | 2++
M.gitignore | 1+
MCargo.toml | 6++++++
MDockerfile.local-testnet | 3++-
MREADME.md | 5+++++
Ae2e/README.md | 93+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ae2e/checkpoints.json | 27+++++++++++++++++++++++++++
Ae2e/docker-compose.e2e.yml | 127+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ae2e/iuna_e2e.py | 494+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ae2e/snapshots/.gitkeep | 1+
Ae2e/snapshots/fallback-invalidation/bootstrap/chain.sqlite3 | 0
Ae2e/snapshots/fallback-invalidation/bootstrap/config.json | 20++++++++++++++++++++
Ae2e/snapshots/fallback-invalidation/bootstrap/ui_data.sqlite3 | 0
Ae2e/snapshots/fallback-invalidation/bootstrap/wallet.json | 12++++++++++++
Ae2e/snapshots/fallback-invalidation/manifest.json | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ae2e/snapshots/fallback-invalidation/node2/chain.sqlite3 | 0
Ae2e/snapshots/fallback-invalidation/node2/config.json | 20++++++++++++++++++++
Ae2e/snapshots/fallback-invalidation/node2/ui_data.sqlite3 | 0
Ae2e/snapshots/fallback-invalidation/node2/wallet.json | 12++++++++++++
Ae2e/snapshots/fallback-invalidation/node3/chain.sqlite3 | 0
Ae2e/snapshots/fallback-invalidation/node3/config.json | 20++++++++++++++++++++
Ae2e/snapshots/fallback-invalidation/node3/ui_data.sqlite3 | 0
Ae2e/snapshots/fallback-invalidation/node3/wallet.json | 12++++++++++++
Ae2e/snapshots/fallback-invalidation/node4/chain.sqlite3 | 0
Ae2e/snapshots/fallback-invalidation/node4/config.json | 20++++++++++++++++++++
Ae2e/snapshots/fallback-invalidation/node4/ui_data.sqlite3 | 0
Ae2e/snapshots/fallback-invalidation/node4/wallet.json | 12++++++++++++
Ae2e/snapshots/fallback-invalidation/node5/chain.sqlite3 | 0
Ae2e/snapshots/fallback-invalidation/node5/config.json | 20++++++++++++++++++++
Ae2e/snapshots/fallback-invalidation/node5/ui_data.sqlite3 | 0
Ae2e/snapshots/fallback-invalidation/node5/wallet.json | 12++++++++++++
Ae2e/snapshots/fallback-invalidation/node6/chain.sqlite3 | 0
Ae2e/snapshots/fallback-invalidation/node6/config.json | 20++++++++++++++++++++
Ae2e/snapshots/fallback-invalidation/node6/ui_data.sqlite3 | 0
Ae2e/snapshots/fallback-invalidation/node6/wallet.json | 12++++++++++++
Ae2e/snapshots/first-objective-checkpoint/bootstrap/chain.sqlite3 | 0
Ae2e/snapshots/first-objective-checkpoint/bootstrap/config.json | 20++++++++++++++++++++
Ae2e/snapshots/first-objective-checkpoint/bootstrap/ui_data.sqlite3 | 0
Ae2e/snapshots/first-objective-checkpoint/bootstrap/wallet.json | 12++++++++++++
Ae2e/snapshots/first-objective-checkpoint/manifest.json | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ae2e/snapshots/first-objective-checkpoint/node2/chain.sqlite3 | 0
Ae2e/snapshots/first-objective-checkpoint/node2/config.json | 20++++++++++++++++++++
Ae2e/snapshots/first-objective-checkpoint/node2/ui_data.sqlite3 | 0
Ae2e/snapshots/first-objective-checkpoint/node2/wallet.json | 12++++++++++++
Ae2e/snapshots/first-objective-checkpoint/node3/chain.sqlite3 | 0
Ae2e/snapshots/first-objective-checkpoint/node3/config.json | 20++++++++++++++++++++
Ae2e/snapshots/first-objective-checkpoint/node3/ui_data.sqlite3 | 0
Ae2e/snapshots/first-objective-checkpoint/node3/wallet.json | 12++++++++++++
Ae2e/snapshots/first-objective-checkpoint/node4/chain.sqlite3 | 0
Ae2e/snapshots/first-objective-checkpoint/node4/config.json | 20++++++++++++++++++++
Ae2e/snapshots/first-objective-checkpoint/node4/ui_data.sqlite3 | 0
Ae2e/snapshots/first-objective-checkpoint/node4/wallet.json | 12++++++++++++
Ae2e/snapshots/first-objective-checkpoint/node5/chain.sqlite3 | 0
Ae2e/snapshots/first-objective-checkpoint/node5/config.json | 20++++++++++++++++++++
Ae2e/snapshots/first-objective-checkpoint/node5/ui_data.sqlite3 | 0
Ae2e/snapshots/first-objective-checkpoint/node5/wallet.json | 12++++++++++++
Ae2e/snapshots/first-objective-checkpoint/node6/chain.sqlite3 | 0
Ae2e/snapshots/first-objective-checkpoint/node6/config.json | 20++++++++++++++++++++
Ae2e/snapshots/first-objective-checkpoint/node6/ui_data.sqlite3 | 0
Ae2e/snapshots/first-objective-checkpoint/node6/wallet.json | 12++++++++++++
Ae2e/snapshots/objective-finality/bootstrap/chain.sqlite3 | 0
Ae2e/snapshots/objective-finality/bootstrap/config.json | 20++++++++++++++++++++
Ae2e/snapshots/objective-finality/bootstrap/ui_data.sqlite3 | 0
Ae2e/snapshots/objective-finality/bootstrap/wallet.json | 12++++++++++++
Ae2e/snapshots/objective-finality/manifest.json | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ae2e/snapshots/objective-finality/node2/chain.sqlite3 | 0
Ae2e/snapshots/objective-finality/node2/config.json | 20++++++++++++++++++++
Ae2e/snapshots/objective-finality/node2/ui_data.sqlite3 | 0
Ae2e/snapshots/objective-finality/node2/wallet.json | 12++++++++++++
Ae2e/snapshots/objective-finality/node3/chain.sqlite3 | 0
Ae2e/snapshots/objective-finality/node3/config.json | 20++++++++++++++++++++
Ae2e/snapshots/objective-finality/node3/ui_data.sqlite3 | 0
Ae2e/snapshots/objective-finality/node3/wallet.json | 12++++++++++++
Ae2e/snapshots/objective-finality/node4/chain.sqlite3 | 0
Ae2e/snapshots/objective-finality/node4/config.json | 20++++++++++++++++++++
Ae2e/snapshots/objective-finality/node4/ui_data.sqlite3 | 0
Ae2e/snapshots/objective-finality/node4/wallet.json | 12++++++++++++
Ae2e/snapshots/objective-finality/node5/chain.sqlite3 | 0
Ae2e/snapshots/objective-finality/node5/config.json | 20++++++++++++++++++++
Ae2e/snapshots/objective-finality/node5/ui_data.sqlite3 | 0
Ae2e/snapshots/objective-finality/node5/wallet.json | 12++++++++++++
Ae2e/snapshots/objective-finality/node6/chain.sqlite3 | 0
Ae2e/snapshots/objective-finality/node6/config.json | 20++++++++++++++++++++
Ae2e/snapshots/objective-finality/node6/ui_data.sqlite3 | 0
Ae2e/snapshots/objective-finality/node6/wallet.json | 12++++++++++++
Ae2e/snapshots/pre-fallback-invalidation/bootstrap/chain.sqlite3 | 0
Ae2e/snapshots/pre-fallback-invalidation/bootstrap/config.json | 20++++++++++++++++++++
Ae2e/snapshots/pre-fallback-invalidation/bootstrap/ui_data.sqlite3 | 0
Ae2e/snapshots/pre-fallback-invalidation/bootstrap/wallet.json | 12++++++++++++
Ae2e/snapshots/pre-fallback-invalidation/manifest.json | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ae2e/snapshots/pre-fallback-invalidation/node2/chain.sqlite3 | 0
Ae2e/snapshots/pre-fallback-invalidation/node2/config.json | 20++++++++++++++++++++
Ae2e/snapshots/pre-fallback-invalidation/node2/ui_data.sqlite3 | 0
Ae2e/snapshots/pre-fallback-invalidation/node2/wallet.json | 12++++++++++++
Ae2e/snapshots/pre-fallback-invalidation/node3/chain.sqlite3 | 0
Ae2e/snapshots/pre-fallback-invalidation/node3/config.json | 20++++++++++++++++++++
Ae2e/snapshots/pre-fallback-invalidation/node3/ui_data.sqlite3 | 0
Ae2e/snapshots/pre-fallback-invalidation/node3/wallet.json | 12++++++++++++
Ae2e/snapshots/pre-fallback-invalidation/node4/chain.sqlite3 | 0
Ae2e/snapshots/pre-fallback-invalidation/node4/config.json | 20++++++++++++++++++++
Ae2e/snapshots/pre-fallback-invalidation/node4/ui_data.sqlite3 | 0
Ae2e/snapshots/pre-fallback-invalidation/node4/wallet.json | 12++++++++++++
Ae2e/snapshots/pre-fallback-invalidation/node5/chain.sqlite3 | 0
Ae2e/snapshots/pre-fallback-invalidation/node5/config.json | 20++++++++++++++++++++
Ae2e/snapshots/pre-fallback-invalidation/node5/ui_data.sqlite3 | 0
Ae2e/snapshots/pre-fallback-invalidation/node5/wallet.json | 12++++++++++++
Ae2e/snapshots/pre-fallback-invalidation/node6/chain.sqlite3 | 0
Ae2e/snapshots/pre-fallback-invalidation/node6/config.json | 20++++++++++++++++++++
Ae2e/snapshots/pre-fallback-invalidation/node6/ui_data.sqlite3 | 0
Ae2e/snapshots/pre-fallback-invalidation/node6/wallet.json | 12++++++++++++
Ae2e/snapshots/pre-objective-finality/bootstrap/chain.sqlite3 | 0
Ae2e/snapshots/pre-objective-finality/bootstrap/config.json | 20++++++++++++++++++++
Ae2e/snapshots/pre-objective-finality/bootstrap/ui_data.sqlite3 | 0
Ae2e/snapshots/pre-objective-finality/bootstrap/wallet.json | 12++++++++++++
Ae2e/snapshots/pre-objective-finality/manifest.json | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ae2e/snapshots/pre-objective-finality/node2/chain.sqlite3 | 0
Ae2e/snapshots/pre-objective-finality/node2/config.json | 20++++++++++++++++++++
Ae2e/snapshots/pre-objective-finality/node2/ui_data.sqlite3 | 0
Ae2e/snapshots/pre-objective-finality/node2/wallet.json | 12++++++++++++
Ae2e/snapshots/pre-objective-finality/node3/chain.sqlite3 | 0
Ae2e/snapshots/pre-objective-finality/node3/config.json | 20++++++++++++++++++++
Ae2e/snapshots/pre-objective-finality/node3/ui_data.sqlite3 | 0
Ae2e/snapshots/pre-objective-finality/node3/wallet.json | 12++++++++++++
Ae2e/snapshots/pre-objective-finality/node4/chain.sqlite3 | 0
Ae2e/snapshots/pre-objective-finality/node4/config.json | 20++++++++++++++++++++
Ae2e/snapshots/pre-objective-finality/node4/ui_data.sqlite3 | 0
Ae2e/snapshots/pre-objective-finality/node4/wallet.json | 12++++++++++++
Ae2e/snapshots/pre-objective-finality/node5/chain.sqlite3 | 0
Ae2e/snapshots/pre-objective-finality/node5/config.json | 20++++++++++++++++++++
Ae2e/snapshots/pre-objective-finality/node5/ui_data.sqlite3 | 0
Ae2e/snapshots/pre-objective-finality/node5/wallet.json | 12++++++++++++
Ae2e/snapshots/pre-objective-finality/node6/chain.sqlite3 | 0
Ae2e/snapshots/pre-objective-finality/node6/config.json | 20++++++++++++++++++++
Ae2e/snapshots/pre-objective-finality/node6/ui_data.sqlite3 | 0
Ae2e/snapshots/pre-objective-finality/node6/wallet.json | 12++++++++++++
Msrc/adapters/p2p/fetch.rs | 39+++++++++++++++++++++++++++++++++++++--
Msrc/app.rs | 4++--
Msrc/app/automatic_mining.rs | 23++++++++++++++++-------
Asrc/bin/iuna-e2e-checkpoint.rs | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/domain/address.rs | 2+-
Msrc/domain/ledger_chain.rs | 4+++-
Msrc/domain/profile.rs | 15++++++++++++++-
Msrc/domain/protocol.rs | 6++++++
Msrc/main.rs | 6+++++-
Msrc/main_tests.rs | 16++++++++++++----
145 files changed, 2205 insertions(+), 20 deletions(-)

diff --git a/.dockerignore b/.dockerignore @@ -1,6 +1,8 @@ target +fuzz/target src-tauri/target src-tauri/binaries +.docker-build .agents .codex .DS_Store diff --git a/.gitignore b/.gitignore @@ -3,6 +3,7 @@ /fuzz/artifacts /.docker-build /.iuna +/e2e/.runtime /src-tauri/target /src-tauri/gen /src-tauri/binaries/iuna-sidecar-* diff --git a/Cargo.toml b/Cargo.toml @@ -24,8 +24,14 @@ tokio = { version = "1.45.1", features = ["full"] } kyn-vdf = "=0.1.1" [features] +e2e = [] fuzzing = [] +[[bin]] +name = "iuna-e2e-checkpoint" +path = "src/bin/iuna-e2e-checkpoint.rs" +required-features = ["e2e"] + [dev-dependencies] proptest = "1.6.0" tempfile = "3.20.0" diff --git a/Dockerfile.local-testnet b/Dockerfile.local-testnet @@ -4,7 +4,8 @@ FROM rust:1.88.0-bookworm AS builder WORKDIR /src/iuna COPY . . -RUN cargo build --release --locked --bin iuna +ARG IUNA_CARGO_FEATURES="" +RUN cargo build --release --locked --bin iuna ${IUNA_CARGO_FEATURES} FROM debian:bookworm-slim diff --git a/README.md b/README.md @@ -136,6 +136,11 @@ Compose: docker compose up --build ``` +For repeatable end-to-end tests around mature protocol heights such as 999, +1000, and 1001, use the isolated 5-second harness documented in +[`e2e/README.md`](e2e/README.md). It captures and restores all six chain +databases and test identities rather than re-mining from genesis for every run. + The compose file starts the static website, one bootstrap genesis node, and five joining nodes on an isolated Docker network. Every node automatically mines with one PoW worker and enables burn/finalization. Joining nodes can therefore earn diff --git a/e2e/README.md b/e2e/README.md @@ -0,0 +1,93 @@ +# Docker Compose end-to-end tests + +This harness runs the six-node network with a deliberately isolated consensus +profile, `iuna-local-e2e-5s-v1`. Its target block time is 5 seconds, its Docker +subnet is `172.29.0.0/24`, and its management ports are `28661` through `28666`. +The regular local testnet keeps its 10-minute target and can run alongside it. + +The e2e binary refuses to start unless `IUNA_LOCAL_TESTNET=true`. Its profile ID +is part of the launch-profile hash, so a 5-second checkpoint cannot be loaded by +the regular local-testnet build. + +## Everyday workflow + +Start a fresh network: + +```sh +./e2e/iuna_e2e.py reset +./e2e/iuna_e2e.py up --build +./e2e/iuna_e2e.py status +``` + +Start from a committed checkpoint and wait for all nodes to converge: + +```sh +./e2e/iuna_e2e.py up --snapshot pre-objective-finality +./e2e/iuna_e2e.py wait 1001 --converge +``` + +Run the same flow as one test, including log collection on failure and teardown: + +```sh +./e2e/iuna_e2e.py smoke \ + --from pre-objective-finality \ + --through 1001 +``` + +Use `--keep` on `smoke` to leave a failed or successful network running. Stop a +network without deleting its mutable data with: + +```sh +./e2e/iuna_e2e.py down +``` + +Runtime data lives in `e2e/.runtime` and is ignored by Git. Set +`IUNA_E2E_RUNTIME_DIR`, `IUNA_E2E_SNAPSHOTS_DIR`, `IUNA_E2E_PROJECT`, or the +`IUNA_E2E_*_PORT` variables when a test needs independent paths or ports. +`reset` only removes the six service directories beneath that configured runtime +directory; committed checkpoints are never touched. + +## Building mature checkpoints + +`checkpoints.json` records the protocol boundaries worth preserving: + +- 299 and 300: fallback-ticket invalidation; +- 999 and 1000: signing v1, replay protection, grinding resistance, and + objective-finality activation; +- 1001: the first block that can certify checkpoint 1000. + +Generate all missing checkpoints during one continuous run: + +```sh +./e2e/iuna_e2e.py reset +./e2e/iuna_e2e.py up --build +./e2e/iuna_e2e.py capture-plan +``` + +At five seconds per block, reaching height 1001 takes roughly 84 minutes plus +startup and synchronization overhead. This is a one-time fixture-building job; +normal tests restore the resulting checkpoints in seconds. Capture one custom +boundary with: + +```sh +./e2e/iuna_e2e.py capture pre-objective-finality --height 999 +``` + +Capture waits until the bootstrap SQLite checkpoint reaches the requested +height, then pauses all containers before copying anything. An e2e-only helper +materializes the canonical compact chain at the exact requested height, even if +the live chain advanced across that height between polls. That canonical chain +database and its prebuilt UI projection are paired with every node's encrypted +test wallet and configuration. +Keeping all six identities matters because their mature tickets and committee +lineage must remain usable after restore. Persisting the derived UI database +keeps mature-checkpoint startup fast. SQLite's backup API removes WAL dependence, +a manifest records the live source height plus every exact node height and tip, +and SHA-256 checksums are verified before restore. + +Snapshots use the intentionally public Compose password `testtesttest` unless +`IUNA_TESTNET_PASSWORD` was set while they were generated. They are disposable +test credentials only. Use the same password when restoring a snapshot. + +Commit reviewed snapshot directories under `e2e/snapshots/`. Do not commit the +mutable `e2e/.runtime` directory. diff --git a/e2e/checkpoints.json b/e2e/checkpoints.json @@ -0,0 +1,27 @@ +[ + { + "name": "pre-fallback-invalidation", + "height": 299, + "purpose": "Last block before fallback ticket invalidation activates" + }, + { + "name": "fallback-invalidation", + "height": 300, + "purpose": "Fallback ticket invalidation activation block" + }, + { + "name": "pre-objective-finality", + "height": 999, + "purpose": "Last legacy signing, replay and fork-choice block" + }, + { + "name": "objective-finality", + "height": 1000, + "purpose": "Signing v1, replay protection and objective finality activation block" + }, + { + "name": "first-objective-checkpoint", + "height": 1001, + "purpose": "First block that can certify checkpoint 1000" + } +] diff --git a/e2e/docker-compose.e2e.yml b/e2e/docker-compose.e2e.yml @@ -0,0 +1,127 @@ +services: + bootstrap: + build: + args: + IUNA_CARGO_FEATURES: "--features e2e" + image: iuna-local-e2e:latest + restart: "no" + command: + - if [ -s /data/chain.sqlite3 ]; then exec iuna --data-dir /data --http 0.0.0.0:18661 --p2p 0.0.0.0:9444 --p2p-announce 172.29.0.10:9444 --debug; else exec iuna --genesis --data-dir /data --http 0.0.0.0:18661 --p2p 0.0.0.0:9444 --p2p-announce 172.29.0.10:9444 --debug; fi + healthcheck: + interval: 1s + retries: 900 + start_period: 2s + ports: !override + - "${IUNA_E2E_BOOTSTRAP_PORT:-28661}:18661" + volumes: !override + - "${IUNA_E2E_RUNTIME_DIR:?set IUNA_E2E_RUNTIME_DIR}/bootstrap:/data" + networks: + iuna-testnet: + ipv4_address: 172.29.0.10 + + node2: + build: + args: + IUNA_CARGO_FEATURES: "--features e2e" + image: iuna-local-e2e:latest + restart: "no" + command: + - exec iuna --join 172.29.0.10:9444 --data-dir /data --http 0.0.0.0:18661 --p2p 0.0.0.0:9444 --p2p-announce 172.29.0.11:9444 --debug + healthcheck: + interval: 1s + retries: 900 + start_period: 2s + ports: !override + - "${IUNA_E2E_NODE2_PORT:-28662}:18661" + volumes: !override + - "${IUNA_E2E_RUNTIME_DIR:?set IUNA_E2E_RUNTIME_DIR}/node2:/data" + networks: + iuna-testnet: + ipv4_address: 172.29.0.11 + + node3: + build: + args: + IUNA_CARGO_FEATURES: "--features e2e" + image: iuna-local-e2e:latest + restart: "no" + command: + - exec iuna --join 172.29.0.10:9444 --data-dir /data --http 0.0.0.0:18661 --p2p 0.0.0.0:9444 --p2p-announce 172.29.0.12:9444 --stratum 0.0.0.0:3333 --debug + healthcheck: + interval: 1s + retries: 900 + start_period: 2s + ports: !override + - "${IUNA_E2E_NODE3_PORT:-28663}:18661" + - "${IUNA_E2E_STRATUM_PORT:-23333}:3333" + volumes: !override + - "${IUNA_E2E_RUNTIME_DIR:?set IUNA_E2E_RUNTIME_DIR}/node3:/data" + networks: + iuna-testnet: + ipv4_address: 172.29.0.12 + + node4: + build: + args: + IUNA_CARGO_FEATURES: "--features e2e" + image: iuna-local-e2e:latest + restart: "no" + command: + - exec iuna --join 172.29.0.10:9444 --data-dir /data --http 0.0.0.0:18661 --p2p 0.0.0.0:9444 --p2p-announce 172.29.0.13:9444 --debug + healthcheck: + interval: 1s + retries: 900 + start_period: 2s + ports: !override + - "${IUNA_E2E_NODE4_PORT:-28664}:18661" + volumes: !override + - "${IUNA_E2E_RUNTIME_DIR:?set IUNA_E2E_RUNTIME_DIR}/node4:/data" + networks: + iuna-testnet: + ipv4_address: 172.29.0.13 + + node5: + build: + args: + IUNA_CARGO_FEATURES: "--features e2e" + image: iuna-local-e2e:latest + restart: "no" + command: + - exec iuna --join 172.29.0.10:9444 --data-dir /data --http 0.0.0.0:18661 --p2p 0.0.0.0:9444 --p2p-announce 172.29.0.14:9444 --debug + healthcheck: + interval: 1s + retries: 900 + start_period: 2s + ports: !override + - "${IUNA_E2E_NODE5_PORT:-28665}:18661" + volumes: !override + - "${IUNA_E2E_RUNTIME_DIR:?set IUNA_E2E_RUNTIME_DIR}/node5:/data" + networks: + iuna-testnet: + ipv4_address: 172.29.0.14 + + node6: + build: + args: + IUNA_CARGO_FEATURES: "--features e2e" + image: iuna-local-e2e:latest + restart: "no" + command: + - exec iuna --join 172.29.0.10:9444 --data-dir /data --http 0.0.0.0:18661 --p2p 0.0.0.0:9444 --p2p-announce 172.29.0.15:9444 --debug + healthcheck: + interval: 1s + retries: 900 + start_period: 2s + ports: !override + - "${IUNA_E2E_NODE6_PORT:-28666}:18661" + volumes: !override + - "${IUNA_E2E_RUNTIME_DIR:?set IUNA_E2E_RUNTIME_DIR}/node6:/data" + networks: + iuna-testnet: + ipv4_address: 172.29.0.15 + +networks: + iuna-testnet: + ipam: + config: !override + - subnet: 172.29.0.0/24 diff --git a/e2e/iuna_e2e.py b/e2e/iuna_e2e.py @@ -0,0 +1,494 @@ +#!/usr/bin/env python3 +"""Docker Compose e2e runner and reproducible chain checkpoint manager.""" + +from __future__ import annotations + +import argparse +import hashlib +import http.cookiejar +import json +import os +from pathlib import Path +import re +import shutil +import sqlite3 +import subprocess +import sys +import tempfile +import time +import urllib.parse +import urllib.request +import urllib.error + + +ROOT = Path(__file__).resolve().parent.parent +E2E_DIR = ROOT / "e2e" +COMPOSE_FILES = (ROOT / "docker-compose.yml", E2E_DIR / "docker-compose.e2e.yml") +SERVICES = ("bootstrap", "node2", "node3", "node4", "node5", "node6") +DEFAULT_PORTS = { + "bootstrap": 28661, + "node2": 28662, + "node3": 28663, + "node4": 28664, + "node5": 28665, + "node6": 28666, +} +PORT_ENV = { + "bootstrap": "IUNA_E2E_BOOTSTRAP_PORT", + "node2": "IUNA_E2E_NODE2_PORT", + "node3": "IUNA_E2E_NODE3_PORT", + "node4": "IUNA_E2E_NODE4_PORT", + "node5": "IUNA_E2E_NODE5_PORT", + "node6": "IUNA_E2E_NODE6_PORT", +} +SNAPSHOT_FILES = ("chain.sqlite3", "ui_data.sqlite3", "wallet.json", "config.json") +EXPECTED_PROFILE = "iuna-local-e2e-5s-v1" +EXPECTED_BLOCK_MS = 5_000 +HTTP_TIMEOUT_SECONDS = 30 +NAME_PATTERN = re.compile(r"^[a-z0-9][a-z0-9._-]*$") +_OPENERS: dict[str, urllib.request.OpenerDirector] = {} + + +class E2EError(RuntimeError): + pass + + +def runtime_dir() -> Path: + return Path(os.environ.get("IUNA_E2E_RUNTIME_DIR", E2E_DIR / ".runtime")).resolve() + + +def snapshots_dir() -> Path: + return Path(os.environ.get("IUNA_E2E_SNAPSHOTS_DIR", E2E_DIR / "snapshots")).resolve() + + +def compose_env() -> dict[str, str]: + env = os.environ.copy() + env["IUNA_E2E_RUNTIME_DIR"] = str(runtime_dir()) + return env + + +def compose_command(*args: str) -> list[str]: + command = [ + "docker", + "compose", + "--project-name", + os.environ.get("IUNA_E2E_PROJECT", "iuna-e2e"), + ] + for compose_file in COMPOSE_FILES: + command.extend(("--file", str(compose_file))) + command.extend(args) + return command + + +def compose(*args: str, check: bool = True) -> subprocess.CompletedProcess[str]: + return subprocess.run( + compose_command(*args), + cwd=ROOT, + env=compose_env(), + check=check, + text=True, + ) + + +def validate_snapshot_name(name: str) -> str: + if not NAME_PATTERN.fullmatch(name): + raise E2EError( + "snapshot names must start with a lowercase letter or digit and only contain " + "lowercase letters, digits, '.', '_' or '-'" + ) + return name + + +def snapshot_path(name: str) -> Path: + return snapshots_dir() / validate_snapshot_name(name) + + +def node_port(service: str) -> int: + return int(os.environ.get(PORT_ENV[service], DEFAULT_PORTS[service])) + + +def node_status(service: str) -> dict: + base_url = f"http://127.0.0.1:{node_port(service)}" + opener = _OPENERS.get(service) + if opener is None: + password = os.environ.get("IUNA_TESTNET_PASSWORD", "testtesttest") + jar = http.cookiejar.CookieJar() + opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(jar)) + login = urllib.request.Request( + f"{base_url}/api/auth/login", + data=urllib.parse.urlencode({"password": password}).encode(), + headers={ + "Content-Type": "application/x-www-form-urlencoded", + "Origin": base_url, + }, + method="POST", + ) + with opener.open(login, timeout=HTTP_TIMEOUT_SECONDS) as response: + result = json.load(response) + if not result.get("ok"): + raise E2EError(f"{service} login failed: {result.get('error', 'unknown error')}") + _OPENERS[service] = opener + with opener.open( + f"{base_url}/api/status", timeout=HTTP_TIMEOUT_SECONDS + ) as response: + return json.load(response) + + +def all_statuses() -> dict[str, dict]: + return {service: node_status(service) for service in SERVICES} + + +def compact_status(status: dict) -> dict: + return { + "height": status["chain"]["height"], + "tip_hash": status["chain"]["tip_hash"], + "finalized_height": status["chain"].get("finalized_height"), + "profile": status["launch_profile"]["profile_id"], + "target_block_ms": status["mining"]["vdf_target_block_ms"], + } + + +def assert_e2e_profile(statuses: dict[str, dict]) -> None: + errors = [] + for service, status in statuses.items(): + profile = status["launch_profile"]["profile_id"] + block_ms = status["mining"]["vdf_target_block_ms"] + if profile != EXPECTED_PROFILE or block_ms != EXPECTED_BLOCK_MS: + errors.append(f"{service}: profile={profile}, target_block_ms={block_ms}") + if errors: + raise E2EError("not running the isolated 5s e2e build: " + "; ".join(errors)) + + +def read_chain_metadata(path: Path) -> dict: + if not path.exists(): + raise E2EError(f"chain database does not exist: {path}") + connection = sqlite3.connect(f"file:{path}?mode=ro", uri=True, timeout=2) + try: + row = connection.execute( + "SELECT height, tip_hash, updated_at_ms FROM chain_snapshots WHERE id = 1" + ).fetchone() + finally: + connection.close() + if row is None: + raise E2EError(f"chain database has no persisted snapshot: {path}") + return {"height": row[0], "tip_hash": row[1], "updated_at_ms": row[2]} + + +def wait_for_persisted_height(target: int, timeout: float) -> dict: + deadline = time.monotonic() + timeout + database = runtime_dir() / "bootstrap" / "chain.sqlite3" + last_height = None + while time.monotonic() < deadline: + try: + metadata = read_chain_metadata(database) + last_height = metadata["height"] + if last_height >= target: + return metadata + except sqlite3.Error: + pass + time.sleep(0.1) + raise E2EError( + f"timed out waiting for persisted bootstrap height {target}; last height={last_height}" + ) + + +def materialize_chain_checkpoint( + source: Path, chain_destination: Path, ui_destination: Path, height: int +) -> None: + subprocess.run( + [ + "cargo", + "run", + "--quiet", + "--features", + "e2e", + "--bin", + "iuna-e2e-checkpoint", + "--", + str(source), + str(chain_destination), + str(ui_destination), + str(height), + ], + cwd=ROOT, + check=True, + text=True, + ) + + +def wait_for_height(target: int, timeout: float, converge: bool) -> dict[str, dict]: + deadline = time.monotonic() + timeout + last_summary = "nodes unavailable" + while time.monotonic() < deadline: + try: + statuses = all_statuses() + assert_e2e_profile(statuses) + tips = { + (status["chain"]["height"], status["chain"]["tip_hash"]) + for status in statuses.values() + } + heights = [status["chain"]["height"] for status in statuses.values()] + last_summary = ", ".join( + f"{service}={status['chain']['height']}" for service, status in statuses.items() + ) + reached = min(heights) >= target + if reached and (not converge or len(tips) == 1): + return statuses + except (E2EError, OSError, KeyError, urllib.error.URLError) as error: + last_summary = str(error) + time.sleep(0.25) + raise E2EError(f"timed out waiting for height {target}: {last_summary}") + + +def sqlite_backup(source: Path, destination: Path) -> None: + source_connection = sqlite3.connect(f"file:{source}?mode=ro", uri=True, timeout=5) + destination_connection = sqlite3.connect(destination) + try: + source_connection.backup(destination_connection) + destination_connection.execute("PRAGMA journal_mode = DELETE") + finally: + destination_connection.close() + source_connection.close() + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as source: + for chunk in iter(lambda: source.read(1024 * 1024), b""): + digest.update(chunk) + return digest.hexdigest() + + +def snapshot_checksums(directory: Path) -> dict[str, str]: + return { + str(path.relative_to(directory)): sha256(path) + for path in sorted(directory.glob("*/*")) + if path.is_file() + } + + +def verify_snapshot(directory: Path) -> dict: + manifest_path = directory / "manifest.json" + if not manifest_path.exists(): + raise E2EError(f"snapshot has no manifest: {directory}") + manifest = json.loads(manifest_path.read_text()) + expected = manifest.get("sha256", {}) + actual = snapshot_checksums(directory) + if actual != expected: + raise E2EError(f"snapshot checksum mismatch: {directory}") + return manifest + + +def capture_snapshot(name: str, height: int, timeout: float, force: bool) -> None: + destination = snapshot_path(name) + if destination.exists() and not force: + raise E2EError(f"snapshot already exists: {destination}; pass --force to replace it") + assert_e2e_profile({"bootstrap": node_status("bootstrap")}) + live_metadata = wait_for_persisted_height(height, timeout) + compose("pause", *SERVICES) + temp_path: Path | None = None + try: + snapshots_dir().mkdir(parents=True, exist_ok=True) + temp_path = Path(tempfile.mkdtemp(prefix=f".{name}-", dir=snapshots_dir())) + canonical_database = temp_path / ".canonical-chain.sqlite3" + canonical_ui_database = temp_path / ".canonical-ui-data.sqlite3" + materialize_chain_checkpoint( + runtime_dir() / "bootstrap" / "chain.sqlite3", + canonical_database, + canonical_ui_database, + height, + ) + nodes = {} + for service in SERVICES: + source_dir = runtime_dir() / service + target_dir = temp_path / service + target_dir.mkdir() + sqlite_backup(canonical_database, target_dir / "chain.sqlite3") + sqlite_backup(canonical_ui_database, target_dir / "ui_data.sqlite3") + for filename in SNAPSHOT_FILES[2:]: + source = source_dir / filename + if not source.exists(): + raise E2EError(f"required {service} snapshot file is missing: {source}") + shutil.copy2(source, target_dir / filename) + nodes[service] = read_chain_metadata(target_dir / "chain.sqlite3") + + for database in (canonical_database, canonical_ui_database): + for suffix in ("", "-shm", "-wal"): + candidate = Path(f"{database}{suffix}") + if candidate.exists(): + candidate.unlink() + + canonical = nodes["bootstrap"] + manifest = { + "format": 1, + "name": name, + "height": canonical["height"], + "tip_hash": canonical["tip_hash"], + "profile_id": EXPECTED_PROFILE, + "target_block_ms": EXPECTED_BLOCK_MS, + "source_height": live_metadata["height"], + "nodes": nodes, + "sha256": snapshot_checksums(temp_path), + } + (temp_path / "manifest.json").write_text(json.dumps(manifest, indent=2) + "\n") + if destination.exists(): + shutil.rmtree(destination) + temp_path.rename(destination) + temp_path = None + print(f"captured {name} at height {height}: {destination}") + finally: + if temp_path is not None: + shutil.rmtree(temp_path, ignore_errors=True) + compose("unpause", *SERVICES, check=False) + + +def restore_snapshot(name: str) -> None: + source = snapshot_path(name) + manifest = verify_snapshot(source) + if manifest.get("profile_id") != EXPECTED_PROFILE: + raise E2EError( + f"snapshot profile is {manifest.get('profile_id')}, expected {EXPECTED_PROFILE}" + ) + compose("down", "--remove-orphans", check=False) + base = runtime_dir() + base.mkdir(parents=True, exist_ok=True) + for service in SERVICES: + target = base / service + if target.exists(): + shutil.rmtree(target) + target.mkdir(parents=True) + for filename in SNAPSHOT_FILES: + snapshot_file = source / service / filename + if filename == "ui_data.sqlite3" and not snapshot_file.exists(): + continue + shutil.copy2(snapshot_file, target / filename) + print(f"restored {name} at height {manifest['height']} into {base}") + + +def reset_runtime() -> None: + compose("down", "--remove-orphans", check=False) + base = runtime_dir() + for service in SERVICES: + target = base / service + if target.exists(): + shutil.rmtree(target) + _OPENERS.clear() + print(f"cleared mutable e2e node data under {base}") + + +def start(build: bool) -> None: + runtime_dir().mkdir(parents=True, exist_ok=True) + for service in SERVICES: + (runtime_dir() / service).mkdir(parents=True, exist_ok=True) + args = ["up", "--detach", "--wait", "--wait-timeout", "600"] + if build: + args.append("--build") + args.extend(SERVICES) + compose(*args) + statuses = all_statuses() + assert_e2e_profile(statuses) + print(json.dumps({name: compact_status(value) for name, value in statuses.items()}, indent=2)) + + +def capture_plan(plan_path: Path, timeout: float, force: bool) -> None: + plan = json.loads(plan_path.read_text()) + for checkpoint in plan: + name = validate_snapshot_name(checkpoint["name"]) + height = int(checkpoint["height"]) + destination = snapshot_path(name) + if destination.exists() and not force: + print(f"keeping existing snapshot {name}") + continue + capture_snapshot(name, height, timeout, force) + + +def smoke(name: str, through: int, timeout: float, build: bool, keep: bool) -> None: + restore_snapshot(name) + try: + start(build) + statuses = wait_for_height(through, timeout, converge=True) + summary = {service: compact_status(status) for service, status in statuses.items()} + print(f"e2e smoke passed through height {through}") + print(json.dumps(summary, indent=2)) + except Exception: + compose("logs", "--tail", "200", *SERVICES, check=False) + raise + finally: + if not keep: + compose("down", "--remove-orphans", check=False) + + +def parser() -> argparse.ArgumentParser: + result = argparse.ArgumentParser(description=__doc__) + commands = result.add_subparsers(dest="command", required=True) + + up = commands.add_parser("up", help="start the isolated six-node e2e network") + up.add_argument("--build", action="store_true") + up.add_argument("--snapshot", help="restore this checkpoint before starting") + + commands.add_parser("down", help="stop the e2e network without deleting runtime data") + commands.add_parser("reset", help="stop the network and delete mutable e2e node data") + commands.add_parser("status", help="show authenticated live status for every node") + + wait = commands.add_parser("wait", help="wait until every node reaches a height") + wait.add_argument("height", type=int) + wait.add_argument("--timeout", type=float, default=600) + wait.add_argument("--converge", action="store_true") + + capture = commands.add_parser("capture", help="capture all node identities and chain DBs") + capture.add_argument("name") + capture.add_argument("--height", type=int, required=True) + capture.add_argument("--timeout", type=float, default=7_200) + capture.add_argument("--force", action="store_true") + + restore = commands.add_parser("restore", help="replace runtime data with a checkpoint") + restore.add_argument("name") + + plan = commands.add_parser("capture-plan", help="capture each checkpoint in a JSON plan") + plan.add_argument("--plan", type=Path, default=E2E_DIR / "checkpoints.json") + plan.add_argument("--timeout", type=float, default=7_200) + plan.add_argument("--force", action="store_true") + + test = commands.add_parser("smoke", help="restore a checkpoint and test network convergence") + test.add_argument("--from", dest="snapshot", required=True) + test.add_argument("--through", type=int, required=True) + test.add_argument("--timeout", type=float, default=600) + test.add_argument("--build", action="store_true") + test.add_argument("--keep", action="store_true") + return result + + +def main() -> int: + args = parser().parse_args() + try: + if args.command == "up": + if args.snapshot: + restore_snapshot(args.snapshot) + start(args.build) + elif args.command == "down": + compose("down", "--remove-orphans") + elif args.command == "reset": + reset_runtime() + elif args.command == "status": + statuses = all_statuses() + assert_e2e_profile(statuses) + print(json.dumps({name: compact_status(value) for name, value in statuses.items()}, indent=2)) + elif args.command == "wait": + statuses = wait_for_height(args.height, args.timeout, args.converge) + print(json.dumps({name: compact_status(value) for name, value in statuses.items()}, indent=2)) + elif args.command == "capture": + capture_snapshot(args.name, args.height, args.timeout, args.force) + elif args.command == "restore": + restore_snapshot(args.name) + elif args.command == "capture-plan": + capture_plan(args.plan, args.timeout, args.force) + elif args.command == "smoke": + smoke(args.snapshot, args.through, args.timeout, args.build, args.keep) + return 0 + except (E2EError, OSError, sqlite3.Error, subprocess.CalledProcessError) as error: + print(f"e2e error: {error}", file=sys.stderr) + return 1 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/e2e/snapshots/.gitkeep b/e2e/snapshots/.gitkeep @@ -0,0 +1 @@ + diff --git a/e2e/snapshots/fallback-invalidation/bootstrap/chain.sqlite3 b/e2e/snapshots/fallback-invalidation/bootstrap/chain.sqlite3 Binary files differ. diff --git a/e2e/snapshots/fallback-invalidation/bootstrap/config.json b/e2e/snapshots/fallback-invalidation/bootstrap/config.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "amount_unit": "microiuna", + "setup_complete": true, + "auth_password_hash": "pbkdf2-sha256$210000$795b8db3cec7f3e710865c4b2f05ee37$709f4e7c66b5ac6153c312a1c602e49c4cfe719389a38dfadadfd339d08676b8", + "mining_enabled": true, + "pow_mining_enabled": false, + "pow_mining_workers": 1, + "burn_per_block": 100, + "burn_fee": 1, + "recovery_vdf_top_rank_percent": 50, + "keep_track_of_metrics": false, + "p2p_accept_inbound": true, + "p2p_bind_port": 9444, + "p2p_announce_addr": "172.29.0.10:9444", + "stratum_enabled": false, + "stratum_bind_port": 3333, + "peers": [], + "address_book": {} +} diff --git a/e2e/snapshots/fallback-invalidation/bootstrap/ui_data.sqlite3 b/e2e/snapshots/fallback-invalidation/bootstrap/ui_data.sqlite3 Binary files differ. diff --git a/e2e/snapshots/fallback-invalidation/bootstrap/wallet.json b/e2e/snapshots/fallback-invalidation/bootstrap/wallet.json @@ -0,0 +1,12 @@ +{ + "version": 3, + "address": "3e4a4204952437f34094ef8eeec99aa859e4dd5129b145c397361c0c8fc986b7", + "encryption": { + "algorithm": "chacha20poly1305", + "kdf": "pbkdf2-sha256", + "kdf_iterations": 210000, + "salt": "e1e747ba2e453941d37f19ea5f30d855", + "nonce": "eccaf1defdea52ae6f60079d", + "ciphertext": "8f2d4b8693fe2ace1d277670cf9fecd53c7077b971f414f984efa85ef2f231bf650fe0b5ce6288d12bdbd60ce80409780b86af7101fed2c6718c177dcfb0791bd99a4ed32ef997a201d480e7ce8c574516f993470e55f37d202e5e9160412088ae45b7f5a21760fb92b5be706036bd0fb2fde98c3193f61c5e542ffda38c85d610b667f9ff66cd4707e5846491f92d9473d4bb9bba24020515b5e9a9e8732dfbc546b5a5c277be43ff3dff662ae0632a71cb2e70ad3a0ae492" + } +} diff --git a/e2e/snapshots/fallback-invalidation/manifest.json b/e2e/snapshots/fallback-invalidation/manifest.json @@ -0,0 +1,67 @@ +{ + "format": 1, + "name": "fallback-invalidation", + "height": 300, + "tip_hash": "bf5721a7beb8d3e23816ad77a8c1a2b7fd764426819e2346c44449e1eeb3e208", + "profile_id": "iuna-local-e2e-5s-v1", + "target_block_ms": 5000, + "source_height": 1002, + "nodes": { + "bootstrap": { + "height": 300, + "tip_hash": "bf5721a7beb8d3e23816ad77a8c1a2b7fd764426819e2346c44449e1eeb3e208", + "updated_at_ms": 1788119397569 + }, + "node2": { + "height": 300, + "tip_hash": "bf5721a7beb8d3e23816ad77a8c1a2b7fd764426819e2346c44449e1eeb3e208", + "updated_at_ms": 1788119397569 + }, + "node3": { + "height": 300, + "tip_hash": "bf5721a7beb8d3e23816ad77a8c1a2b7fd764426819e2346c44449e1eeb3e208", + "updated_at_ms": 1788119397569 + }, + "node4": { + "height": 300, + "tip_hash": "bf5721a7beb8d3e23816ad77a8c1a2b7fd764426819e2346c44449e1eeb3e208", + "updated_at_ms": 1788119397569 + }, + "node5": { + "height": 300, + "tip_hash": "bf5721a7beb8d3e23816ad77a8c1a2b7fd764426819e2346c44449e1eeb3e208", + "updated_at_ms": 1788119397569 + }, + "node6": { + "height": 300, + "tip_hash": "bf5721a7beb8d3e23816ad77a8c1a2b7fd764426819e2346c44449e1eeb3e208", + "updated_at_ms": 1788119397569 + } + }, + "sha256": { + "bootstrap/chain.sqlite3": "f2dc3d878834c9fbb33f6a9ae5f7bc2f45f447fe77894f1bb8437e8517a89374", + "bootstrap/config.json": "ee490011fee4bad2a08641cca4710efad5ee0cc7ff0f418e9b6b3b97f6d64c8e", + "bootstrap/ui_data.sqlite3": "d41012a512727846ff6a48ae2f64d50a3f52101ddd2142e873f8a5a3783ff7f5", + "bootstrap/wallet.json": "9e545dee2d7d8c430a301fd9cc4530467c6ba36787d2407ec31eee96eee88874", + "node2/chain.sqlite3": "f2dc3d878834c9fbb33f6a9ae5f7bc2f45f447fe77894f1bb8437e8517a89374", + "node2/config.json": "5f38677b8e290f412a2ff5833518a1b1fec75d9c8ab9dbc72b1762fd889e33c8", + "node2/ui_data.sqlite3": "d41012a512727846ff6a48ae2f64d50a3f52101ddd2142e873f8a5a3783ff7f5", + "node2/wallet.json": "80c81d94fa958deb3212c3ae52bcfcdcf1f2ce446ec3c4addcfb8ffa6e669a4b", + "node3/chain.sqlite3": "f2dc3d878834c9fbb33f6a9ae5f7bc2f45f447fe77894f1bb8437e8517a89374", + "node3/config.json": "63a8c0d8b06091dbfb899bba7f6603497c44e7af1bee9f21cc5152a3fafc037d", + "node3/ui_data.sqlite3": "d41012a512727846ff6a48ae2f64d50a3f52101ddd2142e873f8a5a3783ff7f5", + "node3/wallet.json": "15d4b71da0e31f6045fc6b98b7d3414f7925556932de42b52bacd35e670c1c86", + "node4/chain.sqlite3": "f2dc3d878834c9fbb33f6a9ae5f7bc2f45f447fe77894f1bb8437e8517a89374", + "node4/config.json": "f9bed39ec29fbff17fb6155e718454706991603d5993632c6f6b18cbf3d80fa4", + "node4/ui_data.sqlite3": "d41012a512727846ff6a48ae2f64d50a3f52101ddd2142e873f8a5a3783ff7f5", + "node4/wallet.json": "204ff6327b0c5da43418f704322fcfe8de09f799239896146bfb0320d42e3780", + "node5/chain.sqlite3": "f2dc3d878834c9fbb33f6a9ae5f7bc2f45f447fe77894f1bb8437e8517a89374", + "node5/config.json": "0bd460df616c8effb1091625887cab053d95e9f30afbc4237e7e5923c0cd6b73", + "node5/ui_data.sqlite3": "d41012a512727846ff6a48ae2f64d50a3f52101ddd2142e873f8a5a3783ff7f5", + "node5/wallet.json": "4612e7e2143a11b5834b89e1dbaebb30d9c898930bfeb3eeedb347771b827808", + "node6/chain.sqlite3": "f2dc3d878834c9fbb33f6a9ae5f7bc2f45f447fe77894f1bb8437e8517a89374", + "node6/config.json": "1d6aaba498ee1f273c89d7f84806318cf5f15c36088346460236e114a0fd73bb", + "node6/ui_data.sqlite3": "d41012a512727846ff6a48ae2f64d50a3f52101ddd2142e873f8a5a3783ff7f5", + "node6/wallet.json": "1eaf0a87b89c5a36a3f43162894922176412817f468e907faa5970f1656a04f7" + } +} diff --git a/e2e/snapshots/fallback-invalidation/node2/chain.sqlite3 b/e2e/snapshots/fallback-invalidation/node2/chain.sqlite3 Binary files differ. diff --git a/e2e/snapshots/fallback-invalidation/node2/config.json b/e2e/snapshots/fallback-invalidation/node2/config.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "amount_unit": "microiuna", + "setup_complete": true, + "auth_password_hash": "pbkdf2-sha256$210000$df0c9708ae4ef33eebe6f1479fb5ec63$f91e1780984648d490b081b22a23c8aceed73684afe7d4abeb079e121e6326e6", + "mining_enabled": true, + "pow_mining_enabled": true, + "pow_mining_workers": 1, + "burn_per_block": 100, + "burn_fee": 1, + "recovery_vdf_top_rank_percent": 50, + "keep_track_of_metrics": false, + "p2p_accept_inbound": true, + "p2p_bind_port": 9444, + "p2p_announce_addr": "172.29.0.11:9444", + "stratum_enabled": false, + "stratum_bind_port": 3333, + "peers": [], + "address_book": {} +} diff --git a/e2e/snapshots/fallback-invalidation/node2/ui_data.sqlite3 b/e2e/snapshots/fallback-invalidation/node2/ui_data.sqlite3 Binary files differ. diff --git a/e2e/snapshots/fallback-invalidation/node2/wallet.json b/e2e/snapshots/fallback-invalidation/node2/wallet.json @@ -0,0 +1,12 @@ +{ + "version": 3, + "address": "1425cb395bea950db7c232bf19aa2dba4f63852f4eea230b05d238fcb57825a8", + "encryption": { + "algorithm": "chacha20poly1305", + "kdf": "pbkdf2-sha256", + "kdf_iterations": 210000, + "salt": "9c5e3443788a6af8f3ffe7c9bd13fdb0", + "nonce": "0853a86f1577ca3089ac60e8", + "ciphertext": "2c8e5149ac86f577ba59635c4d06eab73535c1c5de0b4113edabdf84ad3c1a29a07836fccb3d70175161eec7e2008aa0d088e201fb40ddc3e6a663b199efab4d2d86f5bad494fe6874b432783314f93575ea94628a4b9d8a13a9ee713b75876a121a6db698ccc510c4d87cc5f374728a11ca3c82c9b081513bc2c707e7170d58b94ea8a307432e874bbf27470c8d8577e7b859d33ab5dbd0f0057df8e74fbb7f1aee406fc9b34007b7925ff64ec91c" + } +} diff --git a/e2e/snapshots/fallback-invalidation/node3/chain.sqlite3 b/e2e/snapshots/fallback-invalidation/node3/chain.sqlite3 Binary files differ. diff --git a/e2e/snapshots/fallback-invalidation/node3/config.json b/e2e/snapshots/fallback-invalidation/node3/config.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "amount_unit": "microiuna", + "setup_complete": true, + "auth_password_hash": "pbkdf2-sha256$210000$874d9b2efb7aebfab8c2fe4097df301d$be5bd2bd0497afc7e4f7c37131e69408fd2cc485398cff16e95257249a0f6d1d", + "mining_enabled": true, + "pow_mining_enabled": true, + "pow_mining_workers": 1, + "burn_per_block": 100, + "burn_fee": 1, + "recovery_vdf_top_rank_percent": 50, + "keep_track_of_metrics": false, + "p2p_accept_inbound": true, + "p2p_bind_port": 9444, + "p2p_announce_addr": "172.29.0.12:9444", + "stratum_enabled": true, + "stratum_bind_port": 3333, + "peers": [], + "address_book": {} +} diff --git a/e2e/snapshots/fallback-invalidation/node3/ui_data.sqlite3 b/e2e/snapshots/fallback-invalidation/node3/ui_data.sqlite3 Binary files differ. diff --git a/e2e/snapshots/fallback-invalidation/node3/wallet.json b/e2e/snapshots/fallback-invalidation/node3/wallet.json @@ -0,0 +1,12 @@ +{ + "version": 3, + "address": "840fb90a44a2b4819e4a8d2212e429f750b1d344c0c76b36f8f3c8c729477b74", + "encryption": { + "algorithm": "chacha20poly1305", + "kdf": "pbkdf2-sha256", + "kdf_iterations": 210000, + "salt": "cb5b63813a202478b4613a957df08eef", + "nonce": "8403301b3c608ba677b43eb6", + "ciphertext": "67171c204a4dd725c07c2efb8a581561c2c3d0d736b9ba8ddae690635b2a10adcfd7e0308f8b872b6a32aa98ad7996776205a84b5a3148ddc3d8071b31f6c37536c7fd7a6567a2b7d3fafd64c50d6e5bf92e7886cb77329c8136a00d622b60a0753958765b8911e2d7fbfb039708ec6cecd8d168426a826d5d8620dd8db30c5ccd9c34116508e0e57388f7362dfbc4ed696641486867e09a6502a72190f0c9e951039e66cf74349a5b77d6d97ccbac7118d119b6343485c57923" + } +} diff --git a/e2e/snapshots/fallback-invalidation/node4/chain.sqlite3 b/e2e/snapshots/fallback-invalidation/node4/chain.sqlite3 Binary files differ. diff --git a/e2e/snapshots/fallback-invalidation/node4/config.json b/e2e/snapshots/fallback-invalidation/node4/config.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "amount_unit": "microiuna", + "setup_complete": true, + "auth_password_hash": "pbkdf2-sha256$210000$38a8a556a0e456c091d24aa8f5d3457f$888b4b3c1259773977c6be6c6283a47f7c194a716dd216d63299cec576562c84", + "mining_enabled": true, + "pow_mining_enabled": true, + "pow_mining_workers": 1, + "burn_per_block": 100, + "burn_fee": 1, + "recovery_vdf_top_rank_percent": 50, + "keep_track_of_metrics": false, + "p2p_accept_inbound": true, + "p2p_bind_port": 9444, + "p2p_announce_addr": "172.29.0.13:9444", + "stratum_enabled": false, + "stratum_bind_port": 3333, + "peers": [], + "address_book": {} +} diff --git a/e2e/snapshots/fallback-invalidation/node4/ui_data.sqlite3 b/e2e/snapshots/fallback-invalidation/node4/ui_data.sqlite3 Binary files differ. diff --git a/e2e/snapshots/fallback-invalidation/node4/wallet.json b/e2e/snapshots/fallback-invalidation/node4/wallet.json @@ -0,0 +1,12 @@ +{ + "version": 3, + "address": "4fcf7e382b2ead5aab1519987fd6d7ba78ccb2f423d3f5f407897ae23d4666a9", + "encryption": { + "algorithm": "chacha20poly1305", + "kdf": "pbkdf2-sha256", + "kdf_iterations": 210000, + "salt": "8acc212746e45b5fe3f2a20714b8d50b", + "nonce": "0d62ae5f2254f4c4a7a85a35", + "ciphertext": "76d14c604a765b2b15229291e7770520c7ade1be929bbb31d85e0cb8c6a768f197d5aa360e48cff0bf29a61943fdf1a129f4ab029aa3aef2db143794905928797295da00af3c323cb16f65010ce8d86cebdc789d1e55c3d0cb30fccf3ca47b51d83c51e13ef450b34263c8fc5783637d6e7406ab23d7f0d10e36f83ead64e7367c2907b968358fc524e2ed6bb9c7a93fd665834b7cdc3c47985fa6510c05999bae796a5d350ef7a2c70a88771109fcc933" + } +} diff --git a/e2e/snapshots/fallback-invalidation/node5/chain.sqlite3 b/e2e/snapshots/fallback-invalidation/node5/chain.sqlite3 Binary files differ. diff --git a/e2e/snapshots/fallback-invalidation/node5/config.json b/e2e/snapshots/fallback-invalidation/node5/config.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "amount_unit": "microiuna", + "setup_complete": true, + "auth_password_hash": "pbkdf2-sha256$210000$b338abc5ee16d0dcd1c7eca6b8c42066$e21c09652fd72a3e9a80fa202db973ef60cb385e66952641e9ade39c9cde91fa", + "mining_enabled": true, + "pow_mining_enabled": true, + "pow_mining_workers": 1, + "burn_per_block": 100, + "burn_fee": 1, + "recovery_vdf_top_rank_percent": 50, + "keep_track_of_metrics": false, + "p2p_accept_inbound": true, + "p2p_bind_port": 9444, + "p2p_announce_addr": "172.29.0.14:9444", + "stratum_enabled": false, + "stratum_bind_port": 3333, + "peers": [], + "address_book": {} +} diff --git a/e2e/snapshots/fallback-invalidation/node5/ui_data.sqlite3 b/e2e/snapshots/fallback-invalidation/node5/ui_data.sqlite3 Binary files differ. diff --git a/e2e/snapshots/fallback-invalidation/node5/wallet.json b/e2e/snapshots/fallback-invalidation/node5/wallet.json @@ -0,0 +1,12 @@ +{ + "version": 3, + "address": "24b37cfe96e5116e9c3de7f6e1ad3cf3a4b967c4b57c142fbf16f8733efafc47", + "encryption": { + "algorithm": "chacha20poly1305", + "kdf": "pbkdf2-sha256", + "kdf_iterations": 210000, + "salt": "628e9496c3a9f564e14584a24f28cc73", + "nonce": "0efe22ab02929c0a31b1ee98", + "ciphertext": "de0f0045b0084dfbe1051f1b37b0d0bde7c51859a63ddacef724af91db0caab19489d1b0e98b07f8acacd679f7f8cfad0c2b79b722beed9b5c483d2b61edde835cd1db531fae5820b1969effcb7387a2fe087b467c5de43afa5f41d3150a8f53cb0ccc2776d393065348b99d3fe7197515d98a40be545c7a2f9010318d035fcd7c3ebd0ab385b262d9149b6443093882812701ee0e346e95768a398cd6e36a1c9da3c9242337afc0114ed47e2b92f3" + } +} diff --git a/e2e/snapshots/fallback-invalidation/node6/chain.sqlite3 b/e2e/snapshots/fallback-invalidation/node6/chain.sqlite3 Binary files differ. diff --git a/e2e/snapshots/fallback-invalidation/node6/config.json b/e2e/snapshots/fallback-invalidation/node6/config.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "amount_unit": "microiuna", + "setup_complete": true, + "auth_password_hash": "pbkdf2-sha256$210000$097e8cb00697e94cae82aaa7de6e31bc$28085e3dec860904e03d9f17fe55158c9a8395040829ec4e5b1770b5a4c5b8c6", + "mining_enabled": true, + "pow_mining_enabled": true, + "pow_mining_workers": 1, + "burn_per_block": 100, + "burn_fee": 1, + "recovery_vdf_top_rank_percent": 50, + "keep_track_of_metrics": false, + "p2p_accept_inbound": true, + "p2p_bind_port": 9444, + "p2p_announce_addr": "172.29.0.15:9444", + "stratum_enabled": false, + "stratum_bind_port": 3333, + "peers": [], + "address_book": {} +} diff --git a/e2e/snapshots/fallback-invalidation/node6/ui_data.sqlite3 b/e2e/snapshots/fallback-invalidation/node6/ui_data.sqlite3 Binary files differ. diff --git a/e2e/snapshots/fallback-invalidation/node6/wallet.json b/e2e/snapshots/fallback-invalidation/node6/wallet.json @@ -0,0 +1,12 @@ +{ + "version": 3, + "address": "2aa3d9d02cb77e3f5f7151d9e32f9a079440028c14eaf5f4fc8e60eeec7f01c4", + "encryption": { + "algorithm": "chacha20poly1305", + "kdf": "pbkdf2-sha256", + "kdf_iterations": 210000, + "salt": "6880300421523e9a060053490bd68130", + "nonce": "3e19ca0e409214d72eb576ee", + "ciphertext": "a8edc95288b9d3b41ea92cd39652aa49b2272f02597cb510c9b11317500d8059e14418ac8a205deaae3e5baeedc0ff38371286853339bb211f8c4c22c8c938eee3c082b6260e604cd9b3caf65d0ca9febc594355225b0fff0bc2265e0832574185d0b5a2d35f8cad4efd6e6fdf895fe8646a0c6057022cc3ccd3975266b940e12ef733260d4a1f64e1af4645340cb7ffc802d74f1d26c9d0307010164d95f337bbb73fa9c9b2d241b47378b521ae99d6ffc1ae83aba4602d015b" + } +} diff --git a/e2e/snapshots/first-objective-checkpoint/bootstrap/chain.sqlite3 b/e2e/snapshots/first-objective-checkpoint/bootstrap/chain.sqlite3 Binary files differ. diff --git a/e2e/snapshots/first-objective-checkpoint/bootstrap/config.json b/e2e/snapshots/first-objective-checkpoint/bootstrap/config.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "amount_unit": "microiuna", + "setup_complete": true, + "auth_password_hash": "pbkdf2-sha256$210000$795b8db3cec7f3e710865c4b2f05ee37$709f4e7c66b5ac6153c312a1c602e49c4cfe719389a38dfadadfd339d08676b8", + "mining_enabled": true, + "pow_mining_enabled": false, + "pow_mining_workers": 1, + "burn_per_block": 100, + "burn_fee": 1, + "recovery_vdf_top_rank_percent": 50, + "keep_track_of_metrics": false, + "p2p_accept_inbound": true, + "p2p_bind_port": 9444, + "p2p_announce_addr": "172.29.0.10:9444", + "stratum_enabled": false, + "stratum_bind_port": 3333, + "peers": [], + "address_book": {} +} diff --git a/e2e/snapshots/first-objective-checkpoint/bootstrap/ui_data.sqlite3 b/e2e/snapshots/first-objective-checkpoint/bootstrap/ui_data.sqlite3 Binary files differ. diff --git a/e2e/snapshots/first-objective-checkpoint/bootstrap/wallet.json b/e2e/snapshots/first-objective-checkpoint/bootstrap/wallet.json @@ -0,0 +1,12 @@ +{ + "version": 3, + "address": "3e4a4204952437f34094ef8eeec99aa859e4dd5129b145c397361c0c8fc986b7", + "encryption": { + "algorithm": "chacha20poly1305", + "kdf": "pbkdf2-sha256", + "kdf_iterations": 210000, + "salt": "e1e747ba2e453941d37f19ea5f30d855", + "nonce": "eccaf1defdea52ae6f60079d", + "ciphertext": "8f2d4b8693fe2ace1d277670cf9fecd53c7077b971f414f984efa85ef2f231bf650fe0b5ce6288d12bdbd60ce80409780b86af7101fed2c6718c177dcfb0791bd99a4ed32ef997a201d480e7ce8c574516f993470e55f37d202e5e9160412088ae45b7f5a21760fb92b5be706036bd0fb2fde98c3193f61c5e542ffda38c85d610b667f9ff66cd4707e5846491f92d9473d4bb9bba24020515b5e9a9e8732dfbc546b5a5c277be43ff3dff662ae0632a71cb2e70ad3a0ae492" + } +} diff --git a/e2e/snapshots/first-objective-checkpoint/manifest.json b/e2e/snapshots/first-objective-checkpoint/manifest.json @@ -0,0 +1,67 @@ +{ + "format": 1, + "name": "first-objective-checkpoint", + "height": 1001, + "tip_hash": "80bb3e5d9534459cdff5f1cdd0c2899acdc9f5942192a31e709e3a2c9015e6cd", + "profile_id": "iuna-local-e2e-5s-v1", + "target_block_ms": 5000, + "source_height": 1002, + "nodes": { + "bootstrap": { + "height": 1001, + "tip_hash": "80bb3e5d9534459cdff5f1cdd0c2899acdc9f5942192a31e709e3a2c9015e6cd", + "updated_at_ms": 1788119608835 + }, + "node2": { + "height": 1001, + "tip_hash": "80bb3e5d9534459cdff5f1cdd0c2899acdc9f5942192a31e709e3a2c9015e6cd", + "updated_at_ms": 1788119608835 + }, + "node3": { + "height": 1001, + "tip_hash": "80bb3e5d9534459cdff5f1cdd0c2899acdc9f5942192a31e709e3a2c9015e6cd", + "updated_at_ms": 1788119608835 + }, + "node4": { + "height": 1001, + "tip_hash": "80bb3e5d9534459cdff5f1cdd0c2899acdc9f5942192a31e709e3a2c9015e6cd", + "updated_at_ms": 1788119608835 + }, + "node5": { + "height": 1001, + "tip_hash": "80bb3e5d9534459cdff5f1cdd0c2899acdc9f5942192a31e709e3a2c9015e6cd", + "updated_at_ms": 1788119608835 + }, + "node6": { + "height": 1001, + "tip_hash": "80bb3e5d9534459cdff5f1cdd0c2899acdc9f5942192a31e709e3a2c9015e6cd", + "updated_at_ms": 1788119608835 + } + }, + "sha256": { + "bootstrap/chain.sqlite3": "907f3387061d99eafcc661d08c55354364654777d37396f7b0ad1876913fcbe6", + "bootstrap/config.json": "ee490011fee4bad2a08641cca4710efad5ee0cc7ff0f418e9b6b3b97f6d64c8e", + "bootstrap/ui_data.sqlite3": "7d4867feba2f3bf8d234d83e435ae149a699d3be732eedfe7b46c49bb47f3f4b", + "bootstrap/wallet.json": "9e545dee2d7d8c430a301fd9cc4530467c6ba36787d2407ec31eee96eee88874", + "node2/chain.sqlite3": "907f3387061d99eafcc661d08c55354364654777d37396f7b0ad1876913fcbe6", + "node2/config.json": "5f38677b8e290f412a2ff5833518a1b1fec75d9c8ab9dbc72b1762fd889e33c8", + "node2/ui_data.sqlite3": "7d4867feba2f3bf8d234d83e435ae149a699d3be732eedfe7b46c49bb47f3f4b", + "node2/wallet.json": "80c81d94fa958deb3212c3ae52bcfcdcf1f2ce446ec3c4addcfb8ffa6e669a4b", + "node3/chain.sqlite3": "907f3387061d99eafcc661d08c55354364654777d37396f7b0ad1876913fcbe6", + "node3/config.json": "63a8c0d8b06091dbfb899bba7f6603497c44e7af1bee9f21cc5152a3fafc037d", + "node3/ui_data.sqlite3": "7d4867feba2f3bf8d234d83e435ae149a699d3be732eedfe7b46c49bb47f3f4b", + "node3/wallet.json": "15d4b71da0e31f6045fc6b98b7d3414f7925556932de42b52bacd35e670c1c86", + "node4/chain.sqlite3": "907f3387061d99eafcc661d08c55354364654777d37396f7b0ad1876913fcbe6", + "node4/config.json": "f9bed39ec29fbff17fb6155e718454706991603d5993632c6f6b18cbf3d80fa4", + "node4/ui_data.sqlite3": "7d4867feba2f3bf8d234d83e435ae149a699d3be732eedfe7b46c49bb47f3f4b", + "node4/wallet.json": "204ff6327b0c5da43418f704322fcfe8de09f799239896146bfb0320d42e3780", + "node5/chain.sqlite3": "907f3387061d99eafcc661d08c55354364654777d37396f7b0ad1876913fcbe6", + "node5/config.json": "0bd460df616c8effb1091625887cab053d95e9f30afbc4237e7e5923c0cd6b73", + "node5/ui_data.sqlite3": "7d4867feba2f3bf8d234d83e435ae149a699d3be732eedfe7b46c49bb47f3f4b", + "node5/wallet.json": "4612e7e2143a11b5834b89e1dbaebb30d9c898930bfeb3eeedb347771b827808", + "node6/chain.sqlite3": "907f3387061d99eafcc661d08c55354364654777d37396f7b0ad1876913fcbe6", + "node6/config.json": "1d6aaba498ee1f273c89d7f84806318cf5f15c36088346460236e114a0fd73bb", + "node6/ui_data.sqlite3": "7d4867feba2f3bf8d234d83e435ae149a699d3be732eedfe7b46c49bb47f3f4b", + "node6/wallet.json": "1eaf0a87b89c5a36a3f43162894922176412817f468e907faa5970f1656a04f7" + } +} diff --git a/e2e/snapshots/first-objective-checkpoint/node2/chain.sqlite3 b/e2e/snapshots/first-objective-checkpoint/node2/chain.sqlite3 Binary files differ. diff --git a/e2e/snapshots/first-objective-checkpoint/node2/config.json b/e2e/snapshots/first-objective-checkpoint/node2/config.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "amount_unit": "microiuna", + "setup_complete": true, + "auth_password_hash": "pbkdf2-sha256$210000$df0c9708ae4ef33eebe6f1479fb5ec63$f91e1780984648d490b081b22a23c8aceed73684afe7d4abeb079e121e6326e6", + "mining_enabled": true, + "pow_mining_enabled": true, + "pow_mining_workers": 1, + "burn_per_block": 100, + "burn_fee": 1, + "recovery_vdf_top_rank_percent": 50, + "keep_track_of_metrics": false, + "p2p_accept_inbound": true, + "p2p_bind_port": 9444, + "p2p_announce_addr": "172.29.0.11:9444", + "stratum_enabled": false, + "stratum_bind_port": 3333, + "peers": [], + "address_book": {} +} diff --git a/e2e/snapshots/first-objective-checkpoint/node2/ui_data.sqlite3 b/e2e/snapshots/first-objective-checkpoint/node2/ui_data.sqlite3 Binary files differ. diff --git a/e2e/snapshots/first-objective-checkpoint/node2/wallet.json b/e2e/snapshots/first-objective-checkpoint/node2/wallet.json @@ -0,0 +1,12 @@ +{ + "version": 3, + "address": "1425cb395bea950db7c232bf19aa2dba4f63852f4eea230b05d238fcb57825a8", + "encryption": { + "algorithm": "chacha20poly1305", + "kdf": "pbkdf2-sha256", + "kdf_iterations": 210000, + "salt": "9c5e3443788a6af8f3ffe7c9bd13fdb0", + "nonce": "0853a86f1577ca3089ac60e8", + "ciphertext": "2c8e5149ac86f577ba59635c4d06eab73535c1c5de0b4113edabdf84ad3c1a29a07836fccb3d70175161eec7e2008aa0d088e201fb40ddc3e6a663b199efab4d2d86f5bad494fe6874b432783314f93575ea94628a4b9d8a13a9ee713b75876a121a6db698ccc510c4d87cc5f374728a11ca3c82c9b081513bc2c707e7170d58b94ea8a307432e874bbf27470c8d8577e7b859d33ab5dbd0f0057df8e74fbb7f1aee406fc9b34007b7925ff64ec91c" + } +} diff --git a/e2e/snapshots/first-objective-checkpoint/node3/chain.sqlite3 b/e2e/snapshots/first-objective-checkpoint/node3/chain.sqlite3 Binary files differ. diff --git a/e2e/snapshots/first-objective-checkpoint/node3/config.json b/e2e/snapshots/first-objective-checkpoint/node3/config.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "amount_unit": "microiuna", + "setup_complete": true, + "auth_password_hash": "pbkdf2-sha256$210000$874d9b2efb7aebfab8c2fe4097df301d$be5bd2bd0497afc7e4f7c37131e69408fd2cc485398cff16e95257249a0f6d1d", + "mining_enabled": true, + "pow_mining_enabled": true, + "pow_mining_workers": 1, + "burn_per_block": 100, + "burn_fee": 1, + "recovery_vdf_top_rank_percent": 50, + "keep_track_of_metrics": false, + "p2p_accept_inbound": true, + "p2p_bind_port": 9444, + "p2p_announce_addr": "172.29.0.12:9444", + "stratum_enabled": true, + "stratum_bind_port": 3333, + "peers": [], + "address_book": {} +} diff --git a/e2e/snapshots/first-objective-checkpoint/node3/ui_data.sqlite3 b/e2e/snapshots/first-objective-checkpoint/node3/ui_data.sqlite3 Binary files differ. diff --git a/e2e/snapshots/first-objective-checkpoint/node3/wallet.json b/e2e/snapshots/first-objective-checkpoint/node3/wallet.json @@ -0,0 +1,12 @@ +{ + "version": 3, + "address": "840fb90a44a2b4819e4a8d2212e429f750b1d344c0c76b36f8f3c8c729477b74", + "encryption": { + "algorithm": "chacha20poly1305", + "kdf": "pbkdf2-sha256", + "kdf_iterations": 210000, + "salt": "cb5b63813a202478b4613a957df08eef", + "nonce": "8403301b3c608ba677b43eb6", + "ciphertext": "67171c204a4dd725c07c2efb8a581561c2c3d0d736b9ba8ddae690635b2a10adcfd7e0308f8b872b6a32aa98ad7996776205a84b5a3148ddc3d8071b31f6c37536c7fd7a6567a2b7d3fafd64c50d6e5bf92e7886cb77329c8136a00d622b60a0753958765b8911e2d7fbfb039708ec6cecd8d168426a826d5d8620dd8db30c5ccd9c34116508e0e57388f7362dfbc4ed696641486867e09a6502a72190f0c9e951039e66cf74349a5b77d6d97ccbac7118d119b6343485c57923" + } +} diff --git a/e2e/snapshots/first-objective-checkpoint/node4/chain.sqlite3 b/e2e/snapshots/first-objective-checkpoint/node4/chain.sqlite3 Binary files differ. diff --git a/e2e/snapshots/first-objective-checkpoint/node4/config.json b/e2e/snapshots/first-objective-checkpoint/node4/config.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "amount_unit": "microiuna", + "setup_complete": true, + "auth_password_hash": "pbkdf2-sha256$210000$38a8a556a0e456c091d24aa8f5d3457f$888b4b3c1259773977c6be6c6283a47f7c194a716dd216d63299cec576562c84", + "mining_enabled": true, + "pow_mining_enabled": true, + "pow_mining_workers": 1, + "burn_per_block": 100, + "burn_fee": 1, + "recovery_vdf_top_rank_percent": 50, + "keep_track_of_metrics": false, + "p2p_accept_inbound": true, + "p2p_bind_port": 9444, + "p2p_announce_addr": "172.29.0.13:9444", + "stratum_enabled": false, + "stratum_bind_port": 3333, + "peers": [], + "address_book": {} +} diff --git a/e2e/snapshots/first-objective-checkpoint/node4/ui_data.sqlite3 b/e2e/snapshots/first-objective-checkpoint/node4/ui_data.sqlite3 Binary files differ. diff --git a/e2e/snapshots/first-objective-checkpoint/node4/wallet.json b/e2e/snapshots/first-objective-checkpoint/node4/wallet.json @@ -0,0 +1,12 @@ +{ + "version": 3, + "address": "4fcf7e382b2ead5aab1519987fd6d7ba78ccb2f423d3f5f407897ae23d4666a9", + "encryption": { + "algorithm": "chacha20poly1305", + "kdf": "pbkdf2-sha256", + "kdf_iterations": 210000, + "salt": "8acc212746e45b5fe3f2a20714b8d50b", + "nonce": "0d62ae5f2254f4c4a7a85a35", + "ciphertext": "76d14c604a765b2b15229291e7770520c7ade1be929bbb31d85e0cb8c6a768f197d5aa360e48cff0bf29a61943fdf1a129f4ab029aa3aef2db143794905928797295da00af3c323cb16f65010ce8d86cebdc789d1e55c3d0cb30fccf3ca47b51d83c51e13ef450b34263c8fc5783637d6e7406ab23d7f0d10e36f83ead64e7367c2907b968358fc524e2ed6bb9c7a93fd665834b7cdc3c47985fa6510c05999bae796a5d350ef7a2c70a88771109fcc933" + } +} diff --git a/e2e/snapshots/first-objective-checkpoint/node5/chain.sqlite3 b/e2e/snapshots/first-objective-checkpoint/node5/chain.sqlite3 Binary files differ. diff --git a/e2e/snapshots/first-objective-checkpoint/node5/config.json b/e2e/snapshots/first-objective-checkpoint/node5/config.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "amount_unit": "microiuna", + "setup_complete": true, + "auth_password_hash": "pbkdf2-sha256$210000$b338abc5ee16d0dcd1c7eca6b8c42066$e21c09652fd72a3e9a80fa202db973ef60cb385e66952641e9ade39c9cde91fa", + "mining_enabled": true, + "pow_mining_enabled": true, + "pow_mining_workers": 1, + "burn_per_block": 100, + "burn_fee": 1, + "recovery_vdf_top_rank_percent": 50, + "keep_track_of_metrics": false, + "p2p_accept_inbound": true, + "p2p_bind_port": 9444, + "p2p_announce_addr": "172.29.0.14:9444", + "stratum_enabled": false, + "stratum_bind_port": 3333, + "peers": [], + "address_book": {} +} diff --git a/e2e/snapshots/first-objective-checkpoint/node5/ui_data.sqlite3 b/e2e/snapshots/first-objective-checkpoint/node5/ui_data.sqlite3 Binary files differ. diff --git a/e2e/snapshots/first-objective-checkpoint/node5/wallet.json b/e2e/snapshots/first-objective-checkpoint/node5/wallet.json @@ -0,0 +1,12 @@ +{ + "version": 3, + "address": "24b37cfe96e5116e9c3de7f6e1ad3cf3a4b967c4b57c142fbf16f8733efafc47", + "encryption": { + "algorithm": "chacha20poly1305", + "kdf": "pbkdf2-sha256", + "kdf_iterations": 210000, + "salt": "628e9496c3a9f564e14584a24f28cc73", + "nonce": "0efe22ab02929c0a31b1ee98", + "ciphertext": "de0f0045b0084dfbe1051f1b37b0d0bde7c51859a63ddacef724af91db0caab19489d1b0e98b07f8acacd679f7f8cfad0c2b79b722beed9b5c483d2b61edde835cd1db531fae5820b1969effcb7387a2fe087b467c5de43afa5f41d3150a8f53cb0ccc2776d393065348b99d3fe7197515d98a40be545c7a2f9010318d035fcd7c3ebd0ab385b262d9149b6443093882812701ee0e346e95768a398cd6e36a1c9da3c9242337afc0114ed47e2b92f3" + } +} diff --git a/e2e/snapshots/first-objective-checkpoint/node6/chain.sqlite3 b/e2e/snapshots/first-objective-checkpoint/node6/chain.sqlite3 Binary files differ. diff --git a/e2e/snapshots/first-objective-checkpoint/node6/config.json b/e2e/snapshots/first-objective-checkpoint/node6/config.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "amount_unit": "microiuna", + "setup_complete": true, + "auth_password_hash": "pbkdf2-sha256$210000$097e8cb00697e94cae82aaa7de6e31bc$28085e3dec860904e03d9f17fe55158c9a8395040829ec4e5b1770b5a4c5b8c6", + "mining_enabled": true, + "pow_mining_enabled": true, + "pow_mining_workers": 1, + "burn_per_block": 100, + "burn_fee": 1, + "recovery_vdf_top_rank_percent": 50, + "keep_track_of_metrics": false, + "p2p_accept_inbound": true, + "p2p_bind_port": 9444, + "p2p_announce_addr": "172.29.0.15:9444", + "stratum_enabled": false, + "stratum_bind_port": 3333, + "peers": [], + "address_book": {} +} diff --git a/e2e/snapshots/first-objective-checkpoint/node6/ui_data.sqlite3 b/e2e/snapshots/first-objective-checkpoint/node6/ui_data.sqlite3 Binary files differ. diff --git a/e2e/snapshots/first-objective-checkpoint/node6/wallet.json b/e2e/snapshots/first-objective-checkpoint/node6/wallet.json @@ -0,0 +1,12 @@ +{ + "version": 3, + "address": "2aa3d9d02cb77e3f5f7151d9e32f9a079440028c14eaf5f4fc8e60eeec7f01c4", + "encryption": { + "algorithm": "chacha20poly1305", + "kdf": "pbkdf2-sha256", + "kdf_iterations": 210000, + "salt": "6880300421523e9a060053490bd68130", + "nonce": "3e19ca0e409214d72eb576ee", + "ciphertext": "a8edc95288b9d3b41ea92cd39652aa49b2272f02597cb510c9b11317500d8059e14418ac8a205deaae3e5baeedc0ff38371286853339bb211f8c4c22c8c938eee3c082b6260e604cd9b3caf65d0ca9febc594355225b0fff0bc2265e0832574185d0b5a2d35f8cad4efd6e6fdf895fe8646a0c6057022cc3ccd3975266b940e12ef733260d4a1f64e1af4645340cb7ffc802d74f1d26c9d0307010164d95f337bbb73fa9c9b2d241b47378b521ae99d6ffc1ae83aba4602d015b" + } +} diff --git a/e2e/snapshots/objective-finality/bootstrap/chain.sqlite3 b/e2e/snapshots/objective-finality/bootstrap/chain.sqlite3 Binary files differ. diff --git a/e2e/snapshots/objective-finality/bootstrap/config.json b/e2e/snapshots/objective-finality/bootstrap/config.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "amount_unit": "microiuna", + "setup_complete": true, + "auth_password_hash": "pbkdf2-sha256$210000$795b8db3cec7f3e710865c4b2f05ee37$709f4e7c66b5ac6153c312a1c602e49c4cfe719389a38dfadadfd339d08676b8", + "mining_enabled": true, + "pow_mining_enabled": false, + "pow_mining_workers": 1, + "burn_per_block": 100, + "burn_fee": 1, + "recovery_vdf_top_rank_percent": 50, + "keep_track_of_metrics": false, + "p2p_accept_inbound": true, + "p2p_bind_port": 9444, + "p2p_announce_addr": "172.29.0.10:9444", + "stratum_enabled": false, + "stratum_bind_port": 3333, + "peers": [], + "address_book": {} +} diff --git a/e2e/snapshots/objective-finality/bootstrap/ui_data.sqlite3 b/e2e/snapshots/objective-finality/bootstrap/ui_data.sqlite3 Binary files differ. diff --git a/e2e/snapshots/objective-finality/bootstrap/wallet.json b/e2e/snapshots/objective-finality/bootstrap/wallet.json @@ -0,0 +1,12 @@ +{ + "version": 3, + "address": "3e4a4204952437f34094ef8eeec99aa859e4dd5129b145c397361c0c8fc986b7", + "encryption": { + "algorithm": "chacha20poly1305", + "kdf": "pbkdf2-sha256", + "kdf_iterations": 210000, + "salt": "e1e747ba2e453941d37f19ea5f30d855", + "nonce": "eccaf1defdea52ae6f60079d", + "ciphertext": "8f2d4b8693fe2ace1d277670cf9fecd53c7077b971f414f984efa85ef2f231bf650fe0b5ce6288d12bdbd60ce80409780b86af7101fed2c6718c177dcfb0791bd99a4ed32ef997a201d480e7ce8c574516f993470e55f37d202e5e9160412088ae45b7f5a21760fb92b5be706036bd0fb2fde98c3193f61c5e542ffda38c85d610b667f9ff66cd4707e5846491f92d9473d4bb9bba24020515b5e9a9e8732dfbc546b5a5c277be43ff3dff662ae0632a71cb2e70ad3a0ae492" + } +} diff --git a/e2e/snapshots/objective-finality/manifest.json b/e2e/snapshots/objective-finality/manifest.json @@ -0,0 +1,67 @@ +{ + "format": 1, + "name": "objective-finality", + "height": 1000, + "tip_hash": "3019077513cc28f557c7dc667dfc2548f05ed2ee32a3717d00cf9bff69f08867", + "profile_id": "iuna-local-e2e-5s-v1", + "target_block_ms": 5000, + "source_height": 1002, + "nodes": { + "bootstrap": { + "height": 1000, + "tip_hash": "3019077513cc28f557c7dc667dfc2548f05ed2ee32a3717d00cf9bff69f08867", + "updated_at_ms": 1788119532744 + }, + "node2": { + "height": 1000, + "tip_hash": "3019077513cc28f557c7dc667dfc2548f05ed2ee32a3717d00cf9bff69f08867", + "updated_at_ms": 1788119532744 + }, + "node3": { + "height": 1000, + "tip_hash": "3019077513cc28f557c7dc667dfc2548f05ed2ee32a3717d00cf9bff69f08867", + "updated_at_ms": 1788119532744 + }, + "node4": { + "height": 1000, + "tip_hash": "3019077513cc28f557c7dc667dfc2548f05ed2ee32a3717d00cf9bff69f08867", + "updated_at_ms": 1788119532744 + }, + "node5": { + "height": 1000, + "tip_hash": "3019077513cc28f557c7dc667dfc2548f05ed2ee32a3717d00cf9bff69f08867", + "updated_at_ms": 1788119532744 + }, + "node6": { + "height": 1000, + "tip_hash": "3019077513cc28f557c7dc667dfc2548f05ed2ee32a3717d00cf9bff69f08867", + "updated_at_ms": 1788119532744 + } + }, + "sha256": { + "bootstrap/chain.sqlite3": "f033556a11826a58f9148990322e68d66ac3b5272735a1ed1bcbbdb21789e955", + "bootstrap/config.json": "ee490011fee4bad2a08641cca4710efad5ee0cc7ff0f418e9b6b3b97f6d64c8e", + "bootstrap/ui_data.sqlite3": "535127daeea2a766f529551884fdddfa436b78c9c8f5db13f767371254d4b869", + "bootstrap/wallet.json": "9e545dee2d7d8c430a301fd9cc4530467c6ba36787d2407ec31eee96eee88874", + "node2/chain.sqlite3": "f033556a11826a58f9148990322e68d66ac3b5272735a1ed1bcbbdb21789e955", + "node2/config.json": "5f38677b8e290f412a2ff5833518a1b1fec75d9c8ab9dbc72b1762fd889e33c8", + "node2/ui_data.sqlite3": "535127daeea2a766f529551884fdddfa436b78c9c8f5db13f767371254d4b869", + "node2/wallet.json": "80c81d94fa958deb3212c3ae52bcfcdcf1f2ce446ec3c4addcfb8ffa6e669a4b", + "node3/chain.sqlite3": "f033556a11826a58f9148990322e68d66ac3b5272735a1ed1bcbbdb21789e955", + "node3/config.json": "63a8c0d8b06091dbfb899bba7f6603497c44e7af1bee9f21cc5152a3fafc037d", + "node3/ui_data.sqlite3": "535127daeea2a766f529551884fdddfa436b78c9c8f5db13f767371254d4b869", + "node3/wallet.json": "15d4b71da0e31f6045fc6b98b7d3414f7925556932de42b52bacd35e670c1c86", + "node4/chain.sqlite3": "f033556a11826a58f9148990322e68d66ac3b5272735a1ed1bcbbdb21789e955", + "node4/config.json": "f9bed39ec29fbff17fb6155e718454706991603d5993632c6f6b18cbf3d80fa4", + "node4/ui_data.sqlite3": "535127daeea2a766f529551884fdddfa436b78c9c8f5db13f767371254d4b869", + "node4/wallet.json": "204ff6327b0c5da43418f704322fcfe8de09f799239896146bfb0320d42e3780", + "node5/chain.sqlite3": "f033556a11826a58f9148990322e68d66ac3b5272735a1ed1bcbbdb21789e955", + "node5/config.json": "0bd460df616c8effb1091625887cab053d95e9f30afbc4237e7e5923c0cd6b73", + "node5/ui_data.sqlite3": "535127daeea2a766f529551884fdddfa436b78c9c8f5db13f767371254d4b869", + "node5/wallet.json": "4612e7e2143a11b5834b89e1dbaebb30d9c898930bfeb3eeedb347771b827808", + "node6/chain.sqlite3": "f033556a11826a58f9148990322e68d66ac3b5272735a1ed1bcbbdb21789e955", + "node6/config.json": "1d6aaba498ee1f273c89d7f84806318cf5f15c36088346460236e114a0fd73bb", + "node6/ui_data.sqlite3": "535127daeea2a766f529551884fdddfa436b78c9c8f5db13f767371254d4b869", + "node6/wallet.json": "1eaf0a87b89c5a36a3f43162894922176412817f468e907faa5970f1656a04f7" + } +} diff --git a/e2e/snapshots/objective-finality/node2/chain.sqlite3 b/e2e/snapshots/objective-finality/node2/chain.sqlite3 Binary files differ. diff --git a/e2e/snapshots/objective-finality/node2/config.json b/e2e/snapshots/objective-finality/node2/config.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "amount_unit": "microiuna", + "setup_complete": true, + "auth_password_hash": "pbkdf2-sha256$210000$df0c9708ae4ef33eebe6f1479fb5ec63$f91e1780984648d490b081b22a23c8aceed73684afe7d4abeb079e121e6326e6", + "mining_enabled": true, + "pow_mining_enabled": true, + "pow_mining_workers": 1, + "burn_per_block": 100, + "burn_fee": 1, + "recovery_vdf_top_rank_percent": 50, + "keep_track_of_metrics": false, + "p2p_accept_inbound": true, + "p2p_bind_port": 9444, + "p2p_announce_addr": "172.29.0.11:9444", + "stratum_enabled": false, + "stratum_bind_port": 3333, + "peers": [], + "address_book": {} +} diff --git a/e2e/snapshots/objective-finality/node2/ui_data.sqlite3 b/e2e/snapshots/objective-finality/node2/ui_data.sqlite3 Binary files differ. diff --git a/e2e/snapshots/objective-finality/node2/wallet.json b/e2e/snapshots/objective-finality/node2/wallet.json @@ -0,0 +1,12 @@ +{ + "version": 3, + "address": "1425cb395bea950db7c232bf19aa2dba4f63852f4eea230b05d238fcb57825a8", + "encryption": { + "algorithm": "chacha20poly1305", + "kdf": "pbkdf2-sha256", + "kdf_iterations": 210000, + "salt": "9c5e3443788a6af8f3ffe7c9bd13fdb0", + "nonce": "0853a86f1577ca3089ac60e8", + "ciphertext": "2c8e5149ac86f577ba59635c4d06eab73535c1c5de0b4113edabdf84ad3c1a29a07836fccb3d70175161eec7e2008aa0d088e201fb40ddc3e6a663b199efab4d2d86f5bad494fe6874b432783314f93575ea94628a4b9d8a13a9ee713b75876a121a6db698ccc510c4d87cc5f374728a11ca3c82c9b081513bc2c707e7170d58b94ea8a307432e874bbf27470c8d8577e7b859d33ab5dbd0f0057df8e74fbb7f1aee406fc9b34007b7925ff64ec91c" + } +} diff --git a/e2e/snapshots/objective-finality/node3/chain.sqlite3 b/e2e/snapshots/objective-finality/node3/chain.sqlite3 Binary files differ. diff --git a/e2e/snapshots/objective-finality/node3/config.json b/e2e/snapshots/objective-finality/node3/config.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "amount_unit": "microiuna", + "setup_complete": true, + "auth_password_hash": "pbkdf2-sha256$210000$874d9b2efb7aebfab8c2fe4097df301d$be5bd2bd0497afc7e4f7c37131e69408fd2cc485398cff16e95257249a0f6d1d", + "mining_enabled": true, + "pow_mining_enabled": true, + "pow_mining_workers": 1, + "burn_per_block": 100, + "burn_fee": 1, + "recovery_vdf_top_rank_percent": 50, + "keep_track_of_metrics": false, + "p2p_accept_inbound": true, + "p2p_bind_port": 9444, + "p2p_announce_addr": "172.29.0.12:9444", + "stratum_enabled": true, + "stratum_bind_port": 3333, + "peers": [], + "address_book": {} +} diff --git a/e2e/snapshots/objective-finality/node3/ui_data.sqlite3 b/e2e/snapshots/objective-finality/node3/ui_data.sqlite3 Binary files differ. diff --git a/e2e/snapshots/objective-finality/node3/wallet.json b/e2e/snapshots/objective-finality/node3/wallet.json @@ -0,0 +1,12 @@ +{ + "version": 3, + "address": "840fb90a44a2b4819e4a8d2212e429f750b1d344c0c76b36f8f3c8c729477b74", + "encryption": { + "algorithm": "chacha20poly1305", + "kdf": "pbkdf2-sha256", + "kdf_iterations": 210000, + "salt": "cb5b63813a202478b4613a957df08eef", + "nonce": "8403301b3c608ba677b43eb6", + "ciphertext": "67171c204a4dd725c07c2efb8a581561c2c3d0d736b9ba8ddae690635b2a10adcfd7e0308f8b872b6a32aa98ad7996776205a84b5a3148ddc3d8071b31f6c37536c7fd7a6567a2b7d3fafd64c50d6e5bf92e7886cb77329c8136a00d622b60a0753958765b8911e2d7fbfb039708ec6cecd8d168426a826d5d8620dd8db30c5ccd9c34116508e0e57388f7362dfbc4ed696641486867e09a6502a72190f0c9e951039e66cf74349a5b77d6d97ccbac7118d119b6343485c57923" + } +} diff --git a/e2e/snapshots/objective-finality/node4/chain.sqlite3 b/e2e/snapshots/objective-finality/node4/chain.sqlite3 Binary files differ. diff --git a/e2e/snapshots/objective-finality/node4/config.json b/e2e/snapshots/objective-finality/node4/config.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "amount_unit": "microiuna", + "setup_complete": true, + "auth_password_hash": "pbkdf2-sha256$210000$38a8a556a0e456c091d24aa8f5d3457f$888b4b3c1259773977c6be6c6283a47f7c194a716dd216d63299cec576562c84", + "mining_enabled": true, + "pow_mining_enabled": true, + "pow_mining_workers": 1, + "burn_per_block": 100, + "burn_fee": 1, + "recovery_vdf_top_rank_percent": 50, + "keep_track_of_metrics": false, + "p2p_accept_inbound": true, + "p2p_bind_port": 9444, + "p2p_announce_addr": "172.29.0.13:9444", + "stratum_enabled": false, + "stratum_bind_port": 3333, + "peers": [], + "address_book": {} +} diff --git a/e2e/snapshots/objective-finality/node4/ui_data.sqlite3 b/e2e/snapshots/objective-finality/node4/ui_data.sqlite3 Binary files differ. diff --git a/e2e/snapshots/objective-finality/node4/wallet.json b/e2e/snapshots/objective-finality/node4/wallet.json @@ -0,0 +1,12 @@ +{ + "version": 3, + "address": "4fcf7e382b2ead5aab1519987fd6d7ba78ccb2f423d3f5f407897ae23d4666a9", + "encryption": { + "algorithm": "chacha20poly1305", + "kdf": "pbkdf2-sha256", + "kdf_iterations": 210000, + "salt": "8acc212746e45b5fe3f2a20714b8d50b", + "nonce": "0d62ae5f2254f4c4a7a85a35", + "ciphertext": "76d14c604a765b2b15229291e7770520c7ade1be929bbb31d85e0cb8c6a768f197d5aa360e48cff0bf29a61943fdf1a129f4ab029aa3aef2db143794905928797295da00af3c323cb16f65010ce8d86cebdc789d1e55c3d0cb30fccf3ca47b51d83c51e13ef450b34263c8fc5783637d6e7406ab23d7f0d10e36f83ead64e7367c2907b968358fc524e2ed6bb9c7a93fd665834b7cdc3c47985fa6510c05999bae796a5d350ef7a2c70a88771109fcc933" + } +} diff --git a/e2e/snapshots/objective-finality/node5/chain.sqlite3 b/e2e/snapshots/objective-finality/node5/chain.sqlite3 Binary files differ. diff --git a/e2e/snapshots/objective-finality/node5/config.json b/e2e/snapshots/objective-finality/node5/config.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "amount_unit": "microiuna", + "setup_complete": true, + "auth_password_hash": "pbkdf2-sha256$210000$b338abc5ee16d0dcd1c7eca6b8c42066$e21c09652fd72a3e9a80fa202db973ef60cb385e66952641e9ade39c9cde91fa", + "mining_enabled": true, + "pow_mining_enabled": true, + "pow_mining_workers": 1, + "burn_per_block": 100, + "burn_fee": 1, + "recovery_vdf_top_rank_percent": 50, + "keep_track_of_metrics": false, + "p2p_accept_inbound": true, + "p2p_bind_port": 9444, + "p2p_announce_addr": "172.29.0.14:9444", + "stratum_enabled": false, + "stratum_bind_port": 3333, + "peers": [], + "address_book": {} +} diff --git a/e2e/snapshots/objective-finality/node5/ui_data.sqlite3 b/e2e/snapshots/objective-finality/node5/ui_data.sqlite3 Binary files differ. diff --git a/e2e/snapshots/objective-finality/node5/wallet.json b/e2e/snapshots/objective-finality/node5/wallet.json @@ -0,0 +1,12 @@ +{ + "version": 3, + "address": "24b37cfe96e5116e9c3de7f6e1ad3cf3a4b967c4b57c142fbf16f8733efafc47", + "encryption": { + "algorithm": "chacha20poly1305", + "kdf": "pbkdf2-sha256", + "kdf_iterations": 210000, + "salt": "628e9496c3a9f564e14584a24f28cc73", + "nonce": "0efe22ab02929c0a31b1ee98", + "ciphertext": "de0f0045b0084dfbe1051f1b37b0d0bde7c51859a63ddacef724af91db0caab19489d1b0e98b07f8acacd679f7f8cfad0c2b79b722beed9b5c483d2b61edde835cd1db531fae5820b1969effcb7387a2fe087b467c5de43afa5f41d3150a8f53cb0ccc2776d393065348b99d3fe7197515d98a40be545c7a2f9010318d035fcd7c3ebd0ab385b262d9149b6443093882812701ee0e346e95768a398cd6e36a1c9da3c9242337afc0114ed47e2b92f3" + } +} diff --git a/e2e/snapshots/objective-finality/node6/chain.sqlite3 b/e2e/snapshots/objective-finality/node6/chain.sqlite3 Binary files differ. diff --git a/e2e/snapshots/objective-finality/node6/config.json b/e2e/snapshots/objective-finality/node6/config.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "amount_unit": "microiuna", + "setup_complete": true, + "auth_password_hash": "pbkdf2-sha256$210000$097e8cb00697e94cae82aaa7de6e31bc$28085e3dec860904e03d9f17fe55158c9a8395040829ec4e5b1770b5a4c5b8c6", + "mining_enabled": true, + "pow_mining_enabled": true, + "pow_mining_workers": 1, + "burn_per_block": 100, + "burn_fee": 1, + "recovery_vdf_top_rank_percent": 50, + "keep_track_of_metrics": false, + "p2p_accept_inbound": true, + "p2p_bind_port": 9444, + "p2p_announce_addr": "172.29.0.15:9444", + "stratum_enabled": false, + "stratum_bind_port": 3333, + "peers": [], + "address_book": {} +} diff --git a/e2e/snapshots/objective-finality/node6/ui_data.sqlite3 b/e2e/snapshots/objective-finality/node6/ui_data.sqlite3 Binary files differ. diff --git a/e2e/snapshots/objective-finality/node6/wallet.json b/e2e/snapshots/objective-finality/node6/wallet.json @@ -0,0 +1,12 @@ +{ + "version": 3, + "address": "2aa3d9d02cb77e3f5f7151d9e32f9a079440028c14eaf5f4fc8e60eeec7f01c4", + "encryption": { + "algorithm": "chacha20poly1305", + "kdf": "pbkdf2-sha256", + "kdf_iterations": 210000, + "salt": "6880300421523e9a060053490bd68130", + "nonce": "3e19ca0e409214d72eb576ee", + "ciphertext": "a8edc95288b9d3b41ea92cd39652aa49b2272f02597cb510c9b11317500d8059e14418ac8a205deaae3e5baeedc0ff38371286853339bb211f8c4c22c8c938eee3c082b6260e604cd9b3caf65d0ca9febc594355225b0fff0bc2265e0832574185d0b5a2d35f8cad4efd6e6fdf895fe8646a0c6057022cc3ccd3975266b940e12ef733260d4a1f64e1af4645340cb7ffc802d74f1d26c9d0307010164d95f337bbb73fa9c9b2d241b47378b521ae99d6ffc1ae83aba4602d015b" + } +} diff --git a/e2e/snapshots/pre-fallback-invalidation/bootstrap/chain.sqlite3 b/e2e/snapshots/pre-fallback-invalidation/bootstrap/chain.sqlite3 Binary files differ. diff --git a/e2e/snapshots/pre-fallback-invalidation/bootstrap/config.json b/e2e/snapshots/pre-fallback-invalidation/bootstrap/config.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "amount_unit": "microiuna", + "setup_complete": true, + "auth_password_hash": "pbkdf2-sha256$210000$795b8db3cec7f3e710865c4b2f05ee37$709f4e7c66b5ac6153c312a1c602e49c4cfe719389a38dfadadfd339d08676b8", + "mining_enabled": true, + "pow_mining_enabled": false, + "pow_mining_workers": 1, + "burn_per_block": 100, + "burn_fee": 1, + "recovery_vdf_top_rank_percent": 50, + "keep_track_of_metrics": false, + "p2p_accept_inbound": true, + "p2p_bind_port": 9444, + "p2p_announce_addr": "172.29.0.10:9444", + "stratum_enabled": false, + "stratum_bind_port": 3333, + "peers": [], + "address_book": {} +} diff --git a/e2e/snapshots/pre-fallback-invalidation/bootstrap/ui_data.sqlite3 b/e2e/snapshots/pre-fallback-invalidation/bootstrap/ui_data.sqlite3 Binary files differ. diff --git a/e2e/snapshots/pre-fallback-invalidation/bootstrap/wallet.json b/e2e/snapshots/pre-fallback-invalidation/bootstrap/wallet.json @@ -0,0 +1,12 @@ +{ + "version": 3, + "address": "3e4a4204952437f34094ef8eeec99aa859e4dd5129b145c397361c0c8fc986b7", + "encryption": { + "algorithm": "chacha20poly1305", + "kdf": "pbkdf2-sha256", + "kdf_iterations": 210000, + "salt": "e1e747ba2e453941d37f19ea5f30d855", + "nonce": "eccaf1defdea52ae6f60079d", + "ciphertext": "8f2d4b8693fe2ace1d277670cf9fecd53c7077b971f414f984efa85ef2f231bf650fe0b5ce6288d12bdbd60ce80409780b86af7101fed2c6718c177dcfb0791bd99a4ed32ef997a201d480e7ce8c574516f993470e55f37d202e5e9160412088ae45b7f5a21760fb92b5be706036bd0fb2fde98c3193f61c5e542ffda38c85d610b667f9ff66cd4707e5846491f92d9473d4bb9bba24020515b5e9a9e8732dfbc546b5a5c277be43ff3dff662ae0632a71cb2e70ad3a0ae492" + } +} diff --git a/e2e/snapshots/pre-fallback-invalidation/manifest.json b/e2e/snapshots/pre-fallback-invalidation/manifest.json @@ -0,0 +1,67 @@ +{ + "format": 1, + "name": "pre-fallback-invalidation", + "height": 299, + "tip_hash": "a20f7af9100ebaf65edb3acfee28a283fb4c1898f6591e8bbfb63f8923ee98c0", + "profile_id": "iuna-local-e2e-5s-v1", + "target_block_ms": 5000, + "source_height": 1002, + "nodes": { + "bootstrap": { + "height": 299, + "tip_hash": "a20f7af9100ebaf65edb3acfee28a283fb4c1898f6591e8bbfb63f8923ee98c0", + "updated_at_ms": 1788119372099 + }, + "node2": { + "height": 299, + "tip_hash": "a20f7af9100ebaf65edb3acfee28a283fb4c1898f6591e8bbfb63f8923ee98c0", + "updated_at_ms": 1788119372099 + }, + "node3": { + "height": 299, + "tip_hash": "a20f7af9100ebaf65edb3acfee28a283fb4c1898f6591e8bbfb63f8923ee98c0", + "updated_at_ms": 1788119372099 + }, + "node4": { + "height": 299, + "tip_hash": "a20f7af9100ebaf65edb3acfee28a283fb4c1898f6591e8bbfb63f8923ee98c0", + "updated_at_ms": 1788119372099 + }, + "node5": { + "height": 299, + "tip_hash": "a20f7af9100ebaf65edb3acfee28a283fb4c1898f6591e8bbfb63f8923ee98c0", + "updated_at_ms": 1788119372099 + }, + "node6": { + "height": 299, + "tip_hash": "a20f7af9100ebaf65edb3acfee28a283fb4c1898f6591e8bbfb63f8923ee98c0", + "updated_at_ms": 1788119372099 + } + }, + "sha256": { + "bootstrap/chain.sqlite3": "bdc6893efdb63a763a4f39f46951c85ca10cd163ff8675a83b9f3807b61c8c07", + "bootstrap/config.json": "ee490011fee4bad2a08641cca4710efad5ee0cc7ff0f418e9b6b3b97f6d64c8e", + "bootstrap/ui_data.sqlite3": "04e4b2c870a0f3e774362fdeab16fb253e3664719fe9072f982b4d67f15e8f61", + "bootstrap/wallet.json": "9e545dee2d7d8c430a301fd9cc4530467c6ba36787d2407ec31eee96eee88874", + "node2/chain.sqlite3": "bdc6893efdb63a763a4f39f46951c85ca10cd163ff8675a83b9f3807b61c8c07", + "node2/config.json": "5f38677b8e290f412a2ff5833518a1b1fec75d9c8ab9dbc72b1762fd889e33c8", + "node2/ui_data.sqlite3": "04e4b2c870a0f3e774362fdeab16fb253e3664719fe9072f982b4d67f15e8f61", + "node2/wallet.json": "80c81d94fa958deb3212c3ae52bcfcdcf1f2ce446ec3c4addcfb8ffa6e669a4b", + "node3/chain.sqlite3": "bdc6893efdb63a763a4f39f46951c85ca10cd163ff8675a83b9f3807b61c8c07", + "node3/config.json": "63a8c0d8b06091dbfb899bba7f6603497c44e7af1bee9f21cc5152a3fafc037d", + "node3/ui_data.sqlite3": "04e4b2c870a0f3e774362fdeab16fb253e3664719fe9072f982b4d67f15e8f61", + "node3/wallet.json": "15d4b71da0e31f6045fc6b98b7d3414f7925556932de42b52bacd35e670c1c86", + "node4/chain.sqlite3": "bdc6893efdb63a763a4f39f46951c85ca10cd163ff8675a83b9f3807b61c8c07", + "node4/config.json": "f9bed39ec29fbff17fb6155e718454706991603d5993632c6f6b18cbf3d80fa4", + "node4/ui_data.sqlite3": "04e4b2c870a0f3e774362fdeab16fb253e3664719fe9072f982b4d67f15e8f61", + "node4/wallet.json": "204ff6327b0c5da43418f704322fcfe8de09f799239896146bfb0320d42e3780", + "node5/chain.sqlite3": "bdc6893efdb63a763a4f39f46951c85ca10cd163ff8675a83b9f3807b61c8c07", + "node5/config.json": "0bd460df616c8effb1091625887cab053d95e9f30afbc4237e7e5923c0cd6b73", + "node5/ui_data.sqlite3": "04e4b2c870a0f3e774362fdeab16fb253e3664719fe9072f982b4d67f15e8f61", + "node5/wallet.json": "4612e7e2143a11b5834b89e1dbaebb30d9c898930bfeb3eeedb347771b827808", + "node6/chain.sqlite3": "bdc6893efdb63a763a4f39f46951c85ca10cd163ff8675a83b9f3807b61c8c07", + "node6/config.json": "1d6aaba498ee1f273c89d7f84806318cf5f15c36088346460236e114a0fd73bb", + "node6/ui_data.sqlite3": "04e4b2c870a0f3e774362fdeab16fb253e3664719fe9072f982b4d67f15e8f61", + "node6/wallet.json": "1eaf0a87b89c5a36a3f43162894922176412817f468e907faa5970f1656a04f7" + } +} diff --git a/e2e/snapshots/pre-fallback-invalidation/node2/chain.sqlite3 b/e2e/snapshots/pre-fallback-invalidation/node2/chain.sqlite3 Binary files differ. diff --git a/e2e/snapshots/pre-fallback-invalidation/node2/config.json b/e2e/snapshots/pre-fallback-invalidation/node2/config.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "amount_unit": "microiuna", + "setup_complete": true, + "auth_password_hash": "pbkdf2-sha256$210000$df0c9708ae4ef33eebe6f1479fb5ec63$f91e1780984648d490b081b22a23c8aceed73684afe7d4abeb079e121e6326e6", + "mining_enabled": true, + "pow_mining_enabled": true, + "pow_mining_workers": 1, + "burn_per_block": 100, + "burn_fee": 1, + "recovery_vdf_top_rank_percent": 50, + "keep_track_of_metrics": false, + "p2p_accept_inbound": true, + "p2p_bind_port": 9444, + "p2p_announce_addr": "172.29.0.11:9444", + "stratum_enabled": false, + "stratum_bind_port": 3333, + "peers": [], + "address_book": {} +} diff --git a/e2e/snapshots/pre-fallback-invalidation/node2/ui_data.sqlite3 b/e2e/snapshots/pre-fallback-invalidation/node2/ui_data.sqlite3 Binary files differ. diff --git a/e2e/snapshots/pre-fallback-invalidation/node2/wallet.json b/e2e/snapshots/pre-fallback-invalidation/node2/wallet.json @@ -0,0 +1,12 @@ +{ + "version": 3, + "address": "1425cb395bea950db7c232bf19aa2dba4f63852f4eea230b05d238fcb57825a8", + "encryption": { + "algorithm": "chacha20poly1305", + "kdf": "pbkdf2-sha256", + "kdf_iterations": 210000, + "salt": "9c5e3443788a6af8f3ffe7c9bd13fdb0", + "nonce": "0853a86f1577ca3089ac60e8", + "ciphertext": "2c8e5149ac86f577ba59635c4d06eab73535c1c5de0b4113edabdf84ad3c1a29a07836fccb3d70175161eec7e2008aa0d088e201fb40ddc3e6a663b199efab4d2d86f5bad494fe6874b432783314f93575ea94628a4b9d8a13a9ee713b75876a121a6db698ccc510c4d87cc5f374728a11ca3c82c9b081513bc2c707e7170d58b94ea8a307432e874bbf27470c8d8577e7b859d33ab5dbd0f0057df8e74fbb7f1aee406fc9b34007b7925ff64ec91c" + } +} diff --git a/e2e/snapshots/pre-fallback-invalidation/node3/chain.sqlite3 b/e2e/snapshots/pre-fallback-invalidation/node3/chain.sqlite3 Binary files differ. diff --git a/e2e/snapshots/pre-fallback-invalidation/node3/config.json b/e2e/snapshots/pre-fallback-invalidation/node3/config.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "amount_unit": "microiuna", + "setup_complete": true, + "auth_password_hash": "pbkdf2-sha256$210000$874d9b2efb7aebfab8c2fe4097df301d$be5bd2bd0497afc7e4f7c37131e69408fd2cc485398cff16e95257249a0f6d1d", + "mining_enabled": true, + "pow_mining_enabled": true, + "pow_mining_workers": 1, + "burn_per_block": 100, + "burn_fee": 1, + "recovery_vdf_top_rank_percent": 50, + "keep_track_of_metrics": false, + "p2p_accept_inbound": true, + "p2p_bind_port": 9444, + "p2p_announce_addr": "172.29.0.12:9444", + "stratum_enabled": true, + "stratum_bind_port": 3333, + "peers": [], + "address_book": {} +} diff --git a/e2e/snapshots/pre-fallback-invalidation/node3/ui_data.sqlite3 b/e2e/snapshots/pre-fallback-invalidation/node3/ui_data.sqlite3 Binary files differ. diff --git a/e2e/snapshots/pre-fallback-invalidation/node3/wallet.json b/e2e/snapshots/pre-fallback-invalidation/node3/wallet.json @@ -0,0 +1,12 @@ +{ + "version": 3, + "address": "840fb90a44a2b4819e4a8d2212e429f750b1d344c0c76b36f8f3c8c729477b74", + "encryption": { + "algorithm": "chacha20poly1305", + "kdf": "pbkdf2-sha256", + "kdf_iterations": 210000, + "salt": "cb5b63813a202478b4613a957df08eef", + "nonce": "8403301b3c608ba677b43eb6", + "ciphertext": "67171c204a4dd725c07c2efb8a581561c2c3d0d736b9ba8ddae690635b2a10adcfd7e0308f8b872b6a32aa98ad7996776205a84b5a3148ddc3d8071b31f6c37536c7fd7a6567a2b7d3fafd64c50d6e5bf92e7886cb77329c8136a00d622b60a0753958765b8911e2d7fbfb039708ec6cecd8d168426a826d5d8620dd8db30c5ccd9c34116508e0e57388f7362dfbc4ed696641486867e09a6502a72190f0c9e951039e66cf74349a5b77d6d97ccbac7118d119b6343485c57923" + } +} diff --git a/e2e/snapshots/pre-fallback-invalidation/node4/chain.sqlite3 b/e2e/snapshots/pre-fallback-invalidation/node4/chain.sqlite3 Binary files differ. diff --git a/e2e/snapshots/pre-fallback-invalidation/node4/config.json b/e2e/snapshots/pre-fallback-invalidation/node4/config.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "amount_unit": "microiuna", + "setup_complete": true, + "auth_password_hash": "pbkdf2-sha256$210000$38a8a556a0e456c091d24aa8f5d3457f$888b4b3c1259773977c6be6c6283a47f7c194a716dd216d63299cec576562c84", + "mining_enabled": true, + "pow_mining_enabled": true, + "pow_mining_workers": 1, + "burn_per_block": 100, + "burn_fee": 1, + "recovery_vdf_top_rank_percent": 50, + "keep_track_of_metrics": false, + "p2p_accept_inbound": true, + "p2p_bind_port": 9444, + "p2p_announce_addr": "172.29.0.13:9444", + "stratum_enabled": false, + "stratum_bind_port": 3333, + "peers": [], + "address_book": {} +} diff --git a/e2e/snapshots/pre-fallback-invalidation/node4/ui_data.sqlite3 b/e2e/snapshots/pre-fallback-invalidation/node4/ui_data.sqlite3 Binary files differ. diff --git a/e2e/snapshots/pre-fallback-invalidation/node4/wallet.json b/e2e/snapshots/pre-fallback-invalidation/node4/wallet.json @@ -0,0 +1,12 @@ +{ + "version": 3, + "address": "4fcf7e382b2ead5aab1519987fd6d7ba78ccb2f423d3f5f407897ae23d4666a9", + "encryption": { + "algorithm": "chacha20poly1305", + "kdf": "pbkdf2-sha256", + "kdf_iterations": 210000, + "salt": "8acc212746e45b5fe3f2a20714b8d50b", + "nonce": "0d62ae5f2254f4c4a7a85a35", + "ciphertext": "76d14c604a765b2b15229291e7770520c7ade1be929bbb31d85e0cb8c6a768f197d5aa360e48cff0bf29a61943fdf1a129f4ab029aa3aef2db143794905928797295da00af3c323cb16f65010ce8d86cebdc789d1e55c3d0cb30fccf3ca47b51d83c51e13ef450b34263c8fc5783637d6e7406ab23d7f0d10e36f83ead64e7367c2907b968358fc524e2ed6bb9c7a93fd665834b7cdc3c47985fa6510c05999bae796a5d350ef7a2c70a88771109fcc933" + } +} diff --git a/e2e/snapshots/pre-fallback-invalidation/node5/chain.sqlite3 b/e2e/snapshots/pre-fallback-invalidation/node5/chain.sqlite3 Binary files differ. diff --git a/e2e/snapshots/pre-fallback-invalidation/node5/config.json b/e2e/snapshots/pre-fallback-invalidation/node5/config.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "amount_unit": "microiuna", + "setup_complete": true, + "auth_password_hash": "pbkdf2-sha256$210000$b338abc5ee16d0dcd1c7eca6b8c42066$e21c09652fd72a3e9a80fa202db973ef60cb385e66952641e9ade39c9cde91fa", + "mining_enabled": true, + "pow_mining_enabled": true, + "pow_mining_workers": 1, + "burn_per_block": 100, + "burn_fee": 1, + "recovery_vdf_top_rank_percent": 50, + "keep_track_of_metrics": false, + "p2p_accept_inbound": true, + "p2p_bind_port": 9444, + "p2p_announce_addr": "172.29.0.14:9444", + "stratum_enabled": false, + "stratum_bind_port": 3333, + "peers": [], + "address_book": {} +} diff --git a/e2e/snapshots/pre-fallback-invalidation/node5/ui_data.sqlite3 b/e2e/snapshots/pre-fallback-invalidation/node5/ui_data.sqlite3 Binary files differ. diff --git a/e2e/snapshots/pre-fallback-invalidation/node5/wallet.json b/e2e/snapshots/pre-fallback-invalidation/node5/wallet.json @@ -0,0 +1,12 @@ +{ + "version": 3, + "address": "24b37cfe96e5116e9c3de7f6e1ad3cf3a4b967c4b57c142fbf16f8733efafc47", + "encryption": { + "algorithm": "chacha20poly1305", + "kdf": "pbkdf2-sha256", + "kdf_iterations": 210000, + "salt": "628e9496c3a9f564e14584a24f28cc73", + "nonce": "0efe22ab02929c0a31b1ee98", + "ciphertext": "de0f0045b0084dfbe1051f1b37b0d0bde7c51859a63ddacef724af91db0caab19489d1b0e98b07f8acacd679f7f8cfad0c2b79b722beed9b5c483d2b61edde835cd1db531fae5820b1969effcb7387a2fe087b467c5de43afa5f41d3150a8f53cb0ccc2776d393065348b99d3fe7197515d98a40be545c7a2f9010318d035fcd7c3ebd0ab385b262d9149b6443093882812701ee0e346e95768a398cd6e36a1c9da3c9242337afc0114ed47e2b92f3" + } +} diff --git a/e2e/snapshots/pre-fallback-invalidation/node6/chain.sqlite3 b/e2e/snapshots/pre-fallback-invalidation/node6/chain.sqlite3 Binary files differ. diff --git a/e2e/snapshots/pre-fallback-invalidation/node6/config.json b/e2e/snapshots/pre-fallback-invalidation/node6/config.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "amount_unit": "microiuna", + "setup_complete": true, + "auth_password_hash": "pbkdf2-sha256$210000$097e8cb00697e94cae82aaa7de6e31bc$28085e3dec860904e03d9f17fe55158c9a8395040829ec4e5b1770b5a4c5b8c6", + "mining_enabled": true, + "pow_mining_enabled": true, + "pow_mining_workers": 1, + "burn_per_block": 100, + "burn_fee": 1, + "recovery_vdf_top_rank_percent": 50, + "keep_track_of_metrics": false, + "p2p_accept_inbound": true, + "p2p_bind_port": 9444, + "p2p_announce_addr": "172.29.0.15:9444", + "stratum_enabled": false, + "stratum_bind_port": 3333, + "peers": [], + "address_book": {} +} diff --git a/e2e/snapshots/pre-fallback-invalidation/node6/ui_data.sqlite3 b/e2e/snapshots/pre-fallback-invalidation/node6/ui_data.sqlite3 Binary files differ. diff --git a/e2e/snapshots/pre-fallback-invalidation/node6/wallet.json b/e2e/snapshots/pre-fallback-invalidation/node6/wallet.json @@ -0,0 +1,12 @@ +{ + "version": 3, + "address": "2aa3d9d02cb77e3f5f7151d9e32f9a079440028c14eaf5f4fc8e60eeec7f01c4", + "encryption": { + "algorithm": "chacha20poly1305", + "kdf": "pbkdf2-sha256", + "kdf_iterations": 210000, + "salt": "6880300421523e9a060053490bd68130", + "nonce": "3e19ca0e409214d72eb576ee", + "ciphertext": "a8edc95288b9d3b41ea92cd39652aa49b2272f02597cb510c9b11317500d8059e14418ac8a205deaae3e5baeedc0ff38371286853339bb211f8c4c22c8c938eee3c082b6260e604cd9b3caf65d0ca9febc594355225b0fff0bc2265e0832574185d0b5a2d35f8cad4efd6e6fdf895fe8646a0c6057022cc3ccd3975266b940e12ef733260d4a1f64e1af4645340cb7ffc802d74f1d26c9d0307010164d95f337bbb73fa9c9b2d241b47378b521ae99d6ffc1ae83aba4602d015b" + } +} diff --git a/e2e/snapshots/pre-objective-finality/bootstrap/chain.sqlite3 b/e2e/snapshots/pre-objective-finality/bootstrap/chain.sqlite3 Binary files differ. diff --git a/e2e/snapshots/pre-objective-finality/bootstrap/config.json b/e2e/snapshots/pre-objective-finality/bootstrap/config.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "amount_unit": "microiuna", + "setup_complete": true, + "auth_password_hash": "pbkdf2-sha256$210000$795b8db3cec7f3e710865c4b2f05ee37$709f4e7c66b5ac6153c312a1c602e49c4cfe719389a38dfadadfd339d08676b8", + "mining_enabled": true, + "pow_mining_enabled": false, + "pow_mining_workers": 1, + "burn_per_block": 100, + "burn_fee": 1, + "recovery_vdf_top_rank_percent": 50, + "keep_track_of_metrics": false, + "p2p_accept_inbound": true, + "p2p_bind_port": 9444, + "p2p_announce_addr": "172.29.0.10:9444", + "stratum_enabled": false, + "stratum_bind_port": 3333, + "peers": [], + "address_book": {} +} diff --git a/e2e/snapshots/pre-objective-finality/bootstrap/ui_data.sqlite3 b/e2e/snapshots/pre-objective-finality/bootstrap/ui_data.sqlite3 Binary files differ. diff --git a/e2e/snapshots/pre-objective-finality/bootstrap/wallet.json b/e2e/snapshots/pre-objective-finality/bootstrap/wallet.json @@ -0,0 +1,12 @@ +{ + "version": 3, + "address": "3e4a4204952437f34094ef8eeec99aa859e4dd5129b145c397361c0c8fc986b7", + "encryption": { + "algorithm": "chacha20poly1305", + "kdf": "pbkdf2-sha256", + "kdf_iterations": 210000, + "salt": "e1e747ba2e453941d37f19ea5f30d855", + "nonce": "eccaf1defdea52ae6f60079d", + "ciphertext": "8f2d4b8693fe2ace1d277670cf9fecd53c7077b971f414f984efa85ef2f231bf650fe0b5ce6288d12bdbd60ce80409780b86af7101fed2c6718c177dcfb0791bd99a4ed32ef997a201d480e7ce8c574516f993470e55f37d202e5e9160412088ae45b7f5a21760fb92b5be706036bd0fb2fde98c3193f61c5e542ffda38c85d610b667f9ff66cd4707e5846491f92d9473d4bb9bba24020515b5e9a9e8732dfbc546b5a5c277be43ff3dff662ae0632a71cb2e70ad3a0ae492" + } +} diff --git a/e2e/snapshots/pre-objective-finality/manifest.json b/e2e/snapshots/pre-objective-finality/manifest.json @@ -0,0 +1,67 @@ +{ + "format": 1, + "name": "pre-objective-finality", + "height": 999, + "tip_hash": "2bcffc68f2ffc08cd07cb02fb9a40cf7e63105e5afa0acd6498218360c6952e2", + "profile_id": "iuna-local-e2e-5s-v1", + "target_block_ms": 5000, + "source_height": 1002, + "nodes": { + "bootstrap": { + "height": 999, + "tip_hash": "2bcffc68f2ffc08cd07cb02fb9a40cf7e63105e5afa0acd6498218360c6952e2", + "updated_at_ms": 1788119423523 + }, + "node2": { + "height": 999, + "tip_hash": "2bcffc68f2ffc08cd07cb02fb9a40cf7e63105e5afa0acd6498218360c6952e2", + "updated_at_ms": 1788119423523 + }, + "node3": { + "height": 999, + "tip_hash": "2bcffc68f2ffc08cd07cb02fb9a40cf7e63105e5afa0acd6498218360c6952e2", + "updated_at_ms": 1788119423523 + }, + "node4": { + "height": 999, + "tip_hash": "2bcffc68f2ffc08cd07cb02fb9a40cf7e63105e5afa0acd6498218360c6952e2", + "updated_at_ms": 1788119423523 + }, + "node5": { + "height": 999, + "tip_hash": "2bcffc68f2ffc08cd07cb02fb9a40cf7e63105e5afa0acd6498218360c6952e2", + "updated_at_ms": 1788119423523 + }, + "node6": { + "height": 999, + "tip_hash": "2bcffc68f2ffc08cd07cb02fb9a40cf7e63105e5afa0acd6498218360c6952e2", + "updated_at_ms": 1788119423523 + } + }, + "sha256": { + "bootstrap/chain.sqlite3": "879ee6f111d0f44841b7a3ca863f1196782ba4f590c571aa29a19d6e81b10d2a", + "bootstrap/config.json": "ee490011fee4bad2a08641cca4710efad5ee0cc7ff0f418e9b6b3b97f6d64c8e", + "bootstrap/ui_data.sqlite3": "2988c4facadfe065fd9ab65ae8e74740811c2dd0a401c942e6316fcbe4f80f92", + "bootstrap/wallet.json": "9e545dee2d7d8c430a301fd9cc4530467c6ba36787d2407ec31eee96eee88874", + "node2/chain.sqlite3": "879ee6f111d0f44841b7a3ca863f1196782ba4f590c571aa29a19d6e81b10d2a", + "node2/config.json": "5f38677b8e290f412a2ff5833518a1b1fec75d9c8ab9dbc72b1762fd889e33c8", + "node2/ui_data.sqlite3": "2988c4facadfe065fd9ab65ae8e74740811c2dd0a401c942e6316fcbe4f80f92", + "node2/wallet.json": "80c81d94fa958deb3212c3ae52bcfcdcf1f2ce446ec3c4addcfb8ffa6e669a4b", + "node3/chain.sqlite3": "879ee6f111d0f44841b7a3ca863f1196782ba4f590c571aa29a19d6e81b10d2a", + "node3/config.json": "63a8c0d8b06091dbfb899bba7f6603497c44e7af1bee9f21cc5152a3fafc037d", + "node3/ui_data.sqlite3": "2988c4facadfe065fd9ab65ae8e74740811c2dd0a401c942e6316fcbe4f80f92", + "node3/wallet.json": "15d4b71da0e31f6045fc6b98b7d3414f7925556932de42b52bacd35e670c1c86", + "node4/chain.sqlite3": "879ee6f111d0f44841b7a3ca863f1196782ba4f590c571aa29a19d6e81b10d2a", + "node4/config.json": "f9bed39ec29fbff17fb6155e718454706991603d5993632c6f6b18cbf3d80fa4", + "node4/ui_data.sqlite3": "2988c4facadfe065fd9ab65ae8e74740811c2dd0a401c942e6316fcbe4f80f92", + "node4/wallet.json": "204ff6327b0c5da43418f704322fcfe8de09f799239896146bfb0320d42e3780", + "node5/chain.sqlite3": "879ee6f111d0f44841b7a3ca863f1196782ba4f590c571aa29a19d6e81b10d2a", + "node5/config.json": "0bd460df616c8effb1091625887cab053d95e9f30afbc4237e7e5923c0cd6b73", + "node5/ui_data.sqlite3": "2988c4facadfe065fd9ab65ae8e74740811c2dd0a401c942e6316fcbe4f80f92", + "node5/wallet.json": "4612e7e2143a11b5834b89e1dbaebb30d9c898930bfeb3eeedb347771b827808", + "node6/chain.sqlite3": "879ee6f111d0f44841b7a3ca863f1196782ba4f590c571aa29a19d6e81b10d2a", + "node6/config.json": "1d6aaba498ee1f273c89d7f84806318cf5f15c36088346460236e114a0fd73bb", + "node6/ui_data.sqlite3": "2988c4facadfe065fd9ab65ae8e74740811c2dd0a401c942e6316fcbe4f80f92", + "node6/wallet.json": "1eaf0a87b89c5a36a3f43162894922176412817f468e907faa5970f1656a04f7" + } +} diff --git a/e2e/snapshots/pre-objective-finality/node2/chain.sqlite3 b/e2e/snapshots/pre-objective-finality/node2/chain.sqlite3 Binary files differ. diff --git a/e2e/snapshots/pre-objective-finality/node2/config.json b/e2e/snapshots/pre-objective-finality/node2/config.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "amount_unit": "microiuna", + "setup_complete": true, + "auth_password_hash": "pbkdf2-sha256$210000$df0c9708ae4ef33eebe6f1479fb5ec63$f91e1780984648d490b081b22a23c8aceed73684afe7d4abeb079e121e6326e6", + "mining_enabled": true, + "pow_mining_enabled": true, + "pow_mining_workers": 1, + "burn_per_block": 100, + "burn_fee": 1, + "recovery_vdf_top_rank_percent": 50, + "keep_track_of_metrics": false, + "p2p_accept_inbound": true, + "p2p_bind_port": 9444, + "p2p_announce_addr": "172.29.0.11:9444", + "stratum_enabled": false, + "stratum_bind_port": 3333, + "peers": [], + "address_book": {} +} diff --git a/e2e/snapshots/pre-objective-finality/node2/ui_data.sqlite3 b/e2e/snapshots/pre-objective-finality/node2/ui_data.sqlite3 Binary files differ. diff --git a/e2e/snapshots/pre-objective-finality/node2/wallet.json b/e2e/snapshots/pre-objective-finality/node2/wallet.json @@ -0,0 +1,12 @@ +{ + "version": 3, + "address": "1425cb395bea950db7c232bf19aa2dba4f63852f4eea230b05d238fcb57825a8", + "encryption": { + "algorithm": "chacha20poly1305", + "kdf": "pbkdf2-sha256", + "kdf_iterations": 210000, + "salt": "9c5e3443788a6af8f3ffe7c9bd13fdb0", + "nonce": "0853a86f1577ca3089ac60e8", + "ciphertext": "2c8e5149ac86f577ba59635c4d06eab73535c1c5de0b4113edabdf84ad3c1a29a07836fccb3d70175161eec7e2008aa0d088e201fb40ddc3e6a663b199efab4d2d86f5bad494fe6874b432783314f93575ea94628a4b9d8a13a9ee713b75876a121a6db698ccc510c4d87cc5f374728a11ca3c82c9b081513bc2c707e7170d58b94ea8a307432e874bbf27470c8d8577e7b859d33ab5dbd0f0057df8e74fbb7f1aee406fc9b34007b7925ff64ec91c" + } +} diff --git a/e2e/snapshots/pre-objective-finality/node3/chain.sqlite3 b/e2e/snapshots/pre-objective-finality/node3/chain.sqlite3 Binary files differ. diff --git a/e2e/snapshots/pre-objective-finality/node3/config.json b/e2e/snapshots/pre-objective-finality/node3/config.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "amount_unit": "microiuna", + "setup_complete": true, + "auth_password_hash": "pbkdf2-sha256$210000$874d9b2efb7aebfab8c2fe4097df301d$be5bd2bd0497afc7e4f7c37131e69408fd2cc485398cff16e95257249a0f6d1d", + "mining_enabled": true, + "pow_mining_enabled": true, + "pow_mining_workers": 1, + "burn_per_block": 100, + "burn_fee": 1, + "recovery_vdf_top_rank_percent": 50, + "keep_track_of_metrics": false, + "p2p_accept_inbound": true, + "p2p_bind_port": 9444, + "p2p_announce_addr": "172.29.0.12:9444", + "stratum_enabled": true, + "stratum_bind_port": 3333, + "peers": [], + "address_book": {} +} diff --git a/e2e/snapshots/pre-objective-finality/node3/ui_data.sqlite3 b/e2e/snapshots/pre-objective-finality/node3/ui_data.sqlite3 Binary files differ. diff --git a/e2e/snapshots/pre-objective-finality/node3/wallet.json b/e2e/snapshots/pre-objective-finality/node3/wallet.json @@ -0,0 +1,12 @@ +{ + "version": 3, + "address": "840fb90a44a2b4819e4a8d2212e429f750b1d344c0c76b36f8f3c8c729477b74", + "encryption": { + "algorithm": "chacha20poly1305", + "kdf": "pbkdf2-sha256", + "kdf_iterations": 210000, + "salt": "cb5b63813a202478b4613a957df08eef", + "nonce": "8403301b3c608ba677b43eb6", + "ciphertext": "67171c204a4dd725c07c2efb8a581561c2c3d0d736b9ba8ddae690635b2a10adcfd7e0308f8b872b6a32aa98ad7996776205a84b5a3148ddc3d8071b31f6c37536c7fd7a6567a2b7d3fafd64c50d6e5bf92e7886cb77329c8136a00d622b60a0753958765b8911e2d7fbfb039708ec6cecd8d168426a826d5d8620dd8db30c5ccd9c34116508e0e57388f7362dfbc4ed696641486867e09a6502a72190f0c9e951039e66cf74349a5b77d6d97ccbac7118d119b6343485c57923" + } +} diff --git a/e2e/snapshots/pre-objective-finality/node4/chain.sqlite3 b/e2e/snapshots/pre-objective-finality/node4/chain.sqlite3 Binary files differ. diff --git a/e2e/snapshots/pre-objective-finality/node4/config.json b/e2e/snapshots/pre-objective-finality/node4/config.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "amount_unit": "microiuna", + "setup_complete": true, + "auth_password_hash": "pbkdf2-sha256$210000$38a8a556a0e456c091d24aa8f5d3457f$888b4b3c1259773977c6be6c6283a47f7c194a716dd216d63299cec576562c84", + "mining_enabled": true, + "pow_mining_enabled": true, + "pow_mining_workers": 1, + "burn_per_block": 100, + "burn_fee": 1, + "recovery_vdf_top_rank_percent": 50, + "keep_track_of_metrics": false, + "p2p_accept_inbound": true, + "p2p_bind_port": 9444, + "p2p_announce_addr": "172.29.0.13:9444", + "stratum_enabled": false, + "stratum_bind_port": 3333, + "peers": [], + "address_book": {} +} diff --git a/e2e/snapshots/pre-objective-finality/node4/ui_data.sqlite3 b/e2e/snapshots/pre-objective-finality/node4/ui_data.sqlite3 Binary files differ. diff --git a/e2e/snapshots/pre-objective-finality/node4/wallet.json b/e2e/snapshots/pre-objective-finality/node4/wallet.json @@ -0,0 +1,12 @@ +{ + "version": 3, + "address": "4fcf7e382b2ead5aab1519987fd6d7ba78ccb2f423d3f5f407897ae23d4666a9", + "encryption": { + "algorithm": "chacha20poly1305", + "kdf": "pbkdf2-sha256", + "kdf_iterations": 210000, + "salt": "8acc212746e45b5fe3f2a20714b8d50b", + "nonce": "0d62ae5f2254f4c4a7a85a35", + "ciphertext": "76d14c604a765b2b15229291e7770520c7ade1be929bbb31d85e0cb8c6a768f197d5aa360e48cff0bf29a61943fdf1a129f4ab029aa3aef2db143794905928797295da00af3c323cb16f65010ce8d86cebdc789d1e55c3d0cb30fccf3ca47b51d83c51e13ef450b34263c8fc5783637d6e7406ab23d7f0d10e36f83ead64e7367c2907b968358fc524e2ed6bb9c7a93fd665834b7cdc3c47985fa6510c05999bae796a5d350ef7a2c70a88771109fcc933" + } +} diff --git a/e2e/snapshots/pre-objective-finality/node5/chain.sqlite3 b/e2e/snapshots/pre-objective-finality/node5/chain.sqlite3 Binary files differ. diff --git a/e2e/snapshots/pre-objective-finality/node5/config.json b/e2e/snapshots/pre-objective-finality/node5/config.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "amount_unit": "microiuna", + "setup_complete": true, + "auth_password_hash": "pbkdf2-sha256$210000$b338abc5ee16d0dcd1c7eca6b8c42066$e21c09652fd72a3e9a80fa202db973ef60cb385e66952641e9ade39c9cde91fa", + "mining_enabled": true, + "pow_mining_enabled": true, + "pow_mining_workers": 1, + "burn_per_block": 100, + "burn_fee": 1, + "recovery_vdf_top_rank_percent": 50, + "keep_track_of_metrics": false, + "p2p_accept_inbound": true, + "p2p_bind_port": 9444, + "p2p_announce_addr": "172.29.0.14:9444", + "stratum_enabled": false, + "stratum_bind_port": 3333, + "peers": [], + "address_book": {} +} diff --git a/e2e/snapshots/pre-objective-finality/node5/ui_data.sqlite3 b/e2e/snapshots/pre-objective-finality/node5/ui_data.sqlite3 Binary files differ. diff --git a/e2e/snapshots/pre-objective-finality/node5/wallet.json b/e2e/snapshots/pre-objective-finality/node5/wallet.json @@ -0,0 +1,12 @@ +{ + "version": 3, + "address": "24b37cfe96e5116e9c3de7f6e1ad3cf3a4b967c4b57c142fbf16f8733efafc47", + "encryption": { + "algorithm": "chacha20poly1305", + "kdf": "pbkdf2-sha256", + "kdf_iterations": 210000, + "salt": "628e9496c3a9f564e14584a24f28cc73", + "nonce": "0efe22ab02929c0a31b1ee98", + "ciphertext": "de0f0045b0084dfbe1051f1b37b0d0bde7c51859a63ddacef724af91db0caab19489d1b0e98b07f8acacd679f7f8cfad0c2b79b722beed9b5c483d2b61edde835cd1db531fae5820b1969effcb7387a2fe087b467c5de43afa5f41d3150a8f53cb0ccc2776d393065348b99d3fe7197515d98a40be545c7a2f9010318d035fcd7c3ebd0ab385b262d9149b6443093882812701ee0e346e95768a398cd6e36a1c9da3c9242337afc0114ed47e2b92f3" + } +} diff --git a/e2e/snapshots/pre-objective-finality/node6/chain.sqlite3 b/e2e/snapshots/pre-objective-finality/node6/chain.sqlite3 Binary files differ. diff --git a/e2e/snapshots/pre-objective-finality/node6/config.json b/e2e/snapshots/pre-objective-finality/node6/config.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "amount_unit": "microiuna", + "setup_complete": true, + "auth_password_hash": "pbkdf2-sha256$210000$097e8cb00697e94cae82aaa7de6e31bc$28085e3dec860904e03d9f17fe55158c9a8395040829ec4e5b1770b5a4c5b8c6", + "mining_enabled": true, + "pow_mining_enabled": true, + "pow_mining_workers": 1, + "burn_per_block": 100, + "burn_fee": 1, + "recovery_vdf_top_rank_percent": 50, + "keep_track_of_metrics": false, + "p2p_accept_inbound": true, + "p2p_bind_port": 9444, + "p2p_announce_addr": "172.29.0.15:9444", + "stratum_enabled": false, + "stratum_bind_port": 3333, + "peers": [], + "address_book": {} +} diff --git a/e2e/snapshots/pre-objective-finality/node6/ui_data.sqlite3 b/e2e/snapshots/pre-objective-finality/node6/ui_data.sqlite3 Binary files differ. diff --git a/e2e/snapshots/pre-objective-finality/node6/wallet.json b/e2e/snapshots/pre-objective-finality/node6/wallet.json @@ -0,0 +1,12 @@ +{ + "version": 3, + "address": "2aa3d9d02cb77e3f5f7151d9e32f9a079440028c14eaf5f4fc8e60eeec7f01c4", + "encryption": { + "algorithm": "chacha20poly1305", + "kdf": "pbkdf2-sha256", + "kdf_iterations": 210000, + "salt": "6880300421523e9a060053490bd68130", + "nonce": "3e19ca0e409214d72eb576ee", + "ciphertext": "a8edc95288b9d3b41ea92cd39652aa49b2272f02597cb510c9b11317500d8059e14418ac8a205deaae3e5baeedc0ff38371286853339bb211f8c4c22c8c938eee3c082b6260e604cd9b3caf65d0ca9febc594355225b0fff0bc2265e0832574185d0b5a2d35f8cad4efd6e6fdf895fe8646a0c6057022cc3ccd3975266b940e12ef733260d4a1f64e1af4645340cb7ffc802d74f1d26c9d0307010164d95f337bbb73fa9c9b2d241b47378b521ae99d6ffc1ae83aba4602d015b" + } +} diff --git a/src/adapters/p2p/fetch.rs b/src/adapters/p2p/fetch.rs @@ -1,4 +1,4 @@ -use std::net::SocketAddr; +use std::{collections::BTreeMap, net::SocketAddr}; use anyhow::{Context, Result}; use tokio::{ @@ -7,7 +7,7 @@ use tokio::{ }; use crate::{ - app::{ChainBootstrap, GossipEnvelope, NETWORK_ID, PROTOCOL_VERSION, now_ms}, + app::{ChainBootstrap, GossipEnvelope, NETWORK_ID, PROTOCOL_VERSION, ProtocolHello, now_ms}, domain::{Block, ChainSnapshot, Ledger, verify_vdf}, }; @@ -99,6 +99,7 @@ pub async fn fetch_snapshot_with_announcement( other => anyhow::bail!("join peer {peer} sent {other:?} instead of peer status"), } + write_envelope(&mut writer, &join_client_hello()).await?; write_envelope(&mut writer, &GossipEnvelope::ChainBootstrapRequest).await?; let bootstrap = read_join_bootstrap_response(peer, &mut reader).await?; @@ -135,6 +136,20 @@ pub async fn fetch_snapshot_with_announcement( Ok(snapshot) } +fn join_client_hello() -> GossipEnvelope { + let setup = Ledger::new(BTreeMap::new(), 1); + GossipEnvelope::Hello(ProtocolHello { + protocol_version: PROTOCOL_VERSION, + network_id: NETWORK_ID.to_string(), + genesis_hash: setup.genesis_hash().to_string(), + listen_addr: None, + node_id: None, + height: 0, + tip_hash: setup.tip_hash().to_string(), + time_ms: now_ms(), + }) +} + async fn read_join_bootstrap_response( peer: &str, reader: &mut LimitedLineReader<OwnedReadHalf>, @@ -265,3 +280,23 @@ pub(super) async fn verify_block_vdf(block: Block) -> Result<Block> { Ok(block) } + +#[cfg(test)] +mod tests { + use super::join_client_hello; + use crate::app::{GossipEnvelope, NETWORK_ID, PROTOCOL_VERSION}; + + #[test] + fn snapshot_join_identifies_as_an_unannounced_setup_placeholder() { + let GossipEnvelope::Hello(hello) = join_client_hello() else { + panic!("join handshake must start with Hello"); + }; + + assert_eq!(hello.protocol_version, PROTOCOL_VERSION); + assert_eq!(hello.network_id, NETWORK_ID); + assert_eq!(hello.height, 0); + assert_eq!(hello.genesis_hash, hello.tip_hash); + assert!(hello.listen_addr.is_none()); + assert!(hello.node_id.is_none()); + } +} diff --git a/src/app.rs b/src/app.rs @@ -51,8 +51,8 @@ pub const PEER_MISBEHAVIOR_BAN_MS: u64 = 10 * 60 * 1_000; pub const PEER_CLOCK_OFFSET_ACCEPTANCE_MS: i64 = 10 * 60 * 1_000; const PEER_CLOCK_OFFSET_STALE_MS: u64 = 20 * 60 * 1_000; const AUTO_POW_NONCE_ATTEMPTS_PER_WORKER_TICK: u64 = 100_000; -const AUTO_PLAINTEXT_BURN_BEFORE_RECOVERY_MS: u64 = 60_000; -const BURN_BUNDLE_COLLECTION_MS: u64 = 30_000; +const AUTO_PLAINTEXT_BURN_BEFORE_RECOVERY_MS: u64 = crate::domain::VDF_TARGET_BLOCK_MS / 10; +const BURN_BUNDLE_COLLECTION_MS: u64 = crate::domain::VDF_TARGET_BLOCK_MS / 20; const MIN_AUTO_BLOCK_ANCHOR_BURN_AMOUNT: Amount = 1; static DEBUG_LOGGING: AtomicBool = AtomicBool::new(false); diff --git a/src/app/automatic_mining.rs b/src/app/automatic_mining.rs @@ -655,17 +655,26 @@ mod tests { }; use tempfile::tempdir; - use super::{NodeCore, burn_bundle_collection_remaining_ms}; + use super::{BURN_BUNDLE_COLLECTION_MS, NodeCore, burn_bundle_collection_remaining_ms}; #[test] - fn burn_bundle_collection_waits_exactly_thirty_seconds() { + fn burn_bundle_collection_waits_for_configured_window() { + let started_at_ms = 1_000; + let last_waiting_ms = started_at_ms + BURN_BUNDLE_COLLECTION_MS - 1; + let finished_ms = started_at_ms + BURN_BUNDLE_COLLECTION_MS; + + assert_eq!( + burn_bundle_collection_remaining_ms(started_at_ms, started_at_ms), + Some(BURN_BUNDLE_COLLECTION_MS) + ); + assert_eq!( + burn_bundle_collection_remaining_ms(started_at_ms, last_waiting_ms), + Some(1) + ); assert_eq!( - burn_bundle_collection_remaining_ms(1_000, 1_000), - Some(30_000) + burn_bundle_collection_remaining_ms(started_at_ms, finished_ms), + None ); - assert_eq!(burn_bundle_collection_remaining_ms(1_000, 30_999), Some(1)); - assert_eq!(burn_bundle_collection_remaining_ms(1_000, 31_000), None); - assert_eq!(burn_bundle_collection_remaining_ms(1_000, 40_000), None); } fn funded_ledger(wallets: &[Wallet]) -> Ledger { diff --git a/src/bin/iuna-e2e-checkpoint.rs b/src/bin/iuna-e2e-checkpoint.rs @@ -0,0 +1,56 @@ +use std::{env, path::PathBuf}; + +use anyhow::{Context, Result, bail}; +use iuna::adapters::{chain_store::SqliteChainStore, ui_data_store::SqliteUiDataStore}; + +fn main() -> Result<()> { + let mut args = env::args_os().skip(1); + let source = PathBuf::from(args.next().context("missing source chain database")?); + let chain_destination = + PathBuf::from(args.next().context("missing destination chain database")?); + let ui_destination = PathBuf::from(args.next().context("missing destination UI database")?); + let height = args + .next() + .context("missing checkpoint height")? + .into_string() + .map_err(|_| anyhow::anyhow!("checkpoint height is not valid UTF-8"))? + .parse::<u64>() + .context("checkpoint height is not an unsigned integer")?; + if args.next().is_some() { + bail!("usage: iuna-e2e-checkpoint SOURCE_DB CHAIN_DB UI_DB HEIGHT"); + } + for destination in [&chain_destination, &ui_destination] { + if destination.exists() { + bail!("destination already exists: {}", destination.display()); + } + } + + let source_store = SqliteChainStore::open(&source)?; + let mut snapshot = source_store + .load()? + .with_context(|| format!("source has no chain snapshot: {}", source.display()))?; + let source_height = snapshot + .blocks + .last() + .context("source chain snapshot is empty")? + .height; + if source_height < height { + bail!("source height {source_height} is below checkpoint height {height}"); + } + + snapshot.blocks.truncate( + usize::try_from(height) + .context("checkpoint height does not fit in memory")? + .checked_add(1) + .context("checkpoint height overflow")?, + ); + SqliteChainStore::open(&chain_destination)?.save(&snapshot)?; + SqliteUiDataStore::open(&ui_destination)?.project_snapshot(&snapshot, false)?; + + let tip = snapshot.blocks.last().context("checkpoint is empty")?; + println!( + "materialized height {} ({}) from source height {}", + tip.height, tip.hash, source_height + ); + Ok(()) +} diff --git a/src/domain/address.rs b/src/domain/address.rs @@ -16,7 +16,7 @@ pub enum AddressNetwork { impl AddressNetwork { pub fn from_profile_id(profile_id: &str) -> Self { - if profile_id == "iuna-local-testnet-v1" { + if matches!(profile_id, "iuna-local-testnet-v1" | "iuna-local-e2e-5s-v1") { Self::Testnet } else { Self::Mainnet diff --git a/src/domain/ledger_chain.rs b/src/domain/ledger_chain.rs @@ -108,7 +108,9 @@ impl Ledger { } pub fn from_persisted_snapshot(snapshot: ChainSnapshot) -> Result<Self> { - Self::from_snapshot_at(snapshot, u64::MAX) + let verify_vdf = !(cfg!(feature = "e2e") + && snapshot.launch_profile.profile_id == LaunchProfile::local_testnet().profile_id); + Self::from_snapshot_with_vdf_policy(snapshot, verify_vdf, u64::MAX) } pub(crate) fn from_preverified_snapshot(snapshot: ChainSnapshot) -> Result<Self> { diff --git a/src/domain/profile.rs b/src/domain/profile.rs @@ -56,7 +56,7 @@ fn default_burn_lineage_maturity_heights() -> u64 { impl LaunchProfile { pub fn local_testnet() -> Self { Self { - profile_id: "iuna-local-testnet-v1".to_string(), + profile_id: local_testnet_profile_id().to_string(), burn_lineage_maturity_heights: 0, ..Self::default() } @@ -93,6 +93,16 @@ impl LaunchProfile { } } +#[cfg(not(feature = "e2e"))] +fn local_testnet_profile_id() -> &'static str { + "iuna-local-testnet-v1" +} + +#[cfg(feature = "e2e")] +fn local_testnet_profile_id() -> &'static str { + "iuna-local-e2e-5s-v1" +} + #[derive(Clone, Debug, Eq, PartialEq)] pub struct GenesisBurn { pub from: String, @@ -147,7 +157,10 @@ mod tests { fn local_testnet_profile_has_immediate_burn_lineage_eligibility() { let profile = LaunchProfile::local_testnet(); + #[cfg(not(feature = "e2e"))] assert_eq!(profile.profile_id, "iuna-local-testnet-v1"); + #[cfg(feature = "e2e")] + assert_eq!(profile.profile_id, "iuna-local-e2e-5s-v1"); assert_eq!(profile.burn_lineage_maturity_heights, 0); assert_ne!(profile.hash(), LaunchProfile::default().hash()); } diff --git a/src/domain/protocol.rs b/src/domain/protocol.rs @@ -8,7 +8,10 @@ pub const DEFAULT_MINE_FEE: Amount = MINE_FINALIZER_FEE; pub const DEFAULT_TRANSACTION_FEE: Amount = MICRO_IUNA; pub const DEFAULT_FEE_PER_BYTE: Amount = 1; pub const MAX_BLOCK_BYTES: usize = 1_000_000; +#[cfg(not(feature = "e2e"))] pub const VDF_TARGET_BLOCK_MS: u64 = 10 * 60 * 1_000; +#[cfg(feature = "e2e")] +pub const VDF_TARGET_BLOCK_MS: u64 = 5_000; pub const RECOVERY_BLOCK_DELAY_MS: u64 = VDF_TARGET_BLOCK_MS * 6; pub const MAX_VDF_ROUNDS: u64 = i64::MAX as u64; pub const MINE_DIFFICULTY_BITS: u32 = 12; @@ -58,7 +61,10 @@ mod tests { assert_eq!(MINE_REWARD, MICRO_IUNA); assert_eq!(MINE_FINALIZER_FEE, MICRO_IUNA); assert_eq!(MAX_BLOCK_BYTES, 1_000_000); + #[cfg(not(feature = "e2e"))] assert_eq!(VDF_TARGET_BLOCK_MS, 10 * 60 * 1_000); + #[cfg(feature = "e2e")] + assert_eq!(VDF_TARGET_BLOCK_MS, 5_000); assert_eq!(RECOVERY_BLOCK_DELAY_MS, 6 * VDF_TARGET_BLOCK_MS); assert_eq!(MINE_DIFFICULTY_BITS, 12); assert_eq!(MINE_ACTIONS_PER_ANCHOR_LIMIT, 2); diff --git a/src/main.rs b/src/main.rs @@ -57,6 +57,11 @@ async fn main() -> Result<()> { let Some(opts) = CliOptions::parse()? else { return Ok(()); }; + let startup_local_testnet = startup_bool_from_env(LOCAL_TESTNET_ENV)?.unwrap_or(false); + #[cfg(feature = "e2e")] + if !startup_local_testnet { + bail!("the e2e build requires {LOCAL_TESTNET_ENV}=true"); + } set_debug_logging(opts.debug); let debug_logging = opts.debug; let wallet_path = opts.wallet_path(); @@ -79,7 +84,6 @@ async fn main() -> Result<()> { let startup_automatic_burn_enabled = startup_bool_from_env(AUTOMATIC_BURN_ENABLED_ENV)?; let startup_pow_mining_enabled = startup_bool_from_env(POW_MINING_ENABLED_ENV)?; let startup_pow_mining_workers = startup_pow_mining_workers_from_env()?; - let startup_local_testnet = startup_bool_from_env(LOCAL_TESTNET_ENV)?.unwrap_or(false); let startup_setup_complete = startup_bool_from_env(SETUP_COMPLETE_ENV)?; let p2p_config_dirty = apply_cli_p2p_config_overrides(&opts, &mut ui_config); let stratum_config_dirty = apply_cli_stratum_config_overrides(&opts, &mut ui_config); diff --git a/src/main_tests.rs b/src/main_tests.rs @@ -414,7 +414,11 @@ fn setup_ledger_uses_the_requested_address_network_profile() { ); assert_eq!( setup_ledger(true).launch_profile().profile_id, - "iuna-local-testnet-v1" + if cfg!(feature = "e2e") { + "iuna-local-e2e-5s-v1" + } else { + "iuna-local-testnet-v1" + } ); } @@ -869,13 +873,17 @@ fn genesis_requires_fresh_wallet_path() { #[test] fn vdf_measurement_extrapolates_to_target() { + let rounds_per_target = 10_000_u64.saturating_mul(VDF_TARGET_BLOCK_MS) / 1_000; + let rounds_from_zero_elapsed = 10_000_u64 + .saturating_mul(VDF_TARGET_BLOCK_MS) + .saturating_mul(1_000_000); assert_eq!( extrapolate_vdf_rounds( 10_000, Duration::from_secs(1), Duration::from_millis(VDF_TARGET_BLOCK_MS), ), - 6_000_000 + rounds_per_target ); assert_eq!( extrapolate_vdf_rounds( @@ -883,7 +891,7 @@ fn vdf_measurement_extrapolates_to_target() { Duration::from_secs(0), Duration::from_millis(VDF_TARGET_BLOCK_MS), ), - 6_000_000_000_000_000 + rounds_from_zero_elapsed ); } @@ -1081,7 +1089,7 @@ async fn startup_resumes_persisted_chain_with_network_accepted_future_tip() { let mut persisted = ledger_with_one_spendable_iuna(&persisted_wallet); let burn = persisted.build_burn(&persisted_wallet, 1, 1).unwrap(); persisted.submit_transaction(burn).unwrap(); - let future_tip_ms = iuna::app::now_ms().saturating_add(VDF_TARGET_BLOCK_MS); + let future_tip_ms = iuna::app::now_ms().saturating_add(10 * 60 * 1_000); let future_block = persisted .mine_next_block(&persisted_wallet, future_tip_ms) .unwrap();