Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
119 commits
Select commit Hold shift + click to select a range
d5bf5ea
perf(fastsync): stop duplicating the header-id list; reuse the refres…
mwaddip Aug 11, 2026
db05894
feat(api): add launchTime/maxPeerHeight to /info; report real chain m…
mwaddip Aug 11, 2026
88f47b2
fix: let jemalloc return freed pages (background_thread + decay)
mwaddip Aug 11, 2026
fe99924
chore: enable redb cache_metrics so cache occupancy is observable
mwaddip Aug 11, 2026
3b5f74f
docs: contract for redb cache budget and cache observability
mwaddip Aug 11, 2026
88f8f8d
docs: record that an in-place redb cache resize moves only 90% of the…
mwaddip Aug 11, 2026
21936da
feat: redb cache budget split across both databases, reported in /deb…
mwaddip Aug 11, 2026
b94ab83
docs: cache_mb semantics change, eviction-vs-occupancy, allocator ove…
mwaddip Aug 11, 2026
caad369
docs: the deferred-eval queue is unbounded in aggregate; specify inst…
mwaddip Aug 12, 2026
ed17e62
docs: journal-events entry for deferred_eval_backlog; correct its hei…
mwaddip Aug 12, 2026
e52e88f
docs: script_verified_height freezes on the first out-of-order eval r…
mwaddip Aug 12, 2026
036a3eb
feat(sync): instrument the deferred-eval backlog; characterize the fr…
mwaddip Aug 12, 2026
aa0a8b9
docs(contracts): specify eval backpressure; correct the DeferredEval …
mwaddip Aug 12, 2026
cdd15d1
feat(validation): weigh a DeferredEval at construction
mwaddip Aug 12, 2026
0589965
feat(sync): bound the deferred-eval queue; fix the frozen script wate…
mwaddip Aug 12, 2026
65e47b4
docs(contracts): fix two journal markers; forbid prefix-colliding mar…
mwaddip Aug 12, 2026
766f0e4
docs(contracts): floor script_verified_height at checkpoint_height
mwaddip Aug 12, 2026
3685f8e
test(journal): drive real emit sites; check the contract's own rules
mwaddip Aug 12, 2026
758eae3
docs(contracts): specify how checkpoint_height reaches sync
mwaddip Aug 12, 2026
9f23c37
feat(sync): floor script_verified_height at the validator's checkpoint
mwaddip Aug 12, 2026
5900ef2
fix: forward resize_cache through the Validator wrapper
mwaddip Aug 12, 2026
8745ddb
docs(contracts): specify inline script evaluation as a mode
mwaddip Aug 12, 2026
e788b41
feat(validation): inline script evaluation as a selectable mode
mwaddip Aug 12, 2026
62e66f6
docs(contracts): correct the inline-eval spec against what shipped
mwaddip Aug 12, 2026
498dcae
feat(sync): honour ScriptEvalMode; advance the frontier under inline
mwaddip Aug 12, 2026
da6e5d0
test(validation): pass ScriptEvalMode at the integration-test call sites
mwaddip Aug 12, 2026
b06e652
build(deps): bump the ergo_avltree_rust fork to b955790
mwaddip Aug 12, 2026
6349d71
docs(contracts): the rewind fix landed upstream, and it binds state/
mwaddip Aug 12, 2026
23de215
refactor(validation): drop the local modified_nodes clear, it moved u…
mwaddip Aug 12, 2026
bf45b9e
docs(contracts): split BlockValidator into three traits for v0.8.0
mwaddip Aug 13, 2026
eafb49f
refactor(validation): add StatePersistence and MiningState, unconsumed
mwaddip Aug 13, 2026
d4b3243
docs(contracts): state_persistence belongs on the trait, not the wrapper
mwaddip Aug 13, 2026
fe26559
refactor(validation): add state_persistence() to BlockValidator
mwaddip Aug 13, 2026
2bf9853
feat(main): step B of the trait split — wrapper accessors
mwaddip Aug 13, 2026
c5aebf7
docs(contracts): digest-mode flush is not the no-validator case
mwaddip Aug 13, 2026
fb7675e
refactor(sync): step C of the trait split — flush via state_persisten…
mwaddip Aug 13, 2026
5008fc9
feat(main): step D of the trait split — mining via the accessor, forw…
mwaddip Aug 13, 2026
78840a8
refactor(validation): step E of the trait split — the staging default…
mwaddip Aug 13, 2026
229da2b
docs(contracts): drop the staging note, the split is complete
mwaddip Aug 13, 2026
5618c54
chore(main): delete an orphaned doc comment above locate_config
mwaddip Aug 13, 2026
265d593
fix(main): remove the SyncConfig fallthrough so field 25 fails to com…
mwaddip Aug 13, 2026
b195fa0
docs(contracts): remove deferred script evaluation from the spec
mwaddip Aug 13, 2026
a275f6f
refactor(validation): remove deferred script evaluation
mwaddip Aug 13, 2026
d90f487
refactor(sync): remove the deferred script-eval machinery
mwaddip Aug 13, 2026
82765d2
feat(main): remove deferred script evaluation — the workspace builds …
mwaddip Aug 13, 2026
5706fbf
docs(contracts): journal events 2.0 — the deferred-eval events are gone
mwaddip Aug 13, 2026
0477774
chore(api): advertise journal-events contract 2.0
mwaddip Aug 13, 2026
c3277d8
docs(contracts): validation_stuck classifies on the variant, not the …
mwaddip Aug 13, 2026
ceaadbb
fix(sync): classify apply_state errors on the variant, not the Displa…
mwaddip Aug 13, 2026
1bad285
docs(contracts): missing_key comes through two variants and means two…
mwaddip Aug 13, 2026
048b6da
chore: release v0.8.0
mwaddip Aug 13, 2026
04cb02d
docs(readme): correct two stale claims and stop hand-maintaining PR l…
mwaddip Aug 13, 2026
f33c22b
docs: sweep the ecosystem inventory against reality
mwaddip Aug 13, 2026
1471acc
docs: drop ergo-proxy-node from the inventory, record why the relay died
mwaddip Aug 13, 2026
fda6efe
feat(main): the node sizes its own memory from its cgroup limit
mwaddip Aug 13, 2026
e52ecae
chore(api): advertise journal-events contract 2.1
mwaddip Aug 13, 2026
94cfd24
docs: the release ships journal-events 2.1, not 2.0
mwaddip Aug 13, 2026
5970220
docs(contracts): fix the selection step order, and rule out a cost sa…
mwaddip Aug 13, 2026
5efb055
fix(mining): bound candidate selection by cost, not size alone
mwaddip Aug 13, 2026
f0517e7
docs: mining candidates are emission-only, and nothing said so
mwaddip Aug 13, 2026
7bc731a
test(main): pin the Validator wrapper's delegation, both arms
mwaddip Aug 13, 2026
760d6bf
docs(contracts): generate_candidate is the only entry point, and it w…
mwaddip Aug 13, 2026
6beeb4a
fix(mining): regenerate the candidate on TTL expiry, not only on a ne…
mwaddip Aug 13, 2026
a85ea9b
feat(mining): assemble a real block in generate_candidate, fee tx inc…
mwaddip Aug 13, 2026
8132e6f
docs(contracts): record what a85ea9b surfaced — context window, confl…
mwaddip Aug 13, 2026
500da61
docs(contracts): SnapshotReader gains resolver() and root_state()
mwaddip Aug 13, 2026
8f25787
feat(state): SnapshotReader gains resolver() and root_state()
mwaddip Aug 13, 2026
1d238e0
docs(contracts): proofs_from_storage — AD proofs without a validator
mwaddip Aug 13, 2026
c95dd9e
feat(validation): proofs_from_storage — AD proofs without a validator
mwaddip Aug 13, 2026
48c386f
docs(contracts): a missing root reports one error, not two
mwaddip Aug 13, 2026
3aecc7f
feat(main): mining assembles real blocks — generate_candidate is now …
mwaddip Aug 13, 2026
37719cc
feat(mining): bound size over the section, cap fee tokens
mwaddip Aug 13, 2026
620268e
docs(contracts): the fee-token cap was wrong twice, and the overhead …
mwaddip Aug 13, 2026
ee61b7f
feat(mining): the fee-token cap is the box, not the count
mwaddip Aug 13, 2026
25ae762
docs(contracts): the fee box holds 121 tokens, not 122 — measure out.…
mwaddip Aug 13, 2026
2fa41d3
docs: mining is Done — verified at runtime, not just compiled
mwaddip Aug 13, 2026
34dff03
fix(main): make the config actually reject unknown keys
mwaddip Aug 13, 2026
65e0b9f
docs(contracts): unresolvable inputs are skipped, and that includes d…
mwaddip Aug 13, 2026
ff7d754
fix(mining): an unresolvable data input skips the tx, it does not evi…
mwaddip Aug 13, 2026
e0d438b
style: first workspace-wide rustfmt pass
mwaddip Aug 13, 2026
abf9fff
ci: gate formatting, and release when a release/* PR merges
mwaddip Aug 13, 2026
b47df79
docs(contracts): mempool must validate against an upcoming preheader
mwaddip Aug 13, 2026
d39fe07
docs(contracts): fee is an output to the fee proposition, not a remai…
mwaddip Aug 13, 2026
3cb4a9d
feat(validation): build_upcoming_state_context for unconfirmed transa…
mwaddip Aug 13, 2026
d11d97e
fix(mempool): a creation height above the preheader is transient, not…
mwaddip Aug 13, 2026
8a31352
fix: publish the upcoming state context to the mempool and API
mwaddip Aug 13, 2026
d181cc4
fix(mempool): read the fee from the fee-proposition output
mwaddip Aug 13, 2026
d98dcf4
docs(changelog): record the three mempool fixes
mwaddip Aug 13, 2026
716e946
docs(contracts): the in-place read-cache limit binds on a warm cache
mwaddip Aug 13, 2026
88c3fc4
docs(contracts): attribute the prover and sync window in /debug/memory
mwaddip Aug 14, 2026
c90a62e
docs(contracts): openapi lists the three published memory fields
mwaddip Aug 14, 2026
ba29cfb
feat(api): publish prover and sync-window bytes on /debug/memory
mwaddip Aug 14, 2026
db71cd1
feat(validation): measure the prover, and find what actually grows
mwaddip Aug 14, 2026
8a897da
docs(contracts): the sync window is exonerated; settle the gauge type
mwaddip Aug 14, 2026
be2dc6e
refactor(api): PublishedGauge is a view over shared storage
mwaddip Aug 14, 2026
66c82dd
feat: wire the prover and sync-window memory gauges
mwaddip Aug 14, 2026
0afc132
docs(contracts): name the prover gauge interval instead of a flush ca…
mwaddip Aug 14, 2026
efa39af
feat(sync): report delivery-tracker memory, and clear the window as a…
mwaddip Aug 14, 2026
64f8a77
fix: the prover gauge needs a wall-clock trigger, not just a block count
mwaddip Aug 14, 2026
b4e954e
docs(contracts): retract the resolution-leak finding — it was wrong
mwaddip Aug 14, 2026
498a538
docs(contracts): b is the target, not the difficulty
mwaddip Aug 15, 2026
c551eb5
feat(pow): give the Autolykos target a name so it can't be re-derived…
mwaddip Aug 15, 2026
e77959d
docs(openapi): MiningCandidate.b is a number, and it is the target
mwaddip Aug 15, 2026
4d63efa
fix(mining): serve the target as b, not the difficulty
mwaddip Aug 15, 2026
e5e43df
chore: record ergo-mining's enr-chain dependency in the lockfile
mwaddip Aug 15, 2026
7bb6557
docs(contracts): the b defect is not a v0.8.0 regression — it is all …
mwaddip Aug 15, 2026
76563e4
docs(changelog): record the mining target defect for v0.8.0
mwaddip Aug 15, 2026
7a905d2
docs(contracts): layered conf.d config, and a startup memory floor
mwaddip Aug 15, 2026
1987ea5
feat(config): parse from a TOML document, not just a path
mwaddip Aug 15, 2026
2a29352
style(frame): give the MAX_BODY_SIZE buffering note its own paragraph
mwaddip Aug 15, 2026
1273fec
feat(config): layered conf.d loading, and a startup memory floor
mwaddip Aug 15, 2026
647bc67
fix(man): regenerate ergo-node-rust.8 — it still had the inverted API…
mwaddip Aug 15, 2026
5e5e96c
feat(deb): debconf first-install interview over a layered conf.d
mwaddip Aug 15, 2026
dccbfb1
chore: member crates inherit the workspace version instead of pinning…
mwaddip Aug 15, 2026
632ba95
docs(contracts): derived validator state must be recovered on resume
mwaddip Aug 15, 2026
71fa26a
fix(deb): three interview defects found by actually running it
mwaddip Aug 15, 2026
19083a8
fix(validation): recover emission_box_id at construction, not on firs…
mwaddip Aug 15, 2026
48c05e3
fix: seed the mining proof cache at startup, and pass an EmissionSource
mwaddip Aug 15, 2026
cc9b750
docs(release): complete the v0.8.0 entry, and give the release page a…
mwaddip Aug 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .github/workflows/fmt.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: fmt

# Gate formatting on every push and PR.
#
# Added 2026-08-13 with the first workspace-wide `cargo fmt` pass. Before that
# nothing enforced formatting and 831 diffs had accumulated across every crate —
# drift that is invisible until someone runs the command, and then arrives as a
# 90-file diff on top of whatever they were actually doing.
#
# Formatting only. Tests and clippy are deliberately NOT gated here: the
# workspace carries a pre-existing enr-p2p doc-lint that would fail a strict
# clippy gate on day one, and a test job needs submodules plus the sigma-rust
# git dependencies, which is a slower and separate decision. A gate that fails
# for reasons unrelated to the change gets ignored, and an ignored gate is worse
# than none.

on:
pull_request:
push:
branches: [main]

permissions:
contents: read

jobs:
rustfmt:
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v5
# No `submodules:` — chain/, p2p/, state/ and store/ were absorbed into
# this repo in 35802a8 and are ordinary directories now. release.yml
# still passes submodules: true, which is a harmless no-op there.

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt

- name: Check workspace formatting
run: cargo fmt --all --check

# The addons are `exclude`d from the workspace with their own lockfiles,
# so `--all` above does not reach them. They were formatted in the same
# pass and are checked explicitly here — otherwise they are exactly the
# code that drifts again, being the part no workspace command touches.
- name: Check addon formatting
run: |
cargo fmt --manifest-path addons/fastsync/Cargo.toml --all --check
cargo fmt --manifest-path addons/indexer/Cargo.toml --all --check
79 changes: 77 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,37 @@ name: release
# and attaches both to a GitHub Release for the tag.

on:
# Two ways in, and they must stay equivalent.
push:
tags:
- 'v*'
# Merging a release/* PR into main releases what was merged. The tag is
# created by this workflow rather than by hand, so the tag and the merge
# cannot disagree about what shipped.
pull_request:
types: [closed]

permissions:
contents: write # required for creating the release + uploading assets
contents: write # release + asset upload, and the tag push on the merge path

jobs:
build-and-release:
runs-on: ubuntu-24.04
# A closed PR is not a merged one, and only release/* branches release.
# Without this the job would run on every closed PR, including abandoned
# ones.
if: >-
github.event_name == 'push' ||
(github.event.pull_request.merged == true &&
startsWith(github.event.pull_request.head.ref, 'release/'))

steps:
- name: Checkout (with submodules)
uses: actions/checkout@v5
with:
# On the merge path the PR ref is gone; take main, which now
# contains the merge commit.
ref: ${{ github.event_name == 'pull_request' && 'main' || github.ref }}
# Top-level submodules only — fetches chain, p2p, state, store,
# facts but NOT their nested facts/ pointers. The nested
# facts/ submodules are docs read by per-submodule Claude
Expand All @@ -29,6 +45,65 @@ jobs:
submodules: true
fetch-depth: 0

# Resolves to the pushed tag on the tag path, or creates one from
# Cargo.toml on the merge path. Everything downstream reads
# steps.tag.outputs.name and does not care which path it came from.
- name: Resolve release tag
id: tag
run: |
set -euo pipefail
if [ "${{ github.event_name }}" = "push" ]; then
echo "name=${GITHUB_REF_NAME}" >> "$GITHUB_OUTPUT"
exit 0
fi
# Read the literal out of [workspace.package] — the one place it
# exists, since every member inherits it via version.workspace.
# Scoped to the section rather than "first ^version line": that was
# correct only by accident of section ordering, and this is the step
# that decides what gets tagged.
version=$(awk '
/^\[workspace\.package\]/ { in_section = 1; next }
/^\[/ { in_section = 0 }
in_section && /^version[[:space:]]*=/ {
match($0, /"[^"]*"/)
print substr($0, RSTART + 1, RLENGTH - 2)
exit
}
' Cargo.toml)
if ! printf '%s' "$version" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+'; then
echo "::error::could not read a version from [workspace.package] in Cargo.toml (got '${version}')"
exit 1
fi
tag="v${version}"
if git rev-parse -q --verify "refs/tags/${tag}" >/dev/null; then
echo "::error::tag ${tag} already exists — bump the workspace version before merging a release branch"
exit 1
fi
# Annotated, with the CHANGELOG section as the message: the release
# body is sourced from the annotation further down, and a lightweight
# tag would leave it empty.
#
# Prefer the release's "### Release summary" subsection: one line per
# change, no reasoning, which is what belongs on a release page. The
# rest of the CHANGELOG entry is the durable record and reads as a
# wall of text there.
#
# Falls back to the whole section when that subsection is absent, so
# re-tagging any older release still produces the body it always did.
section=$(awk -v v="## ${tag}" '$0 ~ "^" v {f=1; next} /^## v/ {f=0} f' CHANGELOG.md)
notes=$(printf '%s\n' "$section" | awk '
/^### Release summary/ { f=1; next }
/^### / { f=0 }
f
' | sed '/^$/d')
[ -z "$notes" ] && notes="$section"
[ -z "$notes" ] && notes="Release ${tag}"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag -a "${tag}" -m "${notes}"
git push origin "${tag}"
echo "name=${tag}" >> "$GITHUB_OUTPUT"

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable

Expand Down Expand Up @@ -81,7 +156,7 @@ jobs:
git fetch --tags --force
{
echo 'body<<EOF_TAG_BODY'
git tag -l --format='%(contents)' "${GITHUB_REF_NAME}"
git tag -l --format='%(contents)' "${{ steps.tag.outputs.name }}"
echo 'EOF_TAG_BODY'
} >> "$GITHUB_OUTPUT"

Expand Down
Loading
Loading