Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
27 changes: 19 additions & 8 deletions .github/workflows/publish-prerelease.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ jobs:
# Gated: this job reads the genesis owner key, which lives only on the `releases`
# environment, so every run waits for a reviewer's approval there.
environment: releases
# Baked into the genesis registry, so it decides which networks the artifact suits.
# Job-level: five steps name the file derived from it and must not disagree.
# One genesis per TLD, since the TLD is baked into the registry: `.testnet` for previewnet,
# `.paseo` for Paseo Asset Hub Next V2. Job-level: several steps name the files it yields.
env:
DOTNS_TLD: testnet
DOTNS_TLDS: testnet paseo
steps:
# On workflow_dispatch the tag does not exist yet; the release step creates it
# from the branch this run was started on. Read through an env var rather than
Expand Down Expand Up @@ -155,7 +155,12 @@ jobs:
FOUNDRY_DISABLE_NIGHTLY_WARNING: "1"
FACTORY_DEPLOYER_KEY: ${{ secrets.FACTORY_DEPLOYER_KEY }}
DOTNS_ADMIN_KEY: ${{ secrets.DOTNS_ADMIN_KEY }}
run: bash scripts/genesis/build-genesis.sh release
run: |
for tld in $DOTNS_TLDS; do
DOTNS_TLD="$tld" bash scripts/genesis/build-genesis.sh release
done
# The address set every genesis above carries, which the builder asserted.
cp deployments/expected.json release/dotns-genesis-addresses.json

- name: Extract ABIs
run: |
Expand Down Expand Up @@ -194,7 +199,7 @@ jobs:
TAG="$RELEASE_TAG"
cd release
zip -r "../dotns-abis-${TAG}.zip" abis/ release-manifest.json codehashes.json \
"dotns-genesis-${DOTNS_TLD}.json"
dotns-genesis-*.json

- name: Generate release body
env:
Expand Down Expand Up @@ -251,7 +256,12 @@ jobs:
echo "not the previous live deployment's."
echo ""
echo "- **Release contents:** [release-manifest.json]($ASSET_BASE/release-manifest.json)"
echo "- [dotns-genesis-${DOTNS_TLD}.json]($ASSET_BASE/dotns-genesis-${DOTNS_TLD}.json) — pallet-revive genesis, \`.${DOTNS_TLD}\` TLD, for ${DOTNS_TLD} networks only."
for tld in $DOTNS_TLDS; do

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The release body names which chain each file is for. This pre-release body does not, and a wipe of Paseo Next V2 may be reading the pre-release.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

echo "- [dotns-genesis-${tld}.json]($ASSET_BASE/dotns-genesis-${tld}.json) - pallet-revive genesis, \`.${tld}\` TLD, for .${tld} networks only."
done
echo "- [dotns-genesis-addresses.json]($ASSET_BASE/dotns-genesis-addresses.json) - the addresses those genesis files carry."
echo ""
echo "Previewnet uses \`.testnet\`, Paseo Asset Hub Next V2 uses \`.paseo\`."
} >> release-body.md

- name: ABI diff since previous release
Expand Down Expand Up @@ -285,7 +295,7 @@ jobs:
release/release-manifest.json
release/codehashes.json
release/abi-diff.json
release/dotns-genesis-${{ env.DOTNS_TLD }}.json
release/dotns-genesis-*.json
body_path: release-body.md
draft: true
prerelease: true
Expand All @@ -304,7 +314,8 @@ jobs:
echo "release-manifest.json"
echo "codehashes.json"
echo "abi-diff.json"
echo "dotns-genesis-${DOTNS_TLD}.json"
echo "dotns-genesis-addresses.json"
for tld in $DOTNS_TLDS; do echo "dotns-genesis-${tld}.json"; done
} | sort > "$RUNNER_TEMP/wanted-assets.txt"
if ! diff -u "$RUNNER_TEMP/wanted-assets.txt" "$RUNNER_TEMP/actual-assets.txt"; then
echo "::error::Draft pre-release $TAG does not match the expected asset set; delete the draft and re-run."
Expand Down
29 changes: 20 additions & 9 deletions .github/workflows/publish-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ jobs:
# Gated: this job reads the genesis owner key, which lives only on the `releases`
# environment, so every run waits for a reviewer's approval there.
environment: releases
# Baked into the genesis registry, so it decides which networks the artifact suits.
# Job-level: five steps name the file derived from it and must not disagree.
# One genesis per TLD, since the TLD is baked into the registry: `.testnet` for previewnet,
# `.paseo` for Paseo Asset Hub Next V2. Job-level: several steps name the files it yields.
env:
DOTNS_TLD: testnet
DOTNS_TLDS: testnet paseo
steps:
# On workflow_dispatch the tag does not exist yet; the release step creates it
# from the branch this run was started on. Read through an env var rather than
Expand Down Expand Up @@ -151,7 +151,12 @@ jobs:
FOUNDRY_DISABLE_NIGHTLY_WARNING: "1"
FACTORY_DEPLOYER_KEY: ${{ secrets.FACTORY_DEPLOYER_KEY }}
DOTNS_ADMIN_KEY: ${{ secrets.DOTNS_ADMIN_KEY }}
run: bash scripts/genesis/build-genesis.sh release
run: |
for tld in $DOTNS_TLDS; do
DOTNS_TLD="$tld" bash scripts/genesis/build-genesis.sh release
done
# The address set every genesis above carries, which the builder asserted.
cp deployments/expected.json release/dotns-genesis-addresses.json

- name: Extract ABIs
run: |
Expand Down Expand Up @@ -188,7 +193,7 @@ jobs:
TAG="$RELEASE_TAG"
cd release
zip -r "../dotns-abis-${TAG}.zip" abis/ deployments.json release-manifest.json \
codehashes.json "dotns-genesis-${DOTNS_TLD}.json"
codehashes.json dotns-genesis-*.json

- name: Generate release body
env:
Expand Down Expand Up @@ -253,8 +258,13 @@ jobs:
echo "Pallet-revive genesis state, for a chain that should carry DotNS from block zero"
echo "rather than deploying it afterwards."
echo ""
echo "- [dotns-genesis-${DOTNS_TLD}.json]($ASSET_BASE/dotns-genesis-${DOTNS_TLD}.json) — registry initialised with the **\`.${DOTNS_TLD}\` TLD**, so it suits **${DOTNS_TLD} networks only** (this is what previewnet uses). Not for a production chain."
echo "- A chain booted from this genesis carries the fresh-deploy address set: \`deployments/expected.json\` in the repository at this tag. [deployments.json]($ASSET_BASE/deployments.json) records the live networks instead, and the two can differ where a live network has moved a contract."
for tld in $DOTNS_TLDS; do
echo "- [dotns-genesis-${tld}.json]($ASSET_BASE/dotns-genesis-${tld}.json) - registry initialised with the **\`.${tld}\` TLD**, so it suits **.${tld} networks only**. Not for a production chain."
done
echo ""
echo "Previewnet uses \`.testnet\`, Paseo Asset Hub Next V2 uses \`.paseo\`."
echo ""
echo "- [dotns-genesis-addresses.json]($ASSET_BASE/dotns-genesis-addresses.json) - the address set a chain booted from any of these genesis files carries. [deployments.json]($ASSET_BASE/deployments.json) records the live networks instead, and the two can differ where a live network has moved a contract."
} >> release-body.md

# `gh release view` with no tag resolves through /releases/latest, which skips
Expand Down Expand Up @@ -302,7 +312,7 @@ jobs:
release/release-manifest.json
release/codehashes.json
release/abi-diff.json
release/dotns-genesis-${{ env.DOTNS_TLD }}.json
release/dotns-genesis-*.json
body_path: release-body.md
draft: true
prerelease: false
Expand All @@ -322,7 +332,8 @@ jobs:
echo "release-manifest.json"
echo "codehashes.json"
echo "abi-diff.json"
echo "dotns-genesis-${DOTNS_TLD}.json"
echo "dotns-genesis-addresses.json"
for tld in $DOTNS_TLDS; do echo "dotns-genesis-${tld}.json"; done
} | sort > "$RUNNER_TEMP/wanted-assets.txt"
if ! diff -u "$RUNNER_TEMP/wanted-assets.txt" "$RUNNER_TEMP/actual-assets.txt"; then
echo "::error::Draft release $TAG does not match the expected asset set; delete the draft and re-run."
Expand Down
2 changes: 1 addition & 1 deletion DEPLOYMENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ If the deployment was intended to update a public environment, update the addres

`deployments/<network>/<chainId>.json` is a **network record**: what is deployed on that live network right now. It is updated only by a real deploy or migration on that network, never by a code change. Everything that answers for reality reads these files: releases copy their addresses verbatim, and pointing tooling or the wire stage at an address with nothing behind it breaks whatever reads it. The CREATE3 parity gates compare `expected.json` rather than these files, so the rule that a code change leaves them alone is enforced in CI instead: `release-metadata.yml` fails a pull request that edits one unless it carries the `deployment-record` label.

`deployments/expected.json` is the **expected set**: the addresses a fresh deploy of the current revision lands through the pinned CREATE3 factory. It is a property of the code, not of any network; the CI deploy job and `scripts/genesis/build-genesis.sh` verify against it, and releases never publish it.
`deployments/expected.json` is the **expected set**: the addresses a fresh deploy of the current revision lands through the pinned CREATE3 factory. It is a property of the code, not of any network; the CI deploy job and `scripts/genesis/build-genesis.sh` verify against it, and releases publish it only as `dotns-genesis-addresses.json`, the address set of their genesis files.

The expected set can legitimately disagree with a network manifest: after a code change moves an address, the expected set carries the new address while every network manifest keeps the old one until that network actually redeploys. The difference between them is the migration backlog, readable as a diff, and it is resolved per network by the event that relocates the contract: a wipe-and-redeploy on a test network, a deliberate migration on one that never wipes.

Expand Down
8 changes: 5 additions & 3 deletions RELEASE_ARTIFACTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ What each release publishes, what the files guarantee, and how to consume them.
| `release-manifest.json` | What this release contains, machine readable |
| `codehashes.json` | Stripped-metadata hash of each contract's built runtime bytecode |
| `abi-diff.json` | Selector-level ABI changes since the previous release, machine readable |
| `dotns-genesis-<tld>.json` | pallet-revive genesis with DotNS deployed, one per TLD (`testnet` for previewnet, `paseo` for Paseo Asset Hub Next V2) |
| `dotns-genesis-addresses.json` | The addresses a chain booted from those genesis files carries, a copy of `deployments/expected.json` |
| `dotns-abis-<tag>.zip` | The same files in one archive |

Every JSON asset is attached to the release individually, at the top level, with no folder. The zip holds the ABIs under `abis/` plus `deployments.json`, `release-manifest.json`, and `codehashes.json` at its root; `abi-diff.json` is generated together with the release body and attached individually.
Every JSON asset is attached to the release individually, at the top level, with no folder. The zip holds the ABIs under `abis/` plus `deployments.json`, `release-manifest.json`, `codehashes.json`, and the `dotns-genesis-*.json` files at its root; `abi-diff.json` is generated together with the release body and attached individually.

The release surface is decided in `.github/abi-contracts.txt` so a contract reaches consumers only when it is listed there.

**Pre-releases carry no addresses.** A pre-release is cut in order to be deployed, so at that point the recorded addresses still belong to the previous deployment of different code. Publishing them under that tag would break the one thing `version` is for, namely that a release's addresses and its ABIs came from the same release. A pre-release therefore ships the ABIs, `release-manifest.json`, `codehashes.json`, and `abi-diff.json`, and the addresses arrive with the release that follows the deployment. `codehashes.json` is on the pre-release deliberately: deploys run from pre-release tags, and an upgrade diffs its build against the previous release's copy before touching a live network.
**Pre-releases carry no live addresses.** A pre-release is cut in order to be deployed, so at that point the recorded addresses still belong to the previous deployment of different code. Publishing them under that tag would break the one thing `version` is for, namely that a release's addresses and its ABIs came from the same release. A pre-release therefore ships the ABIs, `release-manifest.json`, `codehashes.json`, `abi-diff.json`, and the genesis files, whose addresses are this commit's own fresh deploy; the live addresses arrive with the release that follows the deployment. `codehashes.json` is on the pre-release deliberately: deploys run from pre-release tags, and an upgrade diffs its build against the previous release's copy before touching a live network.

`deployments.json` and `release-manifest.json` were also added after this repository had already published releases, so an older release carries only the per-contract ABIs and the zip. That is expected rather than broken, and it cannot be corrected: releases here are immutable, so no asset can be attached after publication. Treat either file being missing as "this release predates it, or is a pre-release" and fall back, or pin a release you have checked.

Expand All @@ -44,7 +46,7 @@ The release surface is decided in `.github/abi-contracts.txt` so a contract reac
- One entry can serve more than one live network. `paseo-assethub` is the deployment that both previewnet and Paseo Asset Hub Next V2 run, because every network deployed through the shared CREATE3 factory lands on the same addresses. So expect entries named after deployments, not after every chain you might connect to.
- The names under `contracts` (`DotnsRegistrar`, `PopRules`) do not change, and a name always means the same contract. Your code can depend on that.
- Addresses are copied from the manifest verbatim, which the deploy pipeline writes EIP-55 checksummed. Compare them case-insensitively rather than relying on the casing.
- Only per-network manifests are published. `deployments/expected.json` — the fresh-deploy address set that CI and the genesis builder verify against (see `DEPLOYMENTS.md`) — is not a network and never appears here, so a release cut while an address move is awaiting its network's redeploy still advertises the addresses each live network actually runs.
- Only per-network manifests are published. `deployments/expected.json` — the fresh-deploy address set that CI and the genesis builder verify against (see `DEPLOYMENTS.md`) — is not a network and never appears here (it ships separately as `dotns-genesis-addresses.json`), so a release cut while an address move is awaiting its network's redeploy still advertises the addresses each live network actually runs.
- `LabelStoreBeacon` and `UserStoreBeacon` appear when deployed but are not network-stable, because the `StoreFactory` initialiser deploys them. Read them from the factory rather than pinning them.

## `release-manifest.json`
Expand Down
2 changes: 1 addition & 1 deletion deployments/previewnet/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# previewnet

The Product Preview Network's Asset Hub (`wss://previewnet.substrate.dev/asset-hub`,
ETH RPC `https://previewnet.substrate.dev/eth-rpc`), TLD `.dot`. Deployed from a v0.8.0
ETH RPC `https://previewnet.substrate.dev/eth-rpc`), TLD `.testnet`. Deployed from a v0.8.0
genesis, so every address matches the fresh-deploy set in `deployments/expected.json`.

The chain id is `420420417`, the same as `paseo-assethub`: pallet-revive testnets share it,
Expand Down
4 changes: 4 additions & 0 deletions scripts/genesis/build-genesis.sh
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ forge clean
forge build
echo ""

# The stages extend an existing manifest, and one left by an earlier build (for another TLD)
# describes a chain this anvil never saw.
rm -f "$DEPLOYMENT_FILE"

# Deploy the Create3Factory from the single-purpose key at nonce 0 so it lands on
# the canonical address, then hand it to the stages via CREATE3_FACTORY (read by
# BaseDeployer._configuredCreate3Factory).
Expand Down
Loading